Add function to import block and track memory region

Make a new function that we can use to track mappings of imported
memory.
This commit is contained in:
Wim Taymans 2019-07-29 17:06:07 +02:00
parent c164cb80c8
commit 796d0133bf
2 changed files with 59 additions and 5 deletions

View file

@ -115,6 +115,7 @@ struct mapping {
int ref;
uint32_t offset;
uint32_t size;
unsigned int do_unmap:1;
struct spa_list link;
void *ptr;
};
@ -271,10 +272,11 @@ static struct mapping * memblock_map(struct memblock *b,
prot |= PROT_WRITE;
if (flags & PW_MEMMAP_FLAG_TWICE) {
errno = -ENOTSUP;
errno = ENOTSUP;
return NULL;
}
ptr = mmap(NULL, size, prot, MAP_SHARED, b->this.fd, offset);
if (ptr == MAP_FAILED) {
pw_log_error("pool %p: Failed to mmap memory fd:%d offset:%u size:%u: %m",
@ -288,6 +290,7 @@ static struct mapping * memblock_map(struct memblock *b,
return NULL;
}
m->ptr = ptr;
m->do_unmap = true;
m->block = b;
m->offset = offset;
m->size = size;
@ -305,9 +308,11 @@ static void mapping_unmap(struct mapping *m)
struct memblock *b = m->block;
struct mempool *p = SPA_CONTAINER_OF(b->this.pool, struct mempool, this);
pw_log_debug("pool %p: mapping:%p fd:%d ptr:%p size:%d", p, m, b->this.fd, m->ptr, m->size);
pw_log_debug("pool %p: mapping:%p fd:%d ptr:%p size:%d block-ref:%d",
p, m, b->this.fd, m->ptr, m->size, b->this.ref);
munmap(m->ptr, m->size);
if (m->do_unmap)
munmap(m->ptr, m->size);
spa_list_remove(&m->link);
free(m);
@ -416,6 +421,8 @@ struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, enum pw_memblock_
b->this.ref = 1;
b->this.pool = pool;
b->this.flags = flags;
b->this.type = type;
b->this.size = size;
spa_list_init(&b->mappings);
spa_list_init(&b->maps);
@ -450,8 +457,6 @@ struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, enum pw_memblock_
}
}
#endif
b->this.type = type;
if (flags & PW_MEMBLOCK_FLAG_MAP && size > 0) {
enum pw_memmap_flags fl = 0;
@ -545,6 +550,52 @@ struct pw_memblock * pw_mempool_import_block(struct pw_mempool *pool,
mem->type, mem->fd);
}
SPA_EXPORT
struct pw_memmap * pw_mempool_import_map(struct pw_mempool *pool,
struct pw_mempool *other, void *data, uint32_t size, uint32_t tag[5])
{
struct pw_memblock *old, *block;
struct memblock *b;
struct pw_memmap *map;
struct mapping *m;
uint32_t offset;
old = pw_mempool_find_ptr(other, data);
if (old == NULL || old->map == NULL) {
errno = EFAULT;
return NULL;
}
block = pw_mempool_import_block(pool, old);
if (block == NULL)
return NULL;
if (block->ref == 1) {
b = SPA_CONTAINER_OF(block, struct memblock, this);
m = calloc(1, sizeof(struct mapping));
if (m == NULL) {
pw_memblock_unref(block);
return NULL;
}
m->ptr = old->map->ptr;
m->block = b;
m->offset = old->map->offset;
m->size = old->map->size;
spa_list_append(&b->mappings, &m->link);
} else {
block->ref--;
}
offset = SPA_PTRDIFF(data, old->map->ptr);
map = pw_memblock_map(block, block->flags, offset, size, tag);
if (map == NULL)
return NULL;
return map;
}
int pw_mempool_unref_id(struct pw_mempool *pool, uint32_t id)
{

View file

@ -153,6 +153,9 @@ struct pw_memmap * pw_mempool_map_id(struct pw_mempool *pool, uint32_t id,
enum pw_memmap_flags flags, uint32_t offset, uint32_t size,
uint32_t tag[5]);
struct pw_memmap * pw_mempool_import_map(struct pw_mempool *pool,
struct pw_mempool *other, void *data, uint32_t size, uint32_t tag[5]);
/** find a map with the given tag */
struct pw_memmap * pw_mempool_find_tag(struct pw_mempool *pool, uint32_t tag[5]);