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

Reply via email to