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