/* * 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 #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// // a single atomic integer wrapper that allows precise ordering of thread // entrance and exit for exact testing of thread interleavings. struct foo { foo (): enter (0), leave (0) { ; } void inc (void) { enter.acquire (); ++value; leave.release (); } std::atomic value = 0; cruft::thread::semaphore enter; cruft::thread::semaphore leave; }; /////////////////////////////////////////////////////////////////////////////// int main () { cruft::TAP::logger tap; cruft::thread::monitor obj; const auto &value = obj->value; auto &enter = obj->enter; auto &leave = obj->leave; std::thread t1 ([&] () { obj->inc (); }); std::thread t2 ([&] () { obj->inc (); }); tap.expect_eq (value, 0, "wrapped class was left initialised"); enter.release (); leave.acquire (); tap.expect_eq (value, 1, "only one thread had access"); enter.release (); leave.acquire (); tap.expect_eq (value, 2, "second thread got access"); t1.join (); t2.join (); return tap.status (); }