libstdc++: Add C++2a synchronization support
[gcc.git] / libstdc++-v3 / testsuite / 29_atomics / atomic_ref / wait_notify.cc
1 // { dg-options "-std=gnu++2a -pthread" }
2 // { dg-do run { target c++2a } }
3 // { dg-require-effective-target pthread }
4 // { dg-require-gthreads "" }
5
6 // Copyright (C) 2020 Free Software Foundation, Inc.
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
11 // Free Software Foundation; either version 3, or (at your option)
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
20 // with this library; see the file COPYING3. If not see
21 // <http://www.gnu.org/licenses/>.
22
23 #include <atomic>
24 #include <thread>
25 #include <mutex>
26 #include <condition_variable>
27 #include <chrono>
28 #include <type_traits>
29
30 #include <testsuite_hooks.h>
31
32 template<typename Tp>
33 Tp check_wait_notify(Tp val1, Tp val2)
34 {
35 using namespace std::literals::chrono_literals;
36
37 std::mutex m;
38 std::condition_variable cv;
39
40 Tp aa = val1;
41 std::atomic_ref<Tp> a(aa);
42 std::thread t([&]
43 {
44 cv.notify_one();
45 a.wait(val1);
46 if (a.load() != val2)
47 a = val1;
48 });
49 std::unique_lock<std::mutex> l(m);
50 cv.wait(l);
51 std::this_thread::sleep_for(100ms);
52 a.store(val2);
53 a.notify_one();
54 t.join();
55 return a.load();
56 }
57
58 template<typename Tp,
59 bool = std::is_integral_v<Tp>
60 || std::is_floating_point_v<Tp>>
61 struct check;
62
63 template<typename Tp>
64 struct check<Tp, true>
65 {
66 check()
67 {
68 Tp a = 0;
69 Tp b = 42;
70 VERIFY(check_wait_notify(a, b) == b);
71 }
72 };
73
74 template<typename Tp>
75 struct check<Tp, false>
76 {
77 check(Tp b)
78 {
79 Tp a;
80 VERIFY(check_wait_notify(a, b) == b);
81 }
82 };
83
84 int
85 main ()
86 {
87 check<long>();
88 check<double>();
89 return 0;
90 }