A simple character FIFO I wrote for my Rocket project.

Dependents:   Rocket

Committer:
danjulio
Date:
Sun Jun 11 04:06:39 2017 +0000
Revision:
0:093546398fcd
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danjulio 0:093546398fcd 1 /*
danjulio 0:093546398fcd 2 * StringFifo: A simple FIFO class for passing strings between threads.
danjulio 0:093546398fcd 3 */
danjulio 0:093546398fcd 4 #include "StringFifo.h"
danjulio 0:093546398fcd 5
danjulio 0:093546398fcd 6 StringFifo::StringFifo(int size)
danjulio 0:093546398fcd 7 {
danjulio 0:093546398fcd 8 sP = (char *) malloc(size);
danjulio 0:093546398fcd 9 if (sP != NULL) {
danjulio 0:093546398fcd 10 len = size;
danjulio 0:093546398fcd 11 } else {
danjulio 0:093546398fcd 12 len = 0;
danjulio 0:093546398fcd 13 }
danjulio 0:093546398fcd 14 pushI = 0;
danjulio 0:093546398fcd 15 popI = 0;
danjulio 0:093546398fcd 16 }
danjulio 0:093546398fcd 17
danjulio 0:093546398fcd 18 StringFifo::~StringFifo()
danjulio 0:093546398fcd 19 {
danjulio 0:093546398fcd 20 free(sP);
danjulio 0:093546398fcd 21 len = 0;
danjulio 0:093546398fcd 22 }
danjulio 0:093546398fcd 23
danjulio 0:093546398fcd 24 void StringFifo::PushString(char* s)
danjulio 0:093546398fcd 25 {
danjulio 0:093546398fcd 26 int sLen;
danjulio 0:093546398fcd 27 int i;
danjulio 0:093546398fcd 28
danjulio 0:093546398fcd 29 push_mutex.lock();
danjulio 0:093546398fcd 30
danjulio 0:093546398fcd 31 // Compute the required room
danjulio 0:093546398fcd 32 sLen = 0;
danjulio 0:093546398fcd 33 while (*(s+sLen) != 0) sLen++;
danjulio 0:093546398fcd 34 sLen += 1; // Add in null character
danjulio 0:093546398fcd 35
danjulio 0:093546398fcd 36 // Wait until there is room
danjulio 0:093546398fcd 37 while (Remaining() < sLen) {
danjulio 0:093546398fcd 38 Thread::yield();
danjulio 0:093546398fcd 39 }
danjulio 0:093546398fcd 40
danjulio 0:093546398fcd 41 // Push the string
danjulio 0:093546398fcd 42 i = pushI;
danjulio 0:093546398fcd 43 while ((*(sP + i) = *s++) != 0) {
danjulio 0:093546398fcd 44 i = (i + 1) % len;
danjulio 0:093546398fcd 45 }
danjulio 0:093546398fcd 46
danjulio 0:093546398fcd 47 // Atomically update pushI
danjulio 0:093546398fcd 48 pushI = (i + 1) % len; // Always point to next location to fill
danjulio 0:093546398fcd 49
danjulio 0:093546398fcd 50 push_mutex.unlock();
danjulio 0:093546398fcd 51 }
danjulio 0:093546398fcd 52
danjulio 0:093546398fcd 53 void StringFifo::PopString(char* s)
danjulio 0:093546398fcd 54 {
danjulio 0:093546398fcd 55 int i;
danjulio 0:093546398fcd 56
danjulio 0:093546398fcd 57 // Wait until there is a string to pop
danjulio 0:093546398fcd 58 while (IsEmpty()) {
danjulio 0:093546398fcd 59 Thread::yield();
danjulio 0:093546398fcd 60 }
danjulio 0:093546398fcd 61
danjulio 0:093546398fcd 62 // Get the string
danjulio 0:093546398fcd 63 i = popI;
danjulio 0:093546398fcd 64 while ((*s++ = *(sP + i)) != 0) {
danjulio 0:093546398fcd 65 i = (i + 1) % len;
danjulio 0:093546398fcd 66 }
danjulio 0:093546398fcd 67
danjulio 0:093546398fcd 68 // Update popI
danjulio 0:093546398fcd 69 popI = (i + 1) % len; // Always point to start of next string
danjulio 0:093546398fcd 70 }
danjulio 0:093546398fcd 71
danjulio 0:093546398fcd 72 int StringFifo::Remaining()
danjulio 0:093546398fcd 73 {
danjulio 0:093546398fcd 74 if (pushI >= popI)
danjulio 0:093546398fcd 75 return (len - pushI + popI);
danjulio 0:093546398fcd 76 else
danjulio 0:093546398fcd 77 return (popI - pushI);
danjulio 0:093546398fcd 78 }