Have a look at the ring buffer in libqb. (http://www.libqb.org). It allows arbitrary sized ring buffers with arbitrary sized blocks of data (rather then pointers as in this implementation).
There is also tracing/logging in this library, but you may be more interested in the on/off model vs the always-on model imposed by libqb. (Even though the always-on model is very low overhead). Regards -steve On 02/16/2012 04:21 AM, Liu Yuan wrote: > From: Liu Yuan <[email protected]> > > > Signed-off-by: Liu Yuan <[email protected]> > --- > include/util.h | 24 ++++++++++++++++++++++ > lib/Makefile.am | 2 +- > lib/ring_buffer.c | 54 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > sheep/trace/graph.c | 2 + > 4 files changed, 81 insertions(+), 1 deletions(-) > create mode 100644 lib/ring_buffer.c > > diff --git a/include/util.h b/include/util.h > index ff86a00..ca43ab9 100644 > --- a/include/util.h > +++ b/include/util.h > @@ -6,6 +6,7 @@ > #include <stdint.h> > > #include "bitops.h" > +#include "list.h" > > #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) > #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) > @@ -69,4 +70,27 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len); > extern ssize_t xpread(int fd, void *buf, size_t count, off_t offset); > extern ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset); > > +/* ring_buffer.c */ > +struct rbuffer { > + struct list_head list; > + char *buffer; /* data buffer */ > + char *buffer_end; > + size_t capacity; /* initial maximum number of items in the > buffer */ > + size_t count; /* number of items in the buffer */ > + size_t sz; /* size of each item in the buffer */ > + char *head; > + char *tail; > +}; > + > +static inline size_t rbuffer_size(struct rbuffer *rbuf) > +{ > + return rbuf->count * rbuf->sz; > +} > + > +void rbuffer_push(struct rbuffer *rbuf, const void *item); > +void rbuffer_pop(struct rbuffer *rbuf, void *item); > +void rbuffer_destroy(struct rbuffer *rbuf); > +void rbuffer_create(struct rbuffer *rbuf, size_t capacity, size_t item_size); > +void rbuffer_reset(struct rbuffer *rbuf); > + > #endif > diff --git a/lib/Makefile.am b/lib/Makefile.am > index c4fb3af..fe41ad0 100644 > --- a/lib/Makefile.am > +++ b/lib/Makefile.am > @@ -4,4 +4,4 @@ INCLUDES = -I$(top_builddir)/include > -I$(top_srcdir)/include > > noinst_LIBRARIES = libsheepdog.a > > -libsheepdog_a_SOURCES = event.c logger.c net.c util.c coroutine.c > +libsheepdog_a_SOURCES = event.c logger.c net.c util.c coroutine.c > ring_buffer.c > diff --git a/lib/ring_buffer.c b/lib/ring_buffer.c > new file mode 100644 > index 0000000..a37d6c7 > --- /dev/null > +++ b/lib/ring_buffer.c > @@ -0,0 +1,54 @@ > +#include <pthread.h> > +#include <stdlib.h> > + > +#include "util.h" > +#include "logger.h" > + > +notrace void rbuffer_create(struct rbuffer *rbuf, size_t capacity, size_t sz) > +{ > + rbuf->buffer = xmalloc(capacity * sz); > + rbuf->buffer_end = rbuf->buffer + capacity * sz; > + rbuf->capacity = capacity; > + rbuf->count = 0; > + rbuf->sz = sz; > + rbuf->head = rbuf->tail = rbuf->buffer; > +} > + > +notrace void rbuffer_destroy(struct rbuffer *rbuf) > +{ > + free(rbuf->buffer); > +} > + > +notrace void rbuffer_reset(struct rbuffer *rbuf) > +{ > + rbuf->count = 0; > + rbuf->head = rbuf->tail = rbuf->buffer; > +} > + > +/* Push the item to the tail of the buffer */ > +notrace void rbuffer_push(struct rbuffer *rbuf, const void *item) > +{ > + if (rbuf->count == rbuf->capacity) { > + dprintf("buffer full\n"); > + return; > + } > + memcpy(rbuf->tail, item, rbuf->sz); > + rbuf->tail += rbuf->sz; > + if (rbuf->tail == rbuf->buffer_end) > + rbuf->tail = rbuf->buffer; > + rbuf->count++; > +} > + > +/* Push the item from the head of the buffer */ > +notrace void rbuffer_pop(struct rbuffer *rbuf, void *item) > +{ > + if (rbuf->count == 0) { > + dprintf("no item left\n"); > + return; > + } > + memcpy(item, rbuf->head, rbuf->sz); > + rbuf->head += rbuf->sz; > + if (rbuf->head == rbuf->buffer_end) > + rbuf->head = rbuf->buffer; > + rbuf->count--; > +} > diff --git a/sheep/trace/graph.c b/sheep/trace/graph.c > index 7dfafc8..58094a3 100644 > --- a/sheep/trace/graph.c > +++ b/sheep/trace/graph.c > @@ -12,6 +12,8 @@ static __thread struct trace_ret_stack { > unsigned long long entry_time; > } trace_ret_stack[100]; /* FIXME: consider stack overrun */ > > +static __thread struct rbuffer rbuf; > + > static void push_return_trace(unsigned long ret, unsigned long long etime, > unsigned long func, int *depth) > { -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
