From b60e60dbaeff9311b3e74a6d54bb3bbb2c1f61e3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 May 2007 00:56:50 +0000 Subject: allow static data in the bufferqs git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@29 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce --- Makefile | 2 +- bufferq.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++----------- bufferq.h | 13 +++++++-- test-bufferq.c | 14 ++++++---- 4 files changed, 91 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 123b97d..76ef581 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ OBJS=$(SOURCES:.c=.o) all: test-bufferq test-llist test-sine test-pull -test-bufferq: test-bufferq.o bufferq.o +test-bufferq: test-bufferq.o bufferq.o malloc.o $(CC) $(CFLAGS) -o $@ $^ test-llist: test-llist.o diff --git a/bufferq.c b/bufferq.c index c4c3ec3..5261f35 100644 --- a/bufferq.c +++ b/bufferq.c @@ -4,6 +4,8 @@ #include "macro.h" #include "bufferq.h" +#define SA_BUFFERQ_CONCAT_DATA(x) ((void*) (uint8_t*) (x) + ALIGN(sizeof(sa_bufferq_item_t))) + int sa_bufferq_init(sa_bufferq_t *q, unsigned nchannels, size_t sample_size) { sa_assert(q); sa_assert(sample_size > 0); @@ -42,19 +44,53 @@ void sa_bufferq_done(sa_bufferq_t *q) { sa_free(q->last); } -static sa_bufferq_item_t* bufferq_item_new(size_t size) { +static sa_bufferq_item_t* bufferq_item_new(const void *d, size_t size, int copy) { sa_bufferq_item_t *i; sa_assert(size > 0); + + if (!copy) { + if (!(i = sa_new(sa_bufferq_item_t, 1))) + return i; + i->type = SA_BUFFERQ_ITEM_STATIC; + i->data = (void*) d; + } else { + if (!(i = sa_malloc(ALIGN(sizeof(sa_bufferq_item_t)) + size))) + return i; + i->type = SA_BUFFERQ_ITEM_CONCATENATED; + i->data = SA_BUFFERQ_CONCAT_DATA(i); + memcpy(i->data, d, size); + } + + i->size = size; + SA_LLIST_ITEM_INIT(sa_bufferq_item_t, bufferq, i); + + return i; +} + +static sa_bufferq_item_t* bufferq_item_make_writable(sa_bufferq_item_t *i) { + void *d; + sa_assert(i); - if (!(i = sa_malloc(ALIGN(sizeof(sa_bufferq_item_t)) + size))) + if (i->type == SA_BUFFERQ_ITEM_CONCATENATED || i->type == SA_BUFFERQ_ITEM_DYNAMIC) return i; - SA_LLIST_ITEM_INIT(sa_bufferq_item_t, bufferq, i); + if (!(d = sa_memdup(i->data, i->size))) + return NULL; + i->data = d; + i->type = SA_BUFFERQ_ITEM_DYNAMIC; return i; } -int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { +static void bufferq_item_free(sa_bufferq_item_t *i) { + sa_assert(i); + + if (i->type == SA_BUFFERQ_ITEM_DYNAMIC) + sa_free(i->data); + sa_free(i); +} + +int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence, int copy) { int64_t idx; sa_bufferq_item_t *i, *j; @@ -103,13 +139,11 @@ int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t if (l > i->idx - idx) l = i->idx - idx; - - if (!(j = bufferq_item_new(l))) - return SA_ERROR_OOM; - memcpy(SA_BUFFERQ_ITEM_DATA(j), data, l); + if (!(j = bufferq_item_new(data, l, copy))) + return SA_ERROR_OOM; + j->idx = idx; - j->size = l; SA_LLIST_INSERT_BEFORE(sa_bufferq_item_t, bufferq, q->items[channel], i, j); @@ -127,7 +161,10 @@ int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t if (l > i->idx + i->size - idx) l = i->idx + i->size - idx; - memcpy((uint8_t*) SA_BUFFERQ_ITEM_DATA(i) + (idx - i->idx), data, l); + if (!(i = bufferq_item_make_writable(i))) + return SA_ERROR_OOM; + + memcpy((uint8_t*) i->data + (idx - i->idx), data, l); idx += l; data += l; @@ -138,12 +175,10 @@ int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t if (nbytes > 0) { sa_assert(!i); - if (!(j = bufferq_item_new(nbytes))) + if (!(j = bufferq_item_new(data, nbytes, copy))) return SA_ERROR_OOM; - memcpy(SA_BUFFERQ_ITEM_DATA(j), data, nbytes); j->idx = idx; - j->size = nbytes; if (q->last[channel]) SA_LLIST_INSERT_AFTER(sa_bufferq_item_t, bufferq, q->items[channel], q->last[channel], j); @@ -186,7 +221,7 @@ int sa_bufferq_get(sa_bufferq_t *q, void *i[], size_t *bytes) { } else { int64_t l; - i[u] = (uint8_t*) SA_BUFFERQ_ITEM_DATA(q->items[u]) + q->read_index - q->items[u]->idx; + i[u] = (uint8_t*) q->items[u]->data + q->read_index - q->items[u]->idx; l = q->items[u]->size - (q->read_index - q->items[u]->idx); @@ -213,7 +248,6 @@ int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { q->read_index += bytes; for (u = 0; u < q->nchannels; u++) { - sa_bufferq_item_t *i; i = q->items[u]; @@ -223,7 +257,7 @@ int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { SA_LLIST_REMOVE(sa_bufferq_item_t, bufferq, q->items[u], i); - sa_free(i); + bufferq_item_free(i); i = n; } @@ -233,3 +267,25 @@ int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes) { return SA_SUCCESS; } + +int sa_bufferq_realloc(sa_bufferq_t *q) { + unsigned u; + sa_assert(q); + + for (u = 0; u < q->nchannels; u++) { + sa_bufferq_item_t *i; + + i = q->items[u]; + + while (i) { + + if (!bufferq_item_make_writable(i)) + return SA_ERROR_OOM; + + i = i->bufferq_next; + } + + } + + return SA_SUCCESS; +} diff --git a/bufferq.h b/bufferq.h index a645398..538bf4d 100644 --- a/bufferq.h +++ b/bufferq.h @@ -7,14 +7,20 @@ #include "llist.h" #include "sydney.h" +typedef enum sa_bufferq_item_type { + SA_BUFFERQ_ITEM_CONCATENATED, + SA_BUFFERQ_ITEM_DYNAMIC, + SA_BUFFERQ_ITEM_STATIC +} sa_bufferq_item_type_t; + typedef struct sa_bufferq_item { + void *data; int64_t idx; size_t size; + sa_bufferq_item_type_t type; SA_LLIST_ITEM(struct sa_bufferq_item, bufferq); } sa_bufferq_item_t; -#define SA_BUFFERQ_ITEM_DATA(x) ((void*) (uint8_t*) (x) + ALIGN(sizeof(sa_bufferq_item_t))) - typedef struct sa_bufferq { SA_LLIST_HEAD(sa_bufferq_item_t, *items); sa_bufferq_item_t **last; @@ -27,7 +33,8 @@ int sa_bufferq_init(sa_bufferq_t *q, unsigned nchannels, size_t sample_size); void sa_bufferq_done(sa_bufferq_t *q); -int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +int sa_bufferq_push(sa_bufferq_t *q, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence, int copy); +int sa_bufferq_realloc(sa_bufferq_t *q); int sa_bufferq_get(sa_bufferq_t *q, void *i[], size_t *bytes); int sa_bufferq_drop(sa_bufferq_t *q, int64_t bytes); diff --git a/test-bufferq.c b/test-bufferq.c index 05fc35b..6c57384 100644 --- a/test-bufferq.c +++ b/test-bufferq.c @@ -6,12 +6,14 @@ int main(int argc, char *argv[]) { sa_bufferq_init(&q, 1, 1); - sa_bufferq_push(&q, 0, "{AAAAAAAA}", 10, 0, SA_SEEK_RELATIVE); - sa_bufferq_push(&q, 0, "", 10, 5, SA_SEEK_RELATIVE); - sa_bufferq_push(&q, 0, "[CCCC]", 6, -18, SA_SEEK_RELATIVE); - sa_bufferq_push(&q, 0, "(DDDD)", 6, -3, SA_SEEK_ABSOLUTE); - sa_bufferq_push(&q, 0, "XXX", 3, 10, SA_SEEK_RELATIVE_END); - sa_bufferq_push(&q, 0, "YYYYY", 5, -4, SA_SEEK_RELATIVE); + sa_bufferq_push(&q, 0, "{AAAAAAAA}", 10, 0, SA_SEEK_RELATIVE, 0); + sa_bufferq_push(&q, 0, "", 10, 5, SA_SEEK_RELATIVE, 0); + sa_bufferq_push(&q, 0, "[CCCC]", 6, -18, SA_SEEK_RELATIVE, 0); + sa_bufferq_push(&q, 0, "(DDDD)", 6, -3, SA_SEEK_ABSOLUTE, 0); + sa_bufferq_push(&q, 0, "XXX", 3, 10, SA_SEEK_RELATIVE_END, 0); + sa_bufferq_push(&q, 0, "YYYYY", 5, -4, SA_SEEK_RELATIVE, 0); + + sa_bufferq_realloc(&q); for (;;) { void *b[1]; -- cgit