[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