[pulseaudio-discuss] [PATCH v2 04/12] pulsecore: Split pa_shm mempool backend into pa_shm and pa_privatemem
Ahmed S. Darwish
darwish.07 at gmail.com
Fri Feb 12 00:12:22 UTC 2016
Mempools use "pa_shm" for their pools memory allocation. pa_shm is
then overloaded with two unrelated tasks: either allocating the pool
using posix SHM or allocating the same pool using private malloc()s.
The choice depends on system configuration and abilities.
This will not scale when a third pool memory allocation mechanism
is added (memfds) . Thus, split pa_shm responsibility into:
- pa_shm: responsible for all *shared* memory, posix and memfds
- pa_privatemem: only responsible for private memory allocations
This way, memfd support can easily be added later.
Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com>
---
src/Makefile.am | 1 +
src/pulsecore/mem.h | 9 +++
src/pulsecore/memblock.c | 68 ++++++++++++---------
src/pulsecore/privatemem.c | 78 ++++++++++++++++++++++++
src/pulsecore/privatemem.h | 35 +++++++++++
src/pulsecore/shm.c | 148 ++++++++++++++++-----------------------------
src/pulsecore/shm.h | 11 ++--
7 files changed, 220 insertions(+), 130 deletions(-)
create mode 100644 src/pulsecore/privatemem.c
create mode 100644 src/pulsecore/privatemem.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 6cb5bd7..f3a62fb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -701,6 +701,7 @@ libpulsecommon_ at PA_MAJORMINOR@_la_SOURCES = \
pulsecore/sample-util.c pulsecore/sample-util.h \
pulsecore/mem.h \
pulsecore/shm.c pulsecore/shm.h \
+ pulsecore/privatemem.c pulsecore/privatemem.h \
pulsecore/bitset.c pulsecore/bitset.h \
pulsecore/socket-client.c pulsecore/socket-client.h \
pulsecore/socket-server.c pulsecore/socket-server.h \
diff --git a/src/pulsecore/mem.h b/src/pulsecore/mem.h
index b6fdba6..d0a063c 100644
--- a/src/pulsecore/mem.h
+++ b/src/pulsecore/mem.h
@@ -24,6 +24,15 @@
#include <pulsecore/macro.h>
+/* Generic interface representing a plain memory area and its size.
+ *
+ * Different memory backends (posix SHM, private, etc.) embed this
+ * structure as their first element for polymorphic access. */
+typedef struct pa_mem {
+ void *ptr;
+ size_t size;
+} pa_mem;
+
typedef enum pa_mem_type {
PA_MEM_TYPE_SHARED_POSIX, /* Data is shared and created using POSIX shm_open() */
PA_MEM_TYPE_SHARED_MEMFD, /* Data is shared and created using Linux memfd_create() */
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index 3a33a6f..154bd67 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -36,7 +36,9 @@
#include <pulse/xmalloc.h>
#include <pulse/def.h>
+#include <pulsecore/mem.h>
#include <pulsecore/shm.h>
+#include <pulsecore/privatemem.h>
#include <pulsecore/log.h>
#include <pulsecore/hashmap.h>
#include <pulsecore/semaphore.h>
@@ -145,8 +147,14 @@ struct pa_mempool {
pa_semaphore *semaphore;
pa_mutex *mutex;
- pa_mem_type_t type;
- pa_shm memory;
+ bool shared;
+ union {
+ pa_mem memory;
+ union {
+ pa_shm shm;
+ pa_privatemem privatemem;
+ } per_type;
+ };
size_t block_size;
unsigned n_blocks;
@@ -748,11 +756,9 @@ static void memblock_replace_import(pa_memblock *b) {
pa_mempool *pa_mempool_new(pa_mem_type_t type, size_t size) {
pa_mempool *p;
- bool shared;
char t1[PA_BYTES_SNPRINT_MAX], t2[PA_BYTES_SNPRINT_MAX];
p = pa_xnew0(pa_mempool, 1);
- p->type = type;
p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE);
if (p->block_size < PA_PAGE_SIZE)
@@ -767,10 +773,13 @@ pa_mempool *pa_mempool_new(pa_mem_type_t type, size_t size) {
p->n_blocks = 2;
}
- shared = pa_mem_type_is_shared(type);
- if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) {
- pa_xfree(p);
- return NULL;
+ if (pa_mem_type_is_shared(type)) {
+ p->shared = true;
+ if (pa_shm_create(&p->per_type.shm, type, p->n_blocks * p->block_size, 0700) < 0)
+ goto mem_create_fail;
+ } else {
+ if (pa_privatemem_create(&p->per_type.privatemem, p->n_blocks * p->block_size) < 0)
+ goto mem_create_fail;
}
pa_log_debug("Using %s memory pool with %u slots of size %s each, total size is %s, maximum usable slot size is %lu",
@@ -791,6 +800,10 @@ pa_mempool *pa_mempool_new(pa_mem_type_t type, size_t size) {
p->free_slots = pa_flist_new(p->n_blocks);
return p;
+
+mem_create_fail:
+ pa_xfree(p);
+ return NULL;
}
void pa_mempool_free(pa_mempool *p) {
@@ -852,15 +865,10 @@ void pa_mempool_free(pa_mempool *p) {
/* PA_DEBUG_TRAP; */
}
- switch (p->type) {
- case PA_MEM_TYPE_SHARED_POSIX:
- case PA_MEM_TYPE_PRIVATE:
- pa_shm_free(&p->memory);
- break;
- case PA_MEM_TYPE_SHARED_MEMFD:
- pa_assert_not_reached();
- break;
- }
+ if (pa_mempool_is_shared(p))
+ pa_shm_free(&p->per_type.shm);
+ else
+ pa_privatemem_free(&p->per_type.privatemem);
pa_mutex_free(p->mutex);
pa_semaphore_free(p->semaphore);
@@ -896,7 +904,7 @@ void pa_mempool_vacuum(pa_mempool *p) {
;
while ((slot = pa_flist_pop(list))) {
- pa_shm_punch(&p->memory, (size_t) ((uint8_t*) slot - (uint8_t*) p->memory.ptr), p->block_size);
+ pa_shm_punch(&p->per_type.shm, (size_t) ((uint8_t*) slot - (uint8_t*) p->memory.ptr), p->block_size);
while (pa_flist_push(p->free_slots, slot))
;
@@ -909,10 +917,10 @@ void pa_mempool_vacuum(pa_mempool *p) {
int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) {
pa_assert(p);
- if (!p->memory.shared)
+ if (!pa_mempool_is_shared(p))
return -1;
- *id = p->memory.id;
+ *id = p->per_type.shm.id;
return 0;
}
@@ -921,7 +929,7 @@ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) {
bool pa_mempool_is_shared(pa_mempool *p) {
pa_assert(p);
- return p->memory.shared;
+ return p->shared;
}
/* For receiving blocks from other nodes */
@@ -964,7 +972,7 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id, bo
seg->writable = writable;
seg->import = i;
- seg->trap = pa_memtrap_add(seg->memory.ptr, seg->memory.size);
+ seg->trap = pa_memtrap_add(seg->memory.mem.ptr, seg->memory.mem.size);
pa_hashmap_put(i->segments, PA_UINT32_TO_PTR(seg->memory.id), seg);
return seg;
@@ -1044,7 +1052,7 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i
goto finish;
}
- if (offset+size > seg->memory.size)
+ if (offset+size > seg->memory.mem.size)
goto finish;
if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks))))
@@ -1055,7 +1063,7 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i
b->type = PA_MEMBLOCK_IMPORTED;
b->read_only = !writable;
b->is_silence = false;
- pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset);
+ pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.mem.ptr + offset);
b->length = size;
pa_atomic_store(&b->n_acquired, 0);
pa_atomic_store(&b->please_signal, 0);
@@ -1103,7 +1111,7 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void
pa_assert(p);
pa_assert(cb);
- if (!p->memory.shared)
+ if (!pa_mempool_is_shared(p))
return NULL;
e = pa_xnew(pa_memexport, 1);
@@ -1231,7 +1239,7 @@ static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) {
/* Self-locked */
int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32_t *shm_id, size_t *offset, size_t * size) {
- pa_shm *memory;
+ pa_shm *memory;
struct memexport_slot *slot;
void *data;
@@ -1274,14 +1282,14 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32
} else {
pa_assert(b->type == PA_MEMBLOCK_POOL || b->type == PA_MEMBLOCK_POOL_EXTERNAL);
pa_assert(b->pool);
- memory = &b->pool->memory;
+ memory = &b->pool->per_type.shm;
}
- pa_assert(data >= memory->ptr);
- pa_assert((uint8_t*) data + b->length <= (uint8_t*) memory->ptr + memory->size);
+ pa_assert(data >= memory->mem.ptr);
+ pa_assert((uint8_t*) data + b->length <= (uint8_t*) memory->mem.ptr + memory->mem.size);
*shm_id = memory->id;
- *offset = (size_t) ((uint8_t*) data - (uint8_t*) memory->ptr);
+ *offset = (size_t) ((uint8_t*) data - (uint8_t*) memory->mem.ptr);
*size = b->length;
pa_memblock_release(b);
diff --git a/src/pulsecore/privatemem.c b/src/pulsecore/privatemem.c
new file mode 100644
index 0000000..99df8c7
--- /dev/null
+++ b/src/pulsecore/privatemem.c
@@ -0,0 +1,78 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2006 Lennart Poettering
+ Copyright 2006 Pierre Ossman <ossman at cendio.se> for Cendio AB
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/shm.h>
+#include <pulsecore/privatemem.h>
+#include <pulsecore/core-error.h>
+#include <pulse/xmalloc.h>
+
+#define MAX_MEM_SIZE PA_MAX_SHM_SIZE
+
+int pa_privatemem_create(pa_privatemem *m, size_t size) {
+ pa_assert(m);
+ pa_assert(size > 0);
+ pa_assert(size <= MAX_MEM_SIZE);
+
+ /* Round up to make it page aligned */
+ size = PA_PAGE_ALIGN(size);
+
+ m->mem.size = size;
+
+#ifdef MAP_ANONYMOUS
+ if ((m->mem.ptr = mmap(NULL, m->mem.size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
+ pa_log("mmap() failed: %s", pa_cstrerror(errno));
+ goto fail;
+ }
+#elif defined(HAVE_POSIX_MEMALIGN)
+ {
+ int r;
+
+ if ((r = posix_memalign(&m->mem.ptr, PA_PAGE_SIZE, size)) < 0) {
+ pa_log("posix_memalign() failed: %s", pa_cstrerror(r));
+ goto fail;
+ }
+ }
+#else
+ m->mem.ptr = pa_xmalloc(m->mem.size);
+#endif
+
+ return 0;
+fail:
+ return -1;
+}
+
+void pa_privatemem_free(pa_privatemem *m) {
+ pa_assert(m);
+ pa_assert(m->mem.ptr);
+ pa_assert(m->mem.size > 0);
+
+#ifdef MAP_ANONYMOUS
+ if (munmap(m->mem.ptr, m->mem.size) < 0)
+ pa_log("munmap() failed: %s", pa_cstrerror(errno));
+#elif defined(HAVE_POSIX_MEMALIGN)
+ free(m->mem.ptr);
+#else
+ pa_xfree(m->mem.ptr);
+#endif
+}
diff --git a/src/pulsecore/privatemem.h b/src/pulsecore/privatemem.h
new file mode 100644
index 0000000..9240ce0
--- /dev/null
+++ b/src/pulsecore/privatemem.h
@@ -0,0 +1,35 @@
+#ifndef foopulseprivatememhfoo
+#define foopulseprivatememhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2015 Ahmed S. Darwish <darwish.07 at gmail.com>
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pulsecore/mem.h>
+
+/* Private memory for the mempools. This is usually used if posix SHM
+ * or Linux memfds are not available, or if we're explicitly asked
+ * not to use any form of shared memory. */
+typedef struct pa_privatemem {
+ pa_mem mem; /* Parent; must be first */
+} pa_privatemem;
+
+int pa_privatemem_create(pa_privatemem *m, size_t size);
+void pa_privatemem_free(pa_privatemem *m);
+
+#endif
diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c
index d613168..4c0ecf1 100644
--- a/src/pulsecore/shm.c
+++ b/src/pulsecore/shm.c
@@ -58,9 +58,6 @@
#define MADV_REMOVE 9
#endif
-/* 1 GiB at max */
-#define MAX_SHM_SIZE (PA_ALIGN(1024*1024*1024))
-
#ifdef __linux__
/* On Linux we know that the shared memory blocks are files in
* /dev/shm. We can use that information to list all blocks and
@@ -100,15 +97,17 @@ static char *segment_name(char *fn, size_t l, unsigned id) {
}
#endif
-int pa_shm_create_rw(pa_shm *m, size_t size, bool shared, mode_t mode) {
+int pa_shm_create(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode) {
#ifdef HAVE_SHM_OPEN
char fn[32];
int fd = -1;
#endif
+ struct shm_marker *marker;
pa_assert(m);
+ pa_assert(pa_mem_type_is_shared(type));
pa_assert(size > 0);
- pa_assert(size <= MAX_SHM_SIZE);
+ pa_assert(size <= PA_MAX_SHM_SIZE);
pa_assert(!(mode & ~0777));
pa_assert(mode >= 0600);
@@ -119,72 +118,42 @@ int pa_shm_create_rw(pa_shm *m, size_t size, bool shared, mode_t mode) {
/* Round up to make it page aligned */
size = PA_PAGE_ALIGN(size);
- if (!shared) {
- m->id = 0;
- m->size = size;
-
-#ifdef MAP_ANONYMOUS
- if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
- pa_log("mmap() failed: %s", pa_cstrerror(errno));
- goto fail;
- }
-#elif defined(HAVE_POSIX_MEMALIGN)
- {
- int r;
-
- if ((r = posix_memalign(&m->ptr, PA_PAGE_SIZE, size)) < 0) {
- pa_log("posix_memalign() failed: %s", pa_cstrerror(r));
- goto fail;
- }
- }
-#else
- m->ptr = pa_xmalloc(m->size);
-#endif
-
- m->do_unlink = false;
-
- } else {
#ifdef HAVE_SHM_OPEN
- struct shm_marker *marker;
+ pa_random(&m->id, sizeof(m->id));
+ segment_name(fn, sizeof(fn), m->id);
- pa_random(&m->id, sizeof(m->id));
- segment_name(fn, sizeof(fn), m->id);
+ if ((fd = shm_open(fn, O_RDWR|O_CREAT|O_EXCL, mode)) < 0) {
+ pa_log("shm_open() failed: %s", pa_cstrerror(errno));
+ goto fail;
+ }
- if ((fd = shm_open(fn, O_RDWR|O_CREAT|O_EXCL, mode)) < 0) {
- pa_log("shm_open() failed: %s", pa_cstrerror(errno));
- goto fail;
- }
+ m->mem.size = size + SHM_MARKER_SIZE;
- m->size = size + SHM_MARKER_SIZE;
-
- if (ftruncate(fd, (off_t) m->size) < 0) {
- pa_log("ftruncate() failed: %s", pa_cstrerror(errno));
- goto fail;
- }
+ if (ftruncate(fd, (off_t) m->mem.size) < 0) {
+ pa_log("ftruncate() failed: %s", pa_cstrerror(errno));
+ goto fail;
+ }
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
#endif
- if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd, (off_t) 0)) == MAP_FAILED) {
- pa_log("mmap() failed: %s", pa_cstrerror(errno));
- goto fail;
- }
-
- /* We store our PID at the end of the shm block, so that we
- * can check for dead shm segments later */
- marker = (struct shm_marker*) ((uint8_t*) m->ptr + m->size - SHM_MARKER_SIZE);
- pa_atomic_store(&marker->pid, (int) getpid());
- pa_atomic_store(&marker->marker, SHM_MARKER);
-
- pa_assert_se(pa_close(fd) == 0);
- m->do_unlink = true;
-#else
+ if ((m->mem.ptr = mmap(NULL, PA_PAGE_ALIGN(m->mem.size), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd, (off_t) 0)) == MAP_FAILED) {
+ pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
-#endif
}
- m->shared = shared;
+ /* We store our PID at the end of the shm block, so that we
+ * can check for dead shm segments later */
+ marker = (struct shm_marker*) ((uint8_t*) m->mem.ptr + m->mem.size - SHM_MARKER_SIZE);
+ pa_atomic_store(&marker->pid, (int) getpid());
+ pa_atomic_store(&marker->marker, SHM_MARKER);
+
+ pa_assert_se(pa_close(fd) == 0);
+ m->do_unlink = true;
+#else
+ goto fail;
+#endif
return 0;
@@ -202,40 +171,28 @@ fail:
void pa_shm_free(pa_shm *m) {
pa_assert(m);
- pa_assert(m->ptr);
- pa_assert(m->size > 0);
+ pa_assert(m->mem.ptr);
+ pa_assert(m->mem.size > 0);
#ifdef MAP_FAILED
- pa_assert(m->ptr != MAP_FAILED);
+ pa_assert(m->mem.ptr != MAP_FAILED);
#endif
- if (!m->shared) {
-#ifdef MAP_ANONYMOUS
- if (munmap(m->ptr, m->size) < 0)
- pa_log("munmap() failed: %s", pa_cstrerror(errno));
-#elif defined(HAVE_POSIX_MEMALIGN)
- free(m->ptr);
-#else
- pa_xfree(m->ptr);
-#endif
- } else {
#ifdef HAVE_SHM_OPEN
- if (munmap(m->ptr, PA_PAGE_ALIGN(m->size)) < 0)
- pa_log("munmap() failed: %s", pa_cstrerror(errno));
+ if (munmap(m->mem.ptr, PA_PAGE_ALIGN(m->mem.size)) < 0)
+ pa_log("munmap() failed: %s", pa_cstrerror(errno));
- if (m->do_unlink) {
- char fn[32];
+ if (m->do_unlink) {
+ char fn[32];
- segment_name(fn, sizeof(fn), m->id);
-
- if (shm_unlink(fn) < 0)
- pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno));
- }
-#else
- /* We shouldn't be here without shm support */
- pa_assert_not_reached();
-#endif
+ segment_name(fn, sizeof(fn), m->id);
+ if (shm_unlink(fn) < 0)
+ pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno));
}
+#else
+ /* We shouldn't be here without shm support */
+ pa_assert_not_reached();
+#endif
pa_zero(*m);
}
@@ -245,19 +202,19 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) {
size_t o;
pa_assert(m);
- pa_assert(m->ptr);
- pa_assert(m->size > 0);
- pa_assert(offset+size <= m->size);
+ pa_assert(m->mem.ptr);
+ pa_assert(m->mem.size > 0);
+ pa_assert(offset+size <= m->mem.size);
#ifdef MAP_FAILED
- pa_assert(m->ptr != MAP_FAILED);
+ pa_assert(m->mem.ptr != MAP_FAILED);
#endif
/* You're welcome to implement this as NOOP on systems that don't
* support it */
/* Align the pointer up to multiples of the page size */
- ptr = (uint8_t*) m->ptr + offset;
+ ptr = (uint8_t*) m->mem.ptr + offset;
o = (size_t) ((uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr));
if (o > 0) {
@@ -310,22 +267,21 @@ static int shm_attach(pa_shm *m, unsigned id, bool writable, bool for_cleanup) {
}
if (st.st_size <= 0 ||
- st.st_size > (off_t) (MAX_SHM_SIZE+SHM_MARKER_SIZE) ||
+ st.st_size > (off_t) (PA_MAX_SHM_SIZE+SHM_MARKER_SIZE) ||
PA_ALIGN((size_t) st.st_size) != (size_t) st.st_size) {
pa_log("Invalid shared memory segment size");
goto fail;
}
- m->size = (size_t) st.st_size;
+ m->mem.size = (size_t) st.st_size;
prot = writable ? PROT_READ | PROT_WRITE : PROT_READ;
- if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), prot, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
+ if ((m->mem.ptr = mmap(NULL, PA_PAGE_ALIGN(m->mem.size), prot, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
}
m->do_unlink = false;
- m->shared = true;
pa_assert_se(pa_close(fd) == 0);
@@ -382,12 +338,12 @@ int pa_shm_cleanup(void) {
if (shm_attach(&seg, id, false, true) < 0)
continue;
- if (seg.size < SHM_MARKER_SIZE) {
+ if (seg.mem.size < SHM_MARKER_SIZE) {
pa_shm_free(&seg);
continue;
}
- m = (struct shm_marker*) ((uint8_t*) seg.ptr + seg.size - SHM_MARKER_SIZE);
+ m = (struct shm_marker*) ((uint8_t*) seg.mem.ptr + seg.mem.size - SHM_MARKER_SIZE);
if (pa_atomic_load(&m->marker) != SHM_MARKER) {
pa_shm_free(&seg);
diff --git a/src/pulsecore/shm.h b/src/pulsecore/shm.h
index d438961..887f516 100644
--- a/src/pulsecore/shm.h
+++ b/src/pulsecore/shm.h
@@ -23,16 +23,19 @@
#include <sys/types.h>
#include <pulsecore/macro.h>
+#include <pulsecore/mem.h>
+
+/* 1 GiB at max */
+#define PA_MAX_SHM_SIZE (PA_ALIGN(1024*1024*1024))
typedef struct pa_shm {
+ pa_mem mem; /* Parent; must be first */
+ pa_mem_type_t type;
unsigned id;
- void *ptr;
- size_t size;
bool do_unlink:1;
- bool shared:1;
} pa_shm;
-int pa_shm_create_rw(pa_shm *m, size_t size, bool shared, mode_t mode);
+int pa_shm_create(pa_shm *m, pa_mem_type_t type, size_t size, mode_t mode);
int pa_shm_attach(pa_shm *m, unsigned id, bool writable);
void pa_shm_punch(pa_shm *m, size_t offset, size_t size);
Regards,
--
Darwish
http://darwish.chasingpointers.com
More information about the pulseaudio-discuss
mailing list