#include "atomic_queue/atomic_queue.h"
#include <thread>
#include <cstdint>
#include <iostream>
int main() {
int constexpr PRODUCERS = 1; int constexpr CONSUMERS = 2; unsigned constexpr N = 1000000; unsigned constexpr CAPACITY = 1024;
using Element = uint32_t; Element constexpr NIL = static_cast<Element>(-1); using Queue = atomic_queue::AtomicQueueB<Element, std::allocator<Element>, NIL>;
Queue q{CAPACITY};
uint64_t results[CONSUMERS];
std::thread consumers[CONSUMERS];
for(int i = 0; i < CONSUMERS; ++i)
consumers[i] = std::thread([&q, &r = results[i]]() {
uint64_t sum = 0;
while(Element n = q.pop()) sum += n;
r = sum;
});
std::thread producers[PRODUCERS];
for(int i = 0; i < PRODUCERS; ++i)
producers[i] = std::thread([&q]() {
for(Element n = N; n; --n)
q.push(n);
});
for(auto& t : producers)
t.join();
for(int i = CONSUMERS; i--;)
q.push(0);
for(auto& t : consumers)
t.join();
uint64_t result = 0;
for(auto& r : results) {
result += r;
if(!r)
std::cerr << "WARNING: consumer " << (&r - results) << " received no messages.\n";
}
uint64_t constexpr expected_result = (N + 1) / 2. * N * PRODUCERS;
if(int64_t result_diff = result - expected_result) {
std::cerr << "ERROR: unexpected result difference " << result_diff << '\n';
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}