|
|
|
|
@ -40,39 +40,162 @@
|
|
|
|
|
|
|
|
|
|
#define USLEEP_TIME 5
|
|
|
|
|
|
|
|
|
|
/* Multi Reader, Single Writer, 8 bits */
|
|
|
|
|
/* Single Reader, Single Writer, 8 bits */
|
|
|
|
|
|
|
|
|
|
RingBuffer8 *RingBufferMrSw8Init(void) {
|
|
|
|
|
RingBuffer8 *rb = SCMalloc(sizeof(RingBuffer8));
|
|
|
|
|
if (rb == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
void *RingBufferSrSw8Get(RingBuffer8 *rb) {
|
|
|
|
|
void *ptr = NULL;
|
|
|
|
|
|
|
|
|
|
/* buffer is empty, wait... */
|
|
|
|
|
while (SC_ATOMIC_GET(rb->read) == SC_ATOMIC_GET(rb->write)) {
|
|
|
|
|
/* break out if the engine wants to shutdown */
|
|
|
|
|
if (rb->shutdown != 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
struct timespec cond_time;
|
|
|
|
|
cond_time.tv_sec = time(NULL) + 1;
|
|
|
|
|
cond_time.tv_nsec = 0;
|
|
|
|
|
SCMutexLock(&rb->wait_mutex);
|
|
|
|
|
SCCondTimedwait(&rb->wait_cond, &rb->wait_mutex, &cond_time);
|
|
|
|
|
SCMutexUnlock(&rb->wait_mutex);
|
|
|
|
|
#else
|
|
|
|
|
usleep(USLEEP_TIME);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(rb, 0x00, sizeof(RingBuffer8));
|
|
|
|
|
ptr = rb->array[SC_ATOMIC_GET(rb->read)];
|
|
|
|
|
SC_ATOMIC_ADD(rb->read, 1);
|
|
|
|
|
|
|
|
|
|
SC_ATOMIC_INIT(rb->write);
|
|
|
|
|
SC_ATOMIC_INIT(rb->read);
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCCondSignal(&rb->wait_cond);
|
|
|
|
|
#endif
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int RingBufferSrSw8Put(RingBuffer8 *rb, void *ptr) {
|
|
|
|
|
/* buffer is full, wait... */
|
|
|
|
|
while ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) {
|
|
|
|
|
/* break out if the engine wants to shutdown */
|
|
|
|
|
if (rb->shutdown != 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCMutexInit(&rb->wait_mutex, NULL);
|
|
|
|
|
SCCondInit(&rb->wait_cond, NULL);
|
|
|
|
|
struct timespec cond_time;
|
|
|
|
|
cond_time.tv_sec = time(NULL) + 1;
|
|
|
|
|
cond_time.tv_nsec = 0;
|
|
|
|
|
SCMutexLock(&rb->wait_mutex);
|
|
|
|
|
SCCondTimedwait(&rb->wait_cond, &rb->wait_mutex, &cond_time);
|
|
|
|
|
SCMutexUnlock(&rb->wait_mutex);
|
|
|
|
|
#else
|
|
|
|
|
usleep(USLEEP_TIME);
|
|
|
|
|
#endif
|
|
|
|
|
return rb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rb->array[SC_ATOMIC_GET(rb->write)] = ptr;
|
|
|
|
|
SC_ATOMIC_ADD(rb->write, 1);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCCondSignal(&rb->wait_cond);
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RingBufferMrSw8Destroy(RingBuffer8 *rb) {
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->write);
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->read);
|
|
|
|
|
/* Single Reader, Multi Writer, 8 bites */
|
|
|
|
|
|
|
|
|
|
void *RingBufferSrMw8Get(RingBuffer8 *rb) {
|
|
|
|
|
void *ptr = NULL;
|
|
|
|
|
|
|
|
|
|
/* buffer is empty, wait... */
|
|
|
|
|
while (SC_ATOMIC_GET(rb->read) == SC_ATOMIC_GET(rb->write)) {
|
|
|
|
|
/* break out if the engine wants to shutdown */
|
|
|
|
|
if (rb->shutdown != 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCMutexDestroy(&rb->wait_mutex);
|
|
|
|
|
SCCondDestroy(&rb->wait_cond);
|
|
|
|
|
struct timespec cond_time;
|
|
|
|
|
cond_time.tv_sec = time(NULL) + 1;
|
|
|
|
|
cond_time.tv_nsec = 0;
|
|
|
|
|
SCMutexLock(&rb->wait_mutex);
|
|
|
|
|
SCCondTimedwait(&rb->wait_cond, &rb->wait_mutex, &cond_time);
|
|
|
|
|
SCMutexUnlock(&rb->wait_mutex);
|
|
|
|
|
#else
|
|
|
|
|
usleep(USLEEP_TIME);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ptr = rb->array[SC_ATOMIC_GET(rb->read)];
|
|
|
|
|
SC_ATOMIC_ADD(rb->read, 1);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCCondSignal(&rb->wait_cond);
|
|
|
|
|
#endif
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief put a ptr in the RingBuffer.
|
|
|
|
|
*
|
|
|
|
|
* As we support multiple writers we need to protect 2 things:
|
|
|
|
|
* 1. writing the ptr to the array
|
|
|
|
|
* 2. incrementing the rb->write idx
|
|
|
|
|
*
|
|
|
|
|
* We can't do both at the same time in one atomic operation, so
|
|
|
|
|
* we need to (spin) lock it. We do increment rb->write atomically
|
|
|
|
|
* after that, so that we don't need to use the lock in our *Get
|
|
|
|
|
* function.
|
|
|
|
|
*
|
|
|
|
|
* \param rb the ringbuffer
|
|
|
|
|
* \param ptr ptr to store
|
|
|
|
|
*
|
|
|
|
|
* \retval 0 ok
|
|
|
|
|
* \retval -1 wait loop interrupted because of engine flags
|
|
|
|
|
*/
|
|
|
|
|
int RingBufferSrMw8Put(RingBuffer8 *rb, void *ptr) {
|
|
|
|
|
SCLogDebug("ptr %p", ptr);
|
|
|
|
|
|
|
|
|
|
/* buffer is full, wait... */
|
|
|
|
|
retry:
|
|
|
|
|
while ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) {
|
|
|
|
|
/* break out if the engine wants to shutdown */
|
|
|
|
|
if (rb->shutdown != 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
struct timespec cond_time;
|
|
|
|
|
cond_time.tv_sec = time(NULL) + 1;
|
|
|
|
|
cond_time.tv_nsec = 0;
|
|
|
|
|
SCMutexLock(&rb->wait_mutex);
|
|
|
|
|
SCCondTimedwait(&rb->wait_cond, &rb->wait_mutex, &cond_time);
|
|
|
|
|
SCMutexUnlock(&rb->wait_mutex);
|
|
|
|
|
#else
|
|
|
|
|
usleep(USLEEP_TIME);
|
|
|
|
|
#endif
|
|
|
|
|
SCFree(rb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* get our lock */
|
|
|
|
|
SCSpinLock(&rb->spin);
|
|
|
|
|
/* if while we got our lock the buffer changed, we need to retry */
|
|
|
|
|
if ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) {
|
|
|
|
|
SCSpinUnlock(&rb->spin);
|
|
|
|
|
goto retry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCLogDebug("rb->write %u, ptr %p", SC_ATOMIC_GET(rb->write), ptr);
|
|
|
|
|
|
|
|
|
|
/* update the ring buffer */
|
|
|
|
|
rb->array[SC_ATOMIC_GET(rb->write)] = ptr;
|
|
|
|
|
SC_ATOMIC_ADD(rb->write, 1);
|
|
|
|
|
SCSpinUnlock(&rb->spin);
|
|
|
|
|
SCLogDebug("ptr %p, done", ptr);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCCondSignal(&rb->wait_cond);
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Multi Reader, Single Writer, 8 bits */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief get the next ptr from the ring buffer
|
|
|
|
|
*
|
|
|
|
|
@ -163,37 +286,6 @@ int RingBufferMrSw8Put(RingBuffer8 *rb, void *ptr) {
|
|
|
|
|
|
|
|
|
|
/* Multi Reader, Single Writer */
|
|
|
|
|
|
|
|
|
|
RingBuffer16 *RingBufferMrSwInit(void) {
|
|
|
|
|
RingBuffer16 *rb = SCMalloc(sizeof(RingBuffer16));
|
|
|
|
|
if (rb == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(rb, 0x00, sizeof(RingBuffer16));
|
|
|
|
|
|
|
|
|
|
SC_ATOMIC_INIT(rb->write);
|
|
|
|
|
SC_ATOMIC_INIT(rb->read);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCMutexInit(&rb->wait_mutex, NULL);
|
|
|
|
|
SCCondInit(&rb->wait_cond, NULL);
|
|
|
|
|
#endif
|
|
|
|
|
return rb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RingBufferMrSwDestroy(RingBuffer16 *rb) {
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->write);
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->read);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCMutexDestroy(&rb->wait_mutex);
|
|
|
|
|
SCCondDestroy(&rb->wait_cond);
|
|
|
|
|
#endif
|
|
|
|
|
SCFree(rb);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief get the next ptr from the ring buffer
|
|
|
|
|
*
|
|
|
|
|
@ -284,38 +376,6 @@ int RingBufferMrSwPut(RingBuffer16 *rb, void *ptr) {
|
|
|
|
|
|
|
|
|
|
/* Single Reader, Single Writer */
|
|
|
|
|
|
|
|
|
|
RingBuffer16 *RingBufferSrSwInit(void) {
|
|
|
|
|
RingBuffer16 *rb = SCMalloc(sizeof(RingBuffer16));
|
|
|
|
|
if (rb == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(rb, 0x00, sizeof(RingBuffer16));
|
|
|
|
|
|
|
|
|
|
SC_ATOMIC_INIT(rb->write);
|
|
|
|
|
SC_ATOMIC_INIT(rb->read);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCMutexInit(&rb->wait_mutex, NULL);
|
|
|
|
|
SCCondInit(&rb->wait_cond, NULL);
|
|
|
|
|
#endif
|
|
|
|
|
return rb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RingBufferSrSwDestroy(RingBuffer16 *rb) {
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->write);
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->read);
|
|
|
|
|
|
|
|
|
|
#ifdef RINGBUFFER_MUTEX_WAIT
|
|
|
|
|
SCMutexDestroy(&rb->wait_mutex);
|
|
|
|
|
SCCondDestroy(&rb->wait_cond);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
SCFree(rb);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *RingBufferSrSwGet(RingBuffer16 *rb) {
|
|
|
|
|
void *ptr = NULL;
|
|
|
|
|
|
|
|
|
|
@ -376,7 +436,7 @@ int RingBufferSrSwPut(RingBuffer16 *rb, void *ptr) {
|
|
|
|
|
|
|
|
|
|
/* Multi Reader, Multi Writer, 8 bits */
|
|
|
|
|
|
|
|
|
|
RingBuffer8 *RingBufferMrMw8Init(void) {
|
|
|
|
|
RingBuffer8 *RingBuffer8Init(void) {
|
|
|
|
|
RingBuffer8 *rb = SCMalloc(sizeof(RingBuffer8));
|
|
|
|
|
if (rb == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
@ -395,7 +455,7 @@ RingBuffer8 *RingBufferMrMw8Init(void) {
|
|
|
|
|
return rb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RingBufferMrMw8Destroy(RingBuffer8 *rb) {
|
|
|
|
|
void RingBuffer8Destroy(RingBuffer8 *rb) {
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->write);
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->read);
|
|
|
|
|
@ -526,7 +586,7 @@ retry:
|
|
|
|
|
|
|
|
|
|
/* Multi Reader, Multi Writer, 16 bits */
|
|
|
|
|
|
|
|
|
|
RingBuffer16 *RingBufferMrMwInit(void) {
|
|
|
|
|
RingBuffer16 *RingBufferInit(void) {
|
|
|
|
|
RingBuffer16 *rb = SCMalloc(sizeof(RingBuffer16));
|
|
|
|
|
if (rb == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
@ -545,7 +605,7 @@ RingBuffer16 *RingBufferMrMwInit(void) {
|
|
|
|
|
return rb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RingBufferMrMwDestroy(RingBuffer16 *rb) {
|
|
|
|
|
void RingBufferDestroy(RingBuffer16 *rb) {
|
|
|
|
|
if (rb != NULL) {
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->write);
|
|
|
|
|
SC_ATOMIC_DESTROY(rb->read);
|
|
|
|
|
|