libstdc++: Add support for C++20 barriers

Message ID 20201217233706.3071964-1-rodgert@appliantology.com
State New
Headers show
Series
  • libstdc++: Add support for C++20 barriers
Related show

Commit Message

Thomas Rodgers Dec. 17, 2020, 11:37 p.m.
From: Thomas Rodgers <trodgers@redhat.com>


Cleans up a few things mentioned on IRC.

Adds <barrier>

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

-- 
2.26.2

Comments

Jeff Law via Gcc-patches Dec. 18, 2020, 10:08 a.m. | #1
On 17/12/20 15:37 -0800, Thomas Rodgers wrote:
>From: Thomas Rodgers <trodgers@redhat.com>

>

>Cleans up a few things mentioned on IRC.

>

>Adds <barrier>

>

>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.



>+#ifndef _GLIBCXX_BARRIER

>+#define _GLIBCXX_BARRIER 1

>+

>+#pragma GCC system_header

>+

>+#if __cplusplus > 201703L

>+#include <bits/atomic_base.h>

>+#if __cpp_lib_atomic_wait  && __cpp_aligned_new


There's an extra space here before the && operator.

>+#endif // __cpp_lib_atomic_wait  && __cpp_aligned_new


And here.

>+#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


This needs to match the condition used in <barrier>.

>+#define __cpp_lib_barrier 201907L

>+#endif


You could just put it inside the previous block where
__cpp_lib_atomic_wait is defined:

#if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX
# define __cpp_lib_atomic_wait 201907L
# if __cpp_aligned_new
#  define __cpp_lib_barrier 201907L
# endif
#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

>+// <http://www.gnu.org/licenses/>.

>+

>+// { dg-options "-std=gnu++2a" }

>+// { dg-do compile { target c++2a } }


This test will fail for non-gthreads targets, because they don't
define the macro. This needs the same condition as the similar
29_atomics/atomic/wait_notify/1.cc test:

// { dg-require-effective-target gthreads }

(which is the new way to say { dg-requires-gthread "" })

>+#include <barrier>

>+

>+#ifndef __cpp_lib_barrier

>+# error "Feature-test macro for barrier missing in <barrier>"

>+#elif __cpp_lib_barrier != 201907L

>+# error "Feature-test macro for barrier has wrong value in <barrier>"

>+#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

>+// <http://www.gnu.org/licenses/>.

>+

>+// { dg-options "-std=gnu++2a" }

>+// { dg-do compile { target c++2a } }


Same here.

>+#include <version>

>+

>+#ifndef __cpp_lib_barrier

>+# error "Feature-test macro for barrier missing in <version>"

>+#elif __cpp_lib_barrier != 201907L

>+# error "Feature-test macro for barrier has wrong value in <version>"

>+#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

>+// <http://www.gnu.org/licenses/>.

>+

>+// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive.pass.cpp


Please replace "implementation" with "test" or something like that,
since this isn't the implementation. Same for all the other tests
taken from LLVM.

>+//===----------------------------------------------------------------------===//

>+//

>+// 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 <barrier>

>+#include <thread>

>+

>+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

>+// <http://www.gnu.org/licenses/>.

>+

>+// 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 <barrier>

>+#include <thread>

>+

>+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

>+// <http://www.gnu.org/licenses/>.

>+

>+// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive_and_drop.pass.cpp


Wrong filename?

>+//===----------------------------------------------------------------------===//

>+//

>+// 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 <barrier>

>+#include <thread>

>+

>+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

>+// <http://www.gnu.org/licenses/>.

>+

>+// 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 <barrier>

>+#include <thread>

>+

>+#include <testsuite_hooks.h>

>+

>+int main(int, char**)

>+{

>+  int x = 0;

>+  auto comp = [&] { x += 1; };

>+  std::barrier<decltype(comp)> 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 } }


This should be 'compile' not 'run'.

I think I'd rather see these static_asserts put into one of the
existing tests, so we don't pay for the overhead of another dejagnu
test (with all its setup and target checking) just for this.

