summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/flist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore/flist.c')
-rw-r--r--src/pulsecore/flist.c41
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);