/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2018 Danny Robson */ #include "job/flag.hpp" #include "job/spinlock.hpp" #include "tap.hpp" #include #include /////////////////////////////////////////////////////////////////////////////// void fight (util::job::flag &start, util::job::spinlock &l, int iterations) { start.wait (); for (int count = 0; count < iterations; ++count) std::lock_guard g (l); }; //----------------------------------------------------------------------------- int main () { util::TAP::logger tap; util::job::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; util::job::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 (); for (auto &t: contestants) t.join (); tap.expect (true, "n-way fight, %! contestants", std::thread::hardware_concurrency ()); } return tap.status (); }