[Sheepdog] [PATCH v4 08/12] trace: add a ring buffer

Liu Yuan namei.unix at gmail.com
Tue Apr 10 09:02:03 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>

Tracers use this ring buffer to store its output internally.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 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 45e99e8..d9e8429 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 rbtree.c
+libsheepdog_a_SOURCES	= event.c logger.c net.c util.c coroutine.c rbtree.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 db173df..94a4f71 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)
 {
-- 
1.7.8.2




More information about the sheepdog mailing list