]>
Commit | Line | Data |
---|---|---|
d1236680 | 1 | // { dg-do run } |
1e42d2f4 | 2 | // { dg-additional-options "-pthread" { target pthread } } |
71c54f8e | 3 | // { dg-require-effective-target c++11 } |
88399079 CF |
4 | // { dg-require-gthreads "" } |
5 | ||
99dee823 | 6 | // Copyright (C) 2008-2021 Free Software Foundation, Inc. |
88399079 CF |
7 | // |
8 | // This file is part of the GNU ISO C++ Library. This library is free | |
9 | // software; you can redistribute it and/or modify it under the | |
10 | // terms of the GNU General Public License as published by the | |
748086b7 | 11 | // Free Software Foundation; either version 3, or (at your option) |
88399079 CF |
12 | // any later version. |
13 | ||
14 | // This library is distributed in the hope that it will be useful, | |
15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | // GNU General Public License for more details. | |
18 | ||
19 | // You should have received a copy of the GNU General Public License along | |
748086b7 JJ |
20 | // with this library; see the file COPYING3. If not see |
21 | // <http://www.gnu.org/licenses/>. | |
88399079 | 22 | |
88399079 CF |
23 | #include <chrono> |
24 | #include <condition_variable> | |
25 | #include <system_error> | |
26 | #include <testsuite_hooks.h> | |
a7334019 | 27 | #include <slow_clock.h> |
88399079 | 28 | |
76e0dd66 | 29 | template <typename ClockType> |
023cee96 | 30 | void test01() |
88399079 | 31 | { |
88399079 CF |
32 | try |
33 | { | |
34 | std::chrono::microseconds ms(500); | |
35 | std::condition_variable c1; | |
36 | std::mutex m; | |
37 | std::unique_lock<std::mutex> l(m); | |
38 | ||
76e0dd66 | 39 | auto then = ClockType::now(); |
cdf5f5a3 PC |
40 | std::cv_status result = c1.wait_until(l, then + ms); |
41 | VERIFY( result == std::cv_status::timeout ); | |
76e0dd66 | 42 | VERIFY( (ClockType::now() - then) >= ms ); |
88399079 CF |
43 | VERIFY( l.owns_lock() ); |
44 | } | |
45 | catch (const std::system_error& e) | |
46 | { | |
47 | VERIFY( false ); | |
48 | } | |
49 | catch (...) | |
50 | { | |
51 | VERIFY( false ); | |
52 | } | |
023cee96 | 53 | } |
88399079 | 54 | |
2f593432 MC |
55 | void test01_alternate_clock() |
56 | { | |
bf1fc37b JW |
57 | using __gnu_test::slow_clock; |
58 | ||
2f593432 MC |
59 | try |
60 | { | |
61 | std::condition_variable c1; | |
62 | std::mutex m; | |
63 | std::unique_lock<std::mutex> l(m); | |
64 | auto const expire = slow_clock::now() + std::chrono::seconds(1); | |
65 | ||
66 | while (slow_clock::now() < expire) | |
67 | { | |
68 | auto const result = c1.wait_until(l, expire); | |
69 | ||
70 | // If wait_until returns before the timeout has expired when | |
71 | // measured against the supplied clock, then wait_until must | |
72 | // return no_timeout. | |
73 | if (slow_clock::now() < expire) | |
74 | VERIFY(result == std::cv_status::no_timeout); | |
75 | ||
76 | // If wait_until returns timeout then the timeout must have | |
77 | // expired. | |
78 | if (result == std::cv_status::timeout) | |
79 | VERIFY(slow_clock::now() >= expire); | |
80 | } | |
81 | } | |
82 | catch (const std::system_error& e) | |
83 | { | |
84 | VERIFY( false ); | |
85 | } | |
86 | catch (...) | |
87 | { | |
88 | VERIFY( false ); | |
89 | } | |
90 | } | |
91 | ||
76e0dd66 MC |
92 | /* User defined clock that ticks in two-thousandths of a second |
93 | forty-two minutes ahead of steady_clock. */ | |
94 | struct user_defined_clock | |
95 | { | |
96 | typedef std::chrono::steady_clock::rep rep; | |
97 | typedef std::ratio<1, 2000> period; | |
98 | typedef std::chrono::duration<rep, period> duration; | |
99 | typedef std::chrono::time_point<user_defined_clock> time_point; | |
100 | ||
101 | static constexpr bool is_steady = true; | |
102 | ||
103 | static time_point now() noexcept | |
104 | { | |
105 | using namespace std::chrono; | |
106 | const auto steady_since_epoch = steady_clock::now().time_since_epoch(); | |
107 | const auto user_since_epoch = duration_cast<duration>(steady_since_epoch); | |
108 | return time_point(user_since_epoch + minutes(42)); | |
109 | } | |
110 | }; | |
111 | ||
112 | /* | |
113 | It's not possible for this test to automatically ensure that the | |
114 | system_clock test cases result in a wait on CLOCK_REALTIME and steady_clock | |
115 | test cases result in a wait on CLOCK_MONOTONIC. It's recommended to run the | |
116 | test under strace(1) and check whether the expected futex calls are made by | |
117 | glibc. See https://gcc.gnu.org/ml/libstdc++/2019-09/msg00022.html for | |
118 | instructions. | |
119 | */ | |
120 | ||
023cee96 PC |
121 | int main() |
122 | { | |
76e0dd66 MC |
123 | test01<std::chrono::steady_clock>(); |
124 | test01<std::chrono::system_clock>(); | |
125 | test01<user_defined_clock>(); | |
2f593432 | 126 | test01_alternate_clock(); |
88399079 | 127 | } |