Skip to content

Commit

Permalink
Require power-of-two size. Add ring_poke.
Browse files Browse the repository at this point in the history
  • Loading branch information
jordansissel committed Aug 5, 2012
1 parent ce6fabf commit 5d1bb29
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 21 deletions.
44 changes: 29 additions & 15 deletions ring.c
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 */
16 changes: 10 additions & 6 deletions ring.h
Original file line number Diff line number Diff line change
@@ -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_ */

0 comments on commit 5d1bb29

Please sign in to comment.