libcruft-util/test/job/queue.cpp
Danny Robson 9bfefb3dab job/queue: use a reaper thread to clear finished tasks
clearing the tasks on the worker threads can cause the queue to stall
while the cookie is notified, released, and deleted. we punt the cleanup
off to a reaper thread so that the workers can continue.
2018-03-22 14:59:03 +11:00

52 lines
1.5 KiB
C++

///////////////////////////////////////////////////////////////////////////////
#include "job/queue.hpp"
#include "tap.hpp"
#include <chrono>
#include <iostream>
///////////////////////////////////////////////////////////////////////////////
void sleep_inc (std::atomic<int> &count) noexcept
{
++count;
}
///////////////////////////////////////////////////////////////////////////////
int
main (void)
{
util::TAP::logger tap;
// dispatch `INNER' simple jobs `OUTTER' times that simply increment an
// atomic variable and quit. this tests that all threads are created,
// executed, and finished. it's not definitive, but executing this many
// items this many times seems reasonably reliable in exposing deadlocks.
bool success = true;
constexpr int OUTTER = 4;
constexpr int INNER = 1<<10;
for (auto i = 0; i < OUTTER && success; ++i) {
std::atomic<int> count = 0;
{
util::job::queue q {std::thread::hardware_concurrency (), INNER};
std::vector<util::job::queue::cookie> cookies;
for (int j = 0; j < INNER; ++j) {
cookies.push_back (
q.submit (
sleep_inc,
std::ref (count)
)
);
}
}
success = count == INNER && success;
}
tap.expect (success, "%! trivial increment jobs of size %!", OUTTER, INNER);
return tap.status ();
}