dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hds / lib / Fifo.cpp
1 #include "Fifo.h"\r
2 \r
3 /**\r
4  *\r
5  */\r
6 Fifo::Fifo(char* name, unsigned size = 18) {\r
7     //std::cout << "Create Fifo." << std::endl;\r
8     //except at the beginning, _head and _tail must never overlap,\r
9     //otherwise one does not know whether the buffer is full or\r
10     //empty. to have nevertheless a buffer with the given capacity,\r
11     //a buffer with one more element is allocated.\r
12     _size = size;\r
13     _buffer = new char[_size];\r
14     //_head = 0;\r
15         _use = 0;\r
16     _tail = 0;\r
17     _name = new char[strlen(name) + 1];\r
18     strcpy(_name, name);\r
19 }\r
20 \r
21 /**\r
22  *\r
23  */\r
24 Fifo::~Fifo() {\r
25     //std::cout << "Delete Fifo." << std::endl;\r
26     if (_buffer) {\r
27         delete _buffer;\r
28     }\r
29     if (_name) {\r
30         delete _name;\r
31     }\r
32     _buffer = 0;\r
33     //_head = 0;\r
34         _use = 0;\r
35     _tail = 0;\r
36     _name = 0;\r
37     //std::cout << "Deleted Fifo." << std::endl;\r
38 }\r
39 \r
40 /**\r
41  *\r
42  */\r
43 unsigned Fifo::read(void *destination, unsigned len) {\r
44     char* buffer = (char*)destination;\r
45     unsigned read = 0;\r
46     //std::cout << "Try to read " << len << " bytes from Fifo " << _name << "." << std::endl;\r
47 \r
48 \r
49     while (read < len) {\r
50             while( _use < len)\r
51                     wait(_writeEvent);\r
52             unsigned tocopy = (len - read <= _use ? len - read : _use);\r
53 \r
54             if ((unsigned)_tail + tocopy < _size) {\r
55                     memcpy(buffer, _buffer + (unsigned)_tail, tocopy);\r
56             }\r
57             else {\r
58                     memcpy(buffer, _buffer + (unsigned)_tail, _size - (unsigned)_tail);\r
59                     memcpy(buffer + _size - (unsigned)_tail, _buffer, tocopy - _size + (unsigned)_tail);\r
60             }\r
61 \r
62             read += tocopy;\r
63             buffer += tocopy;\r
64             _tail = (_tail + tocopy) % _size;\r
65             _use -= read;\r
66             _readEvent.notify();\r
67     }\r
68 \r
69     /*while (read < len) {\r
70           if (used() == 0) {\r
71                 wait(_writeEvent);\r
72           } else if ((len - read) < used()) {\r
73                 while (read < len) {\r
74                   unsigned tocopy = (len - read + _tail >= _size) ? _size - _tail : len - read;\r
75                   memcpy(buffer, _buffer + _tail, tocopy);\r
76                   _tail = (_tail + tocopy) % _size;\r
77                   read += tocopy;\r
78                   buffer += tocopy;\r
79                 }\r
80                 _readEvent.notify();\r
81           } else {\r
82                 *buffer++ = *(_buffer + _tail % _size);\r
83                 _tail = (_tail + 1) % _size;\r
84                 read++;\r
85                 _readEvent.notify();\r
86           }\r
87         }*/\r
88 \r
89     //std::cout << "Read " << read << " bytes from Fifo " << _name << "." << std::endl;\r
90     return read;\r
91 }\r
92 \r
93 /**\r
94  *\r
95  */\r
96 unsigned Fifo::write(const void *source, unsigned len) {\r
97     char* buffer = (char*)source;\r
98     unsigned write = 0;\r
99         unsigned head = (_tail + _use) % _size;\r
100     //std::cout << "Try to write " << len << " bytes to Fifo " << _name << std::endl;\r
101 \r
102     while (write < len) {\r
103             while (unused() < len) \r
104                     wait(_readEvent);\r
105             unsigned tocopy = (len - write <= unused() ? len - write : unused());\r
106 \r
107             if (head + tocopy < _size) {\r
108                     memcpy(_buffer + head, buffer, tocopy);\r
109             }\r
110             else {\r
111                     memcpy(_buffer + head, buffer, _size - head);\r
112                     memcpy(_buffer, buffer + _size - head, tocopy - _size + head);\r
113             }\r
114 \r
115             write += tocopy;\r
116             buffer += tocopy;\r
117             head = (head + tocopy) % _size;\r
118             _use += write;\r
119             _writeEvent.notify();\r
120     }\r
121 \r
122     /* while (write < len) {\r
123       if (unused() == 0) {\r
124         wait(_readEvent);\r
125       } else if ((len - write) < unused()) {\r
126         while (write < len) {\r
127           unsigned tocopy = (len - write + _head >= _size) ? _size - _head : len - write;\r
128           memcpy(_buffer + _head, buffer, tocopy);\r
129           _head = (_head + tocopy) % _size;\r
130           write += tocopy;\r
131           buffer += tocopy;\r
132         }\r
133         _writeEvent.notify();\r
134       } else {\r
135         *(_buffer + (unsigned)(_head) % _size) = *buffer++;\r
136         _head = (_head + 1) % _size;\r
137         write++;\r
138         _writeEvent.notify();\r
139       }\r
140     }*/\r
141 \r
142     //std::cout << "Wrote " << write << " bytes to Fifo " << _name << "." << std::endl;\r
143     return write;\r
144 }\r
145 \r
146 /**\r
147  *\r
148  */\r
149 unsigned Fifo::size() const {\r
150     return (_size);\r
151 }\r
152 \r
153 /**\r
154  *\r
155  */\r
156 unsigned Fifo::unused() const {\r
157     return (_size) - _use;\r
158 }\r
159 \r
160 /**\r
161  *\r
162  */\r
163 unsigned Fifo::used() const {\r
164     return _use;\r
165 }\r
166 \r
167 /**\r
168  *\r
169  */\r
170 char* Fifo::getName() const {\r
171     return _name;\r
172 }\r
173 \r
174 /**\r
175  * Test the implementation\r
176  */\r
177 /*\r
178 class producer : public sc_module\r
179 {\r
180    public:\r
181      Fifo *fifo;\r
182 \r
183      SC_HAS_PROCESS(producer);\r
184 \r
185      producer(sc_module_name name) : sc_module(name)\r
186      {\r
187        SC_THREAD(main);\r
188      }\r
189 \r
190      void main()\r
191      {\r
192        const char *str =\r
193          "Visit www.systemc.org and see what SystemC can do for you today!\n";\r
194 \r
195        while (*str) {\r
196          fifo->write((void*)str++, 4);\r
197        }\r
198      }\r
199 };\r
200 \r
201 class consumer : public sc_module\r
202 {\r
203    public:\r
204      Fifo *fifo;\r
205 \r
206      SC_HAS_PROCESS(consumer);\r
207 \r
208      consumer(sc_module_name name) : sc_module(name)\r
209      {\r
210        SC_THREAD(main);\r
211      }\r
212 \r
213      void main()\r
214      {\r
215        char c;\r
216        cout << endl << endl;\r
217 \r
218        while (true) {\r
219          fifo->read(&c, 4);\r
220          cout << c << flush;\r
221 \r
222          if (fifo->used() == 1)\r
223              cout << "<1>" << flush;\r
224          if (fifo->used() == 9)\r
225              cout << "<9>" << flush;\r
226        }\r
227      }\r
228 };\r
229 \r
230 class top : public sc_module\r
231 {\r
232    public:\r
233      Fifo *fifo_inst;\r
234      producer *prod_inst;\r
235      consumer *cons_inst;\r
236 \r
237      top(sc_module_name name) : sc_module(name)\r
238      {\r
239        fifo_inst = new Fifo("myfifo", 10);\r
240 \r
241        prod_inst = new producer("producer");\r
242        prod_inst->fifo = fifo_inst;\r
243 \r
244        cons_inst = new consumer("consumer");\r
245        cons_inst->fifo = fifo_inst;\r
246      }\r
247 };\r
248 \r
249 int sc_main (int argc , char *argv[]) {\r
250    top top1("top");\r
251    sc_start();\r
252    return 0;\r
253 }\r
254 */\r