dol: initial dol commit
[jump.git] / dol / src / dol / visitor / protothread / lib / WindowedFifo.cpp
1 #include "WindowedFifo.h"\r
2 \r
3 /**\r
4  *\r
5  */\r
6 WindowedFifo::WindowedFifo(unsigned size = 20) {\r
7     //std::cout << "Create WindowedFifo." << std::endl;\r
8     _size = size;\r
9     _buffer = new char[_size];\r
10     _head = 0;\r
11     _tail = 0;\r
12     _headRoom = 0;\r
13     _tailRoom = 0;\r
14     _use = 0;\r
15     //indicates whether Fifo is empty or full if _head == _tail\r
16     //_isFull = false;\r
17     _isHeadReserved = false;\r
18     _isTailReserved = false;\r
19 }\r
20 \r
21 /**\r
22  *\r
23  */\r
24 WindowedFifo::~WindowedFifo() {\r
25     //std::cout << "Delete WindowedFifo." << std::endl;\r
26     if (_buffer) {\r
27         delete _buffer;\r
28     }\r
29     _buffer = 0;\r
30     _head = 0;\r
31     _tail = 0;\r
32     _use = 0;\r
33     //std::cout << "Deleted WindowedFifo." << std::endl;\r
34 }\r
35 \r
36 /**\r
37  *\r
38  */\r
39 unsigned WindowedFifo::reserve(void** dest, unsigned len) {\r
40     char** destination = (char**)dest;\r
41     //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;\r
42 \r
43     //can only reserve once piece at a time\r
44     if (_isHeadReserved) {\r
45         *destination = 0;\r
46         return 0;\r
47     }\r
48 \r
49     //reserve at most as much memory as still available in the buffer\r
50     unsigned write = (len <= _size - _use ? len : _size - _use);\r
51 \r
52     if (write > 0) {\r
53         //if wrap-around in buffer: return only buffer for the\r
54         //contiguous buffer space\r
55         if (_head + write > _size) {\r
56             write = _size - _head;\r
57         }\r
58 \r
59         _headRoom = (_head + write) == _size? 0 : _head + write;\r
60         *destination = &(_buffer[_head]);\r
61         _isHeadReserved = true;\r
62     }\r
63 \r
64     //std::cout << "Reserved " << write << " bytes." << std::endl;\r
65     _writeReserve = write; \r
66     return write;\r
67 }\r
68 \r
69 /**\r
70  *\r
71  */\r
72 void WindowedFifo::release() {\r
73     if (_isHeadReserved) {\r
74         //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;\r
75         _head = _headRoom;\r
76         _use += _writeReserve;\r
77         _isHeadReserved = false;\r
78     }\r
79 }\r
80 \r
81 /**\r
82  *\r
83  */\r
84 unsigned WindowedFifo::capture(void **dest, unsigned len) {\r
85     char** destination = (char**)dest;\r
86     //std::cout << "Attempt to capture " << len << " bytes." << std::endl;\r
87 \r
88     if (_isTailReserved) {\r
89         //std::cout << "Only one attempt to capture allowed." << std::endl;\r
90         *destination = 0;\r
91         return 0;\r
92     }\r
93 \r
94     //capture at most as much data as available in the buffer\r
95     unsigned read = (len <= _use ? len : _use);\r
96 \r
97     if (read > 0) {\r
98         //if wrap-around in buffer: return only buffer for the\r
99         //conntiguous buffer space\r
100         if (_tail + read> _size) {\r
101             read = _size - _tail;\r
102         }\r
103 \r
104         _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;\r
105         *destination = &(_buffer[_tail]);\r
106         _isTailReserved = true;\r
107     }\r
108 \r
109     //std::cout << "Captured " << read << " bytes." << std::endl;\r
110 \r
111     _readReserve = read; \r
112     return read;\r
113 }\r
114 \r
115 /**\r
116  *\r
117  */\r
118 void WindowedFifo::consume() {\r
119     if (_isTailReserved) {\r
120         //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;\r
121         _tail = _tailRoom;\r
122         _use -= _readReserve;\r
123         _isTailReserved = false;\r
124     }\r
125 }\r
126 \r
127 /**\r
128  *\r
129  */\r
130 unsigned WindowedFifo::size() const {\r
131     return _size;\r
132 }\r
133 \r
134 /**\r
135  *\r
136  */\r
137 unsigned WindowedFifo::unused() const {\r
138     return _size - _use;\r
139 }\r
140 \r
141 /**\r
142  *\r
143  */\r
144 unsigned WindowedFifo::used() const {\r
145         return _use;\r
146 }\r
147 \r
148 /**\r
149  * Test the implementation\r
150  */\r
151 /*\r
152 #include <iostream>\r
153 #include <iomanip>\r
154 using namespace std;\r
155 \r
156 int main() {\r
157     WindowedFifo *myFifo = new WindowedFifo(16);\r
158 \r
159     int* buf1;\r
160     int* buf2;\r
161     int x = myFifo->reserve((void**)&buf1, 8);\r
162     *buf1 = 10;\r
163     *(buf1 + 1) = 20;\r
164     myFifo->release();\r
165     int y = myFifo->capture((void**)&buf2, 8);\r
166     std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl;\r
167     myFifo->consume();\r
168 \r
169     for (int j = 0; j < 3; j++) {\r
170         for (int i = 0; i < 6; i++) {\r
171             std::cout << "write " << i << " to Fifo.    ";\r
172             int write = myFifo->reserve((void**)&buf1, sizeof(int));\r
173             if (write == sizeof(int)) {\r
174                 *buf1 = i;\r
175                 myFifo->release();\r
176                 std::cout << "used: " << std::setw(2) << myFifo->used()\r
177                         << ", unused: " << std::setw(2) << myFifo->unused()\r
178                         << ", size: "  << std::setw(2) << myFifo->size()\r
179                         << std::endl;\r
180             } else {\r
181                 std::cout << std::endl;\r
182             }\r
183         }\r
184         for (int i = 0; i < 16; i++) {\r
185             char* buf3;\r
186             int read = myFifo->capture((void**)&buf3, sizeof(char));\r
187             if (read == sizeof(char)) {\r
188                 std::cout << "read " << (unsigned)*buf3 << "  from Fifo   ";\r
189                 std::cout << "used: " << std::setw(2) << myFifo->used()\r
190                         << ", unused: " << std::setw(2) << myFifo->unused()\r
191                         << ", size: "  << std::setw(2) << myFifo->size()\r
192                         << std::endl;\r
193                 myFifo->consume();\r
194             } else {\r
195                 std::cout << "read nothing from Fifo." << std::endl;\r
196             }\r
197 \r
198         }\r
199     }\r
200     delete myFifo;\r
201     return 0;\r
202 }\r
203 */\r