summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2010-01-06 23:45:20 +0100
committerJérémy Zurcher <jeremy@asynk.ch>2010-01-06 23:45:20 +0100
commit82a5bc70e5f85d7d40e04e6a7dc567b086025421 (patch)
tree6f6eb3ec2a9bf27e180dc264abe4802bc2d0b1c0
parentce1dcb6ed32396910e3400e3a816b76d22d5a0de (diff)
downloadlock_free-82a5bc70e5f85d7d40e04e6a7dc567b086025421.zip
lock_free-82a5bc70e5f85d7d40e04e6a7dc567b086025421.tar.gz
ring buffer read : set read_from=-1 if read_from==write_to
-rw-r--r--lf_ring_buffer.c11
-rw-r--r--lf_ring_buffer_test.c5
2 files changed, 12 insertions, 4 deletions
diff --git a/lf_ring_buffer.c b/lf_ring_buffer.c
index 75b2f17..ad866e0 100644
--- a/lf_ring_buffer.c
+++ b/lf_ring_buffer.c
@@ -149,8 +149,15 @@ int lf_ring_buffer_read( lf_ring_buffer_t *r, void *data, int flags ) {
if (next==r->n_buf) next=0;
/* will do bad things if data dst buffer is too small !! */
memcpy( data, r->buffer[idx].data, LFRB_DATA_SIZE );
- _LOG_( "write: CAS %d %d %d\n", r->read_from, idx, next );
- if( CompareAndSwapInt( &r->read_from, idx, next ) ) break;
+ _LOG_( "read: CAS %d %d %d\n", r->read_from, idx, next );
+ if( CompareAndSwapInt( &r->read_from, idx, next ) ) {
+ if(r->read_from==r->write_to) {
+ /* the buffer is actually empty but writers will see it as full */
+ _LOG_( "read: empty CAS %d %d %d\n", r->read_from, next, -1 );
+ CompareAndSwapInt( &r->read_from, next, -1 );
+ }
+ break;
+ }
} else {
_LOG_("read: not available\n");
if(IS_NOT_BLOCKING(flags)) return -1;
diff --git a/lf_ring_buffer_test.c b/lf_ring_buffer_test.c
index 348d202..e9e199a 100644
--- a/lf_ring_buffer_test.c
+++ b/lf_ring_buffer_test.c
@@ -6,8 +6,7 @@
#include "lf_ring_buffer.h"
-//#define BUFFER_LEN 5000000
-#define BUFFER_LEN 500
+#define BUFFER_LEN 5000000
static rb_data_t data[BUFFER_LEN][RB_DATA_LEN];
@@ -25,12 +24,14 @@ static void report( int n, uint64_t dt ) {
fprintf(stdout,"%d operations in %d [ms] => %d [us] => %d [ns]\t >>> %d [ns/op]\n", n, (int)(dt/1000000), (int)(dt/1000), (int)dt, (int)(dt/n) );
}
+/*
static void feed_data( int n){
int i;
for(i=0; i<n; i++){
sprintf(data[i],"hello world %04d\n",i);
}
}
+*/
static uint64_t sequential_writes( lf_ring_buffer_t *ring, int n, int flags ) {
int i;