[pulseaudio-discuss] [PATCH 05/11] pulsecore: Provide an abstract interface for pa_shm and pa_privatemem
Ahmed S. Darwish
darwish.07 at gmail.com
Sun Sep 20 14:31:34 PDT 2015
Given this new interface, we can now remove the pool's pointer and
size fields: they can be obtained through polymorphic access.
Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com>
---
src/Makefile.am | 1 +
src/pulsecore/mem.h | 43 +++++++++++++++++++++++++++++++++++++++++++
src/pulsecore/memblock.c | 33 ++++++++++++++-------------------
src/pulsecore/privatemem.h | 5 +++--
src/pulsecore/shm.h | 7 ++++---
5 files changed, 65 insertions(+), 24 deletions(-)
create mode 100644 src/pulsecore/mem.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 19b335c..d4a6b5d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -697,6 +697,7 @@ libpulsecommon_ at PA_MAJORMINOR@_la_SOURCES = \
pulsecore/refcnt.h \
pulsecore/srbchannel.c pulsecore/srbchannel.h \
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 \
diff --git a/src/pulsecore/mem.h b/src/pulsecore/mem.h
new file mode 100644
index 0000000..7390e47
--- /dev/null
+++ b/src/pulsecore/mem.h
@@ -0,0 +1,43 @@
+#ifndef SRC_PULSECORE_MEM_H_
+#define SRC_PULSECORE_MEM_H_
+
+/***
+ 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 <pulse/gccmacro.h>
+
+/* Parent anonymous structure representing a plain memory area and its
+ * size. Different structures inherit from this, representing different
+ * memory area types (e.g. Posix SHM, Linux memfds, or private).
+ *
+ * To inherit from this object, just include __PA_MEM_STRUCT__ as the
+ * very first element of your structure. Check "pa_mempool", "pa_shm",
+ * and "pa_memfd" for a concrete inheritance relationships example. */
+#define __PA_PARENT_MEM_STRUCT__ struct { \
+ void *ptr; \
+ size_t size; \
+} PA_GCC_PACKED
+
+/* A non-anonymous type for the parent. Useful in unions and for
+ * casting a child pointer to the parent's one (polymorphic access). */
+typedef struct pa_mem {
+ __PA_PARENT_MEM_STRUCT__;
+} pa_mem;
+
+#endif /* SRC_PULSECORE_MEM_H_ */
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index d66cd52..e809f27 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -36,6 +36,7 @@
#include <pulse/xmalloc.h>
#include <pulse/def.h>
+#include <pulsecore/mem.h>
#include <pulsecore/shm.h>
#include <pulsecore/privatemem.h>
#include <pulsecore/log.h>
@@ -148,12 +149,12 @@ struct pa_mempool {
pa_mempool_type_t type;
union {
- pa_shm shm;
- pa_privatemem privatemem;
- } per_type;
-
- void *ptr;
- size_t size;
+ pa_mem mem;
+ union {
+ pa_shm shm;
+ pa_privatemem privatemem;
+ } per_type;
+ };
size_t block_size;
unsigned n_blocks;
@@ -270,7 +271,7 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {
if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks)
pa_atomic_dec(&p->n_init);
else
- slot = (struct mempool_slot*) ((uint8_t*) p->ptr + (p->block_size * (size_t) idx));
+ slot = (struct mempool_slot*) ((uint8_t*) p->mem.ptr + (p->block_size * (size_t) idx));
if (!slot) {
if (pa_log_ratelimit(PA_LOG_DEBUG))
@@ -298,10 +299,10 @@ static inline void* mempool_slot_data(struct mempool_slot *slot) {
static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) {
pa_assert(p);
- pa_assert((uint8_t*) ptr >= (uint8_t*) p->ptr);
- pa_assert((uint8_t*) ptr < (uint8_t*) p->ptr + p->size);
+ pa_assert((uint8_t*) ptr >= (uint8_t*) p->mem.ptr);
+ pa_assert((uint8_t*) ptr < (uint8_t*) p->mem.ptr + p->mem.size);
- return (unsigned) ((size_t) ((uint8_t*) ptr - (uint8_t*) p->ptr) / p->block_size);
+ return (unsigned) ((size_t) ((uint8_t*) ptr - (uint8_t*) p->mem.ptr) / p->block_size);
}
/* No lock necessary */
@@ -311,7 +312,7 @@ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) {
if ((idx = mempool_slot_idx(p, ptr)) == (unsigned) -1)
return NULL;
- return (struct mempool_slot*) ((uint8_t*) p->ptr + (idx * p->block_size));
+ return (struct mempool_slot*) ((uint8_t*) p->mem.ptr + (idx * p->block_size));
}
/* No lock necessary */
@@ -793,9 +794,6 @@ pa_mempool *pa_mempool_new(pa_mempool_type_t type, size_t size) {
case PA_MEMPOOL_SHARED_POSIX:
if (pa_shm_create(&p->per_type.shm, pa_mem_size, 0700) < 0)
goto fail;
-
- p->ptr = p->per_type.shm.ptr;
- p->size = p->per_type.shm.size;
break;
case PA_MEMPOOL_SHARED_MEMFD:
pa_assert_not_reached();
@@ -803,9 +801,6 @@ pa_mempool *pa_mempool_new(pa_mempool_type_t type, size_t size) {
case PA_MEMPOOL_PRIVATE:
if (pa_privatemem_create(&p->per_type.privatemem, pa_mem_size) < 0)
goto fail;
-
- p->ptr = p->per_type.privatemem.ptr;
- p->size = p->per_type.privatemem.size;
break;
default:
pa_assert_not_reached();
@@ -867,7 +862,7 @@ void pa_mempool_free(pa_mempool *p) {
struct mempool_slot *slot;
pa_memblock *b, *k;
- slot = (struct mempool_slot*) ((uint8_t*) p->ptr + (p->block_size * (size_t) i));
+ slot = (struct mempool_slot*) ((uint8_t*) p->mem.ptr + (p->block_size * (size_t) i));
b = mempool_slot_data(slot);
while ((k = pa_flist_pop(p->free_slots))) {
@@ -943,7 +938,7 @@ void pa_mempool_vacuum(pa_mempool *p) {
;
while ((slot = pa_flist_pop(list))) {
- pa_shm_punch(p->ptr, p->size, (size_t) ((uint8_t*) slot - (uint8_t*) p->ptr), p->block_size);
+ pa_shm_punch(p->mem.ptr, p->mem.size, (size_t) ((uint8_t*) slot - (uint8_t*) p->mem.ptr), p->block_size);
while (pa_flist_push(p->free_slots, slot))
;
diff --git a/src/pulsecore/privatemem.h b/src/pulsecore/privatemem.h
index a6ae710..ac4e256 100644
--- a/src/pulsecore/privatemem.h
+++ b/src/pulsecore/privatemem.h
@@ -20,12 +20,13 @@
License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
+#include "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 {
- void *ptr;
- size_t size;
+ __PA_PARENT_MEM_STRUCT__; /* Parent anonymous struct; must be first */
} pa_privatemem;
int pa_privatemem_create(pa_privatemem *m, size_t size);
diff --git a/src/pulsecore/shm.h b/src/pulsecore/shm.h
index 0e6e9b6..a8b2546 100644
--- a/src/pulsecore/shm.h
+++ b/src/pulsecore/shm.h
@@ -23,11 +23,12 @@
#include <sys/types.h>
#include <pulsecore/macro.h>
+#include "mem.h"
+
typedef struct pa_shm {
+ __PA_PARENT_MEM_STRUCT__; /* Parent anonymous struct; must be first */
unsigned id;
- void *ptr;
- size_t size;
- bool do_unlink:1;
+ bool do_unlink;
} pa_shm;
/* 1 GiB at max */
--
Darwish
http://darwish.chasingpointers.com
More information about the pulseaudio-discuss
mailing list