| 165 | } |
| 166 | |
| 167 | void demonstrateSingleReaderSingleWriterFIFO() |
| 168 | { |
| 169 | std::cout << "\n=== SingleReaderSingleWriterFIFO Demo ===\n"; |
| 170 | |
| 171 | choc::fifo::SingleReaderSingleWriterFIFO<Task> fifo; |
| 172 | fifo.reset (10); // 10 item capacity |
| 173 | |
| 174 | std::atomic<bool> shouldStop{false}; |
| 175 | std::atomic<int> tasksProduced{0}; |
| 176 | std::atomic<int> tasksConsumed{0}; |
| 177 | |
| 178 | // Producer thread |
| 179 | std::thread producer ([&]() |
| 180 | { |
| 181 | int taskID = 0; |
| 182 | |
| 183 | while (! shouldStop.load()) |
| 184 | { |
| 185 | ++taskID; |
| 186 | Task task (taskID, "Single writer task " + std::to_string (taskID)); |
| 187 | |
| 188 | if (fifo.push (task)) |
| 189 | { |
| 190 | tasksProduced.fetch_add (1); |
| 191 | std::cout << "Produced task " << task.id << "\n"; |
| 192 | } |
| 193 | else |
| 194 | { |
| 195 | std::cout << "FIFO full, couldn't produce task " << task.id << "\n"; |
| 196 | } |
| 197 | |
| 198 | std::this_thread::sleep_for (std::chrono::milliseconds (100)); |
| 199 | } |
| 200 | }); |
| 201 | |
| 202 | // Consumer thread |
| 203 | std::thread consumer ([&]() |
| 204 | { |
| 205 | Task task; |
| 206 | |
| 207 | while (! shouldStop.load() || fifo.getUsedSlots() > 0) |
| 208 | { |
| 209 | if (fifo.pop (task)) |
| 210 | { |
| 211 | tasksConsumed.fetch_add (1); |
| 212 | auto now = std::chrono::steady_clock::now(); |
| 213 | auto latency = std::chrono::duration_cast<std::chrono::milliseconds>(now - task.timestamp); |
| 214 | std::cout << "Consumed task " << task.id << " (" << task.description << ") - latency: " << latency.count() << "ms\n"; |
| 215 | } |
| 216 | |
| 217 | std::this_thread::sleep_for (std::chrono::milliseconds (150)); |
| 218 | } |
| 219 | }); |
| 220 | |
| 221 | // Let it run for a while |
| 222 | std::this_thread::sleep_for (std::chrono::seconds (2)); |
| 223 | shouldStop.store (true); |
| 224 | |