mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
client-node: remove hardcoded limit for io areas
When we run out of io_areas, just allocate another memblock and continue with the new block.
This commit is contained in:
parent
76c793128b
commit
b9cf2638b3
1 changed files with 60 additions and 26 deletions
|
|
@ -31,7 +31,8 @@ PW_LOG_TOPIC_EXTERN(mod_topic);
|
||||||
#define MAX_BUFFERS 64
|
#define MAX_BUFFERS 64
|
||||||
#define MAX_METAS 16u
|
#define MAX_METAS 16u
|
||||||
#define MAX_DATAS 64u
|
#define MAX_DATAS 64u
|
||||||
#define MAX_AREAS 2048
|
#define AREA_SIZE (4096u / sizeof(struct spa_io_buffers))
|
||||||
|
#define MAX_AREAS 32
|
||||||
|
|
||||||
#define CHECK_FREE_PORT(this,d,p) (p <= pw_map_get_size(&this->ports[d]) && !CHECK_PORT(this,d,p))
|
#define CHECK_FREE_PORT(this,d,p) (p <= pw_map_get_size(&this->ports[d]) && !CHECK_PORT(this,d,p))
|
||||||
#define CHECK_PORT(this,d,p) (pw_map_lookup(&this->ports[d], p) != NULL)
|
#define CHECK_PORT(this,d,p) (pw_map_lookup(&this->ports[d], p) != NULL)
|
||||||
|
|
@ -115,7 +116,7 @@ struct impl {
|
||||||
struct node node;
|
struct node node;
|
||||||
|
|
||||||
struct pw_map io_map;
|
struct pw_map io_map;
|
||||||
struct pw_memblock *io_areas;
|
struct pw_array io_areas;
|
||||||
|
|
||||||
struct pw_memblock *activation;
|
struct pw_memblock *activation;
|
||||||
|
|
||||||
|
|
@ -1267,6 +1268,29 @@ void pw_impl_client_node_registered(struct pw_impl_client_node *this, struct pw_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_area(struct impl *impl)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
struct pw_memblock *area;
|
||||||
|
|
||||||
|
size = sizeof(struct spa_io_buffers) * AREA_SIZE;
|
||||||
|
|
||||||
|
area = pw_mempool_alloc(impl->context->pool,
|
||||||
|
PW_MEMBLOCK_FLAG_READWRITE |
|
||||||
|
PW_MEMBLOCK_FLAG_MAP |
|
||||||
|
PW_MEMBLOCK_FLAG_SEAL,
|
||||||
|
SPA_DATA_MemFd, size);
|
||||||
|
if (area == NULL)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
pw_log_debug("%p: io area %u %p", impl,
|
||||||
|
(unsigned)pw_array_get_len(&impl->io_areas, struct pw_memblock*),
|
||||||
|
area->map->ptr);
|
||||||
|
|
||||||
|
pw_array_add_ptr(&impl->io_areas, area);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void node_initialized(void *data)
|
static void node_initialized(void *data)
|
||||||
{
|
{
|
||||||
struct impl *impl = data;
|
struct impl *impl = data;
|
||||||
|
|
@ -1274,7 +1298,6 @@ static void node_initialized(void *data)
|
||||||
struct node *node = &impl->node;
|
struct node *node = &impl->node;
|
||||||
struct pw_global *global;
|
struct pw_global *global;
|
||||||
struct spa_system *data_system = impl->node.data_system;
|
struct spa_system *data_system = impl->node.data_system;
|
||||||
size_t size;
|
|
||||||
|
|
||||||
impl->fds[0] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
|
impl->fds[0] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
|
||||||
impl->fds[1] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
|
impl->fds[1] = spa_system_eventfd_create(data_system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK);
|
||||||
|
|
@ -1286,17 +1309,8 @@ static void node_initialized(void *data)
|
||||||
spa_loop_add_source(node->data_loop, &node->data_source);
|
spa_loop_add_source(node->data_loop, &node->data_source);
|
||||||
pw_log_debug("%p: transport read-fd:%d write-fd:%d", node, impl->fds[0], impl->fds[1]);
|
pw_log_debug("%p: transport read-fd:%d write-fd:%d", node, impl->fds[0], impl->fds[1]);
|
||||||
|
|
||||||
size = sizeof(struct spa_io_buffers) * MAX_AREAS;
|
if (add_area(impl) < 0)
|
||||||
|
return;
|
||||||
impl->io_areas = pw_mempool_alloc(impl->context->pool,
|
|
||||||
PW_MEMBLOCK_FLAG_READWRITE |
|
|
||||||
PW_MEMBLOCK_FLAG_MAP |
|
|
||||||
PW_MEMBLOCK_FLAG_SEAL,
|
|
||||||
SPA_DATA_MemFd, size);
|
|
||||||
if (impl->io_areas == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pw_log_debug("%p: io areas %p", node, impl->io_areas->map->ptr);
|
|
||||||
|
|
||||||
if ((global = pw_impl_node_get_global(this->node)) != NULL)
|
if ((global = pw_impl_node_get_global(this->node)) != NULL)
|
||||||
pw_impl_client_node_registered(this, global);
|
pw_impl_client_node_registered(this, global);
|
||||||
|
|
@ -1310,6 +1324,7 @@ static void node_free(void *data)
|
||||||
struct spa_system *data_system = node->data_system;
|
struct spa_system *data_system = node->data_system;
|
||||||
uint32_t tag[5] = { impl->node_id, };
|
uint32_t tag[5] = { impl->node_id, };
|
||||||
struct pw_memmap *mm;
|
struct pw_memmap *mm;
|
||||||
|
struct pw_memblock **area;
|
||||||
|
|
||||||
this->node = NULL;
|
this->node = NULL;
|
||||||
|
|
||||||
|
|
@ -1326,8 +1341,12 @@ static void node_free(void *data)
|
||||||
|
|
||||||
if (impl->activation)
|
if (impl->activation)
|
||||||
pw_memblock_unref(impl->activation);
|
pw_memblock_unref(impl->activation);
|
||||||
if (impl->io_areas)
|
|
||||||
pw_memblock_unref(impl->io_areas);
|
pw_array_for_each(area, &impl->io_areas) {
|
||||||
|
if (*area)
|
||||||
|
pw_memblock_unref(*area);
|
||||||
|
}
|
||||||
|
pw_array_clear(&impl->io_areas);
|
||||||
|
|
||||||
pw_map_clear(&impl->node.ports[0]);
|
pw_map_clear(&impl->node.ports[0]);
|
||||||
pw_map_clear(&impl->node.ports[1]);
|
pw_map_clear(&impl->node.ports[1]);
|
||||||
|
|
@ -1345,6 +1364,8 @@ static int port_init_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
struct port *port = data;
|
struct port *port = data;
|
||||||
struct impl *impl = port->impl;
|
struct impl *impl = port->impl;
|
||||||
struct mix *m;
|
struct mix *m;
|
||||||
|
uint32_t idx, pos, len;
|
||||||
|
struct pw_memblock *area;
|
||||||
|
|
||||||
if ((m = ensure_mix(impl, port, mix->port.port_id)) == NULL)
|
if ((m = ensure_mix(impl, port, mix->port.port_id)) == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
@ -1354,22 +1375,34 @@ static int port_init_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
m->valid = false;
|
m->valid = false;
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
if (mix->id >= MAX_AREAS) {
|
|
||||||
pw_map_remove(&impl->io_map, mix->id);
|
|
||||||
m->valid = false;
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
mix->io = SPA_PTROFF(impl->io_areas->map->ptr,
|
idx = mix->id / AREA_SIZE;
|
||||||
mix->id * sizeof(struct spa_io_buffers), void);
|
pos = mix->id % AREA_SIZE;
|
||||||
|
|
||||||
|
len = pw_array_get_len(&impl->io_areas, struct pw_memblock *);
|
||||||
|
if (idx > len)
|
||||||
|
goto no_mem;
|
||||||
|
if (idx == len) {
|
||||||
|
pw_log_debug("%p: extend area idx:%u pos:%u", impl, idx, pos);
|
||||||
|
if (add_area(impl) < 0)
|
||||||
|
goto no_mem;
|
||||||
|
}
|
||||||
|
area = *pw_array_get_unchecked(&impl->io_areas, idx, struct pw_memblock*);
|
||||||
|
|
||||||
|
mix->io = SPA_PTROFF(area->map->ptr,
|
||||||
|
pos * sizeof(struct spa_io_buffers), void);
|
||||||
*mix->io = SPA_IO_BUFFERS_INIT;
|
*mix->io = SPA_IO_BUFFERS_INIT;
|
||||||
|
|
||||||
m->peer_id = mix->peer_id;
|
m->peer_id = mix->peer_id;
|
||||||
|
|
||||||
pw_log_debug("%p: init mix id:%d io:%p base:%p", impl,
|
pw_log_debug("%p: init mix id:%d io:%p base:%p", impl,
|
||||||
mix->id, mix->io, impl->io_areas->map->ptr);
|
mix->id, mix->io, area->map->ptr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
no_mem:
|
||||||
|
pw_map_remove(&impl->io_map, mix->id);
|
||||||
|
m->valid = false;
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port_release_mix(void *data, struct pw_impl_port_mix *mix)
|
static int port_release_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
|
|
@ -1379,8 +1412,8 @@ static int port_release_mix(void *data, struct pw_impl_port_mix *mix)
|
||||||
struct node *this = &impl->node;
|
struct node *this = &impl->node;
|
||||||
struct mix *m;
|
struct mix *m;
|
||||||
|
|
||||||
pw_log_debug("%p: remove mix id:%d io:%p base:%p",
|
pw_log_debug("%p: remove mix id:%d io:%p",
|
||||||
this, mix->id, mix->io, impl->io_areas->map->ptr);
|
this, mix->id, mix->io);
|
||||||
|
|
||||||
if ((m = find_mix(port, mix->port.port_id)) == NULL || !m->valid)
|
if ((m = find_mix(port, mix->port.port_id)) == NULL || !m->valid)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -1701,6 +1734,7 @@ struct pw_impl_client_node *pw_impl_client_node_new(struct pw_resource *resource
|
||||||
pw_map_init(&impl->node.ports[0], 64, 64);
|
pw_map_init(&impl->node.ports[0], 64, 64);
|
||||||
pw_map_init(&impl->node.ports[1], 64, 64);
|
pw_map_init(&impl->node.ports[1], 64, 64);
|
||||||
pw_map_init(&impl->io_map, 64, 64);
|
pw_map_init(&impl->io_map, 64, 64);
|
||||||
|
pw_array_init(&impl->io_areas, 64 * sizeof(struct pw_memblock*));
|
||||||
|
|
||||||
this->resource = resource;
|
this->resource = resource;
|
||||||
this->node = pw_spa_node_new(context,
|
this->node = pw_spa_node_new(context,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue