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.
This commit is contained in:
Wim Taymans 2019-07-24 10:33:26 +02:00
parent 2caf81c97c
commit bae1426615
6 changed files with 30 additions and 29 deletions

View file

@ -43,6 +43,7 @@ enum spa_data_type {
* struct spa_data is set. */ * struct spa_data is set. */
SPA_DATA_MemFd, /**< generic fd, mmap to get to memory */ SPA_DATA_MemFd, /**< generic fd, mmap to get to memory */
SPA_DATA_DmaBuf, /**< fd to dmabuf memory */ SPA_DATA_DmaBuf, /**< fd to dmabuf memory */
SPA_DATA_MemId, /**< memory is identified with an id */
SPA_DATA_LAST, /**< not part of ABI */ SPA_DATA_LAST, /**< not part of ABI */
}; };

View file

@ -74,6 +74,7 @@ struct buffer {
struct spa_buffer buffer; struct spa_buffer buffer;
struct spa_meta metas[4]; struct spa_meta metas[4];
struct spa_data datas[4]; struct spa_data datas[4];
struct pw_memblock *mem;
}; };
struct mix { struct mix {
@ -235,9 +236,6 @@ static int clear_buffers(struct node *this, struct mix *mix)
uint32_t i, j; uint32_t i, j;
struct impl *impl = this->impl; struct impl *impl = this->impl;
if (this->resource == NULL)
return 0;
for (i = 0; i < mix->n_buffers; i++) { for (i = 0; i < mix->n_buffers; i++) {
struct buffer *b = &mix->buffers[i]; struct buffer *b = &mix->buffers[i];
struct pw_memblock *m; 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++) { for (j = 0; j < b->buffer.n_datas; j++) {
struct spa_data *d = &b->datas[j]; struct spa_data *d = &b->datas[j];
if (d->type == SPA_DATA_DmaBuf || if (d->type == SPA_DATA_MemId) {
d->type == SPA_DATA_MemFd) {
uint32_t id; uint32_t id;
id = SPA_PTR_TO_UINT32(b->buffer.datas[j].data); id = SPA_PTR_TO_UINT32(b->buffer.datas[j].data);
m = pw_mempool_find_id(this->resource->client->pool, id); 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_log_debug(NAME " %p: mem %d", impl, m->id);
pw_memblock_unref(m);
}
} }
} }
pw_memblock_unref(b->mem);
} }
mix->n_buffers = 0; mix->n_buffers = 0;
return 0; return 0;
@ -766,6 +766,8 @@ do_port_use_buffers(struct impl *impl,
if (m == NULL) if (m == NULL)
return -errno; return -errno;
b->mem = m;
mb[i].buffer = &b->buffer; mb[i].buffer = &b->buffer;
mb[i].mem_id = m->id; mb[i].mem_id = m->id;
mb[i].offset = SPA_PTRDIFF(baseptr, SPA_MEMBER(mem->map->ptr, 0, void)); 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); d->type, d->fd, d->flags);
if (m == NULL) if (m == NULL)
return -errno; return -errno;
b->buffer.datas[j].type = SPA_DATA_MemId;
b->buffer.datas[j].data = SPA_UINT32_TO_PTR(m->id); b->buffer.datas[j].data = SPA_UINT32_TO_PTR(m->id);
} else if (d->type == SPA_DATA_MemPtr) { } else if (d->type == SPA_DATA_MemPtr) {
spa_log_debug(this->log, "mem %d %zd", j, SPA_PTRDIFF(d->data, baseptr)); spa_log_debug(this->log, "mem %d %zd", j, SPA_PTRDIFF(d->data, baseptr));

View file

@ -48,8 +48,7 @@
struct buffer { struct buffer {
uint32_t id; uint32_t id;
struct spa_buffer *buf; struct spa_buffer *buf;
struct pw_memmap **mem; struct pw_memmap *mem;
uint32_t n_mem;
}; };
struct io { struct io {
@ -534,7 +533,6 @@ static int clear_buffers(struct node_data *data, struct mix *mix)
{ {
struct pw_port *port = mix->port; struct pw_port *port = mix->port;
struct buffer *b; struct buffer *b;
uint32_t i;
int res; int res;
pw_log_debug("port %p: clear buffers %d", port, mix->mix_id); 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) { 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",
pw_log_debug("port %p: clear buffer %d map %p", port, b->id, b->mem);
port, b->id, b->mem[i]); pw_memmap_free(b->mem);
pw_memmap_free(b->mem[i]);
}
b->n_mem = 0;
free(b->buf); free(b->buf);
} }
mix->buffers.size = 0; mix->buffers.size = 0;
@ -639,19 +634,17 @@ client_node_port_use_buffers(void *object,
goto error_exit_cleanup; goto error_exit_cleanup;
} }
bid->id = i; bid->id = i;
bid->mem = mm;
if (mlock(mm->ptr, mm->size) < 0) if (mlock(mm->ptr, mm->size) < 0)
pw_log_warn("Failed to mlock memory %p %u: %m", pw_log_warn("Failed to mlock memory %p %u: %m",
mm->ptr, mm->size); mm->ptr, mm->size);
size = sizeof(struct spa_buffer); size = sizeof(struct spa_buffer);
size += sizeof(struct pw_memmap *);
for (j = 0; j < buffers[i].buffer->n_metas; j++) for (j = 0; j < buffers[i].buffer->n_metas; j++)
size += sizeof(struct spa_meta); 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 spa_data);
size += sizeof(struct pw_memmap *);
}
b = bid->buf = malloc(size); b = bid->buf = malloc(size);
if (b == NULL) { 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->metas = SPA_MEMBER(b, sizeof(struct spa_buffer), struct spa_meta);
b->datas = SPA_MEMBER(b->metas, sizeof(struct spa_meta) * b->n_metas, b->datas = SPA_MEMBER(b->metas, sizeof(struct spa_meta) * b->n_metas,
struct spa_data); 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, pw_log_debug("add buffer %d %d %u %u", mm->block->id,
bid->id, buffers[i].offset, buffers[i].size); bid->id, buffers[i].offset, buffers[i].size);

View file

@ -228,9 +228,11 @@ static void pool_added(void *data, struct pw_memblock *block)
{ {
struct impl *impl = data; struct impl *impl = data;
struct pw_client *client = &impl->this; struct pw_client *client = &impl->this;
if (client->core_resource) if (client->core_resource) {
pw_core_resource_add_mem(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) static void pool_removed(void *data, struct pw_memblock *block)

View file

@ -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, 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); &mm->this, b->this.fd, mm->this.ptr, m, m->ref);
spa_list_remove(&mm->link);
if (--m->ref == 0) if (--m->ref == 0)
mapping_unmap(m); mapping_unmap(m);
spa_list_remove(&mm->link);
free(mm); free(mm);
return 0; return 0;

View file

@ -34,9 +34,13 @@ extern "C" {
/** Flags passed to \ref pw_mempool_alloc() \memberof pw_memblock */ /** Flags passed to \ref pw_mempool_alloc() \memberof pw_memblock */
enum pw_memblock_flags { enum pw_memblock_flags {
PW_MEMBLOCK_FLAG_NONE = 0, PW_MEMBLOCK_FLAG_NONE = 0,
PW_MEMBLOCK_FLAG_SEAL = (1 << 0), PW_MEMBLOCK_FLAG_READABLE = (1 << 0),
PW_MEMBLOCK_FLAG_MAP = (1 << 1), PW_MEMBLOCK_FLAG_WRITABLE = (1 << 1),
PW_MEMBLOCK_FLAG_DONT_CLOSE = (1 << 2), 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 { 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_WRITE = (1 << 1), /**< map in write mode */
PW_MEMMAP_FLAG_TWICE = (1 << 2), /**< map the same area twice afer eachother, PW_MEMMAP_FLAG_TWICE = (1 << 2), /**< map the same area twice afer eachother,
* creating a circular ringbuffer */ * creating a circular ringbuffer */
PW_MEMMAP_FLAG_READWRITE = PW_MEMMAP_FLAG_READ | PW_MEMMAP_FLAG_WRITE,
}; };
struct pw_memchunk; struct pw_memchunk;