[PATCH] libstdc++: Add support for C++20 barriers
Jonathan Wakely
jwakely@redhat.com
Thu Dec 17 14:06:26 GMT 2020
On 27/11/20 17:46 +0000, Jonathan Wakely wrote:
>On 20/11/20 16:30 -0800, Thomas Rodgers wrote:
>>From: Thomas Rodgers <trodgers@redhat.com>
>>
>>Should include all discussion on and off list to date.
>
>Most of the comments in
>https://gcc.gnu.org/pipermail/gcc-patches/2020-November/558090.html
>still apply to this version.
>
>>Adds <barrier>
>>
>>libstdc++/ChangeLog:
>>
>> * include/Makefile.am (std_headers): Add new header.
>> * include/Makefile.in: Regenerate.
>> * 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/include/Makefile.am | 1 +
>>libstdc++-v3/include/Makefile.in | 1 +
>>libstdc++-v3/include/std/barrier | 258 ++++++++++++++++++
>>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 | 51 ++++
>>.../30_threads/barrier/arrive_and_drop.cc | 49 ++++
>>.../30_threads/barrier/arrive_and_wait.cc | 51 ++++
>>.../30_threads/barrier/completion.cc | 54 ++++
>>.../testsuite/30_threads/barrier/max.cc | 44 +++
>>11 files changed, 566 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/include/Makefile.am b/libstdc++-v3/include/Makefile.am
>>index ca413b8fdfe..a20dd461fd1 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 \
>
>The new header should also be added to include/precompiled/stdc++.h
>and doc/doxygen/user.cfg.in
>
>>diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
>>new file mode 100644
>>index 00000000000..a6cc6a058dd
>>--- /dev/null
>>+++ b/libstdc++-v3/include/std/barrier
>>@@ -0,0 +1,258 @@
>>+// <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
>>+//
>>+//===---------------------------------------------------------------===//
>
>This file doesn't have the usual @file doxygen block.
>
>>+
>>+#ifndef _GLIBCXX_BARRIER
>>+#define _GLIBCXX_BARRIER 1
>>+
>>+#pragma GCC system_header
>>+
>>+#if __cplusplus > 201703L
>>+#include <bits/c++config.h>
>>+
>>+#if defined(_GLIBCXX_HAS_GTHREADS)
>
>This doesn't match the condition used in <bits/atomic_wait.h>. I've
>added _GLIBCXX_HAVE_ATOMIC_WAIT so it could check that.
>
>>+#define __cpp_lib_barrier 201907L
>>+#include <bits/atomic_base.h>
>>+#include <bits/atomic_wait.h>
>
>This is already included by <bits/atomic_base.h>
>
>I suggest:
>
>#if __cplusplus > 201703L
>#include <bits/atomic_base.h>
>#ifdef _GLIBCXX_HAVE_ATOMIC_WAIT
>#include <bits/functional_hash.h>
>...
>#define __cpp_lib_barrier 201907L
>
>We should only define the __cpp_lib macro after including all other
>headers, otherwise we advertise to those headers that the feature
>exists, but it hasn't been defined yet. Nothing is trying to use
>barrier in the rest of the library yet, but that could change.
>
>>+#include <bits/functional_hash.h>
>>+
>>+#include <memory>
>>+
>>+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.
>>+
>>+*/
>>+
>>+ using __barrier_phase_t = uint8_t;
>>+
>>+ template<typename _CompletionF>
>>+ class __tree_barrier
>>+ {
>>+ struct alignas(64) /* naturally-align the heap state */ __state_t
>>+ {
>>+ struct
>>+ {
>>+ __atomic_base<__barrier_phase_t> __phase = { 0 };
>>+ } __tickets[64];
>>+ };
>>+
>>+ ptrdiff_t _M_expected;
>>+ unique_ptr<char[]> _M_state_allocation;
>>+ __state_t* _M_state;
>>+ __atomic_base<ptrdiff_t> _M_expected_adjustment;
>>+ _CompletionF _M_completion;
>>+
>>+ 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 size_t __phase_alignment =
>>+ __atomic_phase_ref_t::required_alignment;
>>+ alignas(__phase_alignment) __barrier_phase_t _M_phase;
>>+
>>+ static __gthread_t
>>+ _S_get_tid() noexcept
>>+ {
>>+#ifdef __GLIBC__
>>+ // For the GNU C library pthread_self() is usable without linking to
>>+ // libpthread.so but returns 0, so we cannot use it in single-threaded
>>+ // programs, because this_thread::get_id() != thread::id{} must be true.
>>+ // We know that pthread_t is an integral type in the GNU C library.
>>+ if (!__gthread_active_p())
>>+ return 1;
>>+#endif
>>+ return __gthread_self();
>
>If you include <bits/std_thread.h> you can use this_thread::get_id()
>here. That avoids needing to repeat the glibc-specific hack.
>
>>+ }
>>+
>>+ bool
>>+ _M_arrive(__barrier_phase_t __old_phase)
>>+ {
>>+ __barrier_phase_t const __half_step = __old_phase + 1,
>>+ __full_step = __old_phase + 2;
>>+ size_t __current_expected = _M_expected;
>>+ size_t __current = _Hash_impl::hash(_S_get_tid())
>>+ % ((_M_expected + 1) >> 1);
>
>If we move std::hash<std::thread::id> into <bits/std_thread.h> then
>you can just use that.
Done in r11-6227.
Tested powerpc64le-linux, committed to trunk.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 2532 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-patches/attachments/20201217/041723b5/attachment.bin>
More information about the Gcc-patches
mailing list