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
13 _buffer = new char[_size];
\r
16 _name = new char[strlen(name) + 1];
\r
17 strcpy(_name, name);
\r
18 _mutex = new Mutex();
\r
19 _readCondition = new Condition(_mutex);
\r
20 _writeCondition = new Condition(_mutex);
\r
27 //std::cout << "Delete Fifo." << std::endl;
\r
34 if (_readCondition) {
\r
35 delete _readCondition;
\r
37 if (_writeCondition) {
\r
38 delete _writeCondition;
\r
49 _writeCondition = 0;
\r
51 //std::cout << "Deleted Fifo." << std::endl;
\r
57 unsigned Fifo::read(void *destination, unsigned len) {
\r
58 char* buffer = (char*)destination;
\r
60 //std::cout << "Try to read " << len << " bytes from Fifo " << _name << "." << std::endl;
\r
62 while (read < len) {
\r
64 while (used() == 0) {
\r
65 _writeCondition->wait();
\r
69 if ((len - read) < used()) {
\r
70 while (read < len) {
\r
72 unsigned tocopy = (len - read + _tail >= _size) ? _size - _tail : len - read;
\r
73 memcpy(buffer, _buffer + _tail, tocopy);
\r
74 _tail = (_tail + tocopy) % _size;
\r
79 _readCondition->notify();
\r
82 *buffer++ = *(_buffer + _tail % _size);
\r
83 _tail = (_tail + 1) % _size;
\r
86 _readCondition->notify();
\r
90 //std::cout << "Read " << read << " bytes from Fifo " << _name << "." << std::endl;
\r
97 unsigned Fifo::write(const void *source, unsigned len) {
\r
98 char* buffer = (char*)source;
\r
100 //std::cout << "Try to write " << len << " bytes to Fifo " << _name << std::endl;
\r
102 while (write < len) {
\r
104 while (unused() == 0) {
\r
105 _readCondition->wait();
\r
109 if ((len - write) < unused()) {
\r
110 while (write < len) {
\r
111 unsigned tocopy = (len - write + _head >= _size) ? _size - _head : len - write;
\r
113 memcpy(_buffer + _head, buffer, tocopy);
\r
114 _head = (_head + tocopy) % _size;
\r
119 _writeCondition->notify();
\r
122 *(_buffer + (unsigned)(_head) % _size) = *buffer++;
\r
123 _head = (_head + 1) % _size;
\r
126 _writeCondition->notify();
\r
129 //std::cout << "Wrote " << write << " bytes to Fifo " << _name << "." << std::endl;
\r
136 unsigned Fifo::size() const {
\r
137 return (_size - 1);
\r
143 unsigned Fifo::unused() const {
\r
144 return (_size - 1) - used();
\r
150 unsigned Fifo::used() const {
\r
151 if (_head >= _tail) {
\r
152 return _head - _tail;
\r
154 return _head + _size - _tail;
\r
160 char* Fifo::getName() const {
\r
165 * Test the implementation
\r
168 #include <iostream>
\r
169 void* producer(void *fifo)
\r
172 "Visit www.systemc.org and see what SystemC can do for you today!\n";
\r
175 //printf("%c", *str);
\r
176 ((Fifo*)fifo)->write((void*)str++, 4);
\r
178 printf("\nproducer returns.\n");
\r
182 void* consumer(void *fifo)
\r
185 while (c != '\n') {
\r
186 ((Fifo*)fifo)->read(&c, 4);
\r
187 std::cout << c << std::flush;
\r
189 if (((Fifo*)fifo)->used() == 1)
\r
190 std::cout << "<1>" << std::flush;
\r
191 if (((Fifo*)fifo)->used() == 9)
\r
192 std::cout << "<9>" << std::flush;
\r
194 printf("\nconsumer returns.\n");
\r
200 Fifo *fifo = new Fifo("fifo", 3);
\r
201 pthread_t *producer_thread = new pthread_t;
\r
202 pthread_t *consumer_thread = new pthread_t;
\r
204 pthread_attr_t attributes;
\r
205 pthread_attr_init(&attributes);
\r
206 pthread_attr_setstacksize(&attributes, 131072);
\r
208 if (pthread_create(consumer_thread, &attributes, consumer, fifo)) {
\r
209 std::cout << "Error: Could not start consumer." << std::endl;
\r
210 std::cout << "Exit." << std::endl;
\r
213 pthread_attr_destroy(&attributes);
\r
215 pthread_attr_init(&attributes);
\r
216 pthread_attr_setstacksize(&attributes, 131072);
\r
217 if (pthread_create(producer_thread, &attributes, producer, fifo)) {
\r
218 std::cout << "Error: Could not start producer." << std::endl;
\r
219 std::cout << "Exit." << std::endl;
\r
222 pthread_attr_destroy(&attributes);
\r
225 pthread_join(*consumer_thread, 0);
\r