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