diff options
Diffstat (limited to 'src/pulsecore/flist.c')
-rw-r--r-- | src/pulsecore/flist.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index 00567ab3..3805e1d1 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -30,6 +30,7 @@ #include <pulsecore/atomic.h> #include <pulsecore/log.h> #include <pulsecore/thread.h> +#include <pulsecore/macro.h> #include <pulse/xmalloc.h> #include "flist.h" @@ -90,18 +91,19 @@ enum { }; struct cell { - pa_atomic_int_t state; + pa_atomic_t state; void *data; }; struct pa_flist { - struct cell *cells; unsigned size; - pa_atomic_int_t length; - pa_atomic_int_t read_idx; - pa_atomic_int_t write_idx; + pa_atomic_t length; + pa_atomic_t read_idx; + pa_atomic_t write_idx; }; +#define PA_FLIST_CELLS(x) ((struct cell*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_flist)))) + static int is_power_of_two(unsigned size) { return !(size & (size - 1)); } @@ -114,10 +116,9 @@ pa_flist *pa_flist_new(unsigned size) { assert(is_power_of_two(size)); - l = pa_xnew(pa_flist, 1); + l = pa_xmalloc0(PA_ALIGN(sizeof(pa_flist)) + (sizeof(struct cell) * size)); l->size = size; - l->cells = pa_xnew0(struct cell, size); pa_atomic_store(&l->read_idx, 0); pa_atomic_store(&l->write_idx, 0); @@ -134,30 +135,35 @@ void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb) { assert(l); if (free_cb) { + struct cell *cells; int len, idx; + cells = PA_FLIST_CELLS(l); + idx = reduce(l, pa_atomic_load(&l->read_idx)); len = pa_atomic_load(&l->length); for (; len > 0; len--) { - if (pa_atomic_load(&l->cells[idx].state) == STATE_USED) - free_cb(l->cells[idx].data); + if (pa_atomic_load(&cells[idx].state) == STATE_USED) + free_cb(cells[idx].data); idx = reduce(l, idx + 1); } } - pa_xfree(l->cells); pa_xfree(l); } int pa_flist_push(pa_flist*l, void *p) { int idx, len, n; + struct cell *cells; assert(l); assert(p); + cells = PA_FLIST_CELLS(l); + n = len = (int) l->size - pa_atomic_load(&l->length) + N_EXTRA_SCAN; _Y; idx = reduce(l, pa_atomic_load(&l->write_idx)); @@ -165,13 +171,13 @@ int pa_flist_push(pa_flist*l, void *p) { for (; n > 0 ; n--) { _Y; - if (pa_atomic_cmpxchg(&l->cells[idx].state, STATE_UNUSED, STATE_BUSY)) { + if (pa_atomic_cmpxchg(&cells[idx].state, STATE_UNUSED, STATE_BUSY)) { _Y; pa_atomic_inc(&l->write_idx); _Y; - l->cells[idx].data = p; + cells[idx].data = p; _Y; - pa_atomic_store(&l->cells[idx].state, STATE_USED); + pa_atomic_store(&cells[idx].state, STATE_USED); _Y; pa_atomic_inc(&l->length); return 0; @@ -191,9 +197,12 @@ int pa_flist_push(pa_flist*l, void *p) { void* pa_flist_pop(pa_flist*l) { int idx, len, n; + struct cell *cells; assert(l); + cells = PA_FLIST_CELLS(l); + n = len = pa_atomic_load(&l->length) + N_EXTRA_SCAN; _Y; idx = reduce(l, pa_atomic_load(&l->read_idx)); @@ -201,14 +210,14 @@ void* pa_flist_pop(pa_flist*l) { for (; n > 0 ; n--) { _Y; - if (pa_atomic_cmpxchg(&l->cells[idx].state, STATE_USED, STATE_BUSY)) { + if (pa_atomic_cmpxchg(&cells[idx].state, STATE_USED, STATE_BUSY)) { void *p; _Y; pa_atomic_inc(&l->read_idx); _Y; - p = l->cells[idx].data; + p = cells[idx].data; _Y; - pa_atomic_store(&l->cells[idx].state, STATE_UNUSED); + pa_atomic_store(&cells[idx].state, STATE_UNUSED); _Y; pa_atomic_dec(&l->length); |