A simple character FIFO I wrote for my Rocket project.

Dependents:   Rocket

StringFifo.cpp

Committer:
danjulio
Date:
2017-06-11
Revision:
0:093546398fcd

File content as of revision 0:093546398fcd:

/*
 * StringFifo: A simple FIFO class for passing strings between threads.
 */
#include "StringFifo.h"

StringFifo::StringFifo(int size)
{
    sP = (char *) malloc(size);
    if (sP != NULL) {
        len = size;
    } else {
        len = 0;
    }
    pushI = 0;
    popI = 0;
}

StringFifo::~StringFifo()
{
    free(sP);
    len = 0;
}

void StringFifo::PushString(char* s)
{
    int sLen;
    int i;

    push_mutex.lock();

    // Compute the required room
    sLen = 0;
    while (*(s+sLen) != 0) sLen++;
    sLen += 1;  // Add in null character
    
    // Wait until there is room
    while (Remaining() < sLen) {
        Thread::yield();
    }
    
    // Push the string
    i = pushI;
    while ((*(sP + i) = *s++) != 0) {
        i = (i + 1) % len;
    }
    
    // Atomically update pushI
    pushI = (i + 1) % len;  // Always point to next location to fill 

    push_mutex.unlock();
}

void StringFifo::PopString(char* s)
{
    int i;

    // Wait until there is a string to pop
    while (IsEmpty()) {
        Thread::yield();
    }
    
    // Get the string
    i = popI;
    while ((*s++ = *(sP + i)) != 0) {
        i = (i + 1) % len;
    }
    
    // Update popI
    popI = (i + 1) % len;  // Always point to start of next string
}

int StringFifo::Remaining()
{
    if (pushI >= popI)
        return (len - pushI + popI);
    else
        return (popI - pushI);
}