73 lines
2.0 KiB
C++
73 lines
2.0 KiB
C++
|
#include "thread/flag.hpp"
|
||
|
#include "parallel/stack.hpp"
|
||
|
|
||
|
#include "tap.hpp"
|
||
|
|
||
|
#include <thread>
|
||
|
|
||
|
|
||
|
int main ()
|
||
|
{
|
||
|
cruft::TAP::logger tap;
|
||
|
|
||
|
{
|
||
|
// Ensure trivial success/failure notifications work
|
||
|
cruft::parallel::stack<int> values (1);
|
||
|
tap.expect_eq (values.push (0), true, "uncontested empty push succeeds");
|
||
|
tap.expect_eq (values.push (0), false, "uncontested full push fails");
|
||
|
|
||
|
int out;
|
||
|
tap.expect_eq (values.pop (&out), true, "uncontested full pop succeeds");
|
||
|
|
||
|
// Use a nullptr to test this case so that we know if the output
|
||
|
// variable is dereferenced before the capacity is tested.
|
||
|
tap.expect_eq (values.pop (nullptr), false, "uncontested empty pop fails");
|
||
|
}
|
||
|
|
||
|
{
|
||
|
static constexpr int SIZE = 4;
|
||
|
cruft::parallel::stack<int> values (SIZE);
|
||
|
for (int i = 0; i < SIZE; ++i)
|
||
|
values.push (i);
|
||
|
|
||
|
bool success = true;
|
||
|
for (int i = SIZE - 1; i >= 0; --i) {
|
||
|
int res = -1;
|
||
|
values.pop (&res);
|
||
|
|
||
|
success = success && res == i;
|
||
|
}
|
||
|
|
||
|
tap.expect (success, "simple popped value sequence matches expected");
|
||
|
}
|
||
|
|
||
|
{
|
||
|
auto fight = [] (cruft::parallel::stack<int> &store, cruft::thread::flag &ev, int iterations) {
|
||
|
ev.wait ();
|
||
|
|
||
|
while (iterations--) {
|
||
|
while (!store.push (iterations))
|
||
|
;
|
||
|
|
||
|
for (int res; !store.pop (&res); )
|
||
|
;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
static int constexpr ITERATIONS = 8 * 1024;
|
||
|
cruft::parallel::stack<int> store (8);
|
||
|
cruft::thread::flag ev;
|
||
|
std::vector<std::thread> contestants;
|
||
|
for (unsigned i = 0; i < std::thread::hardware_concurrency () + 1; ++i)
|
||
|
contestants.emplace_back (fight, std::ref (store), std::ref (ev), ITERATIONS);
|
||
|
|
||
|
ev.notify_all ();
|
||
|
|
||
|
for (auto &t: contestants)
|
||
|
t.join ();
|
||
|
|
||
|
tap.expect (true, "n-way fight, %! contestants", contestants.size ());
|
||
|
}
|
||
|
|
||
|
return tap.status ();
|
||
|
}
|