1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // Copyright (C) 2011 Vicente J. Botet Escriba 10 // 11 // Distributed under the Boost Software License, Version 1.0. (See accompanying 12 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 13 14 // <boost/thread/condition_variable> 15 16 // class condition_variable; 17 18 // condition_variable(const condition_variable&) = delete; 19 20 #include <boost/thread/condition_variable.hpp> 21 #include <boost/thread/mutex.hpp> 22 #include <boost/thread/thread.hpp> 23 #include <boost/detail/lightweight_test.hpp> 24 #include <cassert> 25 #include <iostream> 26 #include "../../../timming.hpp" 27 28 #if defined BOOST_THREAD_USES_CHRONO 29 typedef boost::chrono::milliseconds milliseconds; 30 typedef boost::chrono::nanoseconds nanoseconds; 31 typedef boost::chrono::milliseconds ms; 32 typedef boost::chrono::nanoseconds ns; 33 struct Clock 34 { 35 typedef boost::chrono::milliseconds duration; 36 typedef duration::rep rep; 37 typedef duration::period period; 38 typedef boost::chrono::time_point<Clock> time_point; 39 static const bool is_steady = true; 40 nowClock41 static time_point now() 42 { 43 using namespace boost::chrono; 44 return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch())); 45 } 46 }; 47 48 class Pred 49 { 50 int& i_; 51 public: Pred(int & i)52 explicit Pred(int& i) : 53 i_(i) 54 { 55 } 56 operator ()()57 bool operator()() 58 { 59 return i_ != 0; 60 } 61 }; 62 63 boost::condition_variable cv; 64 boost::mutex mut; 65 66 int test1 = 0; 67 int test2 = 0; 68 69 int runs = 0; 70 71 const ms max_diff(BOOST_THREAD_TEST_TIME_MS); 72 f()73void f() 74 { 75 try { 76 boost::unique_lock<boost::mutex> lk(mut); 77 assert(test2 == 0); 78 test1 = 1; 79 cv.notify_one(); 80 Clock::time_point t0 = Clock::now(); 81 Clock::time_point t = t0 + Clock::duration(250); 82 bool r = cv.wait_until(lk, t, Pred(test2)); 83 Clock::time_point t1 = Clock::now(); 84 if (runs == 0) 85 { 86 assert(t1 - t0 < max_diff); 87 assert(test2 != 0); 88 assert(r); 89 } 90 else 91 { 92 const nanoseconds d = t1 - t0 - milliseconds(250); 93 std::cout << "diff= " << d.count() << std::endl; 94 std::cout << "max_diff= " << max_diff.count() << std::endl; 95 assert(d < max_diff); 96 assert(test2 == 0); 97 assert(!r); 98 } 99 ++runs; 100 } catch(...) { 101 std::cout << "ERROR exception" << __LINE__ << std::endl; 102 assert(false); 103 } 104 } 105 main()106int main() 107 { 108 try 109 { 110 boost::unique_lock<boost::mutex> lk(mut); 111 boost::thread t(f); 112 BOOST_TEST(test1 == 0); 113 while (test1 == 0) 114 cv.wait(lk); 115 BOOST_TEST(test1 != 0); 116 test2 = 1; 117 lk.unlock(); 118 cv.notify_one(); 119 t.join(); 120 } catch(...) { 121 BOOST_TEST(false); 122 std::cout << "ERROR exception" << __LINE__ << std::endl; 123 } 124 test1 = 0; 125 test2 = 0; 126 try 127 { 128 boost::unique_lock<boost::mutex> lk(mut); 129 boost::thread t(f); 130 BOOST_TEST(test1 == 0); 131 while (test1 == 0) 132 cv.wait(lk); 133 BOOST_TEST(test1 != 0); 134 lk.unlock(); 135 t.join(); 136 } catch(...) { 137 BOOST_TEST(false); 138 std::cout << "ERROR exception" << __LINE__ << std::endl; 139 } 140 141 return boost::report_errors(); 142 } 143 144 #else 145 #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" 146 #endif 147