diff options
author | Thomas Rodgers <trodgers@redhat.com> | 2020-11-20 12:29:34 -0800 |
---|---|---|
committer | Thomas Rodgers <trodgers@redhat.com> | 2020-11-20 14:40:18 -0800 |
commit | 83a1beee2766f01a1f46f81ed53f679419318942 (patch) | |
tree | 91d590aea81ac38d24b814371ebe533d12d6cfa0 /libstdc++-v3/testsuite | |
parent | 89d9c634dc5c10b499c23297ef70133066946790 (diff) | |
download | gcc-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')
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); + } + } + } +}; |