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 }
7 // Copyright (C) 2021-2023 Free Software Foundation, Inc.
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)
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.
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/>.
27 #include <testsuite_hooks.h>
30 struct atomics_sharing_same_waiter
32 std::atomic
<T
> tmp
[49 * 4] = {};
33 std::atomic
<T
>* a
[4] = {
41 constexpr unsigned key(void * a
)
43 constexpr uintptr_t ct
= 16;
44 return (uintptr_t(a
) >> 2) % ct
;
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
)
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]));
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); });
67 // make sure the all threads already await
68 std::this_thread::sleep_for(std::chrono::milliseconds
{100});
70 atomics
.a
[2]->store(1);
71 atomics
.a
[2]->notify_one();
73 VERIFY(std::future_status::timeout
== fut0
.wait_for(std::chrono::milliseconds
{100}));
74 VERIFY(atomics
.a
[0]->load() == 0);
76 VERIFY(std::future_status::timeout
== fut1
.wait_for(std::chrono::milliseconds
{100}));
77 VERIFY(atomics
.a
[1]->load() == 0);
79 VERIFY(std::future_status::ready
== fut2
.wait_for(std::chrono::milliseconds
{100}));
80 VERIFY(atomics
.a
[2]->load() == 1);
82 VERIFY(std::future_status::timeout
== fut3
.wait_for(std::chrono::milliseconds
{100}));
83 VERIFY(atomics
.a
[3]->load() == 0);
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();