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 
10 // Copyright (C) 2011 Vicente J. Botet Escriba
11 //
12 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
13 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
14 
15 // <boost/thread/locks.hpp>
16 
17 // template <class Mutex> class unique_lock;
18 
19 // void lock();
20 
21 #include <boost/thread/lock_types.hpp>
22 #include <boost/thread/mutex.hpp>
23 #include <boost/thread/thread.hpp>
24 #include <boost/detail/lightweight_test.hpp>
25 #include <iostream>
26 #include "../../../../../timming.hpp"
27 
28 boost::mutex m;
29 
30 #if defined BOOST_THREAD_USES_CHRONO
31 typedef boost::chrono::high_resolution_clock Clock;
32 typedef Clock::time_point time_point;
33 typedef Clock::duration duration;
34 typedef boost::chrono::milliseconds ms;
35 typedef boost::chrono::nanoseconds ns;
36 time_point t0;
37 time_point t1;
38 #else
39 #endif
40 
41 const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
42 
f()43 void f()
44 {
45 #if defined BOOST_THREAD_USES_CHRONO
46   boost::unique_lock < boost::mutex > lk(m, boost::defer_lock);
47   t0 = Clock::now();
48   lk.lock();
49   t1 = Clock::now();
50   BOOST_TEST(lk.owns_lock() == true);
51   try
52   {
53     lk.lock();
54     BOOST_TEST(false);
55   }
56   catch (boost::system::system_error& e)
57   {
58     BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
59   }
60   lk.unlock();
61   lk.release();
62   try
63   {
64     lk.lock();
65     BOOST_TEST(false);
66   }
67   catch (boost::system::system_error& e)
68   {
69     BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
70   }
71 #else
72   boost::unique_lock < boost::mutex > lk(m, boost::defer_lock);
73   //time_point t0 = Clock::now();
74   lk.lock();
75   //time_point t1 = Clock::now();
76   BOOST_TEST(lk.owns_lock() == true);
77   //ns d = t1 - t0 - ms(250);
78   //BOOST_TEST(d < max_diff);
79   try
80   {
81     lk.lock();
82     BOOST_TEST(false);
83   }
84   catch (boost::system::system_error& e)
85   {
86     BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
87   }
88   lk.unlock();
89   lk.release();
90   try
91   {
92     lk.lock();
93     BOOST_TEST(false);
94   }
95   catch (boost::system::system_error& e)
96   {
97     BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
98   }
99 #endif
100 }
101 
main()102 int main()
103 {
104   m.lock();
105   boost::thread t(f);
106 #if defined BOOST_THREAD_USES_CHRONO
107   time_point t2 = Clock::now();
108   boost::this_thread::sleep_for(ms(250));
109   time_point t3 = Clock::now();
110 #else
111 #endif
112   m.unlock();
113   t.join();
114 
115 #if defined BOOST_THREAD_USES_CHRONO
116   ns sleep_time = t3 - t2;
117   ns d_ns = t1 - t0 - sleep_time;
118   ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
119   // BOOST_TEST_GE(d_ms.count(), 0);
120   BOOST_THREAD_TEST_IT(d_ms, max_diff);
121   BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
122 #endif
123 
124   return boost::report_errors();
125 }
126 
127 
128