diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-07-24 10:33:26 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-07-24 10:33:26 +0200 |
commit | bae142661561aeca334957866b1254a050d66bcf (patch) | |
tree | 7f0839c482390a32a9ad333d86cd4aa20bc2dfef | |
parent | 2caf81c97c0aee3ac67f80233decbcfb830979e4 (diff) |
mem: use MemId to pass buffer memory
Track memory on buffers in the server and simplify some memory tracking
on the client.
Don't send internal memblock flags to client.
Add read/write flags to memblock.
-rw-r--r-- | spa/include/spa/buffer/buffer.h | 1 | ||||
-rw-r--r-- | src/modules/module-client-node/client-node.c | 15 | ||||
-rw-r--r-- | src/modules/module-client-node/remote-node.c | 23 | ||||
-rw-r--r-- | src/pipewire/client.c | 6 | ||||
-rw-r--r-- | src/pipewire/mem.c | 3 | ||||
-rw-r--r-- | src/pipewire/mem.h | 11 |
6 files changed, 30 insertions, 29 deletions
diff --git a/spa/include/spa/buffer/buffer.h b/spa/include/spa/buffer/buffer.h index 65223ada..1a123ba8 100644 --- a/spa/include/spa/buffer/buffer.h +++ b/spa/include/spa/buffer/buffer.h @@ -43,6 +43,7 @@ enum spa_data_type { * struct spa_data is set. */ SPA_DATA_MemFd, /**< generic fd, mmap to get to memory */ SPA_DATA_DmaBuf, /**< fd to dmabuf memory */ + SPA_DATA_MemId, /**< memory is identified with an id */ SPA_DATA_LAST, /**< not part of ABI */ }; diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 87c2ea5b..ba62058a 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -74,6 +74,7 @@ struct buffer { struct spa_buffer buffer; struct spa_meta metas[4]; struct spa_data datas[4]; + struct pw_memblock *mem; }; struct mix { @@ -235,9 +236,6 @@ static int clear_buffers(struct node *this, struct mix *mix) uint32_t i, j; struct impl *impl = this->impl; - if (this->resource == NULL) - return 0; - for (i = 0; i < mix->n_buffers; i++) { struct buffer *b = &mix->buffers[i]; struct pw_memblock *m; @@ -247,16 +245,18 @@ static int clear_buffers(struct node *this, struct mix *mix) for (j = 0; j < b->buffer.n_datas; j++) { struct spa_data *d = &b->datas[j]; - if (d->type == SPA_DATA_DmaBuf || - d->type == SPA_DATA_MemFd) { + if (d->type == SPA_DATA_MemId) { uint32_t id; id = SPA_PTR_TO_UINT32(b->buffer.datas[j].data); m = pw_mempool_find_id(this->resource->client->pool, id); - if (m) + if (m) { pw_log_debug(NAME " %p: mem %d", impl, m->id); + pw_memblock_unref(m); + } } } + pw_memblock_unref(b->mem); } mix->n_buffers = 0; return 0; @@ -766,6 +766,8 @@ do_port_use_buffers(struct impl *impl, if (m == NULL) return -errno; + b->mem = m; + mb[i].buffer = &b->buffer; mb[i].mem_id = m->id; mb[i].offset = SPA_PTRDIFF(baseptr, SPA_MEMBER(mem->map->ptr, 0, void)); @@ -788,6 +790,7 @@ do_port_use_buffers(struct impl *impl, d->type, d->fd, d->flags); if (m == NULL) return -errno; + b->buffer.datas[j].type = SPA_DATA_MemId; b->buffer.datas[j].data = SPA_UINT32_TO_PTR(m->id); } else if (d->type == SPA_DATA_MemPtr) { spa_log_debug(this->log, "mem %d %zd", j, SPA_PTRDIFF(d->data, baseptr)); diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index fe9d941b..0f1532b2 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -48,8 +48,7 @@ struct buffer { uint32_t id; struct spa_buffer *buf; - struct pw_memmap **mem; - uint32_t n_mem; + struct pw_memmap *mem; }; struct io { @@ -534,7 +533,6 @@ static int clear_buffers(struct node_data *data, struct mix *mix) { struct pw_port *port = mix->port; struct buffer *b; - uint32_t i; int res; pw_log_debug("port %p: clear buffers %d", port, mix->mix_id); @@ -544,12 +542,9 @@ static int clear_buffers(struct node_data *data, struct mix *mix) } pw_array_for_each(b, &mix->buffers) { - for (i = 0; i < b->n_mem; i++) { - pw_log_debug("port %p: clear buffer %d map %p", - port, b->id, b->mem[i]); - pw_memmap_free(b->mem[i]); - } - b->n_mem = 0; + pw_log_debug("port %p: clear buffer %d map %p", + port, b->id, b->mem); + pw_memmap_free(b->mem); free(b->buf); } mix->buffers.size = 0; @@ -639,19 +634,17 @@ client_node_port_use_buffers(void *object, goto error_exit_cleanup; } bid->id = i; + bid->mem = mm; if (mlock(mm->ptr, mm->size) < 0) pw_log_warn("Failed to mlock memory %p %u: %m", mm->ptr, mm->size); size = sizeof(struct spa_buffer); - size += sizeof(struct pw_memmap *); for (j = 0; j < buffers[i].buffer->n_metas; j++) size += sizeof(struct spa_meta); - for (j = 0; j < buffers[i].buffer->n_datas; j++) { + for (j = 0; j < buffers[i].buffer->n_datas; j++) size += sizeof(struct spa_data); - size += sizeof(struct pw_memmap *); - } b = bid->buf = malloc(size); if (b == NULL) { @@ -663,10 +656,6 @@ client_node_port_use_buffers(void *object, b->metas = SPA_MEMBER(b, sizeof(struct spa_buffer), struct spa_meta); b->datas = SPA_MEMBER(b->metas, sizeof(struct spa_meta) * b->n_metas, struct spa_data); - bid->mem = SPA_MEMBER(b->datas, sizeof(struct spa_data) * b->n_datas, - struct pw_memmap *); - bid->n_mem = 0; - bid->mem[bid->n_mem++] = mm; pw_log_debug("add buffer %d %d %u %u", mm->block->id, bid->id, buffers[i].offset, buffers[i].size); diff --git a/src/pipewire/client.c b/src/pipewire/client.c index 716ef7e0..536a92a0 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -228,9 +228,11 @@ static void pool_added(void *data, struct pw_memblock *block) { struct impl *impl = data; struct pw_client *client = &impl->this; - if (client->core_resource) + if (client->core_resource) { pw_core_resource_add_mem(client->core_resource, - block->id, block->type, block->fd, block->flags); + block->id, block->type, block->fd, + block->flags & PW_MEMBLOCK_FLAG_READWRITE); + } } static void pool_removed(void *data, struct pw_memblock *block) diff --git a/src/pipewire/mem.c b/src/pipewire/mem.c index 20ea03bc..fa1d7e5d 100644 --- a/src/pipewire/mem.c +++ b/src/pipewire/mem.c @@ -376,10 +376,11 @@ int pw_memmap_free(struct pw_memmap *map) pw_log_debug("pool %p: map:%p fd:%d ptr:%p map:%p ref:%d", p, &mm->this, b->this.fd, mm->this.ptr, m, m->ref); + spa_list_remove(&mm->link); + if (--m->ref == 0) mapping_unmap(m); - spa_list_remove(&mm->link); free(mm); return 0; diff --git a/src/pipewire/mem.h b/src/pipewire/mem.h index f93148d2..2bb61e83 100644 --- a/src/pipewire/mem.h +++ b/src/pipewire/mem.h @@ -34,9 +34,13 @@ extern "C" { /** Flags passed to \ref pw_mempool_alloc() \memberof pw_memblock */ enum pw_memblock_flags { PW_MEMBLOCK_FLAG_NONE = 0, - PW_MEMBLOCK_FLAG_SEAL = (1 << 0), - PW_MEMBLOCK_FLAG_MAP = (1 << 1), - PW_MEMBLOCK_FLAG_DONT_CLOSE = (1 << 2), + PW_MEMBLOCK_FLAG_READABLE = (1 << 0), + PW_MEMBLOCK_FLAG_WRITABLE = (1 << 1), + PW_MEMBLOCK_FLAG_SEAL = (1 << 2), + PW_MEMBLOCK_FLAG_MAP = (1 << 3), + PW_MEMBLOCK_FLAG_DONT_CLOSE = (1 << 4), + + PW_MEMBLOCK_FLAG_READWRITE = PW_MEMBLOCK_FLAG_READABLE | PW_MEMBLOCK_FLAG_WRITABLE, }; enum pw_memmap_flags { @@ -45,6 +49,7 @@ enum pw_memmap_flags { PW_MEMMAP_FLAG_WRITE = (1 << 1), /**< map in write mode */ PW_MEMMAP_FLAG_TWICE = (1 << 2), /**< map the same area twice afer eachother, * creating a circular ringbuffer */ + PW_MEMMAP_FLAG_READWRITE = PW_MEMMAP_FLAG_READ | PW_MEMMAP_FLAG_WRITE, }; struct pw_memchunk; |