Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Require power-of-two size. Add ring_poke.

  • Loading branch information...
commit 5d1bb29ec6be793c31b77aab1ea1f8679aebf737 1 parent ce6fabf
@jordansissel jordansissel authored
Showing with 39 additions and 21 deletions.
  1. +29 −15 ring.c
  2. +10 −6 ring.h
View
44 ring.c
@@ -1,7 +1,11 @@
#include "ring.h"
+#include "insist.h"
#include <jemalloc/jemalloc.h>
-struct ring *ring_new_size(size_t size) {
+struct ring *ring_new_size(uint32_t size) {
+ insist((size & (size - 1)) == 0,
+ "size must be a power of two, %d is not.", size);
+
struct ring *r = malloc(sizeof(struct ring));
r->writer = 0;
r->reader = 0;
@@ -16,35 +20,45 @@ inline int ring_is_empty(struct ring *ring) {
return ring->count == 0;
} /* ring_is_empty */
-int ring_is_full(struct ring *ring) {
+inline int ring_is_full(struct ring *ring) {
return ring->count == ring->size;
} /* ring_is_full */
-int ring_pop(struct ring *ring, void **object_ret) {
- if (ring_is_empty(ring)) {
+inline int ring_pop(struct ring *ring, void **object_ret) {
+ int rc = ring_peek(ring, 0, object_ret);
+ if (rc != RING_OK) {
return RING_IS_EMPTY;
}
- *object_ret = ring->buffer[ring->reader];
-
- ring->reader++;
+ /* increment reader position and wrap write if necessary */
+ ring->reader = (ring->reader + 1) & (ring->size - 1);
ring->count--;
- if (ring->reader == ring->size) {
- ring->reader = 0; /* wrap around */
- }
return RING_OK;
} /* ring_pop */
-int ring_push(struct ring *ring, void *object) {
+inline int ring_push(struct ring *ring, void *object) {
if (ring_is_full(ring)) {
return RING_IS_FULL;
}
ring->buffer[ring->writer] = object;
- ring->writer++;
+ /* increment write position and wrap write if necessary */
+ ring->writer = (ring->writer + 1) & (ring->size - 1);
ring->count++;
- if (ring->writer == ring->size) {
- ring->writer = 0; /* wrap around */
- }
return RING_OK;
} /* ring_push */
+
+inline uint32_t ring_count(struct ring *ring) {
+ return ring->count;
+} /* ring count */
+
+inline int ring_peek(struct ring *ring, uint32_t i, void **object_ret) {
+ if (i >= ring->count) {
+ return RING_INDEX_OUT_OF_BOUNDS;
+ }
+ /* item 0 is the next one after the reader
+ * we mask with 'size - 1' as a way of wrapping the value since we enforce
+ * power-of-two-ness */
+ *object_ret = ring->buffer[(ring->reader + i) & (ring->size - 1)];
+ return RING_OK;
+} /* ring_peek */
View
16 ring.h
@@ -1,25 +1,29 @@
#ifndef _RING_H_
#define _RING_H_
-#include <sys/types.h>
+#include <stdint.h>
struct ring {
- size_t writer;
- size_t reader;
- size_t size;
- size_t count;
+ uint32_t writer; /* write position */
+ uint32_t reader; /* read position */
+ uint32_t size; /* maximum number of items */
+ uint32_t count; /* current count of items */
void **buffer; /* array of pointers to whatever objects we're storing */
};
#define RING_OK 0x00
#define RING_IS_EMPTY 0x01
#define RING_IS_FULL 0x02
+#define RING_INDEX_OUT_OF_BOUNDS 0x03
-struct ring *ring_new_size(size_t count);
+struct ring *ring_new_size(uint32_t count);
int ring_is_empty(struct ring *ring);
int ring_is_full(struct ring *ring);
+uint32_t ring_count(struct ring *ring);
+
int ring_pop(struct ring *ring, void **object_ret);
+int ring_peek(struct ring *ring, uint32_t index, void **object_ret);
int ring_push(struct ring *ring, void *object);
#endif /* _RING_H_ */
Please sign in to comment.
Something went wrong with that request. Please try again.