X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fprotothread%2Flib%2FWindowedFifo.cpp;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fprotothread%2Flib%2FWindowedFifo.cpp;h=743fc0ba7346be3c4f96a3b05bbe8f2bef5dd62c;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/protothread/lib/WindowedFifo.cpp b/dol/src/dol/visitor/protothread/lib/WindowedFifo.cpp new file mode 100644 index 0000000..743fc0b --- /dev/null +++ b/dol/src/dol/visitor/protothread/lib/WindowedFifo.cpp @@ -0,0 +1,203 @@ +#include "WindowedFifo.h" + +/** + * + */ +WindowedFifo::WindowedFifo(unsigned size = 20) { + //std::cout << "Create WindowedFifo." << std::endl; + _size = size; + _buffer = new char[_size]; + _head = 0; + _tail = 0; + _headRoom = 0; + _tailRoom = 0; + _use = 0; + //indicates whether Fifo is empty or full if _head == _tail + //_isFull = false; + _isHeadReserved = false; + _isTailReserved = false; +} + +/** + * + */ +WindowedFifo::~WindowedFifo() { + //std::cout << "Delete WindowedFifo." << std::endl; + if (_buffer) { + delete _buffer; + } + _buffer = 0; + _head = 0; + _tail = 0; + _use = 0; + //std::cout << "Deleted WindowedFifo." << std::endl; +} + +/** + * + */ +unsigned WindowedFifo::reserve(void** dest, unsigned len) { + char** destination = (char**)dest; + //std::cout << "Attempt to reserve " << len << " bytes." << std::endl; + + //can only reserve once piece at a time + if (_isHeadReserved) { + *destination = 0; + return 0; + } + + //reserve at most as much memory as still available in the buffer + unsigned write = (len <= _size - _use ? len : _size - _use); + + if (write > 0) { + //if wrap-around in buffer: return only buffer for the + //contiguous buffer space + if (_head + write > _size) { + write = _size - _head; + } + + _headRoom = (_head + write) == _size? 0 : _head + write; + *destination = &(_buffer[_head]); + _isHeadReserved = true; + } + + //std::cout << "Reserved " << write << " bytes." << std::endl; + _writeReserve = write; + return write; +} + +/** + * + */ +void WindowedFifo::release() { + if (_isHeadReserved) { + //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl; + _head = _headRoom; + _use += _writeReserve; + _isHeadReserved = false; + } +} + +/** + * + */ +unsigned WindowedFifo::capture(void **dest, unsigned len) { + char** destination = (char**)dest; + //std::cout << "Attempt to capture " << len << " bytes." << std::endl; + + if (_isTailReserved) { + //std::cout << "Only one attempt to capture allowed." << std::endl; + *destination = 0; + return 0; + } + + //capture at most as much data as available in the buffer + unsigned read = (len <= _use ? len : _use); + + if (read > 0) { + //if wrap-around in buffer: return only buffer for the + //conntiguous buffer space + if (_tail + read> _size) { + read = _size - _tail; + } + + _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read; + *destination = &(_buffer[_tail]); + _isTailReserved = true; + } + + //std::cout << "Captured " << read << " bytes." << std::endl; + + _readReserve = read; + return read; +} + +/** + * + */ +void WindowedFifo::consume() { + if (_isTailReserved) { + //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl; + _tail = _tailRoom; + _use -= _readReserve; + _isTailReserved = false; + } +} + +/** + * + */ +unsigned WindowedFifo::size() const { + return _size; +} + +/** + * + */ +unsigned WindowedFifo::unused() const { + return _size - _use; +} + +/** + * + */ +unsigned WindowedFifo::used() const { + return _use; +} + +/** + * Test the implementation + */ +/* +#include +#include +using namespace std; + +int main() { + WindowedFifo *myFifo = new WindowedFifo(16); + + int* buf1; + int* buf2; + int x = myFifo->reserve((void**)&buf1, 8); + *buf1 = 10; + *(buf1 + 1) = 20; + myFifo->release(); + int y = myFifo->capture((void**)&buf2, 8); + std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl; + myFifo->consume(); + + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 6; i++) { + std::cout << "write " << i << " to Fifo. "; + int write = myFifo->reserve((void**)&buf1, sizeof(int)); + if (write == sizeof(int)) { + *buf1 = i; + myFifo->release(); + std::cout << "used: " << std::setw(2) << myFifo->used() + << ", unused: " << std::setw(2) << myFifo->unused() + << ", size: " << std::setw(2) << myFifo->size() + << std::endl; + } else { + std::cout << std::endl; + } + } + for (int i = 0; i < 16; i++) { + char* buf3; + int read = myFifo->capture((void**)&buf3, sizeof(char)); + if (read == sizeof(char)) { + std::cout << "read " << (unsigned)*buf3 << " from Fifo "; + std::cout << "used: " << std::setw(2) << myFifo->used() + << ", unused: " << std::setw(2) << myFifo->unused() + << ", size: " << std::setw(2) << myFifo->size() + << std::endl; + myFifo->consume(); + } else { + std::cout << "read nothing from Fifo." << std::endl; + } + + } + } + delete myFifo; + return 0; +} +*/