]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/util/atomic/wait_notify_util.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / util / atomic / wait_notify_util.h
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
83a1beee
TR
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
18#include <atomic>
19#include <chrono>
20#include <condition_variable>
21#include <concepts>
22#include <mutex>
23#include <thread>
24
25#include <testsuite_hooks.h>
26
27#include <iostream>
28
29template<typename Tp>
30Tp check_wait_notify(Tp val1, Tp val2)
31 requires std::equality_comparable<Tp>
32{
33 using namespace std::literals::chrono_literals;
34
35 std::mutex m;
36 std::condition_variable cv;
f76cad69 37 std::unique_lock<std::mutex> l(m);
83a1beee
TR
38
39 std::atomic<Tp> a(val1);
40 std::thread t([&]
41 {
f76cad69
JW
42 {
43 // This ensures we block until cv.wait(l) starts.
44 std::lock_guard<std::mutex> ll(m);
45 }
83a1beee
TR
46 cv.notify_one();
47 a.wait(val1);
48 if (a.load() != val2)
49 a = val1;
50 });
83a1beee
TR
51 cv.wait(l);
52 std::this_thread::sleep_for(100ms);
53 a.store(val2);
54 a.notify_one();
55 t.join();
56 return a.load();
57}
58
59template<typename Tp>
60Tp check_wait_notify(Tp val1, Tp val2)
61{
62 using namespace std::literals::chrono_literals;
63
64 std::mutex m;
65 std::condition_variable cv;
f76cad69 66 std::unique_lock<std::mutex> l(m);
83a1beee
TR
67
68 std::atomic<Tp> a(val1);
69 std::thread t([&]
70 {
f76cad69
JW
71 {
72 // This ensures we block until cv.wait(l) starts.
73 std::lock_guard<std::mutex> ll(m);
74 }
83a1beee
TR
75 cv.notify_one();
76 a.wait(val1);
77 auto v = a.load();
78 // TODO this needs to zero padding bits when we can do that
79 if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
80 a = val1;
81 });
83a1beee
TR
82 cv.wait(l);
83 std::this_thread::sleep_for(100ms);
84 a.store(val2);
85 a.notify_one();
86 t.join();
87 return a.load();
88}
89
90template<typename Tp>
91Tp check_atomic_wait_notify(Tp val1, Tp val2)
92 requires std::equality_comparable<Tp>
93{
94 using namespace std::literals::chrono_literals;
95
96 std::mutex m;
97 std::condition_variable cv;
f76cad69 98 std::unique_lock<std::mutex> l(m);
83a1beee
TR
99
100 std::atomic<Tp> a(val1);
101 std::thread t([&]
102 {
f76cad69
JW
103 {
104 // This ensures we block until cv.wait(l) starts.
105 std::lock_guard<std::mutex> ll(m);
106 }
83a1beee
TR
107 cv.notify_one();
108 std::atomic_wait(&a, val1);
109 if (a.load() != val2)
110 a = val1;
111 });
83a1beee
TR
112 cv.wait(l);
113 std::this_thread::sleep_for(100ms);
114 a.store(val2);
115 std::atomic_notify_one(&a);
116 t.join();
117 return a.load();
118}
119
120template<typename Tp>
121Tp check_atomic_wait_notify(Tp val1, Tp val2)
122{
123 using namespace std::literals::chrono_literals;
124
125 std::mutex m;
126 std::condition_variable cv;
f76cad69 127 std::unique_lock<std::mutex> l(m);
83a1beee
TR
128
129 std::atomic<Tp> a(val1);
130 std::thread t([&]
131 {
f76cad69
JW
132 {
133 // This ensures we block until cv.wait(l) starts.
134 std::lock_guard<std::mutex> ll(m);
135 }
83a1beee
TR
136 cv.notify_one();
137 std::atomic_wait(&a, val1);
138 auto v = a.load();
139 // TODO this needs to zero padding bits when we can do that
140 if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
141 a = val1;
142 });
83a1beee
TR
143 cv.wait(l);
144 std::this_thread::sleep_for(100ms);
145 a.store(val2);
146 std::atomic_notify_one(&a);
147 t.join();
148 return a.load();
149}
150
151template<typename Tp>
152struct check
153{
154 check(Tp a = 0, Tp b = 42)
155 {
156 if constexpr (std::equality_comparable<Tp>)
157 {
158 VERIFY( check_wait_notify(a, b) == b);
159 VERIFY( check_atomic_wait_notify(a, b) == b);
160 }
161 else
162 {
163 {
164 // TODO this needs to zero padding bits when we can do that
165 auto v = check_wait_notify(a, b);
166 VERIFY( __builtin_memcmp(&v, &b, sizeof(Tp)) == 0 );
167 }
168
169 {
170 // TODO this needs to zero padding bits when we can do that
171 auto v = check_atomic_wait_notify(a, b);
172 VERIFY( __builtin_memcmp(&v, &b, sizeof(Tp)) == 0);
173 }
174 }
175 }
176};