Maybe in barrier/1.cc since that's not doing very much work either
(and don't forget to move the dg-additional-options there too).

>+// { 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

>+// <http://www.gnu.org/licenses/>.

>+

>+// 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 <barrier>

>+#include <thread>

>+

>+int main(int, char**)

>+{

>+  static_assert(std::barrier<>::max() > 0, "");

>+  auto l = [](){};

>+  static_assert(std::barrier<decltype(l)>::max() > 0, "");


No need for the string literals here, this is C++20.

OK with those changes, thanks.
Jeff Law via Gcc-patches Jan. 7, 2021, 8:56 p.m. | #2
Tested x86_64-pc-linux-gnu, committed to master.

Jonathan Wakely writes:

> On 17/12/20 15:37 -0800, Thomas Rodgers wrote:

>>From: Thomas Rodgers <trodgers@redhat.com>

>>

>>Cleans up a few things mentioned on IRC.

>>

>>Adds <barrier>

>>

>>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.

>

>

>>+#ifndef _GLIBCXX_BARRIER

>>+#define _GLIBCXX_BARRIER 1

>>+

>>+#pragma GCC system_header

>>+

>>+#if __cplusplus > 201703L

>>+#include <bits/atomic_base.h>

>>+#if __cpp_lib_atomic_wait  && __cpp_aligned_new

>

> There's an extra space here before the && operator.

>

>>+#endif // __cpp_lib_atomic_wait  && __cpp_aligned_new

>

> And here.

>

>>+#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

>

> This needs to match the condition used in <barrier>.

>

>>+#define __cpp_lib_barrier 201907L

>>+#endif

>

> You could just put it inside the previous block where

> __cpp_lib_atomic_wait is defined:

>

> #if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX

> # define __cpp_lib_atomic_wait 201907L

> # if __cpp_aligned_new

> #  define __cpp_lib_barrier 201907L

> # endif

> #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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// { dg-options "-std=gnu++2a" }

>>+// { dg-do compile { target c++2a } }

>

> This test will fail for non-gthreads targets, because they don't

> define the macro. This needs the same condition as the similar

> 29_atomics/atomic/wait_notify/1.cc test:

>

> // { dg-require-effective-target gthreads }

>

> (which is the new way to say { dg-requires-gthread "" })

>

>>+#include <barrier>

>>+

>>+#ifndef __cpp_lib_barrier

>>+# error "Feature-test macro for barrier missing in <barrier>"

>>+#elif __cpp_lib_barrier != 201907L

>>+# error "Feature-test macro for barrier has wrong value in <barrier>"

>>+#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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// { dg-options "-std=gnu++2a" }

>>+// { dg-do compile { target c++2a } }

>

> Same here.

>

>>+#include <version>

>>+

>>+#ifndef __cpp_lib_barrier

>>+# error "Feature-test macro for barrier missing in <version>"

>>+#elif __cpp_lib_barrier != 201907L

>>+# error "Feature-test macro for barrier has wrong value in <version>"

>>+#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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive.pass.cpp

>

> Please replace "implementation" with "test" or something like that,

> since this isn't the implementation. Same for all the other tests

> taken from LLVM.

>

>>+//===----------------------------------------------------------------------===//

>>+//

>>+// 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 <barrier>

>>+#include <thread>

>>+

>>+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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// 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 <barrier>

>>+#include <thread>

>>+

>>+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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// This implementation is based on libcxx/test/std/thread/thread.barrier/arrive_and_drop.pass.cpp

>

> Wrong filename?

>

>>+//===----------------------------------------------------------------------===//

>>+//

>>+// 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 <barrier>

>>+#include <thread>

>>+

>>+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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// 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 <barrier>

>>+#include <thread>

>>+

>>+#include <testsuite_hooks.h>

>>+

>>+int main(int, char**)

>>+{

>>+  int x = 0;

>>+  auto comp = [&] { x += 1; };

>>+  std::barrier<decltype(comp)> 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 } }

>

> This should be 'compile' not 'run'.

>

> I think I'd rather see these static_asserts put into one of the

> existing tests, so we don't pay for the overhead of another dejagnu

> test (with all its setup and target checking) just for this.

>

> Maybe in barrier/1.cc since that's not doing very much work either

> (and don't forget to move the dg-additional-options there too).

>

>>+// { 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

>>+// <http://www.gnu.org/licenses/>.

>>+

>>+// 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 <barrier>

>>+#include <thread>

>>+

>>+int main(int, char**)

>>+{

>>+  static_assert(std::barrier<>::max() > 0, "");

>>+  auto l = [](){};

>>+  static_assert(std::barrier<decltype(l)>::max() > 0, "");

>

> No need for the string literals here, this is C++20.

>

> OK with those changes, thanks.
Jeff Law via Gcc-patches Jan. 14, 2021, 2:26 p.m. | #3
On 07/01/21 12:56 -0800, Thomas Rodgers via Libstdc++ wrote:
>

>Tested x86_64-pc-linux-gnu, committed to master.


The copyright years need updating. Pushed to master.
commit 194a9d67be45568d81bb8c17e9102e31c1309e5f
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Jan 14 14:25:05 2021

    libstdc++: Update copyright dates on new files
    
    The patch adding these files was approved in 2020 but it wasn't
    committed until 2021, so the copyright years were not updated along with
    the years in all the existing files.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/barrier: Update copyright years. Fix whitespace.
            * include/std/version: Fix whitespace.
            * testsuite/30_threads/barrier/1.cc: Update copyright years.
            * testsuite/30_threads/barrier/2.cc: Likewise.
            * testsuite/30_threads/barrier/arrive.cc: Likewise.
            * testsuite/30_threads/barrier/arrive_and_drop.cc: Likewise.
            * testsuite/30_threads/barrier/arrive_and_wait.cc: Likewise.
            * testsuite/30_threads/barrier/completion.cc: Likewise.

diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
index f1143da89b4..e09212dfcb9 100644
--- a/libstdc++-v3/include/std/barrier
+++ b/libstdc++-v3/include/std/barrier
@@ -1,6 +1,6 @@
 // <barrier> -*- C++ -*-
 
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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
@@ -103,7 +103,7 @@ It looks different from literature pseudocode for two main reasons:
 			   static_cast<__barrier_phase_t>(__old_phase_val + 2);
 
 	size_t __current_expected = _M_expected;
-	std::hash<std::thread::id>__hasher;
+	std::hash<std::thread::id> __hasher;
 	size_t __current = __hasher(std::this_thread::get_id())
 					  % ((_M_expected + 1) >> 1);
 
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 9516558d8b4..e3d52b88c21 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -200,8 +200,8 @@
 #if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX
 # define __cpp_lib_atomic_wait 201907L
 # if __cpp_aligned_new
-# define __cpp_lib_barrier 201907L
-#endif
+#  define __cpp_lib_barrier 201907L
+# endif
 #endif
 #define __cpp_lib_bind_front 201907L
 #if __has_builtin(__builtin_bit_cast)
diff --git a/libstdc++-v3/testsuite/30_threads/barrier/1.cc b/libstdc++-v3/testsuite/30_threads/barrier/1.cc
index 4c15deb1398..a21fae32127 100644
--- a/libstdc++-v3/testsuite/30_threads/barrier/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/barrier/1.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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
diff --git a/libstdc++-v3/testsuite/30_threads/barrier/2.cc b/libstdc++-v3/testsuite/30_threads/barrier/2.cc
index 0fac1ef3f3c..94e37d739da 100644
--- a/libstdc++-v3/testsuite/30_threads/barrier/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/barrier/2.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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
diff --git a/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc b/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc
index 6e64e378cb0..fb0f56292c0 100644
--- a/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc
+++ b/libstdc++-v3/testsuite/30_threads/barrier/arrive.cc
@@ -3,7 +3,7 @@
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
 
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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
diff --git a/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc
index 55f40e17062..22b40200c80 100644
--- a/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc
+++ b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc
@@ -3,7 +3,7 @@
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
 
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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
diff --git a/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc
index 2a3a69ae3c0..f9b4fa29063 100644
--- a/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc
+++ b/libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc
@@ -3,7 +3,7 @@
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
 
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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
diff --git a/libstdc++-v3/testsuite/30_threads/barrier/completion.cc b/libstdc++-v3/testsuite/30_threads/barrier/completion.cc
index ef6d2c3eac6..27be0844a60 100644
--- a/libstdc++-v3/testsuite/30_threads/barrier/completion.cc
+++ b/libstdc++-v3/testsuite/30_threads/barrier/completion.cc
@@ -3,7 +3,7 @@
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
 
-// Copyright (C) 2020 Free Software Foundation, Inc.
+// Copyright (C) 2020-2021 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

Patch

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 <barrier>
 #include <bit>
 #include <compare>
 #include <concepts>
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 @@ 
+// <barrier> -*- 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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <bits/atomic_base.h>
+#if __cpp_lib_atomic_wait  && __cpp_aligned_new
+#include <bits/functional_hash.h>
+#include <bits/std_thread.h>
+#include <bits/unique_ptr.h>
+
+#include <array>
+
+#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<typename _CompletionF>
+    class __tree_barrier
+    {
+      using __atomic_phase_ref_t = std::__atomic_ref<__barrier_phase_t>;
+      using __atomic_phase_const_ref_t = std::__atomic_ref<const __barrier_phase_t>;
+      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<ptrdiff_t> _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<unsigned char>(__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<std::thread::id>__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<unsigned char>(__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<typename _CompletionF = __empty_completion>
+    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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <barrier>
+
+#ifndef __cpp_lib_barrier
+# error "Feature-test macro for barrier missing in <barrier>"
+#elif __cpp_lib_barrier != 201907L
+# error "Feature-test macro for barrier has wrong value in <barrier>"
+#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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_barrier
+# error "Feature-test macro for barrier missing in <version>"
+#elif __cpp_lib_barrier != 201907L
+# error "Feature-test macro for barrier has wrong value in <version>"
+#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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <barrier>
+#include <thread>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <barrier>
+#include <thread>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <barrier>
+#include <thread>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <barrier>
+#include <thread>
+
+#include <testsuite_hooks.h>
+
+int main(int, char**)
+{
+  int x = 0;
+  auto comp = [&] { x += 1; };
+  std::barrier<decltype(comp)> 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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <barrier>
+#include <thread>
+
+int main(int, char**)
+{
+  static_assert(std::barrier<>::max() > 0, "");
+  auto l = [](){};
+  static_assert(std::barrier<decltype(l)>::max() > 0, "");
+}