/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2018 Danny Robson */ #include "thread/flag.hpp" #include "thread/spinlock.hpp" #include "tap.hpp" #include #include /////////////////////////////////////////////////////////////////////////////// void fight (cruft::thread::flag &start, cruft::thread::spinlock &l, int iterations) { start.wait (); for (int count = 0; count < iterations; ++count) std::lock_guard g (l); }; //----------------------------------------------------------------------------- int main () { cruft::TAP::logger tap; cruft::thread::spinlock l; l.lock (); tap.expect (true, "locked without contention"); l.unlock (); tap.expect (true, "unlocked without contention"); if (std::thread::hardware_concurrency () < 2) { tap.skip ("n-way fight"); } else { constexpr int iterations = 1 << 12; cruft::thread::flag start_flag; std::vector contestants; for (unsigned i = 0; i < std::thread::hardware_concurrency (); ++i) contestants.emplace_back (fight, std::ref (start_flag), std::ref (l), iterations); start_flag.notify_all (); for (auto &t: contestants) t.join (); tap.expect (true, "n-way fight, {} contestants", std::thread::hardware_concurrency ()); } return tap.status (); }