]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 29_atomics / atomic / wait_notify / 100334.cc
1 // { dg-options "-std=gnu++2a" }
2 // { dg-do run { target c++2a } }
3 // { dg-require-gthreads "" }
4 // { dg-additional-options "-pthread" { target pthread } }
5 // { dg-add-options libatomic }
6
7 // Copyright (C) 2021-2023 Free Software Foundation, Inc.
8 //
9 // This file is part of the GNU ISO C++ Library. This library is free
10 // software; you can redistribute it and/or modify it under the
11 // terms of the GNU General Public License as published by the
12 // Free Software Foundation; either version 3, or (at your option)
13 // any later version.
14
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19
20 // You should have received a copy of the GNU General Public License along
21 // with this library; see the file COPYING3. If not see
22 // <http://www.gnu.org/licenses/>.
23
24 #include <atomic>
25 #include <future>
26
27 #include <testsuite_hooks.h>
28
29 template <typename T>
30 struct atomics_sharing_same_waiter
31 {
32 std::atomic<T> tmp[49 * 4] = {};
33 std::atomic<T>* a[4] = {
34 { &tmp[0] },
35 { &tmp[16 * 4] },
36 { &tmp[32 * 4] },
37 { &tmp[48 * 4] }
38 };
39 };
40
41 constexpr unsigned key(void * a)
42 {
43 constexpr uintptr_t ct = 16;
44 return (uintptr_t(a) >> 2) % ct;
45 }
46
47 int
48 main()
49 {
50 // all atomic share the same waiter
51 // atomics_sharing_same_waiter<char> atomics;
52 atomics_sharing_same_waiter<char> atomics;
53 for (auto& atom : atomics.a)
54 {
55 atom->store(0);
56 }
57
58 auto a = &std::__detail::__waiter_pool_base::_S_for(reinterpret_cast<char *>(atomics.a[0]));
59 auto b = &std::__detail::__waiter_pool_base::_S_for(reinterpret_cast<char *>(atomics.a[1]));
60 VERIFY( a == b );
61
62 auto fut0 = std::async(std::launch::async, [&] { atomics.a[0]->wait(0); });
63 auto fut1 = std::async(std::launch::async, [&] { atomics.a[1]->wait(0); });
64 auto fut2 = std::async(std::launch::async, [&] { atomics.a[2]->wait(0); });
65 auto fut3 = std::async(std::launch::async, [&] { atomics.a[3]->wait(0); });
66
67 // make sure the all threads already await
68 std::this_thread::sleep_for(std::chrono::milliseconds{100});
69
70 atomics.a[2]->store(1);
71 atomics.a[2]->notify_one();
72
73 VERIFY(std::future_status::timeout == fut0.wait_for(std::chrono::milliseconds{100}));
74 VERIFY(atomics.a[0]->load() == 0);
75
76 VERIFY(std::future_status::timeout == fut1.wait_for(std::chrono::milliseconds{100}));
77 VERIFY(atomics.a[1]->load() == 0);
78
79 VERIFY(std::future_status::ready == fut2.wait_for(std::chrono::milliseconds{100}));
80 VERIFY(atomics.a[2]->load() == 1);
81
82 VERIFY(std::future_status::timeout == fut3.wait_for(std::chrono::milliseconds{100}));
83 VERIFY(atomics.a[3]->load() == 0);
84
85 atomics.a[0]->store(1);
86 atomics.a[0]->notify_one();
87 atomics.a[1]->store(1);
88 atomics.a[1]->notify_one();
89 atomics.a[3]->store(1);
90 atomics.a[3]->notify_one();
91
92 return 0;
93 }