From patchwork Thu Dec 17 23:37:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Rodgers X-Patchwork-Id: 1417995 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=appliantology.com Authentication-Results: ozlabs.org; dkim=pass (4096-bit key; secure) header.d=kolabnow.com header.i=@kolabnow.com header.a=rsa-sha256 header.s=dkim20160331 header.b=EeXN1Ccw; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CxpLv463mz9sW8 for ; Fri, 18 Dec 2020 10:37:26 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B3D553896C1C; Thu, 17 Dec 2020 23:37:22 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx.kolabnow.com (mx.kolabnow.com [95.128.36.42]) by sourceware.org (Postfix) with ESMTPS id A9B3A3896C0C; Thu, 17 Dec 2020 23:37:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A9B3A3896C0C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=appliantology.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=rodgert@appliantology.com Received: from localhost (unknown [127.0.0.1]) by ext-mx-out001.mykolab.com (Postfix) with ESMTP id 563C763E; Fri, 18 Dec 2020 00:37:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolabnow.com; h= content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:date:subject:subject:from:from:received :received:received; s=dkim20160331; t=1608248234; x=1610062635; bh=n9VGINQmxiKF33GdbXv/cH9OY0rSZz/a4izu2haETck=; b=EeXN1Ccw+xiQ CJklcMR1vtAMwwmrv8Q8/SP22H4UBQEwN5CJ7mcxJ30nkzttKJXMvmuCxmw2Dw7w k1HyjriwQ3PHuef5j2etgnDn2GxQ215A9sMkjYeJ2zQOKehEPUO1VonL4p20BU61 Lr+5+xfOdU71M7G35ajDTDCzHBnfDscVvICe/SewpkmIfQCZyYo2Twlaq2SCC5ae JH5D+g+HCXej8P6pOOSfq7td9SpagC1KMxiZuubQqB/pRstVsV6lCQmwoMUVNzS0 4cxGSwsy+cOZ1b4ftNzZzE6HJbohWaanCZXxxGLkFWU7aIc0pBkMMsuHXsMZzjEk aqpUXVGLl4dELm0gcnxGuYegJeFqRqUzC7JUay44G0xERNZMtuKnVVibmFNcpttn Np58Ze9bCzML/BB0zPZj7+kkv/kO3d/EhRO5NDaKaC0AvTMmrvOoehNDNhCT4zms /9theoqt2WCnl/HWbdP9Ut+HfIpObTVUAm0G1MGAvj+Neu/JSjeQycMxvc2dXORq m16iguks8rCbzGCOR4TtBch7dN4aCHGgBk24RFuN1jtFDsbz7xMS7AHXIx8Qo4ve 7UZoMGUxqFf3DuBlvMVBxrTf/oKZsnH8NQmkMID6Si9SvVpCF7uHqjs/u+zJMNPo 4bBgpm0k80nocdckktJuCwVj15dlfOU= X-Virus-Scanned: amavisd-new at mykolab.com X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 Received: from mx.kolabnow.com ([127.0.0.1]) by localhost (ext-mx-out001.mykolab.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bCiGoqm0nX3X; Fri, 18 Dec 2020 00:37:14 +0100 (CET) Received: from int-mx002.mykolab.com (unknown [10.9.13.2]) by ext-mx-out001.mykolab.com (Postfix) with ESMTPS id D135F521; Fri, 18 Dec 2020 00:37:13 +0100 (CET) Received: from ext-subm002.mykolab.com (unknown [10.9.6.2]) by int-mx002.mykolab.com (Postfix) with ESMTPS id 68EA527E4; Fri, 18 Dec 2020 00:37:13 +0100 (CET) From: Thomas Rodgers To: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org Subject: [PATCH] libstdc++: Add support for C++20 barriers Date: Thu, 17 Dec 2020 15:37:06 -0800 Message-Id: <20201217233706.3071964-1-rodgert@appliantology.com> In-Reply-To: <20201217191130.3049887-1-rodgert@appliantology.com> References: <20201217191130.3049887-1-rodgert@appliantology.com> MIME-Version: 1.0 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: trodgers@redhat.com Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" From: Thomas Rodgers Cleans up a few things mentioned on IRC. Adds libstdc++/ChangeLog: * doc/doxygen/user.cfg.in: Add new header. * include/Makefile.am (std_headers): likewise. * include/Makefile.in: Regenerate. * include/precompiled/stdc++.h: Add new header. * include/std/barrier: New file. * include/std/version: Add __cpp_lib_barrier feature test macro. * testsuite/30_thread/barrier/1.cc: New test. * testsuite/30_thread/barrier/2.cc: Likewise. * testsuite/30_thread/barrier/arrive_and_drop.cc: Likewise. * testsuite/30_thread/barrier/arrive_and_wait.cc: Likewise. * testsuite/30_thread/barrier/arrive.cc: Likewise. * testsuite/30_thread/barrier/completion.cc: Likewise. * testsuite/30_thread/barrier/max.cc: Likewise. --- libstdc++-v3/doc/doxygen/user.cfg.in | 1 + libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/precompiled/stdc++.h | 1 + libstdc++-v3/include/std/barrier | 249 ++++++++++++++++++ libstdc++-v3/include/std/version | 3 + .../testsuite/30_threads/barrier/1.cc | 27 ++ .../testsuite/30_threads/barrier/2.cc | 27 ++ .../testsuite/30_threads/barrier/arrive.cc | 48 ++++ .../30_threads/barrier/arrive_and_drop.cc | 46 ++++ .../30_threads/barrier/arrive_and_wait.cc | 46 ++++ .../30_threads/barrier/completion.cc | 53 ++++ .../testsuite/30_threads/barrier/max.cc | 40 +++ 13 files changed, 543 insertions(+) create mode 100644 libstdc++-v3/include/std/barrier create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/1.cc create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/2.cc create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/arrive.cc create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/completion.cc create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/max.cc diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in index 2261d572efb..fb90db65e55 100644 --- a/libstdc++-v3/doc/doxygen/user.cfg.in +++ b/libstdc++-v3/doc/doxygen/user.cfg.in @@ -850,6 +850,7 @@ INPUT = @srcdir@/doc/doxygen/doxygroups.cc \ include/any \ include/array \ include/atomic \ + include/barrier \ include/bit \ include/bitset \ include/charconv \ diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 958dfea5a98..231f7c3ec8f 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -30,6 +30,7 @@ std_headers = \ ${std_srcdir}/any \ ${std_srcdir}/array \ ${std_srcdir}/atomic \ + ${std_srcdir}/barrier \ ${std_srcdir}/bit \ ${std_srcdir}/bitset \ ${std_srcdir}/charconv \ diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index 692fae76a42..424c0e277d1 100644 --- a/libstdc++-v3/include/precompiled/stdc++.h +++ b/libstdc++-v3/include/precompiled/stdc++.h @@ -134,6 +134,7 @@ #endif #if __cplusplus > 201703L +#include #include #include #include diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier new file mode 100644 index 00000000000..db514540e37 --- /dev/null +++ b/libstdc++-v3/include/std/barrier @@ -0,0 +1,249 @@ +// -*- C++ -*- + +// 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 +// . + +// This implementation is based on libcxx/include/barrier +//===-- barrier.h --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------===// + +/** @file include/barrier + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_BARRIER +#define _GLIBCXX_BARRIER 1 + +#pragma GCC system_header + +#if __cplusplus > 201703L +#include +#if __cpp_lib_atomic_wait && __cpp_aligned_new +#include +#include +#include + +#include + +#define __cpp_lib_barrier 201907L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + struct __empty_completion + { + _GLIBCXX_ALWAYS_INLINE void + operator()() noexcept + { } + }; + +/* + +The default implementation of __tree_barrier is a classic tree barrier. + +It looks different from literature pseudocode for two main reasons: + 1. Threads that call into std::barrier functions do not provide indices, + so a numbering step is added before the actual barrier algorithm, + appearing as an N+1 round to the N rounds of the tree barrier. + 2. A great deal of attention has been paid to avoid cache line thrashing + by flattening the tree structure into cache-line sized arrays, that + are indexed in an efficient way. + +*/ + + enum class __barrier_phase_t : unsigned char { }; + + template + class __tree_barrier + { + using __atomic_phase_ref_t = std::__atomic_ref<__barrier_phase_t>; + using __atomic_phase_const_ref_t = std::__atomic_ref; + static constexpr auto __phase_alignment = + __atomic_phase_ref_t::required_alignment; + + using __tickets_t = std::array<__barrier_phase_t, 64>; + struct alignas(64) /* naturally-align the heap state */ __state_t + { + alignas(__phase_alignment) __tickets_t __tickets; + }; + + ptrdiff_t _M_expected; + unique_ptr<__state_t[]> _M_state; + __atomic_base _M_expected_adjustment; + _CompletionF _M_completion; + + alignas(__phase_alignment) __barrier_phase_t _M_phase; + + bool + _M_arrive(__barrier_phase_t __old_phase) + { + const auto __old_phase_val = static_cast(__old_phase); + const auto __half_step = + static_cast<__barrier_phase_t>(__old_phase_val + 1); + const auto __full_step = + static_cast<__barrier_phase_t>(__old_phase_val + 2); + + size_t __current_expected = _M_expected; + std::hash__hasher; + size_t __current = __hasher(std::this_thread::get_id()) + % ((_M_expected + 1) >> 1); + + for (int __round = 0; ; ++__round) + { + if (__current_expected <= 1) + return true; + size_t const __end_node = ((__current_expected + 1) >> 1), + __last_node = __end_node - 1; + for ( ; ; ++__current) + { + if (__current == __end_node) + __current = 0; + auto __expect = __old_phase; + __atomic_phase_ref_t __phase(_M_state[__current] + .__tickets[__round]); + if (__current == __last_node && (__current_expected & 1)) + { + if (__phase.compare_exchange_strong(__expect, __full_step, + memory_order_acq_rel)) + break; // I'm 1 in 1, go to next __round + } + else if (__phase.compare_exchange_strong(__expect, __half_step, + memory_order_acq_rel)) + { + return false; // I'm 1 in 2, done with arrival + } + else if (__expect == __half_step) + { + if (__phase.compare_exchange_strong(__expect, __full_step, + memory_order_acq_rel)) + break; // I'm 2 in 2, go to next __round + } + } + __current_expected = __last_node + 1; + __current >>= 1; + } + } + + public: + using arrival_token = __barrier_phase_t; + + static constexpr ptrdiff_t + max() noexcept + { return __PTRDIFF_MAX__; } + + __tree_barrier(ptrdiff_t __expected, _CompletionF __completion) + : _M_expected(__expected), _M_expected_adjustment(0), + _M_completion(move(__completion)), + _M_phase(static_cast<__barrier_phase_t>(0)) + { + size_t const __count = (_M_expected + 1) >> 1; + + _M_state = std::make_unique<__state_t[]>(__count); + } + + [[nodiscard]] arrival_token + arrive(ptrdiff_t __update) + { + __atomic_phase_ref_t __phase(_M_phase); + const auto __old_phase = __phase.load(memory_order_relaxed); + const auto __cur = static_cast(__old_phase); + for(; __update; --__update) + { + if(_M_arrive(__old_phase)) + { + _M_completion(); + _M_expected += _M_expected_adjustment.load(memory_order_relaxed); + _M_expected_adjustment.store(0, memory_order_relaxed); + auto __new_phase = static_cast<__barrier_phase_t>(__cur + 2); + __phase.store(__new_phase, memory_order_release); + __phase.notify_all(); + } + } + return __old_phase; + } + + void + wait(arrival_token&& __old_phase) const + { + __atomic_phase_const_ref_t __phase(_M_phase); + auto const __test_fn = [=, this] + { + return __phase.load(memory_order_acquire) != __old_phase; + }; + std::__atomic_wait(&_M_phase, __old_phase, __test_fn); + } + + void + arrive_and_drop() + { + _M_expected_adjustment.fetch_sub(1, memory_order_relaxed); + (void)arrive(1); + } + }; + + template + class barrier + { + // Note, we may introduce a "central" barrier algorithm at some point + // for more space constrained targets + using __algorithm_t = __tree_barrier<_CompletionF>; + __algorithm_t _M_b; + + public: + using arrival_token = typename __tree_barrier<_CompletionF>::arrival_token; + + static constexpr ptrdiff_t + max() noexcept + { return __algorithm_t::max(); } + + explicit barrier(ptrdiff_t __count, + _CompletionF __completion = _CompletionF()) + : _M_b(__count, std::move(__completion)) + { } + + barrier(barrier const&) = delete; + barrier& operator=(barrier const&) = delete; + + [[nodiscard]] arrival_token + arrive(ptrdiff_t __update = 1) + { return _M_b.arrive(__update); } + + void + wait(arrival_token&& __phase) const + { _M_b.wait(std::move(__phase)); } + + void + arrive_and_wait() + { wait(arrive()); } + + void + arrive_and_drop() + { _M_b.arrive_and_drop(); } + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace +#endif // __cpp_lib_atomic_wait && __cpp_aligned_new +#endif // __cplusplus > 201703L +#endif // _GLIBCXX_BARRIER + diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index e4a8bed52ab..07d17433c5b 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -200,6 +200,9 @@ #if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX # define __cpp_lib_atomic_wait 201907L #endif +#if __cpp_lib_atomic_wait +#define __cpp_lib_barrier 201907L +#endif #define __cpp_lib_bind_front 201907L #if __has_builtin(__builtin_bit_cast) # define __cpp_lib_bit_cast 201806L diff --git a/libstdc++-v3/testsuite/30_threads/barrier/1.cc b/libstdc++-v3/testsuite/30_threads/barrier/1.cc new file mode 100644 index 00000000000..0b38160a58b --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +#ifndef __cpp_lib_barrier +# error "Feature-test macro for barrier missing in " +#elif __cpp_lib_barrier != 201907L +# error "Feature-test macro for barrier has wrong value in " +#endif diff --git a/libstdc++-v3/testsuite/30_threads/barrier/2.cc b/libstdc++-v3/testsuite/30_threads/barrier/2.cc new file mode 100644 index 00000000000..1d8d83639e0 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/2.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2019-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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +#ifndef __cpp_lib_barrier +# error "Feature-test macro for barrier missing in " +#elif __cpp_lib_barrier != 201907L +# error "Feature-test macro for barrier has wrong value in " +#endif diff --git a/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc b/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc new file mode 100644 index 00000000000..df70587db5b --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc @@ -0,0 +1,48 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-gthreads "" } +// { dg-additional-options "-pthread" { target pthread } } + +// 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 +// . + +// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive.pass.cpp +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +int main(int, char**) +{ + std::barrier<> b(2); + + auto tok = b.arrive(); + std::thread t([&](){ + (void)b.arrive(); + }); + b.wait(std::move(tok)); + t.join(); + + auto tok2 = b.arrive(2); + b.wait(std::move(tok2)); +} diff --git a/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc new file mode 100644 index 00000000000..746a8f470e3 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-gthreads "" } +// { dg-additional-options "-pthread" { target pthread } } + +// 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 +// . + +// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive_and_drop.pass.cpp +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +int main(int, char**) +{ + std::barrier<> b(2); + + std::thread t([&](){ + b.arrive_and_drop(); + }); + + b.arrive_and_wait(); + b.arrive_and_wait(); + t.join(); +} diff --git a/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc new file mode 100644 index 00000000000..509986f3b78 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-gthreads "" } +// { dg-additional-options "-pthread" { target pthread } } + +// 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 +// . + +// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive_and_drop.pass.cpp +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +int main(int, char**) +{ + std::barrier<> b(2); + + std::thread t([&](){ + for(int i = 0; i < 10; ++i) + b.arrive_and_wait(); + }); + for(int i = 0; i < 10; ++i) + b.arrive_and_wait(); + t.join(); +} diff --git a/libstdc++-v3/testsuite/30_threads/barrier/completion.cc b/libstdc++-v3/testsuite/30_threads/barrier/completion.cc new file mode 100644 index 00000000000..c7997d9d7fb --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/completion.cc @@ -0,0 +1,53 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-gthreads "" } +// { dg-additional-options "-pthread" { target pthread } } + +// 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 +// . + +// This implementation is based on libcxx/test/std/thread/thread.barrier/completion.pass.cpp +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include + +int main(int, char**) +{ + int x = 0; + auto comp = [&] { x += 1; }; + std::barrier b(2, comp); + + std::thread t([&](){ + for(int i = 0; i < 10; ++i) + b.arrive_and_wait(); + }); + + for(int i = 0; i < 10; ++i) + b.arrive_and_wait(); + + VERIFY( x == 10 ); + t.join(); +} diff --git a/libstdc++-v3/testsuite/30_threads/barrier/max.cc b/libstdc++-v3/testsuite/30_threads/barrier/max.cc new file mode 100644 index 00000000000..278bc3fdd10 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/barrier/max.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-gthreads "" } +// { dg-additional-options "-pthread" { target pthread } } + +// 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 +// . + +// This implementation is based on libcxx/test/std/thread/thread.barrier/max.pass.cpp +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +int main(int, char**) +{ + static_assert(std::barrier<>::max() > 0, ""); + auto l = [](){}; + static_assert(std::barrier::max() > 0, ""); +}