AT&T ECOMP Vendor Event Listener library  0.1
ring_buffer.c
Go to the documentation of this file.
1 /**************************************************************************/
37 #include <assert.h>
38 #include <malloc.h>
39 
40 #include "ring_buffer.h"
41 #include "evel.h"
42 
43 /**************************************************************************/
53 void ring_buffer_initialize(ring_buffer * buffer, int size)
54 {
55  int pthread_rc = 0;
56 
57  EVEL_ENTER();
58 
59  /***************************************************************************/
60  /* Check assumptions. */
61  /***************************************************************************/
62  assert(buffer != NULL);
63  assert(size > 0);
64 
65  /***************************************************************************/
66  /* Initialize the synchronization objects. */
67  /***************************************************************************/
68  pthread_rc = pthread_mutex_init(&buffer->ring_mutex, NULL);
69  assert(pthread_rc == 0);
70  pthread_rc = pthread_cond_init(&buffer->ring_cv, NULL);
71  assert(pthread_rc == 0);
72 
73  /***************************************************************************/
74  /* Allocate the ring buffer itself. */
75  /***************************************************************************/
76  buffer->ring = malloc(size * sizeof(void *));
77  assert(buffer->ring != NULL);
78 
79  /***************************************************************************/
80  /* Initialize the ring as empty. */
81  /***************************************************************************/
82  buffer->next_write = 0;
83  buffer->next_read = 0;
84  buffer->size = size;
85 
86  EVEL_EXIT();
87 }
88 
89 /**************************************************************************/
101 {
102  void *msg = NULL;
103  EVEL_DEBUG("RBR: Ring buffer read");
104 
105  pthread_mutex_lock(&buffer->ring_mutex);
106  while (1)
107  {
108  EVEL_DEBUG("RBR: got lock. NR=%d NW=%d",
109  buffer->next_read,
110  buffer->next_write);
111  if(buffer->next_read != buffer->next_write)
112  {
113  EVEL_DEBUG("RBR: buffer has item available");
114  msg = (buffer->ring)[buffer->next_read];
115  buffer->ring[buffer->next_read] = NULL;
116  buffer->next_read = (buffer->next_read + 1) % buffer->size;
117  EVEL_DEBUG("RBR: next read location is %d", buffer->next_read);
118  pthread_mutex_unlock(&buffer->ring_mutex);
119  break;
120  }
121  else
122  {
123  EVEL_DEBUG("RBR: Waiting for condition variable");
124  pthread_cond_wait(&buffer->ring_cv, &buffer->ring_mutex);
125  EVEL_DEBUG("RBR: Condition variable wait completed");
126  }
127  }
128  EVEL_DEBUG("RBR: Ring buffer read returning data at %lp", msg);
129  return msg;
130 }
131 
132 /**************************************************************************/
146 int ring_buffer_write(ring_buffer * buffer, void * msg)
147 {
148  int item_count = 0;
149  int items_written = 0;
150  EVEL_DEBUG("RBW: Ring Buffer Write message at %lp", msg);
151 
152  pthread_mutex_lock(&buffer->ring_mutex);
153  EVEL_DEBUG("RBW: got lock. NR=%d NW=%d SZ=%d",
154  buffer->next_read,
155  buffer->next_write,
156  buffer->size);
157 
158  item_count = (buffer->next_write - buffer->next_read) % buffer->size;
159  if (item_count < 0)
160  {
161  item_count += buffer->size;
162  }
163  if (item_count < buffer->size - 1)
164  {
165  EVEL_DEBUG("RBW: %d items in buffer", item_count);
166  buffer->ring[buffer->next_write] = msg;
167  buffer->next_write = (buffer->next_write + 1) % buffer->size;
168  EVEL_DEBUG("RBW: next write location is %d", buffer->next_write);
169  items_written = 1;
170  }
171  else
172  {
173  EVEL_ERROR("RBW: ring buffer full - unable to write event");
174  }
175 
176  pthread_mutex_unlock(&buffer->ring_mutex);
177  EVEL_DEBUG("RBW: released lock");
178  pthread_cond_signal(&buffer->ring_cv);
179 
180  return items_written;
181 }
182 
183 /**************************************************************************/
195 {
196  int is_empty = 0;
197  EVEL_DEBUG("RBE: Ring empty check");
198 
199  pthread_mutex_lock(&buffer->ring_mutex);
200  is_empty = (buffer->next_read == buffer->next_write);
201  pthread_mutex_unlock(&buffer->ring_mutex);
202 
203  EVEL_DEBUG("RBE: Ring state= %d", is_empty);
204  return is_empty;
205 }
206 
pthread_cond_t ring_cv
Definition: ring_buffer.h:51
#define EVEL_DEBUG(FMT,...)
Definition: evel.h:3621
void * ring_buffer_read(ring_buffer *buffer)
Read an element from a ring_buffer.
Definition: ring_buffer.c:100
#define EVEL_EXIT()
Definition: evel.h:3631
pthread_mutex_t ring_mutex
Definition: ring_buffer.h:52
#define EVEL_ENTER()
Definition: evel.h:3626
int ring_buffer_write(ring_buffer *buffer, void *msg)
Write an element into a ring_buffer.
Definition: ring_buffer.c:146
Header for EVEL library.
A ring buffer.
void ring_buffer_initialize(ring_buffer *buffer, int size)
Ring buffer initialization.
Definition: ring_buffer.c:53
#define EVEL_ERROR(FMT,...)
Definition: evel.h:3624
int ring_buffer_is_empty(ring_buffer *buffer)
Tests whether there is data in the ring_buffer.
Definition: ring_buffer.c:194
void ** ring
Definition: ring_buffer.h:50
Ring buffer structure.
Definition: ring_buffer.h:45
int next_write
Definition: ring_buffer.h:48