1 #include "WindowedFifo.h"
6 WindowedFifo::WindowedFifo(unsigned size = 20) {
7 //std::cout << "Create WindowedFifo." << std::endl;
10 _buffer = (char *) _malloc_align(_size, ALIGNMENT_FACTOR);
12 fprintf(stderr,"[WFIFO] Memory allocation failure\n");
21 _isHeadReserved = false;
22 _isTailReserved = false;
32 WindowedFifo::~WindowedFifo() {
33 //std::cout << "Delete WindowedFifo." << std::endl;
41 //std::cout << "Deleted WindowedFifo." << std::endl;
47 unsigned WindowedFifo::reserve(char** destination, unsigned len) {
49 //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;
51 //can only reserve once piece at a time
52 if (_isHeadReserved) {
57 //reserve at most as much memory as still available in the buffer
58 unsigned write = (len <= _size - _use ? len : 0);
61 //if wrap-around in buffer: return only buffer for the
62 //contiguous buffer space
63 if (_head + write > _size) {
64 write = _size - _head;
67 _headRoom = (_head + write) == _size ? 0 : _head + write;
68 *destination = &(_buffer[_head]);
69 _isHeadReserved = true;
72 //std::cout << "Reserved " << write << " bytes." << std::endl;
73 _writeReserve = write;
80 void WindowedFifo::release() {
81 if (_isHeadReserved) {
82 //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;
84 _use += _writeReserve;
85 _isHeadReserved = false;
92 unsigned WindowedFifo::capture(char **destination, unsigned len) {
94 //std::cout << "Attempt to capture " << len << " bytes." << std::endl;
96 if (_isTailReserved) {
97 //std::cout << "Only one attempt to capture allowed." << std::endl;
102 //capture at most as much data as available in the buffer
103 unsigned read = (len <= _use ? len : 0);
106 //if wrap-around in buffer: return only buffer for the
107 //conntiguous buffer space
108 if (_tail + read > _size) {
109 read = _size - _tail;
112 _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;
113 *destination = &(_buffer[_tail]);
114 _isTailReserved = true;
118 //std::cout << "Captured " << read << " bytes." << std::endl;
126 void WindowedFifo::consume() {
127 if (_isTailReserved) {
128 //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;
130 _use -= _readReserve;
131 _isTailReserved = false;
138 unsigned WindowedFifo::size() const {
145 unsigned WindowedFifo::unused() const {
152 unsigned WindowedFifo::used() const {
157 * Get the pointer to the start of the queue
159 char *WindowedFifo::getQueuePointer() {
164 * Has completed a dma read process, i.e. has read out of the queue
166 void WindowedFifo::dmaRead(unsigned len) {
168 _blocked = BLOCKED_MAX_NR;
170 _tail = ((unsigned) (_tail + len) % _size);
178 * Start a DMA request, returns the current space one have
180 unsigned WindowedFifo::dmaStart() {
183 if (_tail + _use > _size) {
184 return _size - _tail;
191 * Is allowed to start a dma request
193 bool WindowedFifo::dmaAllowed() {
194 #ifndef STORE_REQUESTS
207 * Is needed for DMA transfers
209 unsigned WindowedFifo::dmaWrite(const void *source, unsigned len) {
211 char* buffer = (char*) source;
213 if (_head + len < _size) {
214 memcpy(_buffer + _head, buffer, len);
216 // We should never be here!
217 memcpy(_buffer + _head, buffer, _size - _head);
218 memcpy(_buffer, buffer + _size - _head, len - _size + _head);
221 _head = (_head + len) >= _size ? _head + len - _size : _head + len;
227 * Test the implementation
231 WindowedFifo *myFifo = new WindowedFifo(16);
235 int x = myFifo->reserve((char**)&buf1, 8);
239 int y = myFifo->capture((char**)&buf2, 8);
240 std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl;
243 for (int j = 0; j < 3; j++) {
244 for (int i = 0; i < 6; i++) {
245 std::cout << "write " << i << " to Fifo. ";
246 int write = myFifo->reserve((char**)&buf1, sizeof(int));
247 if (write == sizeof(int)) {
250 std::cout << "used: " << std::setw(2) << myFifo->used()
251 << ", unused: " << std::setw(2) << myFifo->unused()
252 << ", size: " << std::setw(2) << myFifo->size()
255 std::cout << std::endl;
258 for (int i = 0; i < 16; i++) {
260 int read = myFifo->capture((char**)&buf3, sizeof(char));
261 if (read == sizeof(char)) {
262 std::cout << "read " << (unsigned)*buf3 << " from Fifo ";
263 std::cout << "used: " << std::setw(2) << myFifo->used()
264 << ", unused: " << std::setw(2) << myFifo->unused()
265 << ", size: " << std::setw(2) << myFifo->size()
269 std::cout << "read nothing from Fifo." << std::endl;