From: drowe67 Date: Mon, 19 Nov 2012 02:54:22 +0000 (+0000) Subject: mods to make fifo thread safe X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=870bd2abd44ab69e7a0cd0c70013d5e103324cc9;p=freetel-svn-tracking.git mods to make fifo thread safe git-svn-id: https://svn.code.sf.net/p/freetel/code@1022 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/fifo.c b/codec2-dev/src/fifo.c index 2773f994..6ac3dbac 100644 --- a/codec2-dev/src/fifo.c +++ b/codec2-dev/src/fifo.c @@ -5,7 +5,10 @@ DATE CREATED: Oct 15 2012 A FIFO design useful in gluing the FDMDV modem and codec together in - integrated applications. + integrated applications. The unittest/tfifo indicates these + routines are thread safe without the need for syncronisisation + object, e.g. a different thread can read and write to a fifo at the + same time. \*---------------------------------------------------------------------------*/ @@ -36,7 +39,6 @@ struct FIFO { short *pin; short *pout; int nshort; - int n; }; struct FIFO *fifo_create(int nshort) { @@ -50,7 +52,6 @@ struct FIFO *fifo_create(int nshort) { fifo->pin = fifo->buf; fifo->pout = fifo->buf; fifo->nshort = nshort; - fifo->n = 0; return fifo; } @@ -67,11 +68,13 @@ int fifo_write(struct FIFO *fifo, short data[], int n) { short *pdata; short *pin = fifo->pin; - //printf(" write %d in: %d\n", n, pin-fifo->pin); assert(fifo != NULL); assert(data != NULL); - fifo_free = fifo->nshort - fifo->n; + // available storage is one less than nshort as prd == pwr + // is reserved for empty rather than full + + fifo_free = fifo->nshort - fifo_used(fifo) - 1; if (n > fifo_free) { return -1; @@ -87,7 +90,6 @@ int fifo_write(struct FIFO *fifo, short data[], int n) { if (pin == (fifo->buf + fifo->nshort)) pin = fifo->buf; } - fifo->n += n; fifo->pin = pin; } @@ -98,13 +100,13 @@ int fifo_read(struct FIFO *fifo, short data[], int n) { int i; short *pdata; + short *pin = fifo->pin; short *pout = fifo->pout; - //printf(" read %d pout: %d\n", n, pout-fifo->buf); assert(fifo != NULL); assert(data != NULL); - if (n > fifo->n) { + if (n > fifo_used(fifo)) { return -1; } else { @@ -118,16 +120,24 @@ int fifo_read(struct FIFO *fifo, short data[], int n) if (pout == (fifo->buf + fifo->nshort)) pout = fifo->buf; } - fifo->n -= n; fifo->pout = pout; } return 0; } -int fifo_n(struct FIFO *fifo) +int fifo_used(struct FIFO *fifo) { - assert(fifo != NULL); - return fifo->n; + short *pin = fifo->pin; + short *pout = fifo->pout; + unsigned int used; + + assert(fifo != NULL); + if (pin >= pout) + used = pin - pout; + else + used = fifo->nshort + (unsigned int)(pin - pout); + + return used; } diff --git a/codec2-dev/src/fifo.h b/codec2-dev/src/fifo.h index e9bf2418..a6a10395 100644 --- a/codec2-dev/src/fifo.h +++ b/codec2-dev/src/fifo.h @@ -39,7 +39,7 @@ struct FIFO *fifo_create(int nshort); void fifo_destroy(struct FIFO *fifo); int fifo_write(struct FIFO *fifo, short data[], int n); int fifo_read(struct FIFO *fifo, short data[], int n); -int fifo_n(struct FIFO *fifo); +int fifo_used(struct FIFO *fifo); #ifdef __cplusplus } diff --git a/codec2-dev/unittest/tfifo.c b/codec2-dev/unittest/tfifo.c index d7c64c72..f52c4cf5 100644 --- a/codec2-dev/unittest/tfifo.c +++ b/codec2-dev/unittest/tfifo.c @@ -15,7 +15,7 @@ #define WRITE_SZ 10 #define READ_SZ 8 #define N_MAX 100 -#define LOOPS 10000 +#define LOOPS 1000000 int run_thread = 1; struct FIFO *f; @@ -25,7 +25,7 @@ void *writer_thread(void *data); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #define USE_THREADS -#define USE_MUTEX +//#define USE_MUTEX int main() { pthread_t awriter_thread; @@ -79,7 +79,7 @@ void writer(void) { short write_buf[WRITE_SZ]; int i; - if ((FIFO_SZ - fifo_n(f)) > WRITE_SZ) { + if ((FIFO_SZ - fifo_used(f)) > WRITE_SZ) { for(i=0; i