mods to make fifo thread safe
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 19 Nov 2012 02:54:22 +0000 (02:54 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 19 Nov 2012 02:54:22 +0000 (02:54 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1022 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/fifo.c
codec2-dev/src/fifo.h
codec2-dev/unittest/tfifo.c

index 2773f994e6352df1270d8258b299f4340ff8a4bb..6ac3dbac73de6be9d819d1c563645eafd6c94b94 100644 (file)
@@ -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;
 }
 
index e9bf2418b8436734c27ea374a17bf4059fbf6033..a6a10395ded05f0711688f77e2060cba4d239907 100644 (file)
@@ -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
 }
index d7c64c72e073b47af0ffd2815494b4f8383d9677..f52c4cf551e383fe8ce9b4b33fb3e0ae5e0073a1 100644 (file)
@@ -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<WRITE_SZ; i++) {
             write_buf[i] = n_in++;
             if (n_in == N_MAX)