summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite
diff options
context:
space:
mode:
authorThomas Rodgers <trodgers@redhat.com>2020-11-20 12:29:34 -0800
committerThomas Rodgers <trodgers@redhat.com>2020-11-20 14:40:18 -0800
commit83a1beee2766f01a1f46f81ed53f679419318942 (patch)
tree91d590aea81ac38d24b814371ebe533d12d6cfa0 /libstdc++-v3/testsuite
parent89d9c634dc5c10b499c23297ef70133066946790 (diff)
downloadgcc-83a1beee2766f01a1f46f81ed53f679419318942.tar.gz
libstdc++: Add C++2a synchronization support
Add support for - * atomic_flag::wait/notify_one/notify_all * atomic::wait/notify_one/notify_all * counting_semaphore * binary_semaphore * latch libstdc++-v3/ChangeLog: * include/Makefile.am (bits_headers): Add new header. * include/Makefile.in: Regenerate. * include/bits/atomic_base.h (__atomic_flag::wait): Define. (__atomic_flag::notify_one): Likewise. (__atomic_flag::notify_all): Likewise. (__atomic_base<_Itp>::wait): Likewise. (__atomic_base<_Itp>::notify_one): Likewise. (__atomic_base<_Itp>::notify_all): Likewise. (__atomic_base<_Ptp*>::wait): Likewise. (__atomic_base<_Ptp*>::notify_one): Likewise. (__atomic_base<_Ptp*>::notify_all): Likewise. (__atomic_impl::wait): Likewise. (__atomic_impl::notify_one): Likewise. (__atomic_impl::notify_all): Likewise. (__atomic_float<_Fp>::wait): Likewise. (__atomic_float<_Fp>::notify_one): Likewise. (__atomic_float<_Fp>::notify_all): Likewise. (__atomic_ref<_Tp>::wait): Likewise. (__atomic_ref<_Tp>::notify_one): Likewise. (__atomic_ref<_Tp>::notify_all): Likewise. (atomic_wait<_Tp>): Likewise. (atomic_wait_explicit<_Tp>): Likewise. (atomic_notify_one<_Tp>): Likewise. (atomic_notify_all<_Tp>): Likewise. * include/bits/atomic_wait.h: New file. * include/bits/atomic_timed_wait.h: New file. * include/bits/semaphore_base.h: New file. * include/std/atomic (atomic<bool>::wait): Define. (atomic<bool>::wait_one): Likewise. (atomic<bool>::wait_all): Likewise. (atomic<_Tp>::wait): Likewise. (atomic<_Tp>::wait_one): Likewise. (atomic<_Tp>::wait_all): Likewise. (atomic<_Tp*>::wait): Likewise. (atomic<_Tp*>::wait_one): Likewise. (atomic<_Tp*>::wait_all): Likewise. * include/std/latch: New file. * include/std/semaphore: New file. * include/std/version: Add __cpp_lib_semaphore and __cpp_lib_latch defines. * testsuite/29_atomics/atomic/wait_notify/bool.cc: New test. * testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise. * testsuite/29_atomics/atomic/wait_notify/generic.cc: Liekwise. * testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise. * testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise. * testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise. * testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise. * testsuite/30_threads/semaphore/1.cc: New test. * testsuite/30_threads/semaphore/2.cc: Likewise. * testsuite/30_threads/semaphore/least_max_value_neg.cc: Likewise. * testsuite/30_threads/semaphore/try_acquire.cc: Likewise. * testsuite/30_threads/semaphore/try_acquire_for.cc: Likewise. * testsuite/30_threads/semaphore/try_acquire_posix.cc: Likewise. * testsuite/30_threads/semaphore/try_acquire_until.cc: Likewise. * testsuite/30_threads/latch/1.cc: New test. * testsuite/30_threads/latch/2.cc: New test. * testsuite/30_threads/latch/3.cc: New test. * testsuite/util/atomic/wait_notify_util.h: New File.
Diffstat (limited to 'libstdc++-v3/testsuite')
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc59
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc31
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc59
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc61
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc31
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc65
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc90
-rw-r--r--libstdc++-v3/testsuite/30_threads/latch/1.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/latch/2.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/latch/3.cc69
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/1.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/2.cc27
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc30
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc55
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc85
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc153
-rw-r--r--libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc94
-rw-r--r--libstdc++-v3/testsuite/util/atomic/wait_notify_util.h160
18 files changed, 1150 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
new file mode 100644
index 00000000000..5f1e30a710f
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
@@ -0,0 +1,59 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <type_traits>
+#include <chrono>
+
+#include <testsuite_hooks.h>
+
+int
+main ()
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ std::atomic<bool> a(false);
+ std::atomic<bool> b(false);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ a.wait(false);
+ if (a.load())
+ {
+ b.store(true);
+ }
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(true);
+ a.notify_one();
+ t.join();
+ VERIFY( b.load() );
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc
new file mode 100644
index 00000000000..0249341055c
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "atomic/wait_notify_util.h"
+
+int
+main ()
+{
+ struct S{ int i; };
+ check<S> check_s{S{0},S{42}};
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc
new file mode 100644
index 00000000000..8531bb2e788
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc
@@ -0,0 +1,59 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <type_traits>
+#include <chrono>
+
+#include <testsuite_hooks.h>
+
+int
+main ()
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ long aa;
+ long bb;
+
+ std::atomic<long*> a(nullptr);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ a.wait(nullptr);
+ if (a.load() == &aa)
+ a.store(&bb);
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(&aa);
+ a.notify_one();
+ t.join();
+ VERIFY( a.load() == &bb);
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
new file mode 100644
index 00000000000..4f026e1dc9c
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
@@ -0,0 +1,61 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <concepts>
+#include <mutex>
+#include <thread>
+
+#include <testsuite_hooks.h>
+
+int
+main()
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ std::atomic_flag a;
+ std::atomic_flag b;
+ std::thread t([&]
+ {
+ cv.notify_one();
+ a.wait(false);
+ b.test_and_set();
+ b.notify_one();
+ });
+
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.test_and_set();
+ a.notify_one();
+ b.wait(false);
+ t.join();
+
+ VERIFY( a.test() );
+ VERIFY( b.test() );
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc
new file mode 100644
index 00000000000..640a84e0342
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "atomic/wait_notify_util.h"
+
+int
+main ()
+{
+ check<float> f;
+ check<double> d;
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc
new file mode 100644
index 00000000000..6e9ee7dbf93
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "atomic/wait_notify_util.h"
+
+void
+test01()
+{
+ struct S{ int i; };
+ std::atomic<S> s;
+
+ s.wait(S{42});
+}
+
+int
+main ()
+{
+ // check<bool> bb;
+ check<char> ch;
+ check<signed char> sch;
+ check<unsigned char> uch;
+ check<short> s;
+ check<unsigned short> us;
+ check<int> i;
+ check<unsigned int> ui;
+ check<long> l;
+ check<unsigned long> ul;
+ check<long long> ll;
+ check<unsigned long long> ull;
+
+ check<wchar_t> wch;
+ check<char8_t> ch8;
+ check<char16_t> ch16;
+ check<char32_t> ch32;
+
+ check<int8_t> i8;
+ check<int16_t> i16;
+ check<int32_t> i32;
+ check<int64_t> i64;
+
+ check<uint8_t> u8;
+ check<uint16_t> u16;
+ check<uint32_t> u32;
+ check<uint64_t> u64;
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
new file mode 100644
index 00000000000..dc5ae7a21ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
@@ -0,0 +1,90 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <chrono>
+#include <type_traits>
+
+#include <testsuite_hooks.h>
+
+template<typename Tp>
+Tp check_wait_notify(Tp val1, Tp val2)
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ Tp aa = val1;
+ std::atomic_ref<Tp> a(aa);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ a.wait(val1);
+ if (a.load() != val2)
+ a = val1;
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ a.notify_one();
+ t.join();
+ return a.load();
+}
+
+template<typename Tp,
+ bool = std::is_integral_v<Tp>
+ || std::is_floating_point_v<Tp>>
+struct check;
+
+template<typename Tp>
+struct check<Tp, true>
+{
+ check()
+ {
+ Tp a = 0;
+ Tp b = 42;
+ VERIFY(check_wait_notify(a, b) == b);
+ }
+};
+
+template<typename Tp>
+struct check<Tp, false>
+{
+ check(Tp b)
+ {
+ Tp a;
+ VERIFY(check_wait_notify(a, b) == b);
+ }
+};
+
+int
+main ()
+{
+ check<long>();
+ check<double>();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/latch/1.cc b/libstdc++-v3/testsuite/30_threads/latch/1.cc
new file mode 100644
index 00000000000..aa203cdf525
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/latch/1.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <latch>
+
+#ifndef __cpp_lib_latch
+# error "Feature-test macro for latch missing in <latch>"
+#elif __cpp_lib_latch!= 201907L
+# error "Feature-test macro for latch has wrong value in <latch>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/latch/2.cc b/libstdc++-v3/testsuite/30_threads/latch/2.cc
new file mode 100644
index 00000000000..318a859ee21
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/latch/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_latch
+# error "Feature-test macro for latch missing in <version>"
+#elif __cpp_lib_latch != 201907L
+# error "Feature-test macro for latch has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/latch/3.cc b/libstdc++-v3/testsuite/30_threads/latch/3.cc
new file mode 100644
index 00000000000..5d08000f430
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/latch/3.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+//
+#include <latch>
+#include <atomic>
+#include <thread>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::latch l(3);
+
+ VERIFY( !l.try_wait() );
+
+ auto fn = [&]
+ {
+ l.count_down();
+ };
+
+ std::thread t0(fn);
+ std::thread t1(fn);
+
+ l.arrive_and_wait();
+ t0.join();
+ t1.join();
+
+ VERIFY( l.try_wait() );
+}
+
+void
+test02()
+{
+ std::latch l(3);
+ std::thread t([&]
+ {
+ l.count_down();
+ });
+
+ l.arrive_and_wait(2);
+ t.join();
+ VERIFY( l.try_wait() );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/1.cc b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc
new file mode 100644
index 00000000000..1bbca687fc3
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <semaphore>
+
+#ifndef __cpp_lib_semaphore
+# error "Feature-test macro for semaphore missing in <semaphore>"
+#elif __cpp_lib_semaphore != 201907L
+# error "Feature-test macro for semaphore has wrong value in <semaphore>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/2.cc b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc
new file mode 100644
index 00000000000..98743f5e27c
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_semaphore
+# error "Feature-test macro for semaphore missing in <version>"
+#elif __cpp_lib_semaphore != 201907L
+# error "Feature-test macro for semaphore has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc
new file mode 100644
index 00000000000..d74cfad53e9
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+
+int main()
+{
+ std::counting_semaphore<-1> sem(2);
+ return 0;
+}
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc
new file mode 100644
index 00000000000..25280441d07
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#include <limits>
+#include <cstddef>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ std::counting_semaphore<10> s(3);
+
+ s.acquire();
+ VERIFY( s.try_acquire() );
+ VERIFY( s.try_acquire() );
+ VERIFY( !s.try_acquire() );
+ s.release();
+ VERIFY( s.try_acquire() );
+}
+
+void test02()
+{
+ std::binary_semaphore s(1);
+
+ s.acquire();
+ VERIFY( !s.try_acquire() );
+ s.release();
+ VERIFY( s.try_acquire() );
+}
+
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
new file mode 100644
index 00000000000..3f450e74661
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
@@ -0,0 +1,85 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#include <chrono>
+#include <thread>
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std::chrono_literals;
+ std::counting_semaphore<10> s(2);
+ s.acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s.try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s.try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test02()
+{
+ using namespace std::chrono_literals;
+ std::binary_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ VERIFY( !s.try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+
+ a.wait(1);
+ VERIFY( s.try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s.acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s.release();
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
new file mode 100644
index 00000000000..13bd7487d56
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
@@ -0,0 +1,153 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+#include <chrono>
+#include <thread>
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(2);
+ s._M_acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s._M_try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s._M_try_acquire_for(dur) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test02()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ VERIFY( !s._M_try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+
+ a.wait(1);
+ VERIFY( s._M_try_acquire_for(dur) );
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s._M_acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s._M_release(1);
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+
+void test03()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(2);
+ s._M_acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s._M_try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s._M_try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test04()
+{
+ using namespace std::chrono_literals;
+ std::__platform_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( !s._M_try_acquire_until(at) );
+
+ b++;
+ b.notify_one();
+ }
+
+ a.wait(1);
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( s._M_try_acquire_until(at) );
+ }
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s._M_acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s._M_release(1);
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+#endif
+
+int main()
+{
+#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
+ test01();
+ test02();
+ test03();
+ test04();
+#endif
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc
new file mode 100644
index 00000000000..af7ab7bac39
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+#include <semaphore>
+#include <chrono>
+#include <thread>
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ using namespace std::chrono_literals;
+ std::counting_semaphore<10> s(2);
+ s.acquire();
+
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( s.try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff < dur );
+ }
+
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ auto const t0 = std::chrono::steady_clock::now();
+ VERIFY( !s.try_acquire_until(at) );
+ auto const diff = std::chrono::steady_clock::now() - t0;
+ VERIFY( diff >= dur );
+ }
+}
+
+void test02()
+{
+ using namespace std::chrono_literals;
+ std::binary_semaphore s(1);
+ std::atomic<int> a(0), b(0);
+ std::thread t([&] {
+ a.wait(0);
+ auto const dur = 250ms;
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( !s.try_acquire_until(at) );
+
+ b++;
+ b.notify_one();
+ }
+
+ a.wait(1);
+ {
+ auto const at = std::chrono::system_clock::now() + dur;
+ VERIFY( s.try_acquire_until(at) );
+ }
+ b++;
+ b.notify_one();
+ });
+ t.detach();
+
+ s.acquire();
+ a++;
+ a.notify_one();
+ b.wait(0);
+ s.release();
+ a++;
+ a.notify_one();
+
+ b.wait(1);
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/util/atomic/wait_notify_util.h b/libstdc++-v3/testsuite/util/atomic/wait_notify_util.h
new file mode 100644
index 00000000000..a319e8b60a6
--- /dev/null
+++ b/libstdc++-v3/testsuite/util/atomic/wait_notify_util.h
@@ -0,0 +1,160 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <concepts>
+#include <mutex>
+#include <thread>
+
+#include <testsuite_hooks.h>
+
+#include <iostream>
+
+template<typename Tp>
+Tp check_wait_notify(Tp val1, Tp val2)
+ requires std::equality_comparable<Tp>
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ a.wait(val1);
+ if (a.load() != val2)
+ a = val1;
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ a.notify_one();
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+Tp check_wait_notify(Tp val1, Tp val2)
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ a.wait(val1);
+ auto v = a.load();
+ // TODO this needs to zero padding bits when we can do that
+ if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
+ a = val1;
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ a.notify_one();
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+Tp check_atomic_wait_notify(Tp val1, Tp val2)
+ requires std::equality_comparable<Tp>
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ std::atomic_wait(&a, val1);
+ if (a.load() != val2)
+ a = val1;
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ std::atomic_notify_one(&a);
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+Tp check_atomic_wait_notify(Tp val1, Tp val2)
+{
+ using namespace std::literals::chrono_literals;
+
+ std::mutex m;
+ std::condition_variable cv;
+
+ std::atomic<Tp> a(val1);
+ std::thread t([&]
+ {
+ cv.notify_one();
+ std::atomic_wait(&a, val1);
+ auto v = a.load();
+ // TODO this needs to zero padding bits when we can do that
+ if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
+ a = val1;
+ });
+ std::unique_lock<std::mutex> l(m);
+ cv.wait(l);
+ std::this_thread::sleep_for(100ms);
+ a.store(val2);
+ std::atomic_notify_one(&a);
+ t.join();
+ return a.load();
+}
+
+template<typename Tp>
+struct check
+{
+ check(Tp a = 0, Tp b = 42)
+ {
+ if constexpr (std::equality_comparable<Tp>)
+ {
+ VERIFY( check_wait_notify(a, b) == b);
+ VERIFY( check_atomic_wait_notify(a, b) == b);
+ }
+ else
+ {
+ {
+ // TODO this needs to zero padding bits when we can do that
+ auto v = check_wait_notify(a, b);
+ VERIFY( __builtin_memcmp(&v, &b, sizeof(Tp)) == 0 );
+ }
+
+ {
+ // TODO this needs to zero padding bits when we can do that
+ auto v = check_atomic_wait_notify(a, b);
+ VERIFY( __builtin_memcmp(&v, &b, sizeof(Tp)) == 0);
+ }
+ }
+ }
+};