mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
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:
parent
c164cb80c8
commit
796d0133bf
2 changed files with 59 additions and 5 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue