Re: [PATCH 1/2] libstdc++: Atomic wait/notify ABI stabilization

2023-12-14 Thread Thomas Rodgers
I need to look at this a bit more (and not on my phone, at lunch).
Ultimately, C++26 expects to add predicate waits and returning a
‘tri-state’ result isn’t something that’s been considered or likely to be
approved.

On Mon, Dec 11, 2023 at 12:18 PM Jonathan Wakely 
wrote:

> CCing Tom's current address, as he's not @redhat.com now.
>
> On Mon, 11 Dec 2023, 19:24 Nate Eldredge, 
> wrote:
>
>> On Mon, 11 Dec 2023, Nate Eldredge wrote:
>>
>> > To fix, we need something like `__args._M_old = __val;` inside the loop
>> in
>> > __atomic_wait_address(), so that we always wait on the exact value that
>> the
>> > predicate __pred() rejected.  Again, there are similar instances in
>> > atomic_timed_wait.h.
>>
>> Thinking through this, there's another problem.  The main loop in
>> __atomic_wait_address() would then be:
>>
>>while (!__pred(__val))
>>  {
>>__args._M_old = __val;
>>__detail::__wait_impl(__wait_addr, &__args);
>>__val = __vfn();
>>  }
>>
>> The idea being that we only call __wait_impl to wait on a value that the
>> predicate said was unacceptable.  But looking for instance at its caller
>> __atomic_semaphore::_M_acquire() in bits/semaphore_base.h, the predicate
>> passed in is _S_do_try_acquire(), whose code is:
>>
>>  _S_do_try_acquire(__detail::__platform_wait_t* __counter,
>>__detail::__platform_wait_t __old) noexcept
>>  {
>>if (__old == 0)
>>  return false;
>>
>>return __atomic_impl::compare_exchange_strong(__counter,
>>  __old, __old - 1,
>>
>>  memory_order::acquire,
>>
>>  memory_order::relaxed);
>>  }
>>
>> It returns false if the value passed in was unacceptable (i.e. zero),
>> *or*
>> if it was nonzero (let's say 1) but the compare_exchange failed because
>> another thread swooped in and modified the semaphore counter.  In that
>> latter case, __atomic_wait_address() would pass 1 to __wait_impl(), which
>> is likewise bad.  If the counter is externally changed back to 1 just
>> before we call __platform_wait (that's the futex call), we would go to
>> sleep waiting on a semaphore that is already available: deadlock.
>>
>> I guess there's a couple ways to fix it.
>>
>> You could have the "predicate" callback instead return a tri-state value:
>> "all done, stop waiting" (like current true), "value passed is not
>> acceptable" (like current false), and "value was acceptable but something
>> else went wrong".  Only the second case should result in calling
>> __wait_impl().  In the third case, __atomic_wait_address() should
>> just reload the value (using __vfn()) and loop again.
>>
>> Or, make the callback __pred() a pure predicate that only tests its input
>> value for acceptability, without any other side effects.  Then have
>> __atomic_wait_address() simply return as soon as __pred(__val) returns
>> true.  It would be up to the caller to actually decrement the semaphore
>> or
>> whatever, and to call __atomic_wait_address() again if this fails.  In
>> that case, __atomic_wait_address should probably return the final value
>> that was read, so the caller can immediately do something like a
>> compare-exchange using it, and not have to do an additional load and
>> predicate test.
>>
>> Or, make __pred() a pure predicate as before, and give
>> __atomic_wait_address yet one more callback function argument, call it
>> __taker(), whose job is to acquire the semaphore etc, and have
>> __atomic_wait_address call it after __pred(__val) returns true.
>>
>> --
>> Nate Eldredge
>> n...@thatsmathematics.com
>>
>>


Re: [PATCH] libstdc++: Split up pstl/set.cc testcase

2023-07-05 Thread Thomas Rodgers via Gcc-patches
Comment added to each file.

Tested x86_64-linux. Pushed to trunk.

On Mon, Jul 3, 2023 at 4:16 PM Jonathan Wakely  wrote:

> On Mon, 3 Jul 2023 at 23:14, Thomas Rodgers via Libstdc++
>  wrote:
> >
> > This testcase is causing some timeout issues. This patch splits the
> > testcase up by individual set algorithm.
>
> I think the Apache license requires a notice saying the original file
> was modified. A comment in each new file noting it was derived from
> pstl/alg_sorting/set.cc (or whatever the file is called upstream)
> should be sufficient.
>
> OK with that change, thanks.
>
>


[PATCH] libstdc++: Split up pstl/set.cc testcase

2023-07-03 Thread Thomas Rodgers via Gcc-patches
This testcase is causing some timeout issues. This patch splits the
testcase up by individual set algorithm.
From 857359b72f8886b6e90db3b596d04f08559d2b51 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Mon, 3 Jul 2023 15:04:45 -0700
Subject: [PATCH] libstdc++: Split up pstl/set.cc testcase

This testcase is causing some timeout issues. This patch splits the
testcase up by individual set algorithm.

libstdc++-v3:/ChangeLog:
	* testsuite/25_algorithms/pstl/alg_sorting/set.cc: Delete
	file.
	* testsuite/25_algorithms/pstl/alg_sorting/set_difference.cc:
	New file.
	* testsuite/25_algorithms/pstl/alg_sorting/set_intersection.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/set_symmetric_difference.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/set_union.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/set_util.h:
	Likewise.
---
 .../25_algorithms/pstl/alg_sorting/set.cc | 289 --
 .../pstl/alg_sorting/set_difference.cc|  90 ++
 .../pstl/alg_sorting/set_intersection.cc  |  91 ++
 .../alg_sorting/set_symmetric_difference.cc   |  92 ++
 .../pstl/alg_sorting/set_union.cc |  90 ++
 .../25_algorithms/pstl/alg_sorting/set_util.h |  72 +
 6 files changed, 435 insertions(+), 289 deletions(-)
 delete mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set_difference.cc
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set_intersection.cc
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set_symmetric_difference.cc
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set_union.cc
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set_util.h

diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc
deleted file mode 100644
index 0343739dfd1..000
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-// -*- C++ -*-
-// { dg-options "-ltbb" }
-// { dg-do run { target c++17 } }
-// { dg-timeout-factor 3 }
-// { dg-require-effective-target tbb_backend }
-
-//===-- set.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 "pstl/pstl_test_config.h"
-
-#ifdef PSTL_STANDALONE_TESTS
-
-#include 
-#include 
-
-#include "pstl/execution"
-#include "pstl/algorithm"
-#else
-#include 
-#include 
-#endif // PSTL_STANDALONE_TESTS
-
-#include "pstl/test_utils.h"
-
-using namespace TestUtils;
-
-template 
-struct Num
-{
-T val;
-
-Num() : val{} {}
-Num(const T& v) : val(v) {}
-
-//for "includes" checks
-template 
-bool
-operator<(const Num& v1) const
-{
-return val < v1.val;
-}
-
-//The types Type1 and Type2 must be such that an object of type InputIt can be dereferenced and then implicitly converted to both of them
-template 
-operator Num() const
-{
-return Num((T1)val);
-}
-
-friend bool
-operator==(const Num& v1, const Num& v2)
-{
-return v1.val == v2.val;
-}
-};
-
-template 
-struct test_set_union
-{
-template 
-typename std::enable_if::value, void>::type
-operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
-   Compare comp)
-{
-using T1 = typename std::iterator_traits::value_type;
-
-auto n1 = std::distance(first1, last1);
-auto n2 = std::distance(first2, last2);
-auto n = n1 + n2;
-Sequence expect(n);
-Sequence out(n);
-
-auto expect_res = std::set_union(first1, last1, first2, last2, expect.begin(), comp);
-auto res = std::set_union(exec, first1, last1, first2, last2, out.begin(), comp);
-
-EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_union");
-EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_union effect");
-}
-
-template 
-typename std::enable_if::value, void>::type
-operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare)
-{
-}
-};
-
-template 
-struct test_set_intersection
-{
-template 
-typename std::enable_if::value, void>::type
-operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
-

Re: [PATCH] libstdc++: Synchronize PSTL with upstream

2023-06-26 Thread Thomas Rodgers via Gcc-patches
On Wed, May 17, 2023 at 12:32 PM Jonathan Wakely  wrote:

> -template 
> -  _OutputIterator
> -__brick_generate_n(_OutputIterator __first, _Size __count, _Generator
> __g, /* is_vector = */ std::true_type) noexcept
> +template 
>
> Missing uglification on Size.
>
> +_RandomAccessIterator
> +__brick_generate_n(_RandomAccessIterator __first, Size __count,
> _Generator __g,
> +   /* is_vector = */ std::true_type) noexcept
>  {
>  return __unseq_backend::__simd_generate_n(__first, __count, __g);
>  }
>
> -template 
> -  _OutputIterator
> -__brick_generate_n(_OutputIterator __first, _Size __count, _Generator
> __g, /* is_vector = */ std::false_type) noexcept
> +template 
>
> Missing uglification on OutputIterator and Size.
>
> +OutputIterator
> +__brick_generate_n(OutputIterator __first, Size __count, _Generator __g,
> /* is_vector = */ std::false_type) noexcept
>
>
> -template  _BinaryOperation>
> -_ForwardIterator2
> -__brick_adjacent_difference(_ForwardIterator1 __first, _ForwardIterator1
> __last, _ForwardIterator2 __d_first,
> -_BinaryOperation __op, /*is_vector=*/std::true_type) noexcept
> +template  class BinaryOperation>
>
> Missing uglification on BinaryOperation.
>
> +_RandomAccessIterator2
> +__brick_adjacent_difference(_RandomAccessIterator1 __first,
> _RandomAccessIterator1 __last,
> +_RandomAccessIterator2 __d_first,
> BinaryOperation __op,
> +/*is_vector=*/std::true_type) noexcept
>
>
> The above problems exist on the declaration and the definitions.
>
>
> --- a/libstdc++-v3/include/pstl/glue_execution_defs.h
> +++ b/libstdc++-v3/include/pstl/glue_execution_defs.h
> @@ -18,8 +18,8 @@ namespace std
>  {
>  // Type trait
>  using __pstl::execution::is_execution_policy;
> -#if _PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
> -#if __INTEL_COMPILER
> +#if defined(_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT)
> +#if defined(__INTEL_COMPILER)
>  template 
>  constexpr bool is_execution_policy_v = is_execution_policy::value;
>  #else
>
> Pre-existing, but that T should be _Tp, but it only affects the Intel
> compiler branch, so meh.
>
> Please fix these and report them upstream too.
>

Ack.


>
> All the actual code changes look good.
>
> I think I'd prefer if __pattern_partial_sort_copy used
> std::uninitialized_copy instead of a loop and placement-new, but that
> doesn't need to hold this up. We could optimize some uses of
> std::conjunction and std::conditional to use our own __and_ and
> __conditional, but I'm not sure it's worth diverging from upstream to do
> that.
>
> Please fix the naming bugs noted above and push to trunk, thanks!
>

There were a handful of additional missed uglifications in -
* libstdc++-v3/include/pstl/glue_algorithm_impl.h
* libstdc++-v3/include/pstl/unseq_backend_simd.h
That are in this commit, but not in the patch as reviewed.

Tested x86_64-linux. Pushed to trunk.


>
> +Reviewed-by: Jonathan Wakely 
>
>
>
>
>
>


Re: [PATCH v2] libstdc++: Do not use pthread_mutex_clocklock with ThreadSanitizer

2023-05-15 Thread Thomas Rodgers via Gcc-patches
On Thu, May 11, 2023 at 1:52 PM Jonathan Wakely  wrote:

> On Thu, 11 May 2023 at 13:42, Jonathan Wakely  wrote:
>
>>
>>
>> On Thu, 11 May 2023 at 13:19, Mike Crowe  wrote:
>>
>>> However, ...
>>>
>>> > > diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
>>> > > index 89e7f5f5f45..e2700b05ec3 100644
>>> > > --- a/libstdc++-v3/acinclude.m4
>>> > > +++ b/libstdc++-v3/acinclude.m4
>>> > > @@ -4284,7 +4284,7 @@
>>> AC_DEFUN([GLIBCXX_CHECK_PTHREAD_COND_CLOCKWAIT], [
>>> > >[glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no])
>>> > >])
>>> > >if test $glibcxx_cv_PTHREAD_COND_CLOCKWAIT = yes; then
>>> > > -AC_DEFINE(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT, 1, [Define if
>>> > > pthread_cond_clockwait is available in .])
>>> > > +AC_DEFINE(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT,
>>> (_GLIBCXX_TSAN==0),
>>> > > [Define if pthread_cond_clockwait is available in .])
>>> > >fi
>>>
>>> TSan does appear to have an interceptor for pthread_cond_clockwait, even
>>> if
>>> it lacks the others. Does this mean that this part is unnecessary?
>>>
>>
>> Ah good point, thanks. I grepped for clocklock but not clockwait.
>>
>
> In fact it seems like we don't need to change
> _GLIBCXX_USE_PTHREAD_RWLOCK_CLOCKLOCK either, because I don't get any tsan
> warnings for that. It doesn't have interceptors for
> pthread_rwlock_{rd,wr}lock, but it doesn't complain anyway (maybe it's
> simply not instrumenting the rwlock functions at all?!)
>
> So I'm now retesting with this version of the patch, which only touches
> the USE_PTHREAD_LOCKLOCK macro.
>
> Please take another look, thanks.
>
> LGTM.


Re: [RFC] libstdc++: Do not use pthread_mutex_clocklock with ThreadSanitizer

2023-05-11 Thread Thomas Rodgers via Gcc-patches
On Thu, May 11, 2023 at 5:21 AM Mike Crowe via Libstdc++ <
libstd...@gcc.gnu.org> wrote:

> On Wednesday 10 May 2023 at 12:31:12 +0100, Jonathan Wakely wrote:
> > On Wed, 10 May 2023 at 12:20, Jonathan Wakely via Libstdc++ <
> > libstd...@gcc.gnu.org> wrote:
> >
> > > This patch would avoid TSan false positives when using timed waiting
> > > functions on mutexes and condvars, but as noted below, it changes the
> > > semantics.
> > >
> > > I'm not sure whether we want this workaround in place until tsan gets
> > > fixed.
> > >
> > > On one hand, there's no guarantee that those functions use the right
> > > clock anyway (and they won't do unless a recent-ish glibc is used). But
> > > on the other hand, if they normally would use the right clock because
> > > you have glibc support, it's not ideal for tsan to cause a different
> > > clock to be used.
> > >
> >
> > But of course, it's not ideal to get false positives from tsan either
> > (especially when it looks like a libstdc++ bug, as initially reported to
> > me).
>
> I think that this is probably the least-worst option in the short term. As
> TSan is distributed with GCC this workaround can be removed as soon as its
> TSan implementation gains the necessary interceptors. I shall look into
> trying to do that.
>
>
I don't have a strong opinion either way on this, but I think documenting
the TSAN suppressions is the option most in keeping with the principle of
Least Astonishment.


> However, ...
>
> > > diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
> > > index 89e7f5f5f45..e2700b05ec3 100644
> > > --- a/libstdc++-v3/acinclude.m4
> > > +++ b/libstdc++-v3/acinclude.m4
> > > @@ -4284,7 +4284,7 @@ AC_DEFUN([GLIBCXX_CHECK_PTHREAD_COND_CLOCKWAIT],
> [
> > >[glibcxx_cv_PTHREAD_COND_CLOCKWAIT=no])
> > >])
> > >if test $glibcxx_cv_PTHREAD_COND_CLOCKWAIT = yes; then
> > > -AC_DEFINE(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT, 1, [Define if
> > > pthread_cond_clockwait is available in .])
> > > +AC_DEFINE(_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT, (_GLIBCXX_TSAN==0),
> > > [Define if pthread_cond_clockwait is available in .])
> > >fi
>
> TSan does appear to have an interceptor for pthread_cond_clockwait, even if
> it lacks the others. Does this mean that this part is unnecessary?
>
> See: https://github.com/google/sanitizers/issues/1259
>
> Thanks.
>
> Mike.
>
>


[PATCH] libstdc++: Synchronize PSTL with upstream (2nd attempt)

2023-04-20 Thread Thomas Rodgers via Gcc-patches
The attached (gzipped) patch brings libstdc++'s PSTL implementation up to
the current upstream version.

Tested x86_64-pc-linux-gnu, specifically with TBB 2020.3 (fedora 37 +
tbb-devel).


0001-libstdc-Synchronize-PSTL-with-upstream.patch.gz
Description: application/gzip


Re: [PATCH] libstdc++: Add missing free functions for atomic_flag [PR103934]

2023-03-09 Thread Thomas Rodgers via Gcc-patches
The second patch has now been backported and pushed to releases/gcc-12 and
releases/gcc-11.

On Mon, Feb 13, 2023 at 6:06 PM Thomas Rodgers  wrote:

> Tested x86_64-pc-linux-gnu. Pushed to trunk.
>
> The first patch has also been backported and pushed to releases/gcc-12 and
> releases/gcc-11
>
> The second patch fails to cleanly cherry-pick. Will resolve and push
> shortly.
>
> On Fri, Feb 10, 2023 at 4:41 PM Jonathan Wakely 
> wrote:
>
>> On Fri, 10 Feb 2023 at 18:25, Thomas Rodgers  wrote:
>> >
>> > This patch did not get committed in a timely manner after it was OK'd.
>> In revisiting the patch some issues were found that have lead me to
>> resubmit for review -
>> >
>> > Specifically -
>> >
>> > The original commit to add C++20 atomic_flag::test did not include the
>> free functions for atomic_flag_test[_explicit]
>> > The original commit to add C++20 atomic_flag::wait/notify did not
>> include the free functions for atomic_flag_wait/notify[_explicit]
>> >
>> > These two commits landed in GCC10 and GCC11 respectively. My original
>> patch included both sets of free functions, but
>> > that complicates the backporting of these changes to GCC10, GCC11, and
>> GCC12.
>>
>> I don't think we need them in GCC 10.
>>
>> > Additionally commit 7c2155 removed const qualification from
>> atomic_flag::notify_one/notify_all but the original version of this
>> > patch accepts the atomic flag as const.
>> >
>> > The original version of this patch did not include test cases for the
>> atomic_flag_test[_explicit] free functions.
>> >
>> > I have split the original patch into two patches, on for the
>> atomic_flag_test free functions, and one for the atomic_flag_wait/notify
>> > free functions.
>>
>> Thanks.
>>
>> For [PATCH 1/2] please name the added functions in the changelog entry:
>>
>> * include/std/atomic (atomic_flag_test): Add.
>> (atomic_flag_test_explicit): Add.
>>
>> Similarly for the changelog in [PATCH 2/2], naming the four new
>> functions added to include/std/atomic.
>>
>> The indentation is off in [PATCH 2/2] for atomic_flag:
>>
>> +#if __cpp_lib_atomic_wait
>> +  inline void
>> +  atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
>> +  { __a->wait(__old); }
>> +
>>
>> And similarly for the other three added functions.
>> The function names should start in the same column as the 'inline' and
>> opening brace of the function body.
>>
>>
>> Both patches are OK for trunk, gcc-12 and gcc-11 with those changes.
>>
>>
>>
>>
>> >
>> >
>> > On Wed, Feb 2, 2022 at 1:35 PM Jonathan Wakely 
>> wrote:
>> >>
>> >> >+  inline void
>> >> >+  atomic_flag_wait_explicit(const atomic_flag* __a, bool __old,
>> >> >+   std::memory_order __m) noexcept
>> >>
>> >> No need for the std:: qualification, and check the indentation.
>> >>
>> >>
>> >> > libstdc++-v3/ChangeLog:
>> >> >
>> >> >PR103934
>> >>
>> >> This needs to include the component: PR libstdc++/103934
>> >>
>> >> >* include/std/atomic: Add missing free functions.
>> >>
>> >> Please name the new functions in the changelog, in the usual format.
>> >> Just the names is fine, no need for the full signatures with
>> >> parameters.
>> >>
>> >> OK for trunk with those changes.
>> >>
>>
>>


Re: [PATCH] libstdc++: Add missing free functions for atomic_flag [PR103934]

2023-02-13 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu. Pushed to trunk.

The first patch has also been backported and pushed to releases/gcc-12 and
releases/gcc-11

The second patch fails to cleanly cherry-pick. Will resolve and push
shortly.

On Fri, Feb 10, 2023 at 4:41 PM Jonathan Wakely  wrote:

> On Fri, 10 Feb 2023 at 18:25, Thomas Rodgers  wrote:
> >
> > This patch did not get committed in a timely manner after it was OK'd.
> In revisiting the patch some issues were found that have lead me to
> resubmit for review -
> >
> > Specifically -
> >
> > The original commit to add C++20 atomic_flag::test did not include the
> free functions for atomic_flag_test[_explicit]
> > The original commit to add C++20 atomic_flag::wait/notify did not
> include the free functions for atomic_flag_wait/notify[_explicit]
> >
> > These two commits landed in GCC10 and GCC11 respectively. My original
> patch included both sets of free functions, but
> > that complicates the backporting of these changes to GCC10, GCC11, and
> GCC12.
>
> I don't think we need them in GCC 10.
>
> > Additionally commit 7c2155 removed const qualification from
> atomic_flag::notify_one/notify_all but the original version of this
> > patch accepts the atomic flag as const.
> >
> > The original version of this patch did not include test cases for the
> atomic_flag_test[_explicit] free functions.
> >
> > I have split the original patch into two patches, on for the
> atomic_flag_test free functions, and one for the atomic_flag_wait/notify
> > free functions.
>
> Thanks.
>
> For [PATCH 1/2] please name the added functions in the changelog entry:
>
> * include/std/atomic (atomic_flag_test): Add.
> (atomic_flag_test_explicit): Add.
>
> Similarly for the changelog in [PATCH 2/2], naming the four new
> functions added to include/std/atomic.
>
> The indentation is off in [PATCH 2/2] for atomic_flag:
>
> +#if __cpp_lib_atomic_wait
> +  inline void
> +  atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
> +  { __a->wait(__old); }
> +
>
> And similarly for the other three added functions.
> The function names should start in the same column as the 'inline' and
> opening brace of the function body.
>
>
> Both patches are OK for trunk, gcc-12 and gcc-11 with those changes.
>
>
>
>
> >
> >
> > On Wed, Feb 2, 2022 at 1:35 PM Jonathan Wakely 
> wrote:
> >>
> >> >+  inline void
> >> >+  atomic_flag_wait_explicit(const atomic_flag* __a, bool __old,
> >> >+   std::memory_order __m) noexcept
> >>
> >> No need for the std:: qualification, and check the indentation.
> >>
> >>
> >> > libstdc++-v3/ChangeLog:
> >> >
> >> >PR103934
> >>
> >> This needs to include the component: PR libstdc++/103934
> >>
> >> >* include/std/atomic: Add missing free functions.
> >>
> >> Please name the new functions in the changelog, in the usual format.
> >> Just the names is fine, no need for the full signatures with
> >> parameters.
> >>
> >> OK for trunk with those changes.
> >>
>
>


Re: [PATCH] libstdc++: Add missing free functions for atomic_flag [PR103934]

2023-02-10 Thread Thomas Rodgers via Gcc-patches
This patch did not get committed in a timely manner after it was OK'd. In
revisiting the patch some issues were found that have lead me to resubmit
for review -

Specifically -

The original commit to add C++20 atomic_flag::test did not include the free
functions for atomic_flag_test[_explicit]
The original commit to add C++20 atomic_flag::wait/notify did not include
the free functions for atomic_flag_wait/notify[_explicit]

These two commits landed in GCC10 and GCC11 respectively. My original patch
included both sets of free functions, but
that complicates the backporting of these changes to GCC10, GCC11, and
GCC12.

Additionally commit 7c2155 removed const qualification from
atomic_flag::notify_one/notify_all but the original version of this
patch accepts the atomic flag as const.

The original version of this patch did not include test cases for the
atomic_flag_test[_explicit] free functions.

I have split the original patch into two patches, on for the
atomic_flag_test free functions, and one for the atomic_flag_wait/notify
free functions.


On Wed, Feb 2, 2022 at 1:35 PM Jonathan Wakely  wrote:

> >+  inline void
> >+  atomic_flag_wait_explicit(const atomic_flag* __a, bool __old,
> >+   std::memory_order __m) noexcept
>
> No need for the std:: qualification, and check the indentation.
>
>
> > libstdc++-v3/ChangeLog:
> >
> >PR103934
>
> This needs to include the component: PR libstdc++/103934
>
> >* include/std/atomic: Add missing free functions.
>
> Please name the new functions in the changelog, in the usual format.
> Just the names is fine, no need for the full signatures with
> parameters.
>
> OK for trunk with those changes.
>
>
From 1338538c1667b7fbe201d22d81254e33a0e7b24c Mon Sep 17 00:00:00 2001
From: Thomas W Rodgers 
Date: Fri, 10 Feb 2023 10:09:06 -0800
Subject: [PATCH 2/2] libstdc++: Add missing free functions for atomic_flag
 [PR103934]

This patch adds -
  atomic_flag_wait
  atomic_flag_wait_explicit
  atomic_flag_notify
  atomic_flag_notify_explicit

Which were missed when commit 83a1be introduced C++20 atomic wait.

libstdc++-v3/ChangeLog:

	PR libstdc++/103934
	* include/std/atomic: Add missing free functions.
	* testsuite/29_atomics/atomic_flag/wait_notify/1.cc:
	Add test case to cover missing atomic_flag free functions.
---
 libstdc++-v3/include/std/atomic   | 19 ++
 .../29_atomics/atomic_flag/wait_notify/1.cc   | 26 +--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 1edd3ae16fa..e82a6427378 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -1259,6 +1259,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   atomic_flag_clear(volatile atomic_flag* __a) noexcept
   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
 
+#if __cpp_lib_atomic_wait
+  inline void
+  atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
+  { __a->wait(__old); }
+
+  inline void
+  atomic_flag_wait_explicit(atomic_flag* __a, bool __old,
+memory_order __m) noexcept
+  { __a->wait(__old, __m); }
+
+  inline void
+  atomic_flag_notify_one(atomic_flag* __a) noexcept
+  { __a->notify_one(); }
+
+  inline void
+  atomic_flag_notify_all(atomic_flag* __a) noexcept
+  { __a->notify_all(); }
+#endif // __cpp_lib_atomic_wait
+
   /// @cond undocumented
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
index 240fb4259f7..777fa915ea1 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
@@ -26,8 +26,8 @@
 
 #include 
 
-int
-main()
+void
+test01()
 {
   std::atomic_flag a;
   VERIFY( !a.test() );
@@ -39,5 +39,27 @@ main()
 });
   a.wait(false);
   t.join();
+}
+
+void
+test02()
+{
+  std::atomic_flag a;
+  VERIFY( !std::atomic_flag_test() );
+  std::atomic_flag_wait(, true);
+  std::thread t([&]
+{
+  std::atomic_flag_test_and_set();
+  std::atomic_flag_notify_one();
+});
+std::atomic_flag_wait(, false);
+t.join();
+}
+
+int
+main()
+{
+  test01();
+  test02();
   return 0;
 }
-- 
2.39.1

From 7f21e98bbefde5437a116ccda35a85922f5882bf Mon Sep 17 00:00:00 2001
From: Thomas W Rodgers 
Date: Fri, 10 Feb 2023 09:35:11 -0800
Subject: [PATCH 1/2] libstdc++: Add missing free functions for atomic_flag
 [PR103934]

This patch adds -
  atomic_flag_test
  atomic_flag_test_explicit

Which were missed when commit 491ba6 introduced C++20 atomic flag
test.

libstdc++-v3/ChangeLog:

	PR libstdc++/103934
	* include/std/atomic: Add missing free functions.
	* testsuite/29_atomics/atomic_flag/test/explicit.cc
Add test case to cover missing atomic_flag free functions.
* 

Re: [RFA] choosing __platform_wait_t on targets without lock-free 64 atomics

2023-01-11 Thread Thomas Rodgers via Gcc-patches
I agree with this change.

On Thu, Jan 5, 2023 at 4:22 PM Jonathan Wakely  wrote:

> How about this?
>
> I don't think we should worry about targets without atomic int, so don't
> bother using types smaller than int.
>
>
> -- >8 --
>
> For non-futex targets the __platform_wait_t type is currently uint64_t,
> but that requires a lock in libatomic for some 32-bit targets. We don't
> really need a 64-bit type, so use unsigned long if that is lock-free,
> and int otherwise. This should mean it's lock-free on a wider set of
> targets.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/atomic_wait.h (__detail::__platform_wait_t):
> Define as unsigned long if always lock-free, and unsigned int
> otherwise.
> ---
>  libstdc++-v3/include/bits/atomic_wait.h | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/bits/atomic_wait.h
> b/libstdc++-v3/include/bits/atomic_wait.h
> index bd1ed56d157..46f39f10cbc 100644
> --- a/libstdc++-v3/include/bits/atomic_wait.h
> +++ b/libstdc++-v3/include/bits/atomic_wait.h
> @@ -64,7 +64,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  // and __platform_notify() if there is a more efficient primitive
> supported
>  // by the platform (e.g. __ulock_wait()/__ulock_wake()) which is better
> than
>  // a mutex/condvar based wait.
> -using __platform_wait_t = uint64_t;
> +# if  ATOMIC_LONG_LOCK_FREE == 2
> +using __platform_wait_t = unsigned long;
> +# else
> +using __platform_wait_t = unsigned int;
> +# endif
>  inline constexpr size_t __platform_wait_alignment
>= __alignof__(__platform_wait_t);
>  #endif
> --
> 2.39.0
>
>


Re: Patch ping (was Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange)

2022-09-09 Thread Thomas Rodgers via Gcc-patches
s/__weak/__is_weak/g  perhaps?

On Fri, Sep 9, 2022 at 11:46 AM Iain Sandoe via Libstdc++ <
libstd...@gcc.gnu.org> wrote:

>
>
> > On 9 Sep 2022, at 19:36, Rainer Orth 
> wrote:
> >
>
> >> Here's a complete patch that combines the various incremental patches
> >> that have been going around. I'm testing this now.
> >>
> >> Please take a look.
> >
> > unfortunately, this patch broke macOS bootstrap (seen on
> > x86_64-apple-darwin11.4.2):
> >
> > In file included from
> /var/gcc/regression/master/10.7-gcc/build/x86_64-apple-darwin11.4.2/libstdc++-v3/include/bits/shared_ptr_atomic.h:33,
> > from
> /var/gcc/regression/master/10.7-gcc/build/x86_64-apple-darwin11.4.2/libstdc++-v3/include/memory:78,
> > from
> /vol/gcc/src/hg/master/darwin/libstdc++-v3/include/precompiled/stdc++.h:82:
> >
> /var/gcc/regression/master/10.7-gcc/build/x86_64-apple-darwin11.4.2/libstdc++-v3/include/bits/atomic_base.h:
> In function 'bool std::__atomic_impl::__compare_exchange(_Tp&, _Val<_Tp>&,
> _Val<_Tp>&, bool, std::memory_order, std::memory_order)':
> >
> /var/gcc/regression/master/10.7-gcc/build/x86_64-apple-darwin11.4.2/libstdc++-v3/include/bits/atomic_base.h:1008:49:
> error: expected primary-expression before ',' token
> > 1008 |   __weak, int(__s),
> int(__f)))
> >  | ^
> >
> /var/gcc/regression/master/10.7-gcc/build/x86_64-apple-darwin11.4.2/libstdc++-v3/include/bits/atomic_base.h:1017:50:
> error: expected primary-expression before ',' token
> > 1017 |__weak, int(__s),
> int(__f));
> >  |  ^
> >
> > Darwin gcc predefines __weak= in gcc/config/darwin-c.cc
> (darwin_cpp_builtins).
>
> yes, __weak and __strong are Objective C things (in principle, applicable
> to non-Darwin targets
> using NeXT runtime - there is at least one such target).
>
> Iain
>
>


Re: Patch ping (was Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange)

2022-09-07 Thread Thomas Rodgers via Gcc-patches
Looks good to me.

Tom.

On Wed, Sep 7, 2022 at 4:56 AM Jonathan Wakely  wrote:

> Here's a complete patch that combines the various incremental patches
> that have been going around. I'm testing this now.
>
> Please take a look.
>


Re: [committed] libstdc++: Add missing runtime exception to licence notice

2022-09-07 Thread Thomas Rodgers via Gcc-patches
Looks good to me.

Tom.

On Wed, Sep 7, 2022 at 12:27 PM Jonathan Wakely via Gcc-patches <
gcc-patches@gcc.gnu.org> wrote:

> Tested powerpc64le-linux, pushed to trunk.
>
> Backports to gcc-11 and gcc-12 needed too.
>
> -- >8 --
>
> This file is missing the GCC Runtime Library Exception text in the
> licence header. That is unintentional, and it should have been present.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/barrier: Add missing runtime exception.
> ---
>  libstdc++-v3/include/std/barrier | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/barrier
> b/libstdc++-v3/include/std/barrier
> index 2a2650546ad..997e0a8f7ab 100644
> --- a/libstdc++-v3/include/std/barrier
> +++ b/libstdc++-v3/include/std/barrier
> @@ -13,8 +13,13 @@
>  // 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
> +// Under Section 7 of GPL version 3, you are granted additional
> +// permissions described in the GCC Runtime Library Exception, version
> +// 3.1, as published by the Free Software Foundation.
> +
> +// You should have received a copy of the GNU General Public License and
> +// a copy of the GCC Runtime Library Exception along with this program;
> +// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  // .
>
>  // This implementation is based on libcxx/include/barrier
> --
> 2.37.3
>
>


Re: Patch ping (was Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange)

2022-09-01 Thread Thomas Rodgers via Gcc-patches
Sorry for the delay in getting to this.

I am currently working on moving the bulk of the atomic wait implementation
into the .so. I'd like to get that work to a stable state before revisiting
this patch, but obviously if we want this to make it into GCC13, it needs
to happen sooner rather than later.

On Thu, Aug 25, 2022 at 3:11 AM Jakub Jelinek  wrote:

> On Tue, Jan 18, 2022 at 09:48:19PM +, Jonathan Wakely via Gcc-patches
> wrote:
> > On Tue, 2 Nov 2021 at 01:26, Thomas Rodgers  wrote:
> >
> > > This should address Jonathan's feedback and adds support for
> atomic_ref
> > >
> >
> >
> > >This change implements P0528 which requires that padding bits not
> > >participate in atomic compare exchange operations. All arguments to the
> > >generic template are 'sanitized' by the __builtin_clearpadding intrisic
> >
> > The name of the intrinsic and the word "instrinsic" have typos.
>
> I'd like to ping this patch.
> To make some progress, I've tried to incorporate some of Jonathan's
> review comments below, but it is incomplete.
>
> ChangeLog + wording above it fixed.
>
> > >
> > >   explicit
> > >   __atomic_ref(_Tp& __t) : _M_ptr(std::__addressof(__t))
> > >-  { __glibcxx_assert(((uintptr_t)_M_ptr % required_alignment) ==
> 0); }
> > >+  {
> > >+ __glibcxx_assert(((uintptr_t)_M_ptr % required_alignment) == 0);
> > >+#if __cplusplus > 201402L && __has_builtin(__builtin_clear_padding)
> > >+ __builtin_clear_padding(_M_ptr);
> > >+#endif
> > >+  }
> >
> > Is this safe to do?
> >
> > What if multiple threads all create a std::atomic_ref round the same
> object
> > at once, they'll all try to clear padding, and so race, won't they?
> > I don't think we can clear padding on atomic_ref construction, only on
> > store and RMW operations.
>
> Didn't touch the above.
> >
> >
> > >--- a/libstdc++-v3/include/std/atomic
> > >+++ b/libstdc++-v3/include/std/atomic
>
> The patch against this file doesn't apply it all.
>
> > >--- /dev/null
> > >+++
> >
> b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc
> > >@@ -0,0 +1,43 @@
> > >+// { dg-options "-std=gnu++2a" }
> > >+// { dg-do run { target c++2a } }
> >
> > This new test is using "2a" not "20".
>
> Fixed thus, but the other testcase wasn't in the patch at all.
>
> Here it is:
>
> libstdc++: Clear padding bits in atomic compare_exchange
>
> This change implements P0528 which requires that padding bits not
> participate in atomic compare exchange operations. All arguments to the
> generic template are 'sanitized' by the __builtin_clear_padding intrinsic
> before they are used in comparisons. This requires that any stores
> also sanitize the incoming value.
>
> Signed-off-by: Thomas Rodgers 
>
> libstdc++-v3/ChangeLog:
>
> * include/std/atomic (atomic::atomic(_Tp)): Clear padding for
> __cplusplus > 201703L.
> (atomic::store()): Clear padding.
> (atomic::exchange()): Likewise.
> (atomic::compare_exchange_weak()): Likewise.
> (atomic::compare_exchange_strong()): Likewise.
> * include/bits/atomic_base.h (__atomic_impl::__clear_padding()):
> New function.
> (__atomic_impl::__maybe_has_padding()): Likewise.
> (__atomic_impl::__compare_exchange()): Likewise.
> (__atomic_impl::compare_exchange_weak()): Delegate to
> __compare_exchange().
> (__atomic_impl::compare_exchange_strong()): Likewise.
> * testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
> test.
> * testsuite/28_atomics/atomic_ref/compare_exchange_padding.cc:
> Likewise.
>
> --- a/libstdc++-v3/include/bits/atomic_base.h.jj2022-05-16
> 09:46:02.361059682 +0200
> +++ b/libstdc++-v3/include/bits/atomic_base.h   2022-08-25
> 12:06:13.758883172 +0200
> @@ -954,6 +954,87 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>/// @endcond
>
> +  // Implementation details of atomic padding handling
> +  namespace __atomic_impl
> +  {
> +template
> +  _GLIBCXX_ALWAYS_INLINE _Tp*
> +  __clear_padding(_Tp& __val) noexcept
> +  {
> +   auto* __ptr = std::__addressof(__val);
> +#if __has_builtin(__builtin_clear_padding)
> +   __builtin_clear_padding(std::__addressof(__val));
> +#endif
> +   return __ptr;
> +  }
> +
> +template
> +  constexpr bool
> +  __maybe_has_padding()
> +  {
> +#if ! __has_

Re: libstdc++: Minor codegen improvement for atomic wait spinloop

2022-07-26 Thread Thomas Rodgers via Gcc-patches
This is now committed to trunk, backported to releases/gcc-12 and
releases/gcc-11.

Apologies for the delay, it's been a wild couple of weeks.

Tom.

On Thu, Jul 7, 2022 at 2:31 AM Jonathan Wakely  wrote:

> On Wed, 6 Jul 2022 at 22:42, Thomas Rodgers  wrote:
> >
> > Ok for trunk? backport?
>
> Yes, for all branches that have the atomic wait code.
>
>
> >
> > On Wed, Jul 6, 2022 at 1:56 PM Jonathan Wakely 
> wrote:
> >>
> >> On Wed, 6 Jul 2022 at 02:05, Thomas Rodgers via Libstdc++
> >>  wrote:
> >> >
> >> > This patch merges the spin loops in the atomic wait implementation
> which is
> >> > a
> >> > minor codegen improvement.
> >> >
> >> > libstdc++-v3/ChangeLog:
> >> >  * include/bits/atomic_wait.h (__atomic_spin): Merge spin
> loops.
> >>
> >> OK, thanks.
> >>
>
>


Re: libstdc++: Minor codegen improvement for atomic wait spinloop

2022-07-06 Thread Thomas Rodgers via Gcc-patches
Ok for trunk? backport?

On Wed, Jul 6, 2022 at 1:56 PM Jonathan Wakely  wrote:

> On Wed, 6 Jul 2022 at 02:05, Thomas Rodgers via Libstdc++
>  wrote:
> >
> > This patch merges the spin loops in the atomic wait implementation which
> is
> > a
> > minor codegen improvement.
> >
> > libstdc++-v3/ChangeLog:
> >  * include/bits/atomic_wait.h (__atomic_spin): Merge spin loops.
>
> OK, thanks.
>
>


libstdc++: Minor codegen improvement for atomic wait spinloop

2022-07-05 Thread Thomas Rodgers via Gcc-patches
This patch merges the spin loops in the atomic wait implementation which is
a
minor codegen improvement.

libstdc++-v3/ChangeLog:
 * include/bits/atomic_wait.h (__atomic_spin): Merge spin loops.


0001-libstdc-Minor-codegen-improvement-for-atomic-wait-sp.patch
Description: Binary data


Re: [PATCH] libstdc++: Make atomic notify_one and notify_all non-const

2022-04-22 Thread Thomas Rodgers via Gcc-patches
Committed to trunk, backported to releases/gcc-11.

On Fri, Feb 11, 2022 at 12:22 PM Jonathan Wakely  wrote:

> On Fri, 11 Feb 2022 at 17:40, Thomas Rodgers via Libstdc++
>  wrote:
> >
> > 
> > PR102994 "atomics: std::atomic::wait is not marked const" raises the
> > issue that the current libstdc++ implementation marks the notify members
> > const, the implementation strategy used by libstdc++, as well as libc++
> > and the Microsoft STL, do not require the atomic to be mutable (it is
> hard
> > to conceive of a desirable implementation approach that would require
> it).
> > The original paper proposing the wait/notify functionality for atomics
> > (p1185) also had these members marked const for the first three
> revisions,
> > but that was changed without explanation in r3 and subsequent revisions
> of
> > the paper.
> >
> > After raising the issue to the authors of p1185 and the author of the
> > libc++ implementation, the consensus seems to be "meh, it's harmless" so
> > there seems little appetite for an LWG issue to revisit the subject.
> >
> > This patch changes the libstdc++ implementation to be in agreement with
> > the standard by removing const from those notify_one/notify_all members.
> >
> > libstdc++-v3/ChangeLog:
>
> Might as well add a "PR libstdc++/102994" here to the bug gets updated
> automatically.
>
> OK for trunk with that change.
>
> > * include/bits/atomic_base.h (atomic_flag::notify_one,
> > notify_all): Remove const qualification.
> > (__atomic_base::notify_one, notify_all): Likewise.
> > * include/std/atomic (atomic::notify_one, notify_all):
> > Likewise.
> > (atomic::notify_one, notify_all): Likewise.
> > (atomic::notify_one, notify_all): Likewise.
> > (atomic_notify_one, atomic_notify_all): Likewise.
> > * testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test
> > to account for change in notify_one/notify_all signature.
> >
> > Tested x86_64-pc-linux-gnu.
>
>


Re: [PATCH] libstdc++: Reduce header dependencies from PSTL headers [PR92546]

2022-03-17 Thread Thomas Rodgers via Gcc-patches
Looks ok to me. I just am curious, does the change to src/c++17/fs_path.cc
need to be part of this change (It's not obvious to me that it is related
to the other changes in the patch).

On Thu, Mar 17, 2022 at 12:01 PM Jonathan Wakely  wrote:

> Tested x86_64-linux. Tom, any objection?
>
> -- >8 --
>
> This avoids including the whole of  in , as the
>  header only actually needs std::pair.
>
> This also avoids including  in , which only
> needs , std::bad_alloc, and std::terminate (which can be
> repalced with std::__terminate). This matters less, because
>  is only included by the  headers and they
> all use  anyway, and are only included by .
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/92546
> * include/pstl/glue_algorithm_defs.h: Replace  with
> .
> * include/pstl/utils.h: Replace  with .
> (__pstl::__internal::__except_handler): Use std::__terminate
> instead of std::terminate.
> * src/c++17/fs_path.cc: Include .
> * testsuite/25_algorithms/adjacent_find/constexpr.cc: Include
> .
> * testsuite/25_algorithms/binary_search/constexpr.cc: Likewise.
> * testsuite/25_algorithms/clamp/constrained.cc: Likewise.
> * testsuite/25_algorithms/equal/constrained.cc: Likewise.
> * testsuite/25_algorithms/for_each/constrained.cc: Likewise.
> * testsuite/25_algorithms/includes/constrained.cc: Likewise.
> * testsuite/25_algorithms/is_heap/constexpr.cc: Likewise.
> * testsuite/25_algorithms/is_heap_until/constexpr.cc: Likewise.
> * testsuite/25_algorithms/is_permutation/constrained.cc: Include
> .
> * testsuite/25_algorithms/is_sorted/constexpr.cc: Include
> .
> * testsuite/25_algorithms/is_sorted_until/constexpr.cc:
> Likewise.
> * testsuite/25_algorithms/lexicographical_compare/constexpr.cc:
> Likewise.
> * testsuite/25_algorithms/lexicographical_compare/constrained.cc:
> Likewise.
> * testsuite/25_algorithms/lexicographical_compare_three_way/1.cc:
> Include .
> * testsuite/25_algorithms/lower_bound/constexpr.cc: Include
> .
> * testsuite/25_algorithms/max/constrained.cc: Likewise.
> * testsuite/25_algorithms/max_element/constrained.cc: Likewise.
> * testsuite/25_algorithms/min/constrained.cc: Likewise.
> * testsuite/25_algorithms/min_element/constrained.cc: Likewise.
> * testsuite/25_algorithms/minmax_element/constrained.cc:
> Likewise.
> * testsuite/25_algorithms/mismatch/constexpr.cc: Likewise.
> * testsuite/25_algorithms/move/93872.cc: Likewise.
> * testsuite/25_algorithms/move_backward/93872.cc: Include
> .
> * testsuite/25_algorithms/nth_element/constexpr.cc: Include
> .
> * testsuite/25_algorithms/partial_sort/constexpr.cc: Likewise.
> * testsuite/25_algorithms/partial_sort_copy/constexpr.cc:
> Likewise.
> * testsuite/25_algorithms/search/constexpr.cc: Likewise.
> * testsuite/25_algorithms/search_n/constrained.cc: Likewise.
> * testsuite/25_algorithms/set_difference/constexpr.cc: Likewise.
> * testsuite/25_algorithms/set_difference/constrained.cc:
> Likewise.
> * testsuite/25_algorithms/set_intersection/constexpr.cc:
> Likewise.
> * testsuite/25_algorithms/set_intersection/constrained.cc:
> Likewise.
> * testsuite/25_algorithms/set_symmetric_difference/constexpr.cc:
> Likewise.
> * testsuite/25_algorithms/set_union/constexpr.cc: Likewise.
> * testsuite/25_algorithms/set_union/constrained.cc: Likewise.
> * testsuite/25_algorithms/sort/constexpr.cc: Likewise.
> * testsuite/25_algorithms/sort_heap/constexpr.cc: Likewise.
> * testsuite/25_algorithms/transform/constrained.cc: Likewise.
> * testsuite/25_algorithms/unique/constexpr.cc: Likewise.
> * testsuite/25_algorithms/unique/constrained.cc: Likewise.
> * testsuite/25_algorithms/unique_copy/constexpr.cc: Likewise.
> * testsuite/25_algorithms/upper_bound/constexpr.cc: Likewise.
> * testsuite/std/ranges/adaptors/elements.cc: Include .
> * testsuite/std/ranges/adaptors/lazy_split.cc: Likewise.
> * testsuite/std/ranges/adaptors/split.cc: Likewise.
> ---
>  libstdc++-v3/include/pstl/glue_algorithm_defs.h   | 2 +-
>  libstdc++-v3/include/pstl/utils.h | 4 ++--
>  libstdc++-v3/src/c++17/fs_path.cc | 1 +
>  .../testsuite/25_algorithms/adjacent_find/constexpr.cc| 1 +
>  .../testsuite/25_algorithms/binary_search/constexpr.cc| 1 +
>  libstdc++-v3/testsuite/25_algorithms/clamp/constrained.cc | 1 +
>  libstdc++-v3/testsuite/25_algorithms/equal/constrained.cc | 1 +
>  libstdc++-v3/testsuite/25_algorithms/for_each/constrained.cc  | 1 +
>  

[PATCH] libstdc++: Make atomic notify_one and notify_all non-const

2022-02-11 Thread Thomas Rodgers via Gcc-patches

PR102994 "atomics: std::atomic::wait is not marked const" raises the
issue that the current libstdc++ implementation marks the notify members
const, the implementation strategy used by libstdc++, as well as libc++
and the Microsoft STL, do not require the atomic to be mutable (it is hard
to conceive of a desirable implementation approach that would require it).
The original paper proposing the wait/notify functionality for atomics
(p1185) also had these members marked const for the first three revisions,
but that was changed without explanation in r3 and subsequent revisions of
the paper.

After raising the issue to the authors of p1185 and the author of the
libc++ implementation, the consensus seems to be "meh, it's harmless" so
there seems little appetite for an LWG issue to revisit the subject.

This patch changes the libstdc++ implementation to be in agreement with
the standard by removing const from those notify_one/notify_all members.

libstdc++-v3/ChangeLog:
* include/bits/atomic_base.h (atomic_flag::notify_one,
notify_all): Remove const qualification.
(__atomic_base::notify_one, notify_all): Likewise.
* include/std/atomic (atomic::notify_one, notify_all):
Likewise.
(atomic::notify_one, notify_all): Likewise.
(atomic::notify_one, notify_all): Likewise.
(atomic_notify_one, atomic_notify_all): Likewise.
* testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test
to account for change in notify_one/notify_all signature.

Tested x86_64-pc-linux-gnu.
From 7ed6dfae5a0a7a9e56291d780e44f99d644847e0 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Thu, 10 Feb 2022 18:55:16 -0800
Subject: [PATCH] libstdc++: Make atomic notify_one and notify_all non-const


PR102994 "atomics: std::atomic::wait is not marked const" raises the
issue that the current libstdc++ implementation marks the notify members
const, the implementation strategy used by libstdc++, as well as libc++
and the Microsoft STL, do not require the atomic to be mutable (it is hard
to conceive of a desirable implementation approach that would require it).
The original paper proposing the wait/notify functionality for atomics
(p1185) also had these members marked const for the first three revisions,
but that was changed without explanation in r3 and subsequent revisions of
the paper.

After raising the issue to the authors of p1185 and the author of the
libc++ implementation, the consensus seems to be "meh, it's harmless" so
there seems little appetite for an LWG issue to revisit the subject.

This patch changes the libstdc++ implementation to be in agreement with
the standard by removing const from those notify_one/notify_all members.

libstdc++-v3/ChangeLog:
	* include/bits/atomic_base.h (atomic_flag::notify_one,
	notify_all): Remove const qualification.
	(__atomic_base::notify_one, notify_all): Likewise.
	* include/std/atomic (atomic::notify_one, notify_all):
	Likewise.
	(atomic::notify_one, notify_all): Likewise.
	(atomic::notify_one, notify_all): Likewise.
	(atomic_notify_one, atomic_notify_all): Likewise.
	* testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test
	to account for change in notify_one/notify_all signature.
---
 libstdc++-v3/include/bits/atomic_base.h  |  8 
 libstdc++-v3/include/std/atomic  | 16 
 .../29_atomics/atomic/wait_notify/102994.cc  |  4 ++--
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index d86766cf39b..adfd9fa3027 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -252,13 +252,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 // TODO add const volatile overload
 
 _GLIBCXX_ALWAYS_INLINE void
-notify_one() const noexcept
+notify_one() noexcept
 { std::__atomic_notify_address(&_M_i, false); }
 
 // TODO add const volatile overload
 
 _GLIBCXX_ALWAYS_INLINE void
-notify_all() const noexcept
+notify_all() noexcept
 { std::__atomic_notify_address(&_M_i, true); }
 
 // TODO add const volatile overload
@@ -600,13 +600,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // TODO add const volatile overload
 
   _GLIBCXX_ALWAYS_INLINE void
-  notify_one() const noexcept
+  notify_one() noexcept
   { std::__atomic_notify_address(&_M_i, false); }
 
   // TODO add const volatile overload
 
   _GLIBCXX_ALWAYS_INLINE void
-  notify_all() const noexcept
+  notify_all() noexcept
   { std::__atomic_notify_address(&_M_i, true); }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index bc57659b6e7..d819b6bf41e 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -172,11 +172,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERS

Re: [PATCH] libstdc++: Strengthen memory order for atomic::wait/notify

2022-02-10 Thread Thomas Rodgers via Gcc-patches
Committed to trunk, backported to gcc-11.

On Wed, Feb 9, 2022 at 12:37 PM Jonathan Wakely  wrote:

> On Wed, 9 Feb 2022 at 17:35, Thomas Rodgers via Libstdc++
>  wrote:
> >
> > This patch changes the memory order used in the spin wait code to match
> > that of libc++.
>
> OK for trunk (and gcc-11 if needed).
>
>


Re: [PATCH] libstdc++: Fix deadlock in atomic wait [PR104442]

2022-02-09 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu, committed to master, backported to gcc-11.

On Wed, Feb 9, 2022 at 9:14 AM Jonathan Wakely  wrote:

> On Wed, 9 Feb 2022 at 17:10, Thomas Rodgers wrote:
> >
> > Updated patch. I reverted the memory order change (and will submit that
> as another patch) and fixed some spelling and grammar errors.
>
> OK for trunk and gcc-11, thanks.
>
>


[PATCH] libstdc++: Strengthen memory order for atomic::wait/notify

2022-02-09 Thread Thomas Rodgers via Gcc-patches
This patch changes the memory order used in the spin wait code to match
that of libc++.
From 92caa08b272520ec4a272b302b37d8fb47afb2ab Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Wed, 9 Feb 2022 09:26:00 -0800
Subject: [PATCH] libstdc++: Strengthen memory order for atomic::wait/notify
 (spinning)

This patch changes the memory order used in the spin wait code to match
that of libc++.

libstdc++-v3/ChangeLog:
	* includ/bits/atomic_wait.h (__waiter_base::_S_do_spin,
	__waiter_base::_S_do_spin_v): Change memory order from relaxed
	to acquire.
---
 libstdc++-v3/include/bits/atomic_wait.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h
index 6ce7f9343cf..125b1cad886 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -332,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
 	else
 	  {
-		__atomic_load(__addr, &__val, __ATOMIC_RELAXED);
+		__atomic_load(__addr, &__val, __ATOMIC_ACQUIRE);
 	  }
 	return __atomic_spin(__pred, __spin);
 	  }
@@ -353,7 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		 __platform_wait_t& __val,
 		 _Spin __spin = _Spin{ })
 	  {
-	__atomic_load(__addr, &__val, __ATOMIC_RELAXED);
+	__atomic_load(__addr, &__val, __ATOMIC_ACQUIRE);
 	return __atomic_spin(__pred, __spin);
 	  }
 
-- 
2.34.1



Re: [PATCH] libstdc++: Fix deadlock in atomic wait [PR104442]

2022-02-09 Thread Thomas Rodgers via Gcc-patches
Updated patch. I reverted the memory order change (and will submit that as
another patch) and fixed some spelling and grammar errors.

On Wed, Feb 9, 2022 at 2:43 AM Jonathan Wakely  wrote:

> On Wed, 9 Feb 2022 at 00:57, Thomas Rodgers via Libstdc++
>  wrote:
> >
> > This issue was observed as a deadloack in
> > 29_atomics/atomic/wait_notify/100334.cc on vxworks. When a wait is
> > "laundered" (e.g. type T* does not suffice as a waitable address for the
> > platform's native waiting primitive), the address waited is that of the
> > _M_ver member of __waiter_pool_base, so several threads may wait on the
> > same address for unrelated atomic's. As noted in the PR, the
> > implementation correctly exits the wait for the thread who's data
> > changed, but not for any other threads waiting on the same address.
> >
> > As noted in the PR the __waiter::_M_do_wait_v member was correctly
> exiting
> > but the other waiters were not reloaded the value of _M_ver before
> > re-entering the wait.
> >
> > Moving the spin call inside the loop accomplishes this, and is
> > consistent with the predicate accepting version of __waiter::_M_do_wait.
>
> There is a change to the memory order in _S_do_spin_v which is not
> described in the commit msg or the changelog. Is that unintentional?
>
> (Aside: why do we even have _S_do_spin_v, it's called in exactly one
> place, so could just be inlined into _M_do_spin_v, couldn't it?)
>
>
From b39283d5100305e7a95d59324059de9952d3a858 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Tue, 8 Feb 2022 16:33:36 -0800
Subject: [PATCH] libstdc++: Fix deadlock in atomic wait [PR104442]

This issue was observed as a deadlock in
29_atomics/atomic/wait_notify/100334.cc on vxworks. When a wait is
"laundered" (e.g. type T* does not suffice as a waitable address for the
platform's native waiting primitive), the address waited is that of the
_M_ver member of __waiter_pool_base, so several threads may wait on the
same address for unrelated atomic objects. As noted in the PR, the
implementation correctly exits the wait for the thread whose data
changed, but not for any other threads waiting on the same address.

As noted in the PR the __waiter::_M_do_wait_v member was correctly exiting
but the other waiters were not reloading the value of _M_ver before
re-entering the wait.

Moving the spin call inside the loop accomplishes this, and is
consistent with the predicate accepting version of __waiter::_M_do_wait.

libstdc++-v3/ChangeLog:

	PR libstdc++/104442
	* include/bits/atomic_wait.h (__waiter::_M_do_wait_v): Move spin
	 loop inside do loop so that threads failing the wait, reload
	 _M_ver.
---
 libstdc++-v3/include/bits/atomic_wait.h | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h
index d7de0d7eb9e..6ce7f9343cf 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -388,12 +388,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  void
 	  _M_do_wait_v(_Tp __old, _ValFn __vfn)
 	  {
-	__platform_wait_t __val;
-	if (__base_type::_M_do_spin_v(__old, __vfn, __val))
-	  return;
-
 	do
 	  {
+		__platform_wait_t __val;
+		if (__base_type::_M_do_spin_v(__old, __vfn, __val))
+		  return;
 		__base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
 	  }
 	while (__detail::__atomic_compare(__old, __vfn()));
-- 
2.34.1



Re: [PATCH] libstdc++: Fix deadlock in atomic wait [PR104442]

2022-02-09 Thread Thomas Rodgers via Gcc-patches
Excessively enthusiastic refactoring. I expect to rewrite most of this as
part of the work I'm starting now for GCC13 stage1.

On Wed, Feb 9, 2022 at 2:43 AM Jonathan Wakely  wrote:

> On Wed, 9 Feb 2022 at 00:57, Thomas Rodgers via Libstdc++
>  wrote:
> >
> > This issue was observed as a deadloack in
> > 29_atomics/atomic/wait_notify/100334.cc on vxworks. When a wait is
> > "laundered" (e.g. type T* does not suffice as a waitable address for the
> > platform's native waiting primitive), the address waited is that of the
> > _M_ver member of __waiter_pool_base, so several threads may wait on the
> > same address for unrelated atomic's. As noted in the PR, the
> > implementation correctly exits the wait for the thread who's data
> > changed, but not for any other threads waiting on the same address.
> >
> > As noted in the PR the __waiter::_M_do_wait_v member was correctly
> exiting
> > but the other waiters were not reloaded the value of _M_ver before
> > re-entering the wait.
> >
> > Moving the spin call inside the loop accomplishes this, and is
> > consistent with the predicate accepting version of __waiter::_M_do_wait.
>
> There is a change to the memory order in _S_do_spin_v which is not
> described in the commit msg or the changelog. Is that unintentional?
>
> (Aside: why do we even have _S_do_spin_v, it's called in exactly one
> place, so could just be inlined into _M_do_spin_v, couldn't it?)
>
>


[PATCH] libstdc++: Fix deadlock in atomic wait [PR104442]

2022-02-08 Thread Thomas Rodgers via Gcc-patches
This issue was observed as a deadloack in
29_atomics/atomic/wait_notify/100334.cc on vxworks. When a wait is
"laundered" (e.g. type T* does not suffice as a waitable address for the
platform's native waiting primitive), the address waited is that of the
_M_ver member of __waiter_pool_base, so several threads may wait on the
same address for unrelated atomic's. As noted in the PR, the
implementation correctly exits the wait for the thread who's data
changed, but not for any other threads waiting on the same address.

As noted in the PR the __waiter::_M_do_wait_v member was correctly exiting
but the other waiters were not reloaded the value of _M_ver before
re-entering the wait.

Moving the spin call inside the loop accomplishes this, and is
consistent with the predicate accepting version of __waiter::_M_do_wait.
From ee66736beca3dce4bc09350c5407a2ac7219fbec Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Tue, 8 Feb 2022 16:33:36 -0800
Subject: [PATCH] libstdc++: Fix deadlock in atomic wait [PR104442]

This issue was observed as a deadloack in
29_atomics/atomic/wait_notify/100334.cc on vxworks. When a wait is
"laundered" (e.g. type T* does not suffice as a waitable address for the
platform's native waiting primitive), the address waited is that of the
_M_ver member of __waiter_pool_base, so several threads may wait on the
same address for unrelated atomic's. As noted in the PR, the
implementation correctly exits the wait for the thread who's data
changed, but not for any other threads waiting on the same address.

As noted in the PR the __waiter::_M_do_wait_v member was correctly exiting
but the other waiters were not reloaded the value of _M_ver before
re-entering the wait.

Moving the spin call inside the loop accomplishes this, and is
consistent with the predicate accepting version of __waiter::_M_do_wait.

libstdc++-v3/ChangeLog:

	PR libstdc++/104442
	* include/bits/atomic_wait.h (__waiter::_M_do_wait_v): Move spin
	 loop inside do loop so that threads failing the wait, reload
	 _M_ver.
---
 libstdc++-v3/include/bits/atomic_wait.h | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h
index d7de0d7eb9e..33ce26ade1b 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -332,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
 	else
 	  {
-		__atomic_load(__addr, &__val, __ATOMIC_RELAXED);
+		__atomic_load(__addr, &__val, __ATOMIC_SEQ_CST);
 	  }
 	return __atomic_spin(__pred, __spin);
 	  }
@@ -388,12 +388,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  void
 	  _M_do_wait_v(_Tp __old, _ValFn __vfn)
 	  {
-	__platform_wait_t __val;
-	if (__base_type::_M_do_spin_v(__old, __vfn, __val))
-	  return;
-
 	do
 	  {
+		__platform_wait_t __val;
+		if (__base_type::_M_do_spin_v(__old, __vfn, __val))
+		  return;
 		__base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
 	  }
 	while (__detail::__atomic_compare(__old, __vfn()));
-- 
2.34.1



Re: [PATCH] Strengthen memory memory order for atomic::wait/notify

2022-02-01 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu, committed to master.
Backported to GCC-11.

On Sun, Jan 16, 2022 at 12:31 PM Jonathan Wakely  wrote:

>
>
> On Sun, 16 Jan 2022 at 01:48, Thomas Rodgers via Libstdc++ <
> libstd...@gcc.gnu.org> wrote:
>
>> This patch updates the memory order of atomic accesses to the waiter's
>> count to match libc++'s usage. It should be backported to GCC11.
>>
>
> The commit subject line says "memory memory order", OK for trunk and
> gcc-11 with that fixed.
>
>
>> Tested x86_64-pc-linux-gnu.
>>
>


[PATCH] Strengthen memory memory order for atomic::wait/notify

2022-01-15 Thread Thomas Rodgers via Gcc-patches
This patch updates the memory order of atomic accesses to the waiter's
count to match libc++'s usage. It should be backported to GCC11.

Tested x86_64-pc-linux-gnu.
From f5ed7674f86283db4f4ff49a2cc65d4f852413a1 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Sat, 15 Jan 2022 17:40:49 -0800
Subject: [PATCH] Strengthen memory memory order for atomic::wait/notify

This matches the memory order in libc++.

libstdc++-v3/ChangeLog:
	* libstdc++-v3/include/bits/atomic_wait.h: Change memory order
	from Acquire/Release with relaxed loads to SeqCst+Release for
	accesses to the waiter's count.
---
 libstdc++-v3/include/bits/atomic_wait.h | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h
index 05cf0013d2a..d7de0d7eb9e 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -209,18 +209,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   void
   _M_enter_wait() noexcept
-  { __atomic_fetch_add(&_M_wait, 1, __ATOMIC_ACQ_REL); }
+  { __atomic_fetch_add(&_M_wait, 1, __ATOMIC_SEQ_CST); }
 
   void
   _M_leave_wait() noexcept
-  { __atomic_fetch_sub(&_M_wait, 1, __ATOMIC_ACQ_REL); }
+  { __atomic_fetch_sub(&_M_wait, 1, __ATOMIC_RELEASE); }
 
   bool
   _M_waiting() const noexcept
   {
 	__platform_wait_t __res;
-	__atomic_load(&_M_wait, &__res, __ATOMIC_ACQUIRE);
-	return __res > 0;
+	__atomic_load(&_M_wait, &__res, __ATOMIC_SEQ_CST);
+	return __res != 0;
   }
 
   void
@@ -258,7 +258,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__platform_wait(__addr, __old);
 #else
 	__platform_wait_t __val;
-	__atomic_load(__addr, &__val, __ATOMIC_RELAXED);
+	__atomic_load(__addr, &__val, __ATOMIC_SEQ_CST);
 	if (__val == __old)
 	  {
 	lock_guard __l(_M_mtx);
@@ -309,7 +309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{
 	  if (_M_laundered())
 	{
-	  __atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
+	  __atomic_fetch_add(_M_addr, 1, __ATOMIC_SEQ_CST);
 	  __all = true;
 	}
 	  _M_w._M_notify(_M_addr, __all, __bare);
-- 
2.31.1



[PATCH] libstdc++: Add missing free functions for atomic_flag [PR103934]

2022-01-14 Thread Thomas Rodgers via Gcc-patches

From c2b74fd7cf2668d288f46da42565e5eb954e5e1f Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Fri, 14 Jan 2022 18:30:27 -0800
Subject: [PATCH] libstdc++: Add missing free functions for atomic_flag
 [PR103934]

libstdc++-v3/ChangeLog:

	PR103934
	* include/std/atomic: Add missing free functions.
	* testsuite/29_atomics/atomic_flag/wait_notify/1.cc:
	Add test case to cover missing atomic_flag free functions.
---
 libstdc++-v3/include/std/atomic   | 39 +++
 .../29_atomics/atomic_flag/wait_notify/1.cc   | 27 +++--
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 9df17704f7e..92c96a9b047 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -1216,6 +1216,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 memory_order __m) noexcept
   { return __a->test_and_set(__m); }
 
+#if __cpp_lib_atomic_flag_test
+  inline bool
+  atomic_flag_test(const atomic_flag* __a) noexcept
+  { return __a->test(); }
+
+  inline bool
+  atomic_flag_test(const volatile atomic_flag* __a) noexcept
+  { return __a->test(); }
+
+  inline bool
+  atomic_flag_test_explicit(const atomic_flag* __a,
+			memory_order __m) noexcept
+  { return __a->test(__m); }
+
+  inline bool
+  atomic_flag_test_explicit(const volatile atomic_flag* __a,
+			memory_order __m) noexcept
+  { return __a->test(__m); }
+#endif
+
   inline void
   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
   { __a->clear(__m); }
@@ -1241,6 +1261,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   atomic_flag_clear(volatile atomic_flag* __a) noexcept
   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
 
+#if __cpp_lib_atomic_wait
+  inline void
+  atomic_flag_wait(const atomic_flag* __a, bool __old) noexcept
+  { __a->wait(__old); }
+
+  inline void
+  atomic_flag_wait_explicit(const atomic_flag* __a, bool __old,
+		   std::memory_order __m) noexcept
+  { __a->wait(__old, __m); }
+
+  inline void
+  atomic_flag_notify_one(const atomic_flag* __a) noexcept
+  { __a->notify_one(); }
+
+  inline void
+  atomic_flag_notify_all(const atomic_flag* __a) noexcept
+  { __a->notify_all(); }
+#endif // __cpp_lib_atomic_wait
+
 
   template
 using __atomic_val_t = typename atomic<_Tp>::value_type;
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
index 87a104059ff..1050b72a1c6 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
@@ -26,8 +26,8 @@
 
 #include 
 
-int
-main()
+void
+test01()
 {
   std::atomic_flag a;
   VERIFY( !a.test() );
@@ -39,5 +39,26 @@ main()
 });
   a.wait(false);
   t.join();
-  return 0;
+}
+
+void
+test02()
+{
+  std::atomic_flag a;
+  VERIFY( !std::atomic_flag_test() );
+  std::atomic_flag_wait(, true);
+  std::thread t([&]
+{
+  std::atomic_flag_test_and_set();
+  std::atomic_flag_notify_one();
+});
+  std::atomic_flag_wait(, false);
+  t.join();
+}
+
+int
+main()
+{
+  test01();
+  test02();
 }
-- 
2.31.1



Re: libstdc++: Make atomic::wait() const [PR102994]

2021-12-09 Thread Thomas Rodgers via Gcc-patches
Tested uild-x86_64-pc-linux-gnu, pushed to trunk and gcc-11.

On Thu, Nov 25, 2021 at 1:24 PM Jonathan Wakely  wrote:

> On Wed, 24 Nov 2021 at 01:27, Thomas Rodgers wrote:
> >
> > const qualification was also missing in the free functions for
> wait/wait_explicit/notify_one/notify_all. Revised patch attached.
>
> Please tweak the whitespace in the new test:
>
> > +test1(const std::atomic , char*p)
>
> The '&' should be on the type not the variable, and there should be a
> space before 'p':
>
> > +test1(const std::atomic& a, char* p)
>
> OK for trunk and gcc-11 with that tweak, thanks!
>
>


Re: libstdc++: Make atomic::wait() const [PR102994]

2021-11-23 Thread Thomas Rodgers via Gcc-patches
const qualification was also missing in the free functions for
wait/wait_explicit/notify_one/notify_all. Revised patch attached.

On Tue, Nov 9, 2021 at 11:40 AM Jonathan Wakely  wrote:

> On Tue, 9 Nov 2021 at 18:09, Thomas Rodgers wrote:
>
>> Revised patch attached.
>>
>
> OK for trunk and gcc-11, thanks.
>
>
>
>> On Fri, Nov 5, 2021 at 4:46 PM Jonathan Wakely 
>> wrote:
>>
>>> On Fri, 5 Nov 2021 at 21:51, Jonathan Wakely via Libstdc++
>>>  wrote:
>>> >
>>> > OK, thanks.
>>>
>>> Actually, we should really have a test to verify it can be called on a
>>> const object. Please add something when you commit, it can be dumb and
>>> simple, it just needs to verify that it can be called.
>>>
>>>
>>> >
>>> >
>>> > On Fri, 5 Nov 2021 at 21:46, Thomas Rodgers via Libstdc++ <
>>> > libstd...@gcc.gnu.org> wrote:
>>> >
>>> > >
>>> > >
>>>
>>>
From 337c147b5bb0265522d5aac4beefb3dec1ebe026 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Tue, 9 Nov 2021 09:42:49 -0800
Subject: [PATCH] libstdc++: Make atomic::wait() const [PR102994]

This was an oversight in the original commit adding wait/notify
to atomic.

libstdc++-v3/ChangeLog:

	PR libstdc++/102994
	* include/bits/atomic_base.h (__atomic_base<_PTp*>::wait()):
	Add const qualifier.
	* include/std/atomic (atomic<_Tp*>::wait(), atomic_wait(),
	atomic_wait_explicit(), atomic_notify_one(), atomic_notify_all()):
	Likewise.
	* testsuite/29_atomics/atomic/wait_notify/102994.cc:
	New test.
---
 libstdc++-v3/include/bits/atomic_base.h   |  2 +-
 libstdc++-v3/include/std/atomic   |  8 
 .../29_atomics/atomic/wait_notify/102994.cc   | 19 +++
 3 files changed, 24 insertions(+), 5 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 9e18aadadaf..a104adc1a10 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -893,7 +893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
   wait(__pointer_type __old,
-	   memory_order __m = memory_order_seq_cst) noexcept
+	   memory_order __m = memory_order_seq_cst) const noexcept
   {
 	std::__atomic_wait_address_v(&_M_p, __old,
  [__m, this]
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 936dd50ba1c..9b827b425dc 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -646,9 +646,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__cmpexch_failure_order(__m));
   }
 
-#if __cpp_lib_atomic_wait 
+#if __cpp_lib_atomic_wait
 void
-wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) noexcept
+wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
 { _M_b.wait(__old, __m); }
 
 // TODO add const volatile overload
@@ -1434,12 +1434,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 inline void
-atomic_notify_one(atomic<_Tp>* __a) noexcept
+atomic_notify_one(const atomic<_Tp>* __a) noexcept
 { __a->notify_one(); }
 
   template
 inline void
-atomic_notify_all(atomic<_Tp>* __a) noexcept
+atomic_notify_all(const atomic<_Tp>* __a) noexcept
 { __a->notify_all(); }
 #endif // __cpp_lib_atomic_wait
 
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc
new file mode 100644
index 000..28c3d66f451
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc
@@ -0,0 +1,19 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+// { dg-require-gthreads "" }
+
+#include 
+
+void
+test1(const std::atomic , char*p)
+{
+  a.wait(p);
+}
+
+void
+test2(const std::atomic* a, int v)
+{
+  std::atomic_wait(a, v);
+  std::atomic_notify_one(a);
+  std::atomic_notify_all(a);
+}
-- 
2.31.1



Re: libstdc++: Make atomic::wait() const [PR102994]

2021-11-09 Thread Thomas Rodgers via Gcc-patches
Revised patch attached.

On Fri, Nov 5, 2021 at 4:46 PM Jonathan Wakely 
wrote:

> On Fri, 5 Nov 2021 at 21:51, Jonathan Wakely via Libstdc++
>  wrote:
> >
> > OK, thanks.
>
> Actually, we should really have a test to verify it can be called on a
> const object. Please add something when you commit, it can be dumb and
> simple, it just needs to verify that it can be called.
>
>
> >
> >
> > On Fri, 5 Nov 2021 at 21:46, Thomas Rodgers via Libstdc++ <
> > libstd...@gcc.gnu.org> wrote:
> >
> > >
> > >
>
>
From 69737be7cda5328eb0f67c9725c3b691bcb6cb2f Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Tue, 9 Nov 2021 09:42:49 -0800
Subject: [PATCH] libstdc++: Make atomic::wait() const [PR102994]

This was an oversight in the original commit adding wait/notify
to atomic.

libstdc++-v3/ChangeLog:

	PR libstdc++/102994
	* include/bits/atomic_base.h (__atomic_base<_PTp*>::wait()):
	Add const qualifier.
	* include/std/atomic (atomic<_Tp*>::wait()):
	Likewise.
	* testsuite/29_atomics/atomic/wait_notify/102994.cc:
	New test.
---
 libstdc++-v3/include/bits/atomic_base.h   |  2 +-
 libstdc++-v3/include/std/atomic   |  4 ++--
 .../testsuite/29_atomics/atomic/wait_notify/102994.cc | 11 +++
 3 files changed, 14 insertions(+), 3 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 9e18aadadaf..a104adc1a10 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -893,7 +893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
   wait(__pointer_type __old,
-	   memory_order __m = memory_order_seq_cst) noexcept
+	   memory_order __m = memory_order_seq_cst) const noexcept
   {
 	std::__atomic_wait_address_v(&_M_p, __old,
  [__m, this]
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 936dd50ba1c..c971b712ef6 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -646,9 +646,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__cmpexch_failure_order(__m));
   }
 
-#if __cpp_lib_atomic_wait 
+#if __cpp_lib_atomic_wait
 void
-wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) noexcept
+wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
 { _M_b.wait(__old, __m); }
 
 // TODO add const volatile overload
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc
new file mode 100644
index 000..bc814a708aa
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/102994.cc
@@ -0,0 +1,11 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+// { dg-require-gthreads "" }
+
+#include 
+
+void
+test_it(const std::atomic , char*p)
+{
+  a.wait(p);
+}
-- 
2.31.1



libstdc++: Make atomic::wait() const [PR102994]

2021-11-05 Thread Thomas Rodgers via Gcc-patches

From 360c094a0725bb0cc444115c0377db10e5e9ae1f Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Fri, 5 Nov 2021 14:30:24 -0700
Subject: [PATCH] libstdc++: Make atomic::wait() const [PR102994]

This was an oversight in the original commit adding wait/notify
to atomic.

libstdc++-v3/ChangeLog:

	PR libstdc++/102994
	* include/bits/atomic_base.h (__atomic_base<_PTp*>::wait())
	add const qualifier.
---
 libstdc++-v3/include/bits/atomic_base.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 9e18aadadaf..a104adc1a10 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -893,7 +893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
   wait(__pointer_type __old,
-	   memory_order __m = memory_order_seq_cst) noexcept
+	   memory_order __m = memory_order_seq_cst) const noexcept
   {
 	std::__atomic_wait_address_v(&_M_p, __old,
  [__m, this]
-- 
2.31.1



Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange

2021-11-02 Thread Thomas Rodgers
This version of the patch specifically doesn’t deal with long double.
Mostly looking for Jonathan’s review to ensure his previous feedback is
addressed. I plan to rev the patch to handle long doubles after some
further discussion with you and Jonathan.

On Tue, Nov 2, 2021 at 12:49 AM Jakub Jelinek  wrote:

> On Mon, Nov 01, 2021 at 06:25:45PM -0700, Thomas Rodgers via Gcc-patches
> wrote:
> > +template
> > +  constexpr bool
> > +  __maybe_has_padding()
> > +  {
> > +#if __has_builtin(__has_unique_object_representations)
> > + return !__has_unique_object_representations(_Tp)
> > +   && !is_floating_point<_Tp>::value;
> > +#else
> > + return true;
> > +#endif
>
> I'm not sure I understand the && !is_floating_point<_Tp>::value.
> Yes, float and double will never have padding, but long double often
> will, e.g. on x86 or ia64 (but e.g. not on ppc, s390x, etc.).
> So, unless we want to play with numeric_limits, it should be either
> just return !__has_unique_object_representations(_Tp);
> or return !__has_unique_object_representations(_Tp)
>   && (!is_floating_point<_Tp>::value
>   || is_same<__remove_cv_t<_Tp>,long double>::value);
> or, with numeric_limits test numeric_limits<_Tp>::digits == 64
> (but I'm sure Jonathan will not want including such a header dependency
> unless it is already included).
> Or I can always provide a new __builtin_clear_padding_p ...
>
> Jakub
>
>


Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange

2021-11-01 Thread Thomas Rodgers via Gcc-patches
This should address Jonathan's feedback and adds support for atomic_ref

On Wed, Sep 29, 2021 at 5:14 AM Jonathan Wakely  wrote:

> On Mon, 27 Sept 2021 at 15:11, Thomas Rodgers 
> wrote:
> >
> > From: Thomas Rodgers 
> >
> > Now with checks for __has_builtin(__builtin_clear_padding)
> >
> > This change implements P0528 which requires that padding bits not
> > participate in atomic compare exchange operations. All arguments to the
> > generic template are 'sanitized' by the __builtin_clearpadding intrisic
> > before they are used in comparisons. This alrequires that any stores
> > also sanitize the incoming value.
> >
> > Signed-off-by: Thomas Rodgers 
> >
> > libstdc++=v3/ChangeLog:
> >
> > * include/std/atomic (atomic::atomic(_Tp) clear padding for
> > __cplusplus > 201703L.
> > (atomic::store()) Clear padding.
> > (atomic::exchange()) Likewise.
> > (atomic::compare_exchange_weak()) Likewise.
> > (atomic::compare_exchange_strong()) Likewise.
>
> Don't we also need this for std::atomic_ref, i.e. for the
> __atomic_impl free functions in ?
>
> There we don't have any distinction between atomic_ref
> and atomic_ref, they both use the same
> implementations. But I think that's OK, as I think the built-in is
> smart enough to be a no-op for types with no padding.
>
> > * testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
> > test.
> > ---
> >  libstdc++-v3/include/std/atomic   | 41 +-
> >  .../atomic/compare_exchange_padding.cc| 42 +++
> >  2 files changed, 81 insertions(+), 2 deletions(-)
> >  create mode 100644
> libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> >
> > diff --git a/libstdc++-v3/include/std/atomic
> b/libstdc++-v3/include/std/atomic
> > index 936dd50ba1c..4ac9ccdc1ab 100644
> > --- a/libstdc++-v3/include/std/atomic
> > +++ b/libstdc++-v3/include/std/atomic
> > @@ -228,7 +228,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >atomic& operator=(const atomic&) = delete;
> >atomic& operator=(const atomic&) volatile = delete;
> >
> > -  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
> > +#if __cplusplus > 201703L && __has_builtin(__builtin_clear_padding)
> > +  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
> > +  { __builtin_clear_padding(std::__addressof(_M_i)); }
> > +#else
> > +  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
> > +  { }
> > +#endif
>
> Please write this as a single function with the preprocessor
> conditions in the body:
>
>   constexpr atomic(_Tp __i) noexcept : _M_i(__i)
>   {
> #if __cplusplus > 201703L && __has_builtin(__builtin_clear_padding)
> __builtin_clear_padding(std::__addressof(_M_i)); }
> #endif
>   }
>
> This not only avoids duplication of the identical parts, but it avoids
> warnings from ld.gold if you use --detect-odr-violations. Otherwise,
> the linker can see a definition of that constructor on two different
> lines (233 and 236), and so warns about possible ODR violations,
> something like "warning: while linking foo: symbol
> 'std::atomic::atomic(int)' defined in multiple places (possible
> ODR violation): ...atomic:233 ... atomic:236"
>
> Can't we clear the padding for >= 201402L instead of only C++20? Only
> C++11 has a problem with the built-in in a constexpr function, right?
> So we can DTRT for C++14 upwards.
>
>
> >
> >operator _Tp() const noexcept
> >{ return load(); }
> > @@ -268,12 +274,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >void
> >store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
> >{
> > +#if __has_builtin(__builtin_clear_padding)
> > +   __builtin_clear_padding(std::__addressof(__i));
> > +#endif
>
> We repeat this *a lot*. When I started work on this I defined a
> non-member function in the __atomic_impl namespace:
>
> template
>   _GLIBCXX_ALWAYS_INLINE void
>   __clear_padding(_Tp& __val) noexcept
>   {
> #if __has_builtin(__builtin_clear_padding)
>__builtin_clear_padding(std::__addressof(__val));
> #endif
>   }
>
> Then you can just use that everywhere (except the constexpr
> constructor), without all the #if checks.
>
>
>
> > __atomic_store(std::__addressof(_M_i), std::__addressof(__i),
> int(__m));
> >}
> >
> >void
> >store(_Tp __i, me

Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange

2021-09-29 Thread Thomas Rodgers via Gcc-patches
On Wed, Sep 29, 2021 at 5:14 AM Jonathan Wakely  wrote:

> On Mon, 27 Sept 2021 at 15:11, Thomas Rodgers 
> wrote:
> >
> > From: Thomas Rodgers 
> >
> > Now with checks for __has_builtin(__builtin_clear_padding)
> >
> > This change implements P0528 which requires that padding bits not
> > participate in atomic compare exchange operations. All arguments to the
> > generic template are 'sanitized' by the __builtin_clearpadding intrisic
> > before they are used in comparisons. This alrequires that any stores
> > also sanitize the incoming value.
> >
> > Signed-off-by: Thomas Rodgers 
> >
> > libstdc++=v3/ChangeLog:
> >
> > * include/std/atomic (atomic::atomic(_Tp) clear padding for
> > __cplusplus > 201703L.
> > (atomic::store()) Clear padding.
> > (atomic::exchange()) Likewise.
> > (atomic::compare_exchange_weak()) Likewise.
> > (atomic::compare_exchange_strong()) Likewise.
>
> Don't we also need this for std::atomic_ref, i.e. for the
> __atomic_impl free functions in ?
>
> There we don't have any distinction between atomic_ref
> and atomic_ref, they both use the same
> implementations. But I think that's OK, as I think the built-in is
> smart enough to be a no-op for types with no padding.
>
> > * testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
> > test.
> > ---
> >  libstdc++-v3/include/std/atomic   | 41 +-
> >  .../atomic/compare_exchange_padding.cc| 42 +++
> >  2 files changed, 81 insertions(+), 2 deletions(-)
> >  create mode 100644
> libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
> >
> > diff --git a/libstdc++-v3/include/std/atomic
> b/libstdc++-v3/include/std/atomic
> > index 936dd50ba1c..4ac9ccdc1ab 100644
> > --- a/libstdc++-v3/include/std/atomic
> > +++ b/libstdc++-v3/include/std/atomic
> > @@ -228,7 +228,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >atomic& operator=(const atomic&) = delete;
> >atomic& operator=(const atomic&) volatile = delete;
> >
> > -  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
> > +#if __cplusplus > 201703L && __has_builtin(__builtin_clear_padding)
> > +  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
> > +  { __builtin_clear_padding(std::__addressof(_M_i)); }
> > +#else
> > +  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
> > +  { }
> > +#endif
>
> Please write this as a single function with the preprocessor
> conditions in the body:
>
>   constexpr atomic(_Tp __i) noexcept : _M_i(__i)
>   {
> #if __cplusplus > 201703L && __has_builtin(__builtin_clear_padding)
> __builtin_clear_padding(std::__addressof(_M_i)); }
> #endif
>   }
>
> This not only avoids duplication of the identical parts, but it avoids
> warnings from ld.gold if you use --detect-odr-violations. Otherwise,
> the linker can see a definition of that constructor on two different
> lines (233 and 236), and so warns about possible ODR violations,
> something like "warning: while linking foo: symbol
> 'std::atomic::atomic(int)' defined in multiple places (possible
> ODR violation): ...atomic:233 ... atomic:236"
>
> Can't we clear the padding for >= 201402L instead of only C++20? Only
> C++11 has a problem with the built-in in a constexpr function, right?
> So we can DTRT for C++14 upwards.
>
>
We can, I was being conservative expecting guiding elvish feedback :)


>
> >
> >operator _Tp() const noexcept
> >{ return load(); }
> > @@ -268,12 +274,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >void
> >store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
> >{
> > +#if __has_builtin(__builtin_clear_padding)
> > +   __builtin_clear_padding(std::__addressof(__i));
> > +#endif
>
> We repeat this *a lot*. When I started work on this I defined a
> non-member function in the __atomic_impl namespace:
>
> template
>   _GLIBCXX_ALWAYS_INLINE void
>   __clear_padding(_Tp& __val) noexcept
>   {
> #if __has_builtin(__builtin_clear_padding)
>__builtin_clear_padding(std::__addressof(__val));
> #endif
>   }
>
> Then you can just use that everywhere (except the constexpr
> constructor), without all the #if checks.
>
>
>
> > __atomic_store(std::__addressof(_M_i), std::__addressof(__i),
> int(__m));
> >}
> >
> >void
> >store(_Tp __i,

[PATCH] libstdc++: Clear padding bits in atomic compare_exchange

2021-09-27 Thread Thomas Rodgers
From: Thomas Rodgers 

Now with checks for __has_builtin(__builtin_clear_padding)

This change implements P0528 which requires that padding bits not
participate in atomic compare exchange operations. All arguments to the
generic template are 'sanitized' by the __builtin_clearpadding intrisic
before they are used in comparisons. This alrequires that any stores
also sanitize the incoming value.

Signed-off-by: Thomas Rodgers 

libstdc++=v3/ChangeLog:

* include/std/atomic (atomic::atomic(_Tp) clear padding for
__cplusplus > 201703L.
(atomic::store()) Clear padding.
(atomic::exchange()) Likewise.
(atomic::compare_exchange_weak()) Likewise.
(atomic::compare_exchange_strong()) Likewise.
* testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
test.
---
 libstdc++-v3/include/std/atomic   | 41 +-
 .../atomic/compare_exchange_padding.cc| 42 +++
 2 files changed, 81 insertions(+), 2 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc

diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 936dd50ba1c..4ac9ccdc1ab 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -228,7 +228,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   atomic& operator=(const atomic&) = delete;
   atomic& operator=(const atomic&) volatile = delete;
 
-  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
+#if __cplusplus > 201703L && __has_builtin(__builtin_clear_padding)
+  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
+  { __builtin_clear_padding(std::__addressof(_M_i)); }
+#else
+  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
+  { }
+#endif
 
   operator _Tp() const noexcept
   { return load(); }
@@ -268,12 +274,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
   {
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
   }
 
   void
   store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
   {
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
   }
 
@@ -300,6 +312,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
  __ptr, int(__m));
return *__ptr;
@@ -311,6 +326,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
  __ptr, int(__m));
return *__ptr;
@@ -322,6 +340,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -334,6 +356,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -358,6 +384,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+#if __has_builtin(__builtin_clear_padding)
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
+#endif
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -370,6 +400,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 

Re: [PATCH] libstdc++: Clear padding bits in atomic compare_exchange

2021-09-23 Thread Thomas Rodgers via Gcc-patches
Agreed, I'll revise the patch to do so.

On Thu, Sep 23, 2021 at 12:07 PM Jakub Jelinek  wrote:

> On Thu, Sep 23, 2021 at 11:08:37AM -0700, Thomas Rodgers wrote:
> > From: Thomas Rodgers 
> >
> > This change implements P0528 which requires that padding bits not
> > participate in atomic compare exchange operations. All arguments to the
>
> Thanks for working on this.
>
> > generic template are 'sanitized' by the __builtin_clear_padding intrinsic
> > before they are used in atomic compare_exchange. This alrequires that any
> > stores also sanitize the incoming value.
>
> Not a review, just random nit.
> Shouldn't the __builtin_clear_padding calls be guarded with
> #if __has_builtin(__builtin_clear_padding)
> or #ifdef _GLIBCXX_HAVE_BUILTIN_CLEAR_PADDING defined based on that?
> I think clang doesn't support it (yet?), and it doesn't support the MSVC
> __builtin_zero_non_value_bits (with very similar, but slightly different,
> behavior).
>
> > Signed-off-by: Thomas Rodgers 
> >
> > libstdc++=v3/ChangeLog:
> >
> >   * include/std/atomic (atomic::atomic(_Tp) clear padding for
> >   __cplusplus > 201703L.
> >   (atomic::store()) Clear padding.
> >   (atomic::exchange()) Likewise.
> >   (atomic::compare_exchange_weak()) Likewise.
> >   (atomic::compare_exchange_strong()) Likewise.
> >   * testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
> >   test.
>
> Jakub
>
>


[PATCH] libstdc++: Clear padding bits in atomic compare_exchange

2021-09-23 Thread Thomas Rodgers
From: Thomas Rodgers 

This change implements P0528 which requires that padding bits not
participate in atomic compare exchange operations. All arguments to the
generic template are 'sanitized' by the __builtin_clear_padding intrinsic
before they are used in atomic compare_exchange. This alrequires that any
stores also sanitize the incoming value.

Signed-off-by: Thomas Rodgers 

libstdc++=v3/ChangeLog:

* include/std/atomic (atomic::atomic(_Tp) clear padding for
__cplusplus > 201703L.
(atomic::store()) Clear padding.
(atomic::exchange()) Likewise.
(atomic::compare_exchange_weak()) Likewise.
(atomic::compare_exchange_strong()) Likewise.
* testsuite/29_atomics/atomic/compare_exchange_padding.cc: New
test.
---
 libstdc++-v3/include/std/atomic   | 23 +-
 .../atomic/compare_exchange_padding.cc| 42 +++
 2 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc

diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 936dd50ba1c..51450badace 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -228,7 +228,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   atomic& operator=(const atomic&) = delete;
   atomic& operator=(const atomic&) volatile = delete;
 
-  constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
+#if __cplusplus > 201703L
+  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
+  { __builtin_clear_padding(std::__addressof(_M_i)); }
+#else
+  atomic(_Tp __i) noexcept : _M_i(__i)
+  { }
+#endif
 
   operator _Tp() const noexcept
   { return load(); }
@@ -268,12 +274,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
   {
+   __builtin_clear_padding(std::__addressof(__i));
__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
   }
 
   void
   store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
   {
+   __builtin_clear_padding(std::__addressof(__i));
__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
   }
 
@@ -300,6 +308,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
+   __builtin_clear_padding(std::__addressof(__i));
__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
  __ptr, int(__m));
return *__ptr;
@@ -311,6 +320,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
+   __builtin_clear_padding(std::__addressof(__i));
__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
  __ptr, int(__m));
return *__ptr;
@@ -322,6 +332,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -334,6 +346,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -358,6 +372,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -370,6 +386,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
 
+   __builtin_clear_padding(std::__addressof(__e));
+   __builtin_clear_padding(std::__addressof(__i));
return __atomic_compare_exchange(std::__addressof(_M_i),
 std::__addressof(__e),
 std::__addressof(__i),
@@ -392,6 +410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 void
 wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
 {
+  __builtin_clear_padding(st

[PATCH] libstdc++: Implement C++20 atomic and atomic

2021-09-17 Thread Thomas Rodgers
From: Thomas Rodgers 

Let's try this one instead.

Signed-off-by: Thomas Rodgers 

libstdc++-v3/ChangeLog:
* acinclude.m4: Update ABI version.
* config/abi/pre/gnu.ver (GLIBCXX_3.4.21): Do not match new _Sp_locker
constructor.
(GLIBCXX_3.4.30): Export _Sp_locker::_M_wait/_M_notify and new
constructor.
* include/bits/shared_ptr_atomic.h: define __cpp_lib_atomic_shared_ptr
feature test macro.
(_Sp_locker::_Sp_locker(const void*, bool): New constructor.
(_Sp_locker::_M_wait()), _Sp_locker::_M_notify()): New methods.
(_Sp_impl): New type.
(atomic>): New partial template specialization.
(atomic>): New partial template specialization.
* include/std/version: define __cpp_lib_atomic_shared_ptr feature
test macro.
* doc/xml/manual/abi.xml: New ABI version.
* src/c++11/Makefile.am: Compile src/c++11/shared_ptr.cc
-std=gnu++20.
* src/c++11/Makefile.in: Regenerate.
* src/c++11/shared_ptr.cc (_Sp_locker::_Sp_locker(const void*, bool),
_Sp_locker::_M_wait(), _Sp_locker::_M_notify(): Implement.
* testsuite/20_util/shared_ptr/atomic/4.cc: New test.
* testsuite/20_util/shared_ptr/atomic/5.cc: Likewise.
* testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc: Likewise.
* testuite/util/testsuite_abi.cc: New ABI version.
---
 libstdc++-v3/acinclude.m4 |   2 +-
 libstdc++-v3/config/abi/pre/gnu.ver   |  12 +-
 libstdc++-v3/configure|   2 +-
 libstdc++-v3/doc/xml/manual/abi.xml   |   1 +
 libstdc++-v3/include/bits/shared_ptr_atomic.h | 309 ++
 libstdc++-v3/include/std/version  |   1 +
 libstdc++-v3/src/c++11/Makefile.am|   6 +
 libstdc++-v3/src/c++11/Makefile.in|   6 +
 libstdc++-v3/src/c++11/shared_ptr.cc  |  86 -
 .../testsuite/20_util/shared_ptr/atomic/4.cc  |  28 ++
 .../testsuite/20_util/shared_ptr/atomic/5.cc  |  28 ++
 .../shared_ptr/atomic/atomic_shared_ptr.cc| 159 +
 libstdc++-v3/testsuite/util/testsuite_abi.cc  |   3 +-
 13 files changed, 637 insertions(+), 6 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/atomic/4.cc
 create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/atomic/5.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 90ecc4a87a2..30a4abb98b3 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -3798,7 +3798,7 @@ changequote([,])dnl
 fi
 
 # For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=6:29:0
+libtool_VERSION=6:30:0
 
 # Everything parsed; figure out what files and settings to use.
 case $enable_symvers in
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index 5323c7f0604..727afd2d488 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1705,8 +1705,9 @@ GLIBCXX_3.4.21 {
 # std::ctype_base::blank
 _ZNSt10ctype_base5blankE;
 
-# std::_Sp_locker::*
-_ZNSt10_Sp_locker[CD]*;
+# std::_Sp_locker:: constructors and destructors
+_ZNSt10_Sp_lockerC*[^b];
+_ZNSt10_Sp_lockerD*;
 
 # std::notify_all_at_thread_exit
 
_ZSt25notify_all_at_thread_exitRSt18condition_variableSt11unique_lockISt5mutexE;
@@ -2397,6 +2398,13 @@ GLIBCXX_3.4.29 {
 
 } GLIBCXX_3.4.28;
 
+GLIBCXX_3.4.30 {
+  # std::_Sp_locker:: wait/notify support
+  _ZNSt10_Sp_lockerC*[b];
+  _ZNSt10_Sp_locker7_M_waitEv;
+  _ZNSt10_Sp_locker9_M_notifyEv;
+} GLIBCXX_3.4.29;
+
 # Symbols in the support library (libsupc++) have their own tag.
 CXXABI_1.3 {
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 13d52eb0c0e..67ee6db1bea 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -74684,7 +74684,7 @@ $as_echo "$as_me: WARNING: === Symbol versioning will 
be disabled." >&2;}
 fi
 
 # For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=6:29:0
+libtool_VERSION=6:30:0
 
 # Everything parsed; figure out what files and settings to use.
 case $enable_symvers in
diff --git a/libstdc++-v3/doc/xml/manual/abi.xml 
b/libstdc++-v3/doc/xml/manual/abi.xml
index c2c0c028a8b..10bef12c768 100644
--- a/libstdc++-v3/doc/xml/manual/abi.xml
+++ b/libstdc++-v3/doc/xml/manual/abi.xml
@@ -348,6 +348,7 @@ compatible.
 GCC 9.3.0: GLIBCXX_3.4.28, CXXABI_1.3.12
 GCC 10.1.0: GLIBCXX_3.4.28, CXXABI_1.3.12
 GCC 11.1.0: GLIBCXX_3.4.29, CXXABI_1.3.13
+GCC 12.1.0: GLIBCXX_3.4.30, CXXABI_1.3.13
 
 
 
diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h 
b/libstdc++-v3/include/bits/shared_ptr_atomic.h
index 6e94d83c46d..2aec3adac7c 100644
--- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
+++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
@@ -32,

[PATCH] libstdc++: Implement C++20 atomic and atomic

2021-09-17 Thread Thomas Rodgers
From: Thomas Rodgers 

Signed-off-by: Thomas Rodgers 

libstdc++-v3/ChangeLog:
* config/abi/pre/gnu.ver (GLIBCXX_3.4.21): Do not match new _Sp_locker
constructor.
(GLIBCXX_3.4.30): Export _Sp_locker::_M_wait/_M_notify and new
constructor.
* include/bits/shared_ptr_atomic.h: define __cpp_lib_atomic_shared_ptr
feature test macro.
(_Sp_locker::_Sp_locker(const void*, bool): New constructor.
(_Sp_locker::_M_wait()), _Sp_locker::_M_notify()): New methods.
(_Sp_impl): New type.
(atomic>): New partial template specialization.
(atomic>): New partial template specialization.
* include/std/version: define __cpp_lib_atomic_shared_ptr feature
test macro.
* src/c++11/Makefile.am: Compile src/c++11/shared_ptr.cc
-std=gnu++20.
* src/c++11/Makefile.in: Regenerate.
* src/c++11/shared_ptr.cc (_Sp_locker::_Sp_locker(const void*, bool),
_Sp_locker::_M_wait(), _Sp_locker::_M_notify(): Implement.
* testsuite/20_util/shared_ptr/atomic/4.cc: New test.
* testsuite/20_util/shared_ptr/atomic/5.cc: Likewise.
* testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc: Likewise.
---
 libstdc++-v3/config/abi/pre/gnu.ver   |  12 +-
 libstdc++-v3/include/bits/shared_ptr_atomic.h | 309 ++
 libstdc++-v3/include/std/version  |   1 +
 libstdc++-v3/src/c++11/Makefile.am|   6 +
 libstdc++-v3/src/c++11/Makefile.in|   6 +
 libstdc++-v3/src/c++11/shared_ptr.cc  |  86 -
 .../testsuite/20_util/shared_ptr/atomic/4.cc  |  28 ++
 .../testsuite/20_util/shared_ptr/atomic/5.cc  |  28 ++
 .../shared_ptr/atomic/atomic_shared_ptr.cc| 159 +
 9 files changed, 632 insertions(+), 3 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/atomic/4.cc
 create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/atomic/5.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/shared_ptr/atomic/atomic_shared_ptr.cc

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index 5323c7f0604..727afd2d488 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1705,8 +1705,9 @@ GLIBCXX_3.4.21 {
 # std::ctype_base::blank
 _ZNSt10ctype_base5blankE;
 
-# std::_Sp_locker::*
-_ZNSt10_Sp_locker[CD]*;
+# std::_Sp_locker:: constructors and destructors
+_ZNSt10_Sp_lockerC*[^b];
+_ZNSt10_Sp_lockerD*;
 
 # std::notify_all_at_thread_exit
 
_ZSt25notify_all_at_thread_exitRSt18condition_variableSt11unique_lockISt5mutexE;
@@ -2397,6 +2398,13 @@ GLIBCXX_3.4.29 {
 
 } GLIBCXX_3.4.28;
 
+GLIBCXX_3.4.30 {
+  # std::_Sp_locker:: wait/notify support
+  _ZNSt10_Sp_lockerC*[b];
+  _ZNSt10_Sp_locker7_M_waitEv;
+  _ZNSt10_Sp_locker9_M_notifyEv;
+} GLIBCXX_3.4.29;
+
 # Symbols in the support library (libsupc++) have their own tag.
 CXXABI_1.3 {
 
diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h 
b/libstdc++-v3/include/bits/shared_ptr_atomic.h
index 6e94d83c46d..2aec3adac7c 100644
--- a/libstdc++-v3/include/bits/shared_ptr_atomic.h
+++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h
@@ -32,6 +32,10 @@
 
 #include 
 
+#if __cplusplus > 201703L
+# define __cpp_lib_atomic_shared_ptr 201711L
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -55,6 +59,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _Sp_locker(const void*, const void*) noexcept;
 ~_Sp_locker();
 
+#if __cpp_lib_atomic_shared_ptr
+// called only by notifiers, does not acquire a lock
+_Sp_locker(const void*, bool) noexcept;
+
+void
+_M_wait() noexcept;
+
+void
+_M_notify() noexcept;
+#endif
+
   private:
 unsigned char _M_key1;
 unsigned char _M_key2;
@@ -327,6 +342,300 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 }
   /// @}
 
+#if __cpp_lib_atomic_shared_ptr
+  template
+struct _Sp_impl
+{
+  using value_type = _Tp;
+
+  static constexpr bool
+  _M_is_always_lock_free = false;
+
+  static bool
+  _M_is_lock_free() noexcept
+  { return false; }
+
+  constexpr _Sp_impl() noexcept = default;
+  _Sp_impl(value_type __r) noexcept
+   : _M_p(move(__r))
+  { }
+
+  _Sp_impl(const _Sp_impl&) = delete;
+  void operator=(const _Sp_impl&) = delete;
+
+  value_type
+  _M_load(memory_order) const noexcept
+  {
+   _Sp_locker __lock{&_M_p};
+   return _M_p;
+  }
+
+  void
+  _M_store(value_type __r, memory_order) noexcept
+  {
+   _Sp_locker __lock{&_M_p};
+   _M_p.swap(__r); // use swap so that *__p not destroyed while lock held
+  }
+
+  value_type
+  _M_exchange(value_type __r, memory_order) noexcept
+  {
+   _Sp_locker __lock{&_M_p};
+   _M_p.swap(__r);
+   return __r;
+  }
+
+  template
+   bool
+   _M_compare_ex

[PATCH] libstdc++: Fix UB in atomic_ref/wait_notify.cc [PR101761]

2021-09-16 Thread Thomas Rodgers
From: Thomas Rodgers 

Remove UB in atomic_ref/wait_notify test.

Signed-off-by: Thomas Rodgers 

libstdc++-v3/ChangeLog:

PR libstdc++/101761
* testsuite/29_atomics/atomic_ref/wait_notify.cc (test): Use
va and vb as arguments to wait/notify, remove unused bb local.

Tested x86_64-pc-linux-gnu, committed to master.
Ok to backport to releases/gcc-11?

---
 .../testsuite/29_atomics/atomic_ref/wait_notify.cc | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
index b75e27617f7..b41d1ac0bb7 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
@@ -33,15 +33,14 @@ template
 if constexpr (std::atomic_ref::is_always_lock_free)
 {
   S aa{ va };
-  S bb{ vb };
   std::atomic_ref a{ aa };
-  a.wait(bb);
+  a.wait(vb);
   std::thread t([&]
 {
- a.store(bb);
+ a.store(vb);
  a.notify_one();
 });
-  a.wait(aa);
+  a.wait(va);
   t.join();
 }
   }
-- 
2.31.1



Re: [PATCH] libstdc++: Define macro before it is first checked

2021-09-02 Thread Thomas Rodgers via Gcc-patches
Agreed.

On Thu, Sep 2, 2021 at 10:58 AM Jonathan Wakely  wrote:

> Signed-off-by: Jonathan Wakely 
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/atomic_wait.h (_GLIBCXX_HAVE_PLATFORM_WAIT):
> Define before first attempt to check it.
>
> Tested x86_64-linux and powerpc64-linux, not committed yet.
>
> I think we need this, otherwise __platform_wait_uses_type is false
> for all T.
>
>
>


Re: [PATCH] c++: implement C++17 hardware interference size

2021-07-20 Thread Thomas Rodgers

On 2021-07-17 06:32, Jonathan Wakely via Gcc-patches wrote:


On Sat, 17 Jul 2021, 09:15 Matthias Kretz,  wrote:

On Friday, 16 July 2021 21:58:36 CEST Jonathan Wakely wrote: On Fri, 16 
Jul 2021 at 20:26, Matthias Kretz  wrote: On Friday, 16 
July 2021 18:54:30 CEST Jonathan Wakely wrote: On Fri, 16 Jul 2021 at 
16:33, Jason Merrill wrote: Adjusting them based on tuning would 
certainly simplify a

 significant


use
case, perhaps the only reasonable use.  Cases more concerned with

 ABI


stability probably shouldn't use them at all. And that would mean

 not


needing to worry about the impossible task of finding the right

 values


for
an entire architecture.
But it would be quite a significant change in behaviour if -mtune
started affecting ABI, wouldn't it?


For existing code -mtune still doesn't affect ABI.
True, because existing code isn't using the constants.


The users who write

struct keep_apart {

alignas(std::hardware_destructive_interference_size) std::atomic
cat;
alignas(std::hardware_destructive_interference_size) std::atomic
dog;

};

*want* to have different sizeof(keep_apart) depending on the CPU the

 code


is compiled for. I.e. they *ask* for getting their ABI broken.


Right, but the person who wants that and the person who chooses the
-mtune option might be different people.


Yes. But it was the intent of the person who wrote the code that the
person
compiling the code can change the data layout of keep_apart via -mtune. 
Of

course, if the one compiling doesn't want to choose because the binary
needs
to work on the widest range of systems, then there's a problem we might
want
to solve (direction of target_clones?). (Or the developer of the library
solves it by providing the ABI for all possible interference_size 
values.)



A distro might add -mtune=core2 to all package builds by default, not
expecting it to cause ABI changes. Some header in a package in the
distro might start using the constants. Now everybody who includes
that header needs to use the same -mtune option as the distro default.


If somebody writes a library with `keep_apart` in the public API/ABI 
then

you're right.

Yes, it's fine if those constants don't affect anything across module
boundaries.


That change in the behaviour and expected use of an existing option
seems scary to me. Even with a warning about using the constants
(because somebody's just going to use #pragma around their use of the
constants to disable the warning, and now the ABI impact of -mtune is
much less obvious).


There are people who say that linking TUs compiled with different 
compiler
flags is UB. In general I think that's correct, but we can make 
explicit

exceptions. Up to now -mtune wouldn't lead to UB, AFAIK, though -march
easily
does. So maybe, to keep the status quo, the constants should be tied to
-march
not -mtune?


It's much less scary in a world where the code is written and used by
the same group of people, but for something like a linux distro it
worries me.


The developer who wants his code to be included in a distro should care
about
binary distribution. If his code has an ABI issue, that's a bug he 
needs

to
fix. It's not the fault of the packager.


Yes but in practice it's the packagers who have to deal with the bug
reports, analyze the problem, and often fix the bug too. It might not be
the packager's fault but it's often their problem :-(

Apropos of nothing, I can absolutely see the use of this creeping into 
Boost at some point.


Re: [PATCH] libstdc++: Fix for deadlock in std::counting_semaphore [PR100806]

2021-06-22 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu.
Committed to master, backported to releases/gcc-11.

On Thu, Jun 17, 2021 at 9:46 AM Jonathan Wakely 
wrote:

> On Wed, 16 Jun 2021 at 20:53, Thomas Rodgers 
> wrote:
> >
> > Same as previous version except removing the copyright notice from the
> > test.
> >
> > libstdc++-v3/ChangeLog:
> > libstdc++/PR100806
> > * include/bits/semaphore_base.h
> (__atomic_semaphore::_M_release():
> > Force _M_release() to wake all waiting threads.
> > * testsuite/30_threads/semaphore/100806.cc: New test.
>
> OK for trunk and 11, thanks.
>
>
> > ---
> >  libstdc++-v3/include/bits/semaphore_base.h|  4 +-
> >  .../testsuite/30_threads/semaphore/100806.cc  | 60 +++
> >  2 files changed, 63 insertions(+), 1 deletion(-)
> >  create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
> >
> > diff --git a/libstdc++-v3/include/bits/semaphore_base.h
> b/libstdc++-v3/include/bits/semaphore_base.h
> > index 9a55978068f..c4565d7e560 100644
> > --- a/libstdc++-v3/include/bits/semaphore_base.h
> > +++ b/libstdc++-v3/include/bits/semaphore_base.h
> > @@ -256,7 +256,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >if (__update > 1)
> > __atomic_notify_address_bare(&_M_counter, true);
> >else
> > -   __atomic_notify_address_bare(&_M_counter, false);
> > +   __atomic_notify_address_bare(&_M_counter, true);
> > +// FIXME - Figure out why this does not wake a waiting thread
> > +// __atomic_notify_address_bare(&_M_counter, false);
> >  }
> >
> >private:
> > diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
> b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
> > new file mode 100644
> > index 000..938c2793be1
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
> > @@ -0,0 +1,60 @@
> > +// { dg-options "-std=gnu++2a -pthread" }
> > +// { dg-do run { target c++2a } }
> > +// { dg-require-effective-target pthread }
> > +// { dg-require-gthreads "" }
> > +// { dg-add-options libatomic }
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +std::counting_semaphore<4> semaphore{6};
> > +
> > +std::mutex mtx;
> > +std::vector results;
> > +
> > +void thread_main(size_t x)
> > +{
> > +  semaphore.acquire();
> > +  std::this_thread::sleep_for(std::chrono::milliseconds(100));
> > +  semaphore.release();
> > +  {
> > +std::ostringstream stm;
> > +stm << "Thread " << x << " finished.";
> > +std::lock_guard g{ mtx };
> > +results.push_back(stm.str());
> > +  }
> > +}
> > +
> > +int main()
> > +{
> > +
> > +constexpr auto nthreads = 10;
> > +
> > +std::vector threads(nthreads);
> > +
> > +
> > +size_t counter{0};
> > +for(auto& t : threads)
> > +{
> > +t = std::thread(thread_main, counter++);
> > +}
> > +
> > +for(auto& t : threads)
> > +  {
> > +t.join();
> > +{
> > +  std::lock_guard g{ mtx };
> > +  for (auto&& r : results)
> > +std::cout << r << '\n';
> > +  std::cout.flush();
> > +  results.clear();
> > +}
> > +  }
> > +}
> > --
> > 2.26.2
> >
>
>


[PATCH] libstdc++: Fix for deadlock in std::counting_semaphore [PR100806]

2021-06-16 Thread Thomas Rodgers
Same as previous version except removing the copyright notice from the
test.

libstdc++-v3/ChangeLog:
libstdc++/PR100806
* include/bits/semaphore_base.h (__atomic_semaphore::_M_release():
Force _M_release() to wake all waiting threads.
* testsuite/30_threads/semaphore/100806.cc: New test.
---
 libstdc++-v3/include/bits/semaphore_base.h|  4 +-
 .../testsuite/30_threads/semaphore/100806.cc  | 60 +++
 2 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/100806.cc

diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 9a55978068f..c4565d7e560 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -256,7 +256,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   if (__update > 1)
__atomic_notify_address_bare(&_M_counter, true);
   else
-   __atomic_notify_address_bare(&_M_counter, false);
+   __atomic_notify_address_bare(&_M_counter, true);
+// FIXME - Figure out why this does not wake a waiting thread
+// __atomic_notify_address_bare(&_M_counter, false);
 }
 
   private:
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
new file mode 100644
index 000..938c2793be1
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+// { dg-add-options libatomic }
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+std::counting_semaphore<4> semaphore{6};
+
+std::mutex mtx;
+std::vector results; 
+
+void thread_main(size_t x)
+{
+  semaphore.acquire();
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+  semaphore.release();
+  {
+std::ostringstream stm;
+stm << "Thread " << x << " finished.";
+std::lock_guard g{ mtx };
+results.push_back(stm.str());
+  }
+}
+
+int main()
+{
+
+constexpr auto nthreads = 10;
+
+std::vector threads(nthreads);
+
+
+size_t counter{0};
+for(auto& t : threads)
+{
+t = std::thread(thread_main, counter++);
+}
+
+for(auto& t : threads)
+  {
+t.join();
+{
+  std::lock_guard g{ mtx };
+  for (auto&& r : results)
+std::cout << r << '\n';
+  std::cout.flush();
+  results.clear();
+}
+  }
+}
-- 
2.26.2



[PATCH] libstdc++: Fix for deadlock in std::counting_semaphore [PR100806]

2021-06-16 Thread Thomas Rodgers
This is an 'interim' fix. For now it forces all waiting threads to wake
on _M_release(). This isn't exactly efficient but resolves the issue
in the immediate term.

libstdc++-v3/ChangeLog:
libstdc++/PR100806
* include/bits/semaphore_base.h (__atomic_semaphore::_M_release():
Force _M_release() to wake all waiting threads.
* testsuite/30_threads/semaphore/100806.cc: New test.
---
 libstdc++-v3/include/bits/semaphore_base.h|  4 +-
 .../testsuite/30_threads/semaphore/100806.cc  | 77 +++
 2 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/100806.cc

diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 9a55978068f..c4565d7e560 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -256,7 +256,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   if (__update > 1)
__atomic_notify_address_bare(&_M_counter, true);
   else
-   __atomic_notify_address_bare(&_M_counter, false);
+   __atomic_notify_address_bare(&_M_counter, true);
+// FIXME - Figure out why this does not wake a waiting thread
+// __atomic_notify_address_bare(&_M_counter, false);
 }
 
   private:
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
new file mode 100644
index 000..483779caf0a
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
@@ -0,0 +1,77 @@
+// 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
+// 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 -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+// { dg-add-options libatomic }
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+std::counting_semaphore<4> semaphore{6};
+
+std::mutex mtx;
+std::vector results; 
+
+void thread_main(size_t x)
+{
+  semaphore.acquire();
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+  semaphore.release();
+  {
+std::ostringstream stm;
+stm << "Thread " << x << " finished.";
+std::lock_guard g{ mtx };
+results.push_back(stm.str());
+  }
+}
+
+int main()
+{
+
+constexpr auto nthreads = 10;
+
+std::vector threads(nthreads);
+
+
+size_t counter{0};
+for(auto& t : threads)
+{
+t = std::thread(thread_main, counter++);
+}
+
+for(auto& t : threads)
+  {
+t.join();
+{
+  std::lock_guard g{ mtx };
+  for (auto&& r : results)
+std::cout << r << '\n';
+  std::cout.flush();
+  results.clear();
+}
+  }
+}
-- 
2.26.2



[committed] libstdc++: Only support atomic_ref::wait tests which are always lockfree

2021-06-09 Thread Thomas Rodgers
Fixes a regression on arm32 targets.

libstdc++/ChangeLog:
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Guard
test logic with constexpr check for is_always_lock_free.

As discussed on IRC.

Tested x86_64-pc-linux-gnu, committed to master, backported to
releases/gcc-11.
---
 .../29_atomics/atomic_ref/wait_notify.cc  | 23 +++
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
index 2500dddf884..c21c3a11ab5 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
@@ -30,17 +30,20 @@ template
   void
   test (S va, S vb)
   {
-S aa{ va };
-S bb{ vb };
-std::atomic_ref a{ aa };
-a.wait(bb);
-std::thread t([&]
+if constexpr (std::atomic_ref::is_always_lock_free)
   {
-a.store(bb);
-a.notify_one();
-  });
-a.wait(aa);
-t.join();
+S aa{ va };
+S bb{ vb };
+std::atomic_ref a{ aa };
+a.wait(bb);
+std::thread t([&]
+  {
+a.store(bb);
+a.notify_one();
+  });
+a.wait(aa);
+t.join();
+  }
   }
 
 int
-- 
2.26.2



Re: [PATCH] Document that -fno-trampolines is for Ada only [PR100735]

2021-06-09 Thread Thomas Rodgers

On 2021-06-09 09:23, Jeff Law via Gcc-patches wrote:


On 5/25/2021 2:23 PM, Paul Eggert wrote:


The GCC manual's documentation of -fno-trampolines was apparently
written from an Ada point of view. However, when I read it I
understandably mistook it to say that -fno-trampolines also works for
C, C++, etc. It doesn't: it is silently ignored for these languages,
and I assume for any language other than Ada.

This confusion caused me to go in the wrong direction in a Gnulib
dicussion, as I mistakenly thought that entire C apps with nested
functions could be compiled with -fno-trampolines and then use nested
C functions in stack overflow handlers where the alternate stack
is allocated via malloc. I was wrong, as this won't work on common
platforms like x86-64 where malloc yields non-executable storage.

gcc/
* doc/invoke.texi (Code Gen Options):
* doc/tm.texi.in (Trampolines):
Document that -fno-trampolines and -ftrampolines work
only with Ada.
So Martin Uecker probably has the most state on this.  IIRC when we 
last discussed -fno-trampolines the belief was that it could be easily 
made to work independent of the language, but that it was ultimately an 
ABI change.   That ultimately derailed plans to use -fno-trampolines 
for other languages in the immediate term.


The patch is fine, I just wanted to give you a bit of background on the 
state.   I'll go ahead and commit it for you.


Jeff


This patch (commit 4a0c4eaea32) is currently breaking the compilation 
with "Verify that you have permission to grant a GFDL license for all". 
It appears that tm.texi and tm.texi.in are out of sync.


Re: [PATCH] libstdc++: Fix Wrong param type in :atomic_ref<_Tp*>::wait [PR100889]

2021-06-09 Thread Thomas Rodgers via Gcc-patches
Pretty sure I know this is, I'll work on a fix today.

On Wed, Jun 9, 2021 at 7:30 AM Christophe Lyon 
wrote:

> Hi,
>
>
> On Wed, 9 Jun 2021 at 01:05, Thomas Rodgers via Gcc-patches
>  wrote:
> >
> > Tested x86_64-pc-linux-gnu, committed to master, backported to
> > releases/gcc-11.
> >
> > On Tue, Jun 8, 2021 at 8:44 AM Jonathan Wakely 
> wrote:
> >
> > > On Tue, 8 Jun 2021 at 01:29, Thomas Rodgers wrote:
> > >
> > >> This time without the repeatred [PR] in the subject line.
> > >>
> > >> Fixes libstdc++/100889
> > >>
> > >
> > > This should be part of the ChangeLog entry instead, preceded by PR so
> it
> > > updates bugzilla, i.e.
> > >
> > >
> > >
> > >> libstdc++-v3/ChangeLog:
> > >>
> > >
> > > PR libstdc++/100889
> > >
> > >
> > >> * include/bits/atomic_base.h (atomic_ref<_Tp*>::wait):
> > >> Change parameter type from _Tp to _Tp*.
> > >> * testsuite/29_atomics/atomic_ref/wait_notify.cc: Extend
> > >> coverage of types tested.
> > >>
> > >
> > >
> > > OK for trunk and gcc-11 with that change, thanks.
> > >
> > >
>
> This is causing a regression on old arm targets:
> --target arm-none-linux-gnueabi
> RUNTESTFLAGS: -march=armv5t
>
> FAIL: 29_atomics/atomic_ref/wait_notify.cc (test for excess errors)
> Excess errors:
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-linux-gnueabi/bin/ld:
> /ccaaHfBz.o: in function `void
> std::__atomic_impl::store(double*,
> std::remove_volatile::type, std::memory_order)':
>
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_base.h:971:
> undefined reference to `__atomic_store_8'
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-linux-gnueabi/bin/ld:
> /ccaaHfBz.o: in function `std::remove_volatile::type
> std::__atomic_impl::load(double const*, std::memory_order)':
>
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_base.h:979:
> undefined reference to `__atomic_load_8'
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-linux-gnueabi/bin/ld:
>
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_base.h:979:
> undefined reference to `__atomic_load_8'
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-linux-gnueabi/bin/ld:
>
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_base.h:979:
> undefined reference to `__atomic_load_8'
> collect2: error: ld returned 1 exit status
>
> Can you check?
>
> Thanks
>
>


Re: [PATCH] [libstdc++] Remove unused hasher instance.

2021-06-08 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu, committed to master, backported to
releases/gcc-11.

On Fri, Jun 4, 2021 at 1:30 PM Jonathan Wakely  wrote:

>
>
> On Fri, 4 Jun 2021 at 20:54, Thomas Rodgers wrote:
>
>> This is a remnant of poorly executed refactoring.
>>
>
> OK for trunk and gcc-11, thanks.
>
>
>
>> libstdc++-v3/ChangeLog:
>>
>> * include/std/barrier (__tree_barrier::_M_arrive): Remove
>> unnecessary hasher instantiation.
>> ---
>>  libstdc++-v3/include/std/barrier | 1 -
>>  1 file changed, 1 deletion(-)
>>
>> diff --git a/libstdc++-v3/include/std/barrier
>> b/libstdc++-v3/include/std/barrier
>> index fd61fb4f9da..4210e30d1ce 100644
>> --- a/libstdc++-v3/include/std/barrier
>> +++ b/libstdc++-v3/include/std/barrier
>> @@ -103,7 +103,6 @@ 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 __hasher;
>> __current %= ((_M_expected + 1) >> 1);
>>
>> for (int __round = 0; ; ++__round)
>> --
>> 2.26.2
>>
>>


Re: [PATCH] libstdc++: Fix Wrong param type in :atomic_ref<_Tp*>::wait [PR100889]

2021-06-08 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu, committed to master, backported to
releases/gcc-11.

On Tue, Jun 8, 2021 at 8:44 AM Jonathan Wakely  wrote:

> On Tue, 8 Jun 2021 at 01:29, Thomas Rodgers wrote:
>
>> This time without the repeatred [PR] in the subject line.
>>
>> Fixes libstdc++/100889
>>
>
> This should be part of the ChangeLog entry instead, preceded by PR so it
> updates bugzilla, i.e.
>
>
>
>> libstdc++-v3/ChangeLog:
>>
>
> PR libstdc++/100889
>
>
>> * include/bits/atomic_base.h (atomic_ref<_Tp*>::wait):
>> Change parameter type from _Tp to _Tp*.
>> * testsuite/29_atomics/atomic_ref/wait_notify.cc: Extend
>> coverage of types tested.
>>
>
>
> OK for trunk and gcc-11 with that change, thanks.
>
>
>
>


[PATCH] libstdc++: Fix Wrong param type in :atomic_ref<_Tp*>::wait [PR100889]

2021-06-07 Thread Thomas Rodgers
This time without the repeatred [PR] in the subject line.

Fixes libstdc++/100889

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (atomic_ref<_Tp*>::wait):
Change parameter type from _Tp to _Tp*.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Extend
coverage of types tested.
---
 libstdc++-v3/include/bits/atomic_base.h   |  2 +-
 .../29_atomics/atomic_ref/wait_notify.cc  | 38 ---
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 029b8ad65a9..20cf1343c58 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1870,7 +1870,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
-  wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+  wait(_Tp* __old, memory_order __m = memory_order_seq_cst) const noexcept
   { __atomic_impl::wait(_M_ptr, __old, __m); }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
index 2fd31304222..2500dddf884 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
@@ -26,22 +26,34 @@
 
 #include 
 
+template
+  void
+  test (S va, S vb)
+  {
+S aa{ va };
+S bb{ vb };
+std::atomic_ref a{ aa };
+a.wait(bb);
+std::thread t([&]
+  {
+a.store(bb);
+a.notify_one();
+  });
+a.wait(aa);
+t.join();
+  }
+
 int
 main ()
 {
+  test(0, 42);
+  test(0, 42);
+  test(0u, 42u);
+  test(0.0f, 42.0f);
+  test(0.0, 42.0);
+  test(nullptr, reinterpret_cast(42));
+
   struct S{ int i; };
-  S aa{ 0 };
-  S bb{ 42 };
-
-  std::atomic_ref a{ aa };
-  VERIFY( a.load().i == aa.i );
-  a.wait(bb);
-  std::thread t([&]
-{
-  a.store(bb);
-  a.notify_one();
-});
-  a.wait(aa);
-  t.join();
+  test(S{ 0 }, S{ 42 });
   return 0;
 }
-- 
2.26.2



[PATCH] libstdc++: Fix Wrong param type in :atomic_ref<_Tp*>::wait [PR100889] [PR100889]

2021-06-07 Thread Thomas Rodgers
Fixes libstdc++/100889

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (atomic_ref<_Tp*>::wait):
Change parameter type from _Tp to _Tp*.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Extend
coverage of types tested.
---
 libstdc++-v3/include/bits/atomic_base.h   |  2 +-
 .../29_atomics/atomic_ref/wait_notify.cc  | 38 ---
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 029b8ad65a9..20cf1343c58 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1870,7 +1870,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
-  wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+  wait(_Tp* __old, memory_order __m = memory_order_seq_cst) const noexcept
   { __atomic_impl::wait(_M_ptr, __old, __m); }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
index 2fd31304222..2500dddf884 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/wait_notify.cc
@@ -26,22 +26,34 @@
 
 #include 
 
+template
+  void
+  test (S va, S vb)
+  {
+S aa{ va };
+S bb{ vb };
+std::atomic_ref a{ aa };
+a.wait(bb);
+std::thread t([&]
+  {
+a.store(bb);
+a.notify_one();
+  });
+a.wait(aa);
+t.join();
+  }
+
 int
 main ()
 {
+  test(0, 42);
+  test(0, 42);
+  test(0u, 42u);
+  test(0.0f, 42.0f);
+  test(0.0, 42.0);
+  test(nullptr, reinterpret_cast(42));
+
   struct S{ int i; };
-  S aa{ 0 };
-  S bb{ 42 };
-
-  std::atomic_ref a{ aa };
-  VERIFY( a.load().i == aa.i );
-  a.wait(bb);
-  std::thread t([&]
-{
-  a.store(bb);
-  a.notify_one();
-});
-  a.wait(aa);
-  t.join();
+  test(S{ 0 }, S{ 42 });
   return 0;
 }
-- 
2.26.2



[PATCH] [libstdc++] Fix Wrong param type in :atomic_ref<_Tp*>::wait [PR100889]

2021-06-04 Thread Thomas Rodgers
Fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100889

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (atomic_ref<_Tp*>::wait):
Change parameter type from _Tp to _Tp*.
* testsuite/29_atomics/atomic_ref/100889.cc: New test.
---
 libstdc++-v3/include/bits/atomic_base.h   |  2 +-
 .../testsuite/29_atomics/atomic_ref/100889.cc | 29 +++
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic_ref/100889.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 029b8ad65a9..20cf1343c58 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1870,7 +1870,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
-  wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+  wait(_Tp* __old, memory_order __m = memory_order_seq_cst) const noexcept
   { __atomic_impl::wait(_M_ptr, __old, __m); }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/100889.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_ref/100889.cc
new file mode 100644
index 000..1ea58cb6947
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/100889.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019-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
+// 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 
+
+void
+test01()
+{
+  void* p;
+  std::atomic_ref a(p);
+  a.store(nullptr);
+}
-- 
2.26.2



[PATCH] PR libstdc++/100889: Fix wrong param type in atomic_ref<_Tp*>::wait

2021-06-04 Thread Thomas Rodgers
Fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100889

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (atomic_ref<_Tp*>::wait):
Change parameter type from _Tp to _Tp*.
* testsuite/29_atomics/atomic_ref/deduction.cc: Add
reproducer case from PR.
---
 libstdc++-v3/include/bits/atomic_base.h   | 2 +-
 libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 029b8ad65a9..20cf1343c58 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1870,7 +1870,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
-  wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
+  wait(_Tp* __old, memory_order __m = memory_order_seq_cst) const noexcept
   { __atomic_impl::wait(_M_ptr, __old, __m); }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc
index 86395b0c2b0..ed46b430f7c 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc
@@ -34,6 +34,7 @@ test01()
   int* p = 
   std::atomic_ref a2(p);
   static_assert(std::is_same_v>);
+  a2.store(nullptr);
 
   struct X { } x;
   std::atomic_ref a3(x);
-- 
2.26.2



[PATCH] [libstdc++] Cleanup atomic timed wait implementation

2021-06-04 Thread Thomas Rodgers
This cleans up the implementation of atomic_timed_wait.h and fixes the
accidental pessimization of spinning after waiting in
__timed_waiter_pool::_M_do_wait_until.

libstdc++-v3/ChangeLog:

* include/bits/atomic_timed_wait.h (__wait_clock_t): Define
conditionally.
(__cond_wait_until_impl): Define conditionally.
(__cond_wait_until): Define conditionally. Simplify clock
type detection/conversion.
(__timed_waiter_pool::_M_do_wait_until): Move the spin above
the wait.

---
 libstdc++-v3/include/bits/atomic_timed_wait.h | 26 ++-
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h 
b/libstdc++-v3/include/bits/atomic_timed_wait.h
index ec7ff51cdbc..19386e5806a 100644
--- a/libstdc++-v3/include/bits/atomic_timed_wait.h
+++ b/libstdc++-v3/include/bits/atomic_timed_wait.h
@@ -51,7 +51,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   namespace __detail
   {
+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX || _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
 using __wait_clock_t = chrono::steady_clock;
+#else
+using __wait_clock_t = chrono::system_clock;
+#endif
 
 template
   __wait_clock_t::time_point
@@ -133,11 +137,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
  }
   }
-#else
+// #elsif 
 // define _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT and implement 
__platform_wait_until()
 // if there is a more efficient primitive supported by the platform
 // (e.g. __ulock_wait())which is better than pthread_cond_clockwait
-#endif // ! PLATFORM_TIMED_WAIT
+#else
+// Use wait on condition variable
 
 // Returns true if wait ended before timeout.
 // _Clock must be either steady_clock or system_clock.
@@ -173,12 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __cond_wait_until(__condvar& __cv, mutex& __mx,
  const chrono::time_point<_Clock, _Dur>& __atime)
   {
-#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
-   if constexpr (is_same_v<_Clock, chrono::steady_clock>)
- return __detail::__cond_wait_until_impl(__cv, __mx, __atime);
-   else
-#endif
-   if constexpr (is_same_v<_Clock, chrono::system_clock>)
+   if constexpr (is_same_v<__wait_clock_t, _Clock>)
  return __detail::__cond_wait_until_impl(__cv, __mx, __atime);
else
  {
@@ -194,6 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
  }
   }
+#endif // ! PLATFORM_TIMED_WAIT
 
 struct __timed_waiter_pool : __waiter_pool_base
 {
@@ -300,17 +301,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  const chrono::time_point<_Clock, _Dur>&
  __atime) noexcept
  {
+
for (auto __now = _Clock::now(); __now < __atime;
  __now = _Clock::now())
  {
+   if (__base_type::_M_do_spin(__pred, __val,
+  __timed_backoff_spin_policy(__atime, __now)))
+ return true;
+
if (__base_type::_M_w._M_do_wait_until(
  __base_type::_M_addr, __val, __atime)
&& __pred())
  return true;
-
-   if (__base_type::_M_do_spin(__pred, __val,
-  __timed_backoff_spin_policy(__atime, __now)))
- return true;
  }
return false;
  }
-- 
2.26.2



[PATCH] [libstdc++] Remove unused hasher instance.

2021-06-04 Thread Thomas Rodgers
This is a remnant of poorly executed refactoring.

libstdc++-v3/ChangeLog:

* include/std/barrier (__tree_barrier::_M_arrive): Remove
unnecessary hasher instantiation.
---
 libstdc++-v3/include/std/barrier | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
index fd61fb4f9da..4210e30d1ce 100644
--- a/libstdc++-v3/include/std/barrier
+++ b/libstdc++-v3/include/std/barrier
@@ -103,7 +103,6 @@ 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 __hasher;
__current %= ((_M_expected + 1) >> 1);
 
for (int __round = 0; ; ++__round)
-- 
2.26.2



Re: [PATCH] libstdc++: Fix wrong thread waking on notify [PR100334]

2021-05-17 Thread Thomas Rodgers

On 2021-05-17 09:43, Jonathan Wakely wrote:

On 14/05/21 18:09 +0100, Jonathan Wakely wrote: On 13/05/21 18:54 
-0700, Thomas Rodgers wrote: From: Thomas Rodgers 



Please ignore the previous patch. This one removes the need to carry 
any

extra state in the case of a 'laundered' atomic wait.

libstdc++/ChangeLog:
* include/bits/atomic_wait.h (__waiter::_M_do_wait_v): loop
until value change observed.
(__waiter_base::_M_laundered): New member function.
(__watier_base::_M_notify): Check _M_laundered() to determine
whether to wake one or all.
(__detail::__atomic_compare): Return true if call to
__builtin_memcmp() == 0.
(__waiter_base::_S_do_spin_v): Adjust predicate.
* testsuite/29_atomics/atomic/wait_notify/100334.cc: New
test.
---
libstdc++-v3/include/bits/atomic_wait.h   | 28 --
.../29_atomics/atomic/wait_notify/100334.cc   | 94 +++
2 files changed, 114 insertions(+), 8 deletions(-)
create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc


diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h

index 984ed70f16c..07bb744d822 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -181,11 +181,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}

+// return true if equal
template
bool __atomic_compare(const _Tp& __a, const _Tp& __b)
{
// TODO make this do the correct padding bit ignoring comparison
-return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) != 0;
+return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) == 0;
}

struct __waiter_pool_base
@@ -300,14 +301,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit __waiter_base(const _Up* __addr) noexcept
: _M_w(_S_for(__addr))
, _M_addr(_S_wait_addr(__addr, &_M_w._M_ver))
-  {
-  }
+  { }
+
+bool
+_M_laundered() const
+{ return _M_addr == &_M_w._M_ver; }

void
_M_notify(bool __all, bool __bare = false)
{
-  if (_M_addr == &_M_w._M_ver)
-__atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
+  if (_M_laundered())
+{
+  __atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
Please mention this increment in the changelog.


Ugh, sorry, I seem to have forgotten how to read a diff.


OK for trunk and gcc-11 with that change, thanks.


OK to push, no changes needed.

Tested x86_64-pc-linux-gnu, committed to master and cherry-picked to 
releases/gcc-11.


[PATCH] libstdc++: Fix wrong thread waking on notify [PR100334]

2021-05-13 Thread Thomas Rodgers
From: Thomas Rodgers 

Please ignore the previous patch. This one removes the need to carry any
extra state in the case of a 'laundered' atomic wait.

libstdc++/ChangeLog:
* include/bits/atomic_wait.h (__waiter::_M_do_wait_v): loop
until value change observed.
(__waiter_base::_M_laundered): New member function.
(__watier_base::_M_notify): Check _M_laundered() to determine
whether to wake one or all.
(__detail::__atomic_compare): Return true if call to
__builtin_memcmp() == 0.
(__waiter_base::_S_do_spin_v): Adjust predicate.
* testsuite/29_atomics/atomic/wait_notify/100334.cc: New
test.
---
 libstdc++-v3/include/bits/atomic_wait.h   | 28 --
 .../29_atomics/atomic/wait_notify/100334.cc   | 94 +++
 2 files changed, 114 insertions(+), 8 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc

diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 984ed70f16c..07bb744d822 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -181,11 +181,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
   }
 
+// return true if equal
 template
   bool __atomic_compare(const _Tp& __a, const _Tp& __b)
   {
// TODO make this do the correct padding bit ignoring comparison
-   return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) != 0;
+   return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) == 0;
   }
 
 struct __waiter_pool_base
@@ -300,14 +301,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  explicit __waiter_base(const _Up* __addr) noexcept
: _M_w(_S_for(__addr))
, _M_addr(_S_wait_addr(__addr, &_M_w._M_ver))
- {
- }
+ { }
+
+   bool
+   _M_laundered() const
+   { return _M_addr == &_M_w._M_ver; }
 
void
_M_notify(bool __all, bool __bare = false)
{
- if (_M_addr == &_M_w._M_ver)
-   __atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
+ if (_M_laundered())
+   {
+ __atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
+ __all = true;
+   }
  _M_w._M_notify(_M_addr, __all, __bare);
}
 
@@ -320,7 +327,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _Spin __spin = _Spin{ })
  {
auto const __pred = [=]
- { return __detail::__atomic_compare(__old, __vfn()); };
+ { return !__detail::__atomic_compare(__old, __vfn()); };
 
if constexpr (__platform_wait_uses_type<_Up>)
  {
@@ -387,7 +394,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__platform_wait_t __val;
if (__base_type::_M_do_spin_v(__old, __vfn, __val))
  return;
-   __base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
+
+   do
+ {
+   __base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
+ }
+   while (__detail::__atomic_compare(__old, __vfn()));
  }
 
template
@@ -452,7 +464,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 __atomic_notify_address(const _Tp* __addr, bool __all) noexcept
 {
   __detail::__bare_wait __w(__addr);
-  __w._M_notify(__all, true);
+  __w._M_notify(__all);
 }
 
   // This call is to be used by atomic types which track contention externally
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc
new file mode 100644
index 000..3e63eca42fa
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc
@@ -0,0 +1,94 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-add-options libatomic }
+
+// Copyright (C) 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include 
+#include 
+
+#include 
+
+template 
+struct atomics_sharing_same_waiter
+{
+   std::atomic tmp[49 * 4] = {};
+   std::atomic* a[4] 

[PATCH] libstdc++: Fix wrong thread waking on notify [PR100334]

2021-05-13 Thread Thomas Rodgers
From: Thomas Rodgers 

libstdc++/ChangeLog:
* include/bits/atomic_wait.h (__waiter::_M_do_wait_v): loop
until value change observed.
(__waiter_base::_M_a): Renamed member from _M_addr, changed
type to uintptr_t.
(__waiter_base::_S_wait_addr): Change return type to uinptr_t,
sets LSB if 'laundering' the wait address 
(__waiter_base::_M_addr): New member, returns wait address,
masking off LSB of _M_a.
(__waiter_base::_M_laundered): New member, returns true if
LSB of _M_a is set.
(__waiter_base::_M_notify): Call _M_addr(), check _M_laundered()
to determine whether to wake one or all.
(__waiter_base::_M_do_spin_v): Call _M_addr().
(__waiter_base::_M_do_spin): Likewise.
(__waiter::_M_do_wait_v): Likewise.
(__waiter::_M_do_wait): Likewise.
(__detail::__atomic_compare): Return true if call to
__builtin_memcmp() == 0.
(__waiter_base::_S_do_spin_v): Adjust predicate.
* testsuite/29_atomics/atomic/wait_notify/100334.cc: New
test.
* include/bits/atomic_timed_wait.h
(__timed_waiter::_M_do_wait_until_v): Call _M_addr().
(__timed_waiter::_M_do_wait_until): Likewise.
---
 libstdc++-v3/include/bits/atomic_timed_wait.h |  6 +-
 libstdc++-v3/include/bits/atomic_wait.h   | 49 ++
 .../29_atomics/atomic/wait_notify/100334.cc   | 94 +++
 3 files changed, 129 insertions(+), 20 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc

diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h 
b/libstdc++-v3/include/bits/atomic_timed_wait.h
index ec7ff51cdbc..5fe64fa2219 100644
--- a/libstdc++-v3/include/bits/atomic_timed_wait.h
+++ b/libstdc++-v3/include/bits/atomic_timed_wait.h
@@ -289,7 +289,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (_M_do_spin(__old, std::move(__vfn), __val,
   __timed_backoff_spin_policy(__atime)))
  return true;
-   return __base_type::_M_w._M_do_wait_until(__base_type::_M_addr, 
__val, __atime);
+   return __base_type::_M_w._M_do_wait_until(__base_type::_M_addr(), 
__val, __atime);
  }
 
// returns true if wait ended before timeout
@@ -304,7 +304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  __now = _Clock::now())
  {
if (__base_type::_M_w._M_do_wait_until(
- __base_type::_M_addr, __val, __atime)
+ __base_type::_M_addr(), __val, __atime)
&& __pred())
  return true;
 
@@ -347,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __reltime = chrono::ceil<__wait_clock_t::duration>(__rtime);
 
return __base_type::_M_w._M_do_wait_until(
- __base_type::_M_addr,
+ __base_type::_M_addr(),
  __val,
  chrono::steady_clock::now() + 
__reltime);
  }
diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 984ed70f16c..06ebcc7bce3 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -181,11 +181,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
   }
 
+// return true if equal
 template
   bool __atomic_compare(const _Tp& __a, const _Tp& __b)
   {
// TODO make this do the correct padding bit ignoring comparison
-   return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) != 0;
+   return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) == 0;
   }
 
 struct __waiter_pool_base
@@ -276,16 +277,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __waiter_type = _Tp;
 
__waiter_type& _M_w;
-   __platform_wait_t* _M_addr;
+   uintptr_t  _M_a;
 
template
- static __platform_wait_t*
+ static uintptr_t
  _S_wait_addr(const _Up* __a, __platform_wait_t* __b)
  {
if constexpr (__platform_wait_uses_type<_Up>)
- return 
reinterpret_cast<__platform_wait_t*>(const_cast<_Up*>(__a));
+ return reinterpret_cast(const_cast<_Up*>(__a));
else
- return __b;
+ return reinterpret_cast(__b) | 0x1;
  }
 
static __waiter_type&
@@ -299,16 +300,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template
  explicit __waiter_base(const _Up* __addr) noexcept
: _M_w(_S_for(__addr))
-   , _M_addr(_S_wait_addr(__addr, &_M_w._M_ver))
- {
- }
+   , _M_a(_S_wait_addr(__addr, &_M_w._M_ver))
+ { }
+
+   __platform_wait_t*
+   _M_addr() const noexcept
+   { return reinterpret_cast<__platform_wait_t*>(_M_a &am

[PATCH] libstdc++: Fix wrong thread waking on notify [PR100334]

2021-05-03 Thread Thomas Rodgers
From: Thomas Rodgers 

This should also be backported to gcc-11

libstdc++/ChangeLog:
* include/bits/atomic_wait.h (__waiter::_M_do_wait_v): loop
until observe value change.
(__waiter_base::_M_laundered): New member.
(__watier_base::_M_notify): Check _M_laundered to determine
whether to wake one or all.
(__detail::__atomic_compare): Do not implicitly convert
result of __buildtin_memcpmp to bool,
(__waiter_base::_S_do_spin_v): Adjust predicate.
* testsuite/29_atomics/atomic/wait_notify/100334.cc: New
test.
---
 libstdc++-v3/include/bits/atomic_wait.h   | 20 +++-
 .../29_atomics/atomic/wait_notify/100334.cc   | 94 +++
 2 files changed, 109 insertions(+), 5 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc

diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 984ed70f16c..528e4868410 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -181,11 +181,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
   }
 
+// return true if equal
 template
   bool __atomic_compare(const _Tp& __a, const _Tp& __b)
   {
// TODO make this do the correct padding bit ignoring comparison
-   return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) != 0;
+   return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) == 0;
   }
 
 struct __waiter_pool_base
@@ -277,6 +278,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
__waiter_type& _M_w;
__platform_wait_t* _M_addr;
+   bool _M_laundered;
 
template
  static __platform_wait_t*
@@ -300,6 +302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  explicit __waiter_base(const _Up* __addr) noexcept
: _M_w(_S_for(__addr))
, _M_addr(_S_wait_addr(__addr, &_M_w._M_ver))
+   , _M_laundered(!__platform_wait_uses_type<_Up>)
  {
  }
 
@@ -308,7 +311,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  if (_M_addr == &_M_w._M_ver)
__atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
- _M_w._M_notify(_M_addr, __all, __bare);
+ _M_w._M_notify(_M_addr,
+(_M_laundered ? true : __all),
+__bare);
}
 
template)
  {
@@ -387,7 +392,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__platform_wait_t __val;
if (__base_type::_M_do_spin_v(__old, __vfn, __val))
  return;
-   __base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
+
+   do
+ {
+   __base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
+ }
+   while (__detail::__atomic_compare(__old, __vfn()));
  }
 
template
@@ -452,7 +462,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 __atomic_notify_address(const _Tp* __addr, bool __all) noexcept
 {
   __detail::__bare_wait __w(__addr);
-  __w._M_notify(__all, true);
+  __w._M_notify(__all);
 }
 
   // This call is to be used by atomic types which track contention externally
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc
new file mode 100644
index 000..3e63eca42fa
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc
@@ -0,0 +1,94 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-require-gthreads "" }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-add-options libatomic }
+
+// Copyright (C) 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include 
+#include 
+
+#include 
+
+template 
+struct atomics_sharing_same_waiter
+{
+   std::atomic tmp[49 * 4] = {};
+   std::atomic* a[4] = {
+  { [0] },
+  { [16 * 4] },
+  { [32 * 4] },
+  { [48 * 4] }
+   };
+};
+
+constexpr unsigned key(void * a)
+{
+  constexpr uintptr_t ct = 16;
+  return (uintptr_t(a) >> 2) % ct;
+}
+
+int
+main()
+{
+  // all atomic share the same waiter
+//  atomics_sharing_same_waiter atomics;
+ 

Re: [PATCH] [libstdc++] Fix "bare" notifications dropped by waiters check

2021-04-22 Thread Thomas Rodgers

On 2021-04-22 02:23, Jonathan Wakely wrote:


On 21/04/21 18:29 -0700, Thomas Rodgers wrote:


From: Thomas Rodgers 

NOTE - This patch also needs to be backported to gcc-11 in order for
semaphore release() to work correctly on non-futex platforms.

Tested sparc-sun-solaris2.11

For types that track whether or not there extant waiters (e.g.
semaphore) internally, the __atomic_notify_address_bare() call was
introduced to avoid the overhead of loading the atomic count of
waiters. For platforms that don't have Futex, however, there was
still a check for waiters, and seeing that there are none (because
in the bare case, the count is not incremented), the notification
is dropped. This commit addresses that case.

libstdc++-v3/ChangeLog:
* include/bits/atomic_wait.h: Always notify waiters in the
in the case of 'bare' address notification.


Repeated text: "in the in the"


---
libstdc++-v3/include/bits/atomic_wait.h | 12 ++--
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h

index 0ac5575190c..984ed70f16c 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -226,9 +226,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}

void
-  _M_notify(const __platform_wait_t* __addr, bool __all) noexcept
+  _M_notify(const __platform_wait_t* __addr, bool __all, bool 
__bare) noexcept

{
-if (!_M_waiting())
+if (!(__bare || _M_waiting()))


Maybe it's just me, but I would find (!__base && !__waiting) to be a
clearer expression of the logic here.

i.e. "return if the wait is not bare and there are no waiters"
rather than "return if the wait is not either bare or has waiters".
The latter makes me take a second to grok.



As discussed on IRC, I went back and forth on this a couple of times and 
neither option seemed particularly great to me. I started down the path 
of propagating the std::true_type/std::false_type bits that the RAII 
wrapper type knows about and making this a compile time choice, but felt 
the change was too big to make this late in the release cycle. I will 
revisit this for stage1 (though ideally all of this will be moved into 
the .so for GCC12 and partially rewritten as part of that process 
anyway).



The patch is OK either way though, with the ChangeLog typo fix.


return;

#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
@@ -304,11 +304,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}

void
-_M_notify(bool __all)
+_M_notify(bool __all, bool __bare = false)
{
if (_M_addr == &_M_w._M_ver)
__atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
-  _M_w._M_notify(_M_addr, __all);
+  _M_w._M_notify(_M_addr, __all, __bare);
}

template// This call is to be used by atomic types which track contention 
externally

@@ -464,7 +464,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__detail::__platform_notify(__addr, __all);
#else
__detail::__bare_wait __w(__addr);
-__w._M_notify(__all);
+__w._M_notify(__all, true);
#endif
}
_GLIBCXX_END_NAMESPACE_VERSION
-- 2.30.2


Tested sparc-sun-solaris2.11.
Committed to master, backported to release/gcc-11.


Re: [PATCH] [libstdc++] Fix test timeout in stop_calback/destroy.cc

2021-04-21 Thread Thomas Rodgers

On 2021-04-21 14:22, Jakub Jelinek wrote:

On Wed, Apr 21, 2021 at 07:23:30PM +0100, Jonathan Wakely via 
Gcc-patches wrote:



We should do this for gcc-11 too if an RM approves it, since acquire()
is currently broken.


Ok, but please commit it soon, we'll need to do a RC2 tomorrow or on 
Friday

and then ideally no changes at all.

Jakub


Backported to releases/gcc-11

Note, there is a second patch that I just submitted that addresses a 
related issue with counting_semaphore::release() on non-Futex platforms 
that needs to also be back ported to gcc-11, otherwise release() is 
broken on not-linux platforms.


[PATCH] [libstdc++] Fix "bare" notifications dropped by waiters check

2021-04-21 Thread Thomas Rodgers
From: Thomas Rodgers 

NOTE - This patch also needs to be backported to gcc-11 in order for
semaphore release() to work correctly on non-futex platforms.

Tested sparc-sun-solaris2.11

For types that track whether or not there extant waiters (e.g.
semaphore) internally, the __atomic_notify_address_bare() call was
introduced to avoid the overhead of loading the atomic count of
waiters. For platforms that don't have Futex, however, there was
still a check for waiters, and seeing that there are none (because
in the bare case, the count is not incremented), the notification
is dropped. This commit addresses that case.

libstdc++-v3/ChangeLog:
* include/bits/atomic_wait.h: Always notify waiters in the
in the case of 'bare' address notification.
---
 libstdc++-v3/include/bits/atomic_wait.h | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 0ac5575190c..984ed70f16c 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -226,9 +226,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
   void
-  _M_notify(const __platform_wait_t* __addr, bool __all) noexcept
+  _M_notify(const __platform_wait_t* __addr, bool __all, bool __bare) 
noexcept
   {
-   if (!_M_waiting())
+   if (!(__bare || _M_waiting()))
  return;
 
 #ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
@@ -304,11 +304,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  }
 
void
-   _M_notify(bool __all)
+   _M_notify(bool __all, bool __bare = false)
{
  if (_M_addr == &_M_w._M_ver)
__atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL);
- _M_w._M_notify(_M_addr, __all);
+ _M_w._M_notify(_M_addr, __all, __bare);
}
 
template

Re: [PATCH] [libstdc++] Fix test timeout in stop_calback/destroy.cc

2021-04-21 Thread Thomas Rodgers

On 2021-04-21 11:23, Jonathan Wakely wrote:


On 21/04/21 10:10 -0700, Thomas Rodgers wrote:


[...snip...]


Please commit your patch to trunk, since that's what you had in your
original patch before I asked you to change it (causing the bug).

We should do this for gcc-11 too if an RM approves it, since acquire()
is currently broken.


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


[PATCH] [libstdc++] Fix test timeout in stop_calback/destroy.cc

2021-04-21 Thread Thomas Rodgers
From: Thomas Rodgers 

A change was made to __atomic_semaphore::_S_do_try_acquire() to
(ideally) let the compare_exchange reload the value of __old rather than
always reloading it twice. This causes _M_acquire to spin indefinitely
if the value of __old is already 0.

libstdc++/ChangeLog:
* include/bits/semaphore_base.h: Always reload __old in
__atomic_semaphore::_S_do_try_acquire().
* testsuite/30_threads/stop_token/stop_callback/destroy.cc
re-enable testcase.
---
 libstdc++-v3/include/bits/semaphore_base.h   | 16 ++--
 .../stop_token/stop_callback/destroy.cc  |  2 --
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 35469e443b0..84b33423fff 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -196,9 +196,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 __atomic_semaphore& operator=(const __atomic_semaphore&) = delete;
 
 static _GLIBCXX_ALWAYS_INLINE bool
-_S_do_try_acquire(__detail::__platform_wait_t* __counter,
- __detail::__platform_wait_t& __old) noexcept
+_S_do_try_acquire(__detail::__platform_wait_t* __counter) noexcept
 {
+  auto __old = __atomic_impl::load(__counter, memory_order::acquire);
   if (__old == 0)
return false;
 
@@ -211,18 +211,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_ALWAYS_INLINE void
 _M_acquire() noexcept
 {
-  auto __old = __atomic_impl::load(&_M_counter, memory_order::acquire);
   auto const __pred =
-   [this, &__old] { return _S_do_try_acquire(>_M_counter, __old); };
+   [this] { return _S_do_try_acquire(>_M_counter); };
   std::__atomic_wait_address_bare(&_M_counter, __pred);
 }
 
 bool
 _M_try_acquire() noexcept
 {
-  auto __old = __atomic_impl::load(&_M_counter, memory_order::acquire);
   auto const __pred =
-   [this, &__old] { return _S_do_try_acquire(>_M_counter, __old); };
+   [this] { return _S_do_try_acquire(>_M_counter); };
   return std::__detail::__atomic_spin(__pred);
 }
 
@@ -231,9 +229,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_try_acquire_until(const chrono::time_point<_Clock,
   _Duration>& __atime) noexcept
   {
-   auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
auto const __pred =
- [this, &__old] { return _S_do_try_acquire(>_M_counter, __old); 
};
+ [this] { return _S_do_try_acquire(>_M_counter); };
 
return __atomic_wait_address_until_bare(&_M_counter, __pred, __atime);
   }
@@ -243,9 +240,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime)
noexcept
   {
-   auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
auto const __pred =
- [this, &__old] { return _S_do_try_acquire(>_M_counter, __old); 
};
+ [this] { return _S_do_try_acquire(>_M_counter); };
 
return __atomic_wait_address_for_bare(&_M_counter, __pred, __rtime);
   }
diff --git 
a/libstdc++-v3/testsuite/30_threads/stop_token/stop_callback/destroy.cc 
b/libstdc++-v3/testsuite/30_threads/stop_token/stop_callback/destroy.cc
index c2cfba027cb..061ed448c33 100644
--- a/libstdc++-v3/testsuite/30_threads/stop_token/stop_callback/destroy.cc
+++ b/libstdc++-v3/testsuite/30_threads/stop_token/stop_callback/destroy.cc
@@ -21,8 +21,6 @@
 // { dg-require-effective-target pthread }
 // { dg-require-gthreads "" }
 
-// { dg-skip-if "FIXME: times out" { *-*-* } }
-
 #include 
 #include 
 #include 
-- 
2.30.2



Re: GCC 11.1 Release Candidate available from gcc.gnu.org

2021-04-21 Thread Thomas Rodgers

On 2021-04-21 05:12, Jonathan Wakely wrote:

On 21/04/21 12:38 +0100, Jonathan Wakely wrote: On 20/04/21 22:12 
-0700, Thomas Rodgers wrote: @@ -86,6 +88,24 @@ 
_GLIBCXX_BEGIN_NAMESPACE_VERSION

}
}

+_GLIBCXX_ALWAYS_INLINE bool
+_M_try_acquire() noexcept
+{
+  for (;;)
+{
+  auto __err = sem_trywait(&_M_semaphore);
+  if (__err && (errno == EINTR))
+continue;
+  else if (__err && (errno == EAGAIN))
+return false;
+  else if (__err)
+std::terminate();
+  else
+break;
+}
+  return true;
+}
+
_GLIBCXX_ALWAYS_INLINE void
_M_release(std::ptrdiff_t __update) noexcept
{
Please just commit this part to trunk and gcc-11, not the macro
renaming (as that's been fixed by Jakub already).


I think on trunk I'd prefer to do the attached. WDYT?

Looks good to me.


[PATCH] [libstdc++] Refactor/cleanup of atomic wait implementation

2021-04-19 Thread Thomas Rodgers
From: Thomas Rodgers 

This patch address jwakely's feedback from 2021-04-15.

This is a substantial rewrite of the atomic wait/notify (and timed wait
counterparts) implementation.

The previous __platform_wait looped on EINTR however this behavior is
not required by the standard. A new _GLIBCXX_HAVE_PLATFORM_WAIT macro
now controls whether wait/notify are implemented using a platform
specific primitive or with a platform agnostic mutex/condvar. This
patch only supplies a definition for linux futexes. A future update
could add support __ulock_wait/wake on Darwin, for instance.

The members of __waiters were lifted to a new base class. The members
are now arranged such that overall sizeof(__waiters_base) fits in two
cache lines (on platforms with at least 64 byte cache lines). The
definition will also use destructive_interference_size for this if it
is available.

The __waiters type is now specific to untimed waits. Timed waits have a
corresponding __timed_waiters type. Much of the code has been moved from
the previous __atomic_wait() free function to the __waiter_base template
and a __waiter derived type is provided to implement the un-timed wait
operations. A similar change has been made to the timed wait
implementation.

The __atomic_spin code has been extended to take a spin policy which is
invoked after the initial busy wait loop. The default policy is to
return from the spin. The timed wait code adds a timed backoff spinning
policy. The code from  which implements this_thread::sleep_for,
sleep_until has been moved to a new  header
which allows the thread sleep code to be consumed without pulling in the
whole of .

The entry points into the wait/notify code have been restructured to
support either -
   * Testing the current value of the atomic stored at the given address
 and waiting on a notification.
   * Applying a predicate to determine if the wait was satisfied.
The entry points were renamed to make it clear that the wait and wake
operations operate on addresses. The first variant takes the expected
value and a function which returns the current value that should be used
in comparison operations, these operations are named with a _v suffix
(e.g. 'value'). All atomic<_Tp> wait/notify operations use the first
variant. Barriers, latches and semaphores use the predicate variant.

This change also centralizes what it means to compare values for the
purposes of atomic::wait rather than scattering through individual
predicates.

This change also centralizes the repetitive code which adjusts for
different user supplied clocks (this should be moved elsewhere
and all such adjustments should use a common implementation).

This change also removes the hashing of the pointer and uses
the pointer value directly for indexing into the waiters table.

libstdc++-v3/ChangeLog:
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/atomic_wait.h: Extensive rewrite.
* include/bits/atomic_timed_wait.h: Likewise.
* include/bits/semaphore_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/this_thread_sleep.h: New file.
* include/std/atomic: Likewise.
* include/std/barrier: Likewise.
* include/std/latch: Likewise.
* testsuite/29_atomics/atomic/wait_notify/bool.cc: Simplify
test.
* testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
* testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/atomic_base.h   |  36 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 457 +++--
 libstdc++-v3/include/bits/atomic_wait.h   | 471 --
 libstdc++-v3/include/bits/semaphore_base.h| 193 +++
 libstdc++-v3/include/bits/this_thread_sleep.h | 119 +
 libstdc++-v3/include/std/atomic   |  15 +-
 libstdc++-v3/include/std/barrier  |  13 +-
 libstdc++-v3/include/std/latch|   8 +-
 libstdc++-v3/include/std/semaphore|   9 +-
 libstdc++-v3/include/std/thread   |  68 +--
 .../29_atomics/atomic/wait_notify/bool.cc |  37 +-
 .../29_atomics/atomic/wait_notify/generic.cc  |  19 +-
 .../29_atomics/atomic/wait_notify/pointers.cc |  36 +-
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  37 +-
 .../29_atomics/atomic_float/wait_notify.cc|  26 +-
 .../29_atomics/atomic_integral/wait_notify.cc

Re: [PATCH 0/3] Uncontroversial improvements to C++20 wait-related implementation

2021-03-26 Thread Thomas Rodgers

On 2021-03-23 09:35, Jonathan Wakely wrote:

On 23/03/21 09:26 -0700, Thiago Macieira via Libstdc++ wrote: On 
Tuesday, 23 March 2021 08:39:43 PDT Thomas Rodgers wrote: I will be 
submitting a new patch for the
atomic.wait/barrier/latch/semaphore functionality a bit later today 
that

subsumes the changes to atomic_wait and latch, and includes the changes
to barrier.
Thanks, Thomas

Is that meant to be part of GCC 11's release?


Yes.

If not, what do we do about preventing the future BC break and 
potential

heisenbugs?

1) do nothing, accept they will happen silently


This is our current policy for experimental features and it isn't
going to change for GCC 11.


2) cause non-silent BC breaks
3) disable the code for now (unless explicitly opted-in)

-- Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel DPG Cloud Engineering


FWIW, I would like to commit to an ABI for this with GCC12 and 
everything currently residing in the __detail namespace would be moved 
into the .so as part of that (likely with a third, and ideally final, 
rewrite).


[PATCH] [libstdc++] Refactor/cleanup of atomic wait implementation

2021-03-23 Thread Thomas Rodgers
From: Thomas Rodgers 

* This patch addresses jwakely's previous feedback.
* This patch also subsumes thiago.macie...@intel.com 's 'Uncontroversial
  improvements to C++20 wait-related implementation'.
* This patch also changes the atomic semaphore implementation to avoid
  checking for any waiters before a FUTEX_WAKE op.

This is a substantial rewrite of the atomic wait/notify (and timed wait
counterparts) implementation.

The previous __platform_wait looped on EINTR however this behavior is
not required by the standard. A new _GLIBCXX_HAVE_PLATFORM_WAIT macro
now controls whether wait/notify are implemented using a platform
specific primitive or with a platform agnostic mutex/condvar. This
patch only supplies a definition for linux futexes. A future update
could add support __ulock_wait/wake on Darwin, for instance.

The members of __waiters were lifted to a new base class. The members
are now arranged such that overall sizeof(__waiters_base) fits in two
cache lines (on platforms with at least 64 byte cache lines). The
definition will also use destructive_interference_size for this if it
is available.

The __waiters type is now specific to untimed waits. Timed waits have a
corresponding __timed_waiters type. Much of the code has been moved from
the previous __atomic_wait() free function to the __waiter_base template
and a __waiter derived type is provided to implement the un-timed wait
operations. A similar change has been made to the timed wait
implementation.

The __atomic_spin code has been extended to take a spin policy which is
invoked after the initial busy wait loop. The default policy is to
return from the spin. The timed wait code adds a timed backoff spinning
policy. The code from  which implements this_thread::sleep_for,
sleep_until has been moved to a new  header
which allows the thread sleep code to be consumed without pulling in the
whole of .

The entry points into the wait/notify code have been restructured to
support either -
   * Testing the current value of the atomic stored at the given address
 and waiting on a notification.
   * Applying a predicate to determine if the wait was satisfied.
The entry points were renamed to make it clear that the wait and wake
operations operate on addresses. The first variant takes the expected
value and a function which returns the current value that should be used
in comparison operations, these operations are named with a _v suffix
(e.g. 'value'). All atomic<_Tp> wait/notify operations use the first
variant. Barriers, latches and semaphores use the predicate variant.

This change also centralizes what it means to compare values for the
purposes of atomic::wait rather than scattering through individual
predicates.

This change also centralizes the repetitive code which adjusts for
different user supplied clocks (this should be moved elsewhere
and all such adjustments should use a common implementation).

This change also removes the hashing of the pointer and uses
the pointer value directly for indexing into the waiters table.

libstdc++-v3/ChangeLog:
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/atomic_wait.h: Extensive rewrite.
* include/bits/atomic_timed_wait.h: Likewise.
* include/bits/semaphore_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/std_thread_sleep.h: New file.
* include/std/atomic: Likewise.
* include/std/barrier: Likewise.
* include/std/latch: Likewise.
* testsuite/29_atomics/atomic/wait_notify/bool.cc: Simplify
test.
* testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
* testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/atomic_base.h   |  36 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 444 ++--
 libstdc++-v3/include/bits/atomic_wait.h   | 475 --
 libstdc++-v3/include/bits/semaphore_base.h| 192 +++
 libstdc++-v3/include/bits/std_thread_sleep.h  | 119 +
 libstdc++-v3/include/std/atomic   |  15 +-
 libstdc++-v3/include/std/barrier  |  13 +-
 libstdc++-v3/include/std/latch|   8 +-
 libstdc++-v3/include/std/semaphore|   9 +-
 libstdc++-v3/include/std/thread   |  68 +--
 .../29_atomics/atomic/wait_notify/bool.cc |  37 +-
 .../29_atomics/atomic/wait_

Re: [PATCH 0/3] Uncontroversial improvements to C++20 wait-related implementation

2021-03-23 Thread Thomas Rodgers

On 2021-03-22 08:29, Thiago Macieira via Libstdc++ wrote:


Discussion at:
https://gcc.gnu.org/pipermail/libstdc++/2021-February/052043.html

This patch set includes the uncontroversial parts that improve
performance but don't otherwise change ABI.

Please note we still need to decide on how to deal with the future ABI
break.

Thiago Macieira (3):
Atomic __platform_wait: accept any 32-bit type, not just int
std::latch: reduce internal implementation from ptrdiff_t to int
barrier: optimise by not having the hasher in a loop

libstdc++-v3/include/bits/atomic_wait.h |  7 ---
libstdc++-v3/include/std/barrier| 10 +-
libstdc++-v3/include/std/latch  |  4 ++--
3 files changed, 11 insertions(+), 10 deletions(-)


ping?


I will be submitting a new patch for the 
atomic.wait/barrier/latch/semaphore functionality a bit later today that 
subsumes the changes to atomic_wait and latch, and includes the changes 
to barrier.


Re: [PATCH 4/5] barrier: use int instead of unsigned char for the phase state

2021-03-01 Thread Thomas Rodgers

On 2021-03-01 10:06, Thiago Macieira wrote:

On Monday, 1 March 2021 09:38:58 PST Thomas Rodgers wrote: And 
_M_phase, despite being non-atomic, is never accessed without the

atomic_ref, aside from the constructor. Both arrive() and wait() start
off by
creating the atomic_ref.
If it's non-atomic, then how is wait() supposed to wait on it,
atomically?



Hey, it's your code :-)

It is using atomics to operate on the value. It's just that the type on 
the

structure isn't an atomic by itself.



Why, I don't know. Olivier's original code did use atomics
<https://github.com/ogiroux/atomic_wait/blob/master/include/barrier#L55-L56>:
   std::atomic expected_adjustment;
   std::atomic<__phase_t> phase;


It is atomic, in that it is always an atomic_ref. This change was made 
at

Jonathan's request.


And I am not disagreeing with that. I am, however saying, that I know
this particular implementation (well the upstream one it is based on)
has been extensively tested by the original author (ogiroux) including
time on Summit. If we are going to start changing his design decisions
(beyond the largely cosmetic, not algorithmic, ones that I have made as
per Jonathan's request), they should be motivated by more than a 'well
we feel int's would be better here because Futex' justification.



That's a reasonable request.

I'd like to see the benchmark results of using a directly-futexable 
type vs
using unsigned char. But even the timing results need to be weighed 
against
the increased memory use for std::barrier, which means it's not a 
directly-
objective conclusion. And given we *may* get 8-bit futexes, it might be 
worth
keeping them this way and just tell people with large contentions to 
upgrade.


We may also want to introduce a central barrier type for memory 
constrained environments. I specifically

removed that from this patch because it -

1) wasn't clear how we'd go about making that decision
2) this support in GCC11 is experimental


That of course rests on the contended atomic_wait being out-of-line.


Re: [PATCH 4/5] barrier: use int instead of unsigned char for the phase state

2021-03-01 Thread Thomas Rodgers

Botched replying to the list, sending again

On 2021-03-01 09:38, Thomas Rodgers wrote:


On 2021-03-01 09:24, Thiago Macieira via Libstdc++ wrote:

On Sunday, 28 February 2021 07:05:47 PST Hans-Peter Nilsson wrote: On 
Fri, 26 Feb 2021, Thiago Macieira via Gcc-patches wrote: ints can be 
used in futexes. chars can't.

Shouldn't that be an atomic type instead of a bare int then?



There are a couple of atomic_refs:

using __atomic_phase_ref_t = std::__atomic_ref<__barrier_phase_t>;
using __atomic_phase_const_ref_t = std::__atomic_ref;

And _M_phase, despite being non-atomic, is never accessed without the
atomic_ref, aside from the constructor. Both arrive() and wait() start 
off by

creating the atomic_ref.


If it's non-atomic, then how is wait() supposed to wait on it, 
atomically?


But I confess I don't understand this code sufficiently to say it is 
correct.
I'm simply saying that waiting on unsigned chars will not use a futex, 
at
least until https://lkml.org/lkml/2019/12/4/1373 is merged into the 
kernel.


And I am not disagreeing with that. I am, however saying, that I know 
this particular implementation (well the upstream one it is based on) 
has been extensively tested by the original author (ogiroux) including 
time on Summit. If we are going to start changing his design decisions 
(beyond the largely cosmetic, not algorithmic, ones that I have made as 
per Jonathan's request), they should be motivated by more than a 'well 
we feel int's would be better here because Futex' justification.


Re: [PATCH 4/5] barrier: use int instead of unsigned char for the phase state

2021-03-01 Thread Thomas Rodgers

On 2021-03-01 09:24, Thiago Macieira via Libstdc++ wrote:

On Sunday, 28 February 2021 07:05:47 PST Hans-Peter Nilsson wrote: On 
Fri, 26 Feb 2021, Thiago Macieira via Gcc-patches wrote: ints can be 
used in futexes. chars can't.

Shouldn't that be an atomic type instead of a bare int then?



There are a couple of atomic_refs:

 using __atomic_phase_ref_t = std::__atomic_ref<__barrier_phase_t>;
 using __atomic_phase_const_ref_t = std::__atomic_ref;

And _M_phase, despite being non-atomic, is never accessed without the
atomic_ref, aside from the constructor. Both arrive() and wait() start 
off by

creating the atomic_ref.


If it's non-atomic, then how is wait() supposed to wait on it, 
atomically?


But I confess I don't understand this code sufficiently to say it is 
correct.
I'm simply saying that waiting on unsigned chars will not use a futex, 
at
least until https://lkml.org/lkml/2019/12/4/1373 is merged into the 
kernel.


And I am not disagreeing with that. I am, however saying, that I know 
this particular implementation (well the upstream one it is based on) 
has been extensively tested by the original author (ogiroux) including 
time on Summit. If we are going to start changing his design decisions 
(beyond the largely cosmetic, not algorithmic, ones that I have made as 
per Jonathan's request), they should be motivated by more than a 'well 
we feel int's would be better here because Futex' justification.


Re: [PATCH 1/5] std::latch: reduce internal implementation from ptrdiff_t to int

2021-03-01 Thread Thomas Rodgers

On 2021-02-28 13:31, Hans-Peter Nilsson wrote:


On Fri, 26 Feb 2021, Thiago Macieira via Gcc-patches wrote:

On Friday, 26 February 2021 11:31:00 PST Andreas Schwab wrote: On Feb 
26 2021, Thiago Macieira wrote: On Friday, 26 February 2021 10:14:42 
PST Andreas Schwab wrote: On Feb 26 2021, Thiago Macieira via 
Gcc-patches wrote: -alignas(__alignof__(ptrdiff_t)) ptrdiff_t 
_M_a;

+alignas(__alignof__(int)) int _M_a;
Futexes must be aligned to 4 bytes.

Agreed, but doesn't this accomplish that?

No.  It uses whatever alignment the type already has, and is an
elaborate no-op.
I thought so too when I read the original line. But I expected it was 
written
like that for a reason, especially since the same pattern appears in 
other

places.


I can change to "alignas(4)" (which is a GCC extension, I believe). Is 
that

the correct solution?
IMNSHO make use of the corresponding atomic type.  Then there'd
be no need for separate what's-the-right-align-curse games.


There is no predicate wait on atomic.


brgds, H-P


Re: [PATCH 4/5] barrier: use int instead of unsigned char for the phase state

2021-03-01 Thread Thomas Rodgers

On 2021-02-28 07:05, Hans-Peter Nilsson wrote:


On Fri, 26 Feb 2021, Thiago Macieira via Gcc-patches wrote:


ints can be used in futexes. chars can't.


Shouldn't that be an atomic type instead of a bare int then?



It's an atomic_ref.


---
libstdc++-v3/include/std/barrier | 21 -
1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/libstdc++-v3/include/std/barrier 
b/libstdc++-v3/include/std/barrier

index e09212dfcb9..ae058bd3dc3 100644
--- a/libstdc++-v3/include/std/barrier
+++ b/libstdc++-v3/include/std/barrier
@@ -70,7 +70,7 @@ It looks different from literature pseudocode for 
two main reasons:


*/

-  enum class __barrier_phase_t : unsigned char { };
+  enum class __barrier_phase_t : int { };


brgds, H-P


[PATCH] [libstdc++] Refactor/cleanup of atomic wait implementation

2021-02-23 Thread Thomas Rodgers
From: Thomas Rodgers 

* This revises the previous version to fix std::__condvar::wait_until() usage.

This is a substantial rewrite of the atomic wait/notify (and timed wait
counterparts) implementation.

The previous __platform_wait looped on EINTR however this behavior is
not required by the standard. A new _GLIBCXX_HAVE_PLATFORM_WAIT macro
now controls whether wait/notify are implemented using a platform
specific primitive or with a platform agnostic mutex/condvar. This
patch only supplies a definition for linux futexes. A future update
could add support __ulock_wait/wake on Darwin, for instance.

The members of __waiters were lifted to a new base class. The members
are now arranged such that overall sizeof(__waiters_base) fits in two
cache lines (on platforms with at least 64 byte cache lines). The
definition will also use destructive_interference_size for this if it
is available.

The __waiters type is now specific to untimed waits. Timed waits have a
corresponding __timed_waiters type. Much of the code has been moved from
the previous __atomic_wait() free function to the __waiter_base template
and a __waiter derived type is provided to implement the un-timed wait
operations. A similar change has been made to the timed wait
implementation.

The __atomic_spin code has been extended to take a spin policy which is
invoked after the initial busy wait loop. The default policy is to
return from the spin. The timed wait code adds a timed backoff spinning
policy. The code from  which implements this_thread::sleep_for,
sleep_until has been moved to a new  header
which allows the thread sleep code to be consumed without pulling in the
whole of .

The entry points into the wait/notify code have been restructured to
support either -
   * Testing the current value of the atomic stored at the given address
 and waiting on a notification.
   * Applying a predicate to determine if the wait was satisfied.
The entry points were renamed to make it clear that the wait and wake
operations operate on addresses. The first variant takes the expected
value and a function which returns the current value that should be used
in comparison operations, these operations are named with a _v suffix
(e.g. 'value'). All atomic<_Tp> wait/notify operations use the first
variant. Barriers, latches and semaphores use the predicate variant.

This change also centralizes what it means to compare values for the
purposes of atomic::wait rather than scattering through individual
predicates.

This change also centralizes the repetitive code which adjusts for
different user supplied clocks (this should be moved elsewhere
and all such adjustments should use a common implementation).

libstdc++-v3/ChangeLog:
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/atomic_wait.h: Extensive rewrite.
* include/bits/atomic_timed_wait.h: Likewise.
* include/bits/semaphore_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/std_thread_sleep.h: New file.
* include/std/atomic: Likewise.
* include/std/barrier: Likewise.
* include/std/latch: Likewise.
* testsuite/29_atomics/atomic/wait_notify/bool.cc: Simplify
test.
* testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
* testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/atomic_base.h   |  36 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 410 +++---
 libstdc++-v3/include/bits/atomic_wait.h   | 400 +++--
 libstdc++-v3/include/bits/semaphore_base.h|  73 +---
 libstdc++-v3/include/bits/std_thread_sleep.h  | 119 +
 libstdc++-v3/include/std/atomic   |  15 +-
 libstdc++-v3/include/std/barrier  |   4 +-
 libstdc++-v3/include/std/latch|   4 +-
 libstdc++-v3/include/std/thread   |  68 +--
 .../29_atomics/atomic/wait_notify/bool.cc |  37 +-
 .../29_atomics/atomic/wait_notify/generic.cc  |  19 +-
 .../29_atomics/atomic/wait_notify/pointers.cc |  36 +-
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  37 +-
 .../29_atomics/atomic_float/wait_notify.cc|  26 +-
 .../29_atomics/atomic_integral/wait_notify.cc |  73 ++--
 .../29_atomics/atomic_ref/wait_notify.cc  |  74 +---
 18 files changed, 802 insertions(+), 631 deletions(-)
 create mode 100644 libstdc++-v3/includ

[PATCH] [libstdc++] Refactor/cleanup of atomic wait implementation

2021-02-22 Thread Thomas Rodgers
From: Thomas Rodgers 

This is a substantial rewrite of the atomic wait/notify (and timed wait
counterparts) implementation.

The previous __platform_wait looped on EINTR however this behavior is
not required by the standard. A new _GLIBCXX_HAVE_PLATFORM_WAIT macro
now controls whether wait/notify are implemented using a platform
specific primitive or with a platform agnostic mutex/condvar. This
patch only supplies a definition for linux futexes. A future update
could add support __ulock_wait/wake on Darwin, for instance.

The members of __waiters were lifted to a new base class. The members
are now arranged such that overall sizeof(__waiters_base) fits in two
cache lines (on platforms with at least 64 byte cache lines). The
definition will also use destructive_interference_size for this if it
is available.

The __waiters type is now specific to untimed waits. Timed waits have a
corresponding __timed_waiters type. Much of the code has been moved from
the previous __atomic_wait() free function to the __waiter_base template
and a __waiter derived type is provided to implement the un-timed wait
operations. A similar change has been made to the timed wait
implementation.

The __atomic_spin code has been extended to take a spin policy which is
invoked after the initial busy wait loop. The default policy is to
return from the spin. The timed wait code adds a timed backoff spinning
policy. The code from  which implements this_thread::sleep_for,
sleep_until has been moved to a new  header
which allows the thread sleep code to be consumed without pulling in the
whole of .

The entry points into the wait/notify code have been restructured to
support either -
   * Testing the current value of the atomic stored at the given address
 and waiting on a notification.
   * Applying a predicate to determine if the wait was satisfied.
The entry points were renamed to make it clear that the wait and wake
operations operate on addresses. The first variant takes the expected
value and a function which returns the current value that should be used
in comparison operations, these operations are named with a _v suffix
(e.g. 'value'). All atomic<_Tp> wait/notify operations use the first
variant. Barriers, latches and semaphores use the predicate variant.

This change also centralizes what it means to compare values for the
purposes of atomic::wait rather than scattering through individual
predicates.

This change also centralizes the repetitive code which adjusts for
different user supplied clocks (this should be moved elsewhere
and all such adjustments should use a common implementation).

libstdc++-v3/ChangeLog:
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/atomic_wait.h: Extensive rewrite.
* include/bits/atomic_timed_wait.h: Likewise.
* include/bits/semaphore_base.h: Adjust all calls
to __atomic_wait/__atomic_notify for new call signatures.
* include/bits/std_thread_sleep.h: New file.
* include/std/atomic: Likewise.
* include/std/barrier: Likewise.
* include/std/latch: Likewise.
* testsuite/29_atomics/atomic/wait_notify/bool.cc: Simplify
test.
* testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
* testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/atomic_base.h   |  36 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 398 +++--
 libstdc++-v3/include/bits/atomic_wait.h   | 400 +++---
 libstdc++-v3/include/bits/semaphore_base.h|  73 +---
 libstdc++-v3/include/bits/std_thread_sleep.h  | 119 ++
 libstdc++-v3/include/std/atomic   |  15 +-
 libstdc++-v3/include/std/barrier  |   4 +-
 libstdc++-v3/include/std/latch|   4 +-
 libstdc++-v3/include/std/thread   |  68 +--
 .../29_atomics/atomic/wait_notify/bool.cc |  37 +-
 .../29_atomics/atomic/wait_notify/generic.cc  |  19 +-
 .../29_atomics/atomic/wait_notify/pointers.cc |  36 +-
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  37 +-
 .../29_atomics/atomic_float/wait_notify.cc|  26 +-
 .../29_atomics/atomic_integral/wait_notify.cc |  73 ++--
 .../29_atomics/atomic_ref/wait_notify.cc  |  74 +---
 18 files changed, 804 insertions(+), 617 deletions(-)
 create mode 100644 libstdc++-v3/include/bits/std_thread_sleep.h

diff --git a/libstdc++-v3/include/Makefile.am b/l

Re: [PATCH] libstdc++: Fix up parallel_backend_serial.h [PR97549]

2021-02-22 Thread Thomas Rodgers via Gcc-patches



- Original Message -
> Hi!
> 
> In GCC 10, parallel_backend.h just included parallel_backend_{serial,tbb}.h
> and
> did nothing beyond that, and parallel_backend_tbb.h provided directly
> namespace __pstl { namespace __par_backend { ... } }
> and defined everything in there, while parallel_backend_serial.h did:
> namespace __pstl { namespace __serial { ... } } and had this
> namespace __pstl { namespace __par_backend { using namespace
> __pstl::__serial; } }
> at the end.
> In GCC 11, parallel_backend.h does:
> namespace __pstl { namespace __par_backend = __serial_backend; }
> after including parallel_backend_serial.h or
> namespace __pstl { namespace __par_backend = __tbb_backend; }
> after including parallel_backend_tbb.h.  The latter then has:
> namespace __pstl { namespace __tbb_backend { ... } }
> and no using etc. at the end, while parallel_backend_serial.h changed to:
> namespace __pstl { namespace __serial_backend { ... } }
> but has this leftover block from the GCC 10 times.  Even changing that
> using namespace __pstl::__serial;
> to
> using namespace __pstl::__serial_backend;
> doesn't work, as it clashes with
> namespace __pstl { namespace __par_backend = __serial_backend; }
> in parallel_backend.h.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux
> both without and with tbb-devel installed.
> 
> Ok for trunk?

Yes, thanks.

> 
> 2021-02-20  Jakub Jelinek  
> 
>   PR libstdc++-v3/97549
>   * include/pstl/parallel_backend_serial.h: Remove __pstl::__par_backend.
> 
> --- libstdc++-v3/include/pstl/parallel_backend_serial.h.jj2020-10-21
> 19:33:24.059872401 +0200
> +++ libstdc++-v3/include/pstl/parallel_backend_serial.h   2021-02-19
> 11:59:56.414645219 +0100
> @@ -127,12 +127,4 @@ __parallel_invoke(_ExecutionPolicy&&, _F
>  } // namespace __serial_backend
>  } // namespace __pstl
>  
> -namespace __pstl
> -{
> -namespace __par_backend
> -{
> -using namespace __pstl::__serial;
> -}
> -} // namespace __pstl
> -
>  #endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */
> 
>   Jakub
> 



Re: [PATCH] libstdc++: Add support for C++20 barriers

2021-01-07 Thread Thomas Rodgers via Gcc-patches


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 
>>
>>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.
>
>
>>+#ifndef _GLIBCXX_BARRIER
>>+#define _GLIBCXX_BARRIER 1
>>+
>>+#pragma GCC system_header
>>+
>>+#if __cplusplus > 201703L
>>+#include 
>>+#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 .
>
>>+#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 000..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 
>>+
>>+#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 000..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 par

[PATCH] libstdc++: Add support for C++20 barriers

2020-12-17 Thread Thomas Rodgers
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 000..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
+// <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
+//
+//===---===//
+
+

[PATCH] libstdc++: Add support for C++20 barriers

2020-12-17 Thread Thomas Rodgers
From: Thomas Rodgers 

Let's see if this one sticks...

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  | 267 ++
 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, 561 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 000..f3c819774bd
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,267 @@
+//  -*- 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
+//
+//===---===//
+
+/** @fil

Re: [PATCH] Add feature test macro for atomic::wait

2020-12-01 Thread Thomas Rodgers via Gcc-patches
Tested x86_64-pc-linux-gnu, committed to trunk.

Jonathan Wakely writes:

> On 30/11/20 10:17 -0800, Thomas Rodgers wrote:
>>From: Thomas Rodgers 
>>
>>Adds __cpp_lib_atomic_wait feature test macro which was overlooked in
>>the initial commit of this feature. Replaces uses of
>>_GLIBCXX_HAVE_ATOMIC_WAIT.
>>
>>libstdc++-v3/ChangeLog:
>>
>>  * include/bits/atomic_base.h: Replace usage of
>>  _GLIBCXX_HAVE_ATOMIC_WAIT with __cpp_lib_atomic_wait.
>>  * include/bits/atomic_timed_wait.h: Likewise.
>>  * include/bits/atomic_wait.h: Define __cpp_lib_atomic_wait
>>  feature test macro.
>>  * include/bits/semaphore_base: Replace usage of
>>  _GLIBCXX_HAVE_ATOMIC_WAIT with __cpp_lib_atomic_wait.
>>  * include/std/atomic: Likewise.
>>  * include/std/latch: Likewise.
>>  * include/std/semaphore: Likewise.
>>  * include/std/version: Define __cpp_lib_atomic wait
>>  feature test macro and replace usage of
>>  _GLIBCXX_HAVE_ATOMIC_WAIT.
>>  * testsuite/29_atomics/atomic/wait_notify/1.cc: New test.
>>  * testsuite/29_atomics/atomic/wait_notify/2.cc: Likewise.
>>
>>---
>> libstdc++-v3/include/bits/atomic_base.h   | 36 +--
>> libstdc++-v3/include/bits/atomic_timed_wait.h |  5 +--
>> libstdc++-v3/include/bits/atomic_wait.h   |  3 +-
>> libstdc++-v3/include/bits/semaphore_base.h|  4 +--
>> libstdc++-v3/include/std/atomic   | 16 -
>> libstdc++-v3/include/std/latch|  4 +--
>> libstdc++-v3/include/std/semaphore|  4 +--
>> libstdc++-v3/include/std/version  |  7 ++--
>> .../29_atomics/atomic/wait_notify/1.cc| 28 +++
>> .../29_atomics/atomic/wait_notify/2.cc| 29 +++
>> 10 files changed, 98 insertions(+), 38 deletions(-)
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/1.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/2.cc
>>
>>diff --git a/libstdc++-v3/include/bits/atomic_base.h 
>>b/libstdc++-v3/include/bits/atomic_base.h
>>index d0d962d3047..ad4e24b4d20 100644
>>--- a/libstdc++-v3/include/bits/atomic_base.h
>>+++ b/libstdc++-v3/include/bits/atomic_base.h
>>@@ -230,7 +230,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>   return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
>> }
>>
>>-#ifdef _GLIBCXX_HAVE_ATOMIC_WAIT
>>+#ifdef __cpp_lib_atomic_wait
>
> I've not always been consistent about using #if or #ifdef for
> __cpp_lib macros, but let's not make that worse in a single patch. I
> think we should just use #if for __cpp_lib macros. That affects
> several places in the patch.
>
>> _GLIBCXX_ALWAYS_INLINE void
>> wait(bool __old,
>>  memory_order __m = memory_order_seq_cst) const noexcept
>>@@ -253,7 +253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> { std::__atomic_notify(&_M_i, true); }
>>
>> // TODO add const volatile overload
>>-#endif // HAVE_ATOMIC_WAIT
>>+#endif // __cpp_lib_atomic_wait
>> #endif // C++20
>>
>> _GLIBCXX_ALWAYS_INLINE void
>>@@ -604,7 +604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> __cmpexch_failure_order(__m));
>>   }
>>
>>-#if __cplusplus > 201703L && defined _GLIBCXX_HAVE_ATOMIC_WAIT
>>+#if __cpp_lib_atomic_wait
>>   _GLIBCXX_ALWAYS_INLINE void
>>   wait(__int_type __old,
>>memory_order __m = memory_order_seq_cst) const noexcept
>>@@ -627,7 +627,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>   { std::__atomic_notify(&_M_i, true); }
>>
>>   // TODO add const volatile overload
>>-#endif // C++20 && HAVE_ATOMIC_WAIT
>>+#endif // __cpp_lib_atomic_wait
>>
>>   _GLIBCXX_ALWAYS_INLINE __int_type
>>   fetch_add(__int_type __i,
>>@@ -898,7 +898,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> int(__m1), int(__m2));
>>   }
>>
>>-#if __cplusplus > 201703L && defined _GLIBCXX_HAVE_ATOMIC_WAIT
>>+#if __cpp_lib_atomic_wait
>>   _GLIBCXX_ALWAYS_INLINE void
>>   wait(__pointer_type __old,
>> memory_order __m = memory_order_seq_cst) noexcept
>>@@ -921,7 +921,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>   { std::__atomic_notify(&_M_p, true); }
>>
>>   // TODO add const volatile overload
>>-#endif // C++20 && HAVE_ATOMIC_WAIT
>>+#endif // __cpp_lib_atomic_wait
>>
>>   _GLIBCXX_ALWAYS_INLINE __pointer_type

[PATCH] Add feature test macro for atomic::wait

2020-11-30 Thread Thomas Rodgers
From: Thomas Rodgers 

Adds __cpp_lib_atomic_wait feature test macro which was overlooked in
the initial commit of this feature. Replaces uses of
_GLIBCXX_HAVE_ATOMIC_WAIT.

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h: Replace usage of
_GLIBCXX_HAVE_ATOMIC_WAIT with __cpp_lib_atomic_wait.
* include/bits/atomic_timed_wait.h: Likewise.
* include/bits/atomic_wait.h: Define __cpp_lib_atomic_wait
feature test macro.
* include/bits/semaphore_base: Replace usage of
_GLIBCXX_HAVE_ATOMIC_WAIT with __cpp_lib_atomic_wait.
* include/std/atomic: Likewise.
* include/std/latch: Likewise.
* include/std/semaphore: Likewise.
* include/std/version: Define __cpp_lib_atomic wait
feature test macro and replace usage of
_GLIBCXX_HAVE_ATOMIC_WAIT.
* testsuite/29_atomics/atomic/wait_notify/1.cc: New test.
* testsuite/29_atomics/atomic/wait_notify/2.cc: Likewise.

---
 libstdc++-v3/include/bits/atomic_base.h   | 36 +--
 libstdc++-v3/include/bits/atomic_timed_wait.h |  5 +--
 libstdc++-v3/include/bits/atomic_wait.h   |  3 +-
 libstdc++-v3/include/bits/semaphore_base.h|  4 +--
 libstdc++-v3/include/std/atomic   | 16 -
 libstdc++-v3/include/std/latch|  4 +--
 libstdc++-v3/include/std/semaphore|  4 +--
 libstdc++-v3/include/std/version  |  7 ++--
 .../29_atomics/atomic/wait_notify/1.cc| 28 +++
 .../29_atomics/atomic/wait_notify/2.cc| 29 +++
 10 files changed, 98 insertions(+), 38 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/1.cc
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/2.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index d0d962d3047..ad4e24b4d20 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -230,7 +230,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
 }
 
-#ifdef _GLIBCXX_HAVE_ATOMIC_WAIT
+#ifdef __cpp_lib_atomic_wait
 _GLIBCXX_ALWAYS_INLINE void
 wait(bool __old,
memory_order __m = memory_order_seq_cst) const noexcept
@@ -253,7 +253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { std::__atomic_notify(&_M_i, true); }
 
 // TODO add const volatile overload
-#endif // HAVE_ATOMIC_WAIT
+#endif // __cpp_lib_atomic_wait 
 #endif // C++20
 
 _GLIBCXX_ALWAYS_INLINE void
@@ -604,7 +604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __cmpexch_failure_order(__m));
   }
 
-#if __cplusplus > 201703L && defined _GLIBCXX_HAVE_ATOMIC_WAIT
+#if __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
   wait(__int_type __old,
  memory_order __m = memory_order_seq_cst) const noexcept
@@ -627,7 +627,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { std::__atomic_notify(&_M_i, true); }
 
   // TODO add const volatile overload
-#endif // C++20 && HAVE_ATOMIC_WAIT
+#endif // __cpp_lib_atomic_wait 
 
   _GLIBCXX_ALWAYS_INLINE __int_type
   fetch_add(__int_type __i,
@@ -898,7 +898,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   int(__m1), int(__m2));
   }
 
-#if __cplusplus > 201703L && defined _GLIBCXX_HAVE_ATOMIC_WAIT
+#if __cpp_lib_atomic_wait 
   _GLIBCXX_ALWAYS_INLINE void
   wait(__pointer_type __old,
   memory_order __m = memory_order_seq_cst) noexcept
@@ -921,7 +921,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { std::__atomic_notify(&_M_p, true); }
 
   // TODO add const volatile overload
-#endif // C++20 && HAVE_ATOMIC_WAIT
+#endif // __cpp_lib_atomic_wait
 
   _GLIBCXX_ALWAYS_INLINE __pointer_type
   fetch_add(ptrdiff_t __d,
@@ -1011,7 +1011,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 int(__success), int(__failure));
   }
 
-#if __cplusplus > 201703L && defined _GLIBCXX_HAVE_ATOMIC_WAIT
+#if __cpp_lib_atomic_wait
 template
   _GLIBCXX_ALWAYS_INLINE void
   wait(const _Tp* __ptr, _Val<_Tp> __old,
@@ -1036,7 +1036,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { std::__atomic_notify(__ptr, true); }
 
   // TODO add const volatile overload
-#endif // C++20 && HAVE_ATOMIC_WAIT
+#endif // __cpp_lib_atomic_wait
 
 template
   _GLIBCXX_ALWAYS_INLINE _Tp
@@ -1291,7 +1291,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __cmpexch_failure_order(__order));
   }
 
-#ifdef _GLIBCXX_HAVE_ATOMIC_WAIT
+#ifdef __cpp_lib_atomic_wait
   _GLIBCXX_ALWAYS_INLINE void
   wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
   { __atomic_impl::wait(&_M_fp, __old, __m); }
@@ -1309,7 +1309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { __atomic_i

[PATCH] libstdc++: Add support for C++20 barriers

2020-11-20 Thread Thomas Rodgers
From: Thomas Rodgers 

Should include all discussion on and off list to date.

Adds 

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 \
diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
new file mode 100644
index 000..a6cc6a058dd
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,258 @@
+//  -*- 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
+//
+//===---===//
+
+#ifndef _GLIBCXX_BARRIER
+#define _GLIBCXX_BARRIER 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+#include 
+
+#if defined(_GLIBCXX_HAS_GTHREADS)
+#define __cpp_lib_barrier 201907L
+#include 
+#include 
+#include 
+
+#include 
+
+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
+class __tree_barrier
+{
+  struct alignas(64) /* naturally-align

Re: [PATCH] libstdc++: Add C++2a synchronization support

2020-11-20 Thread Thomas Rodgers
Tested x86_64-pc-linux-gnu, committed.

> On Oct 27, 2020, at 3:23 AM, Jonathan Wakely  wrote:
> 
> On 26/10/20 14:48 -0700, Thomas Rodgers wrote:
>> +#include 
>> +
>> +#if __has_include()
>> +#define _GLIBCXX_HAVE_POSIX_SEMAPHORE 1
>> +#include 
> 
> It occurs to me now that this check probably isn't robust enough. For
> any POSIX system it's probably safe to assume that  means
> the POSIX header and so sem_t is available.
> 
> But on non-POSIX systems there could be some other, unrelated header
> called  in the include paths that the user is compiling
> this header with. It's not inconceivable that the user's own project
> or some third party lib could provide a file called semaphore.h, which
> wouldn't define sem_t, sem_init etc.
> 
> It's OK for now, but we should revisit this and add an autoconf check
> for sem_init etc. to check at build time whether we've got POSIX
> semaphores available or not.
> 
> Please add a "FIXME: replace this with an autoconf check" comment
> here.
> 
> OK for trunk with that change, thanks.
> 



Re: [PATCH] libstdc++: Enable without gthreads

2020-11-16 Thread Thomas Rodgers
This patch looks good to me.

It would be great to find a way to do a similar refactoring of 
condition_variable.

> On Nov 12, 2020, at 9:07 AM, Jonathan Wakely via Libstdc++ 
>  wrote:
> 
> On 11/11/20 17:31 +, Jonathan Wakely wrote:
>> On 11/11/20 16:13 +, Jonathan Wakely wrote:
>>> This makes it possible to use std::thread in single-threaded builds.
>>> All member functions are available, but attempting to create a new
>>> thread will throw an exception.
>>> 
>>> The main benefit for most targets is that other headers such as 
>>> do not need to include the whole of  just to be able to create a
>>> std::thread. That avoids including  and std::jthread where
>>> not required.
>> 
>> I forgot to mention that this patch also reduces the size of the
>>  header, by only including  instead of the
>> whole of . That could be done separately from the rest of the
>> changes here.
>> 
>> It would be possible to split std::thread and this_thread::get_id()
>> into a new header without also making them work without gthreads.
>> 
>> That would still reduce the size of the  header, because it
>> wouldn't need the whole of . But it wouldn't get rid of
>> preprocessor checks for _GLIBCXX_HAS_GTHREADS in .
>> 
>> Allowing std::this_thread::get_id() and std::this_thread::yield() to
>> work without threads seems worth doing (we already make
>> std::this_thread::sleep_until and std::this_thread::sleep_for work
>> without threads).
> 
> Here's a slightly more conservative version of the patch. This moves
> std::thread and this_thread::get_id() and this_thread::yield() to a
> new header, and makes *most* of std::thread defined without gthreads
> (because we need the nested thread::id type to be returned from
> this_thread::get_id()). But it doesn't declare the std::thread
> constructor that creates new threads.
> 
> That means std::thread is present, but you can't even try to create
> new threads. This means we don't need to export the std::thread
> symbols from libstdc++.so for a target where they are unusable and
> just throw an exception.
> 
> This still has the main benefits of making  include a lot less
> code, and removing some #if conditions in .
> 
> One other change from the previous patch worth mentioning is that I've
> made  include  so that
> std::reference_wrapper (and std::ref and std::cref) are defined by
> . That isn't required, but it is a tiny header and being able
> to use std::ref to pass lvalues to new threads without including
> all of  seems like a kindness to users.
> 
> Both this and the previous patch require some GDB changes, because GDB
> currently assumes that if std::thread is declared in  that it
> is usable and multiple threads are supported. That's no longer true,
> because we would declare a useless std::thread after this patch. Tom
> Tromey has patches to make GDB handle this though.
> 
> Tested powerpc64le-linux, --enable-threads and --disable-threads.
> 
> Thoughts?
> 
> 
> 



Re: [PATCH] libstdc++: Implement C++20 features for

2020-11-04 Thread Thomas Rodgers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97719

> On Nov 4, 2020, at 11:54 AM, Stephan Bergmann  wrote:
> 
> On 07/10/2020 18:55, Thomas Rodgers wrote:
>> From: Thomas Rodgers 
>> New ctors and ::view() accessor for -
>>   * basic_stingbuf
>>   * basic_istringstream
>>   * basic_ostringstream
>>   * basic_stringstreamm
>> New ::get_allocator() accessor for basic_stringbuf.
> I found that this 
> <https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=a0e4d7b44c544c84cffc7ff9c64b6f1af14fb08d>
>  "libstdc++: Implement C++20 features for " changed the behavior of
> 
>> $ cat test.cc
>> #include 
>> #include 
>> #include 
>> int main() {
>>  std::stringstream s("a");
>>  std::istreambuf_iterator i(s);
>>  if (i != std::istreambuf_iterator()) std::cout << *i << '\n';
>> }
>> $ g++ -std=c++20 test.cc
>> $ ./a.out
> 
> from printing "a" to printing nothing.  (The `i != ...` comparison appears to 
> change i from pointing at "a" to pointing to null, and returns false.)
> 
> I ran into this when building LibreOffice, and I hope test.cc is a faithfully 
> minimized reproducer.  However, I know little about std::istreambuf_iterator, 
> so it may well be that the code isn't even valid.
> 



Re: [PATCH] libstdc++: Add support for C++20 barriers

2020-11-04 Thread Thomas Rodgers



> On Nov 4, 2020, at 10:50 AM, Jonathan Wakely  wrote:
> 
> On 04/11/20 09:29 -0800, Thomas Rodgers wrote:
>> From: Thomas Rodgers 
>> 
>> Adds 
>> 
>> libstdc++/ChangeLog:
>> 
>>  * include/Makefile.am (std_headers): Add new header.
>>  * include/Makefile.in: Regenerate.
>>  * include/std/barrier: New file.
>>  * 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/std/barrier  | 248 ++
>> .../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 
>> 8 files changed, 551 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/std/barrier 
>> b/libstdc++-v3/include/std/barrier
>> new file mode 100644
>> index 000..80e6d668cf5
>> --- /dev/null
>> +++ b/libstdc++-v3/include/std/barrier
>> @@ -0,0 +1,248 @@
>> +//  -*- 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
>> +//
>> +//===---===//
>> +
>> +#ifndef _GLIBCXX_BARRIER
>> +#define _GLIBCXX_BARRIER 1
>> +
>> +#pragma GCC system_header
>> +
>> +#if __cplusplus > 201703L
>> +#define __cpp_lib_barrier 201907L
> 
> This feature test macro will be defined unconditionally, even if
> _GLIBCXX_HAS_GTHREADS is not defined. It should be inside the check
> for gthreads.
> 
> You're also missing an edit to  (which should depend on the
> same conditions).
> 
> 
>> +#include 
>> +
>> +#if defined(_GLIBCXX_HAS_GTHREADS)
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +
>> +namespace std _GLIBCXX_VISIBILITY(default)
>> +{
>> +_GLIBCXX_BEGIN_NAMESPACE_VERSION
>> +
>> +  struct __empty_completion
>> +  {
>> +_GLIBCXX_ALWAYS_INLINE void
>> +operator()() noexcept
>> +{ }
>> +  };
>> +
>> +/*
>> +
>> +The default implementation of __barrier_base is a classic tree barrier.
>> +
>> +It looks different from literatu

Re: [PATCH] libstdc++: Add support for C++20 barriers

2020-11-04 Thread Thomas Rodgers



> On Nov 4, 2020, at 10:52 AM, Jonathan Wakely  wrote:
> 
> On 04/11/20 10:41 -0800, Thomas Rodgers wrote:
>> From: Thomas Rodgers 
>> 
>> IGNORE the previous version of this patch please.
> 
> OK, but all my comments seem to apply to this one too.
> 

Sure :)

>> Adds 
>> 
>> libstdc++/ChangeLog:
>> 
>>  * include/Makefile.am (std_headers): Add new header.
>>  * include/Makefile.in: Regenerate.
>>  * include/std/barrier: New file.
>>  * 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/bits/atomic_base.h   |  11 +-
>> libstdc++-v3/include/std/barrier  | 248 ++
>> libstdc++-v3/include/std/version  |   1 +
>> .../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 
>> 12 files changed, 562 insertions(+), 3 deletions(-)
>> 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 382e94322c1..9e497835ee0 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/bits/atomic_base.h 
>> b/libstdc++-v3/include/bits/atomic_base.h
>> index dd4db926592..1ad34719d3e 100644
>> --- a/libstdc++-v3/include/bits/atomic_base.h
>> +++ b/libstdc++-v3/include/bits/atomic_base.h
>> @@ -603,13 +603,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>  }
>> 
>> #if __cplusplus > 201703L
>> +  template
>> +_GLIBCXX_ALWAYS_INLINE void
>> +_M_wait(__int_type __old, const _Func& __fn) const noexcept
>> +{ std::__atomic_wait(&_M_i, __old, __fn); }
>> +
>>  _GLIBCXX_ALWAYS_INLINE void
>>  wait(__int_type __old,
>>memory_order __m = memory_order_seq_cst) const noexcept
>>  {
>> -std::__atomic_wait(&_M_i, __old,
>> -   [__m, this, __old]
>> -   { return this->load(__m) != __old; });
>> +_M_wait(__old,
>> +[__m, this, __old]
>> +{ return this->load(__m) != __old; });
>>  }
> 
> This looks like it's not meant to be part of this patch.
> 
> It also looks wrong for any patch, because it adds _M_wait as a public
> member.
> 
> Not sure what this piece is for :-)
> 

It is used at include/std/barrier:197 to keep the implementation as close as 
possible to the libc++ version upon which it is based.


> 



[PATCH] libstdc++: Add support for C++20 barriers

2020-11-04 Thread Thomas Rodgers
From: Thomas Rodgers 

IGNORE the previous version of this patch please.

Adds 

libstdc++/ChangeLog:

* include/Makefile.am (std_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/std/barrier: New file.
* 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/bits/atomic_base.h   |  11 +-
 libstdc++-v3/include/std/barrier  | 248 ++
 libstdc++-v3/include/std/version  |   1 +
 .../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 
 12 files changed, 562 insertions(+), 3 deletions(-)
 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 382e94322c1..9e497835ee0 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/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index dd4db926592..1ad34719d3e 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -603,13 +603,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 #if __cplusplus > 201703L
+  template
+   _GLIBCXX_ALWAYS_INLINE void
+   _M_wait(__int_type __old, const _Func& __fn) const noexcept
+   { std::__atomic_wait(&_M_i, __old, __fn); }
+
   _GLIBCXX_ALWAYS_INLINE void
   wait(__int_type __old,
  memory_order __m = memory_order_seq_cst) const noexcept
   {
-   std::__atomic_wait(&_M_i, __old,
-  [__m, this, __old]
-  { return this->load(__m) != __old; });
+   _M_wait(__old,
+   [__m, this, __old]
+   { return this->load(__m) != __old; });
   }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
new file mode 100644
index 000..50654b00a0c
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,248 @@
+//  -*- 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
+//
+//===---===//
+
+#ifndef _GLIBCXX_BARRIER
+#define _GLIBCXX_BARRIER 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+#define __cpp_lib_barrier 20190

[PATCH] libstdc++: Add support for C++20 barriers

2020-11-04 Thread Thomas Rodgers
From: Thomas Rodgers 

Adds 

libstdc++/ChangeLog:

* include/Makefile.am (std_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/std/barrier: New file.
* 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/std/barrier  | 248 ++
 .../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 
 8 files changed, 551 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/std/barrier b/libstdc++-v3/include/std/barrier
new file mode 100644
index 000..80e6d668cf5
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,248 @@
+//  -*- 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
+//
+//===---===//
+
+#ifndef _GLIBCXX_BARRIER
+#define _GLIBCXX_BARRIER 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+#define __cpp_lib_barrier 201907L
+
+#include 
+
+#if defined(_GLIBCXX_HAS_GTHREADS)
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  struct __empty_completion
+  {
+_GLIBCXX_ALWAYS_INLINE void
+operator()() noexcept
+{ }
+  };
+
+/*
+
+The default implementation of __barrier_base 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
+class __barrier_base
+{
+  struct alignas(64) /* naturally-align the heap state */ __state_t
+  {
+   struct
+   {
+ __atomic_base<__barrier_phase_t> __phase = ATOMIC_VAR_INIT(0);
+   } __tickets[64];
+  };
+
+  ptrdiff_t _M_expected;
+  unique_ptr _M_state_allocation;
+  __state_t*   _M_state;
+  __atomic_base _M_expected_adjustment;
+  _CompletionF _M_completion;
+  __atomic_base<__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() != thre

Re: [PATCH] libstdc++: Add c++2a

2020-11-02 Thread Thomas Rodgers via Gcc-patches


Testsed x86_64-pc-linux-gnu, committed to master.

Jonathan Wakely writes:

> On 02/11/20 08:10 -0800, Thomas Rodgers wrote:
>>From: Thomas Rodgers 
>>
>>IGNORE the previous patch.
>>
>>Changes implementation to use a private __mutex type as discussed on
>>IRC.
>>
>>libstdc++/ChangeLog:
>>  libstdc++-v3/doc/doxygen/user.cfg.in (INPUT): Add new header.
>>  libstdc++-v3/include/Makefile.am (std_headers): Add new header.
>>  libstdc++-v3/include/Makefile.in: Regenerate.
>>  libstdc++-v3/include/precompiled/stdc++.h: Include new header.
>>  (basic_streambuf): Befriend __detail::__streambuf_core_access.
>>  libstdc++-v3/include/std/syncstream: New header.
>>  libstdc++-v3/include/std/version: Add __cpp_lib_syncbuf:
>>  libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc: New test.
>>  libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc: Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc:
>>  Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc:
>>  Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc:
>>  Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc: Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc: Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc:
>>  Likewise.
>>  libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.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 |   2 +-
>> libstdc++-v3/include/std/syncstream   | 333 ++
>> libstdc++-v3/include/std/version  |   4 +
>> .../testsuite/27_io/basic_syncbuf/1.cc|  28 ++
>> .../testsuite/27_io/basic_syncbuf/2.cc|  28 ++
>> .../27_io/basic_syncbuf/basic_ops/1.cc| 137 +++
>> .../27_io/basic_syncbuf/requirements/types.cc |  42 +++
>> .../27_io/basic_syncbuf/sync_ops/1.cc | 130 +++
>> .../testsuite/27_io/basic_syncstream/1.cc |  28 ++
>> .../testsuite/27_io/basic_syncstream/2.cc |  28 ++
>> .../27_io/basic_syncstream/basic_ops/1.cc | 134 +++
>> .../basic_syncstream/requirements/types.cc|  43 +++
>> 15 files changed, 939 insertions(+), 1 deletion(-)
>> create mode 100644 libstdc++-v3/include/std/syncstream
>> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc
>> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc
>> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc
>> create mode 100644 
>> libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc
>> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
>> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc
>> create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc
>> create mode 100644 
>> libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
>> create mode 100644 
>> libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.cc
>>
>>diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in 
>>b/libstdc++-v3/doc/doxygen/user.cfg.in
>>index 9b49a15d31b..320f6dea688 100644
>>--- a/libstdc++-v3/doc/doxygen/user.cfg.in
>>+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
>>@@ -897,6 +897,7 @@ INPUT  = 
>>@srcdir@/doc/doxygen/doxygroups.cc \
>>  include/streambuf \
>>  include/string \
>>  include/string_view \
>>+ include/syncstream \
>>  include/system_error \
>>  include/thread \
>>  include/tuple \
>>diff --git a/libstdc++-v3/include/Makefile.am 
>>b/libstdc++-v3/include/Makefile.am
>>index c90ac555e15..8652b921274 100644
>>--- a/libstdc++-v3/include/Makefile.am
>>+++ b/libstdc++-v3/include/Makefile.am
>>@@ -73,6 +73,7 @@ std_headers = \
>>  ${std_srcdir}/shared_mutex \
>>  ${std_srcdir}/span \
>>  ${std_srcdir}/sstream \
>>+ ${std_srcdir}/syncstream \
>>  ${std_srcdir}/stack \
>>  ${std_srcdir}/stdexcept \
>>  ${std_srcdir}/stop_token \
>>diff --git a/libstdc++-v3/include/precompiled/stdc++.h 
>>b/libstdc++-v3/include/precompiled/stdc++.h
>>index 7518a98

[PATCH] libstdc++: Add c++2a

2020-11-02 Thread Thomas Rodgers
From: Thomas Rodgers 

IGNORE the previous patch.

Changes implementation to use a private __mutex type as discussed on
IRC.

libstdc++/ChangeLog:
libstdc++-v3/doc/doxygen/user.cfg.in (INPUT): Add new header.
libstdc++-v3/include/Makefile.am (std_headers): Add new header.
libstdc++-v3/include/Makefile.in: Regenerate.
libstdc++-v3/include/precompiled/stdc++.h: Include new header.
(basic_streambuf): Befriend __detail::__streambuf_core_access.
libstdc++-v3/include/std/syncstream: New header.
libstdc++-v3/include/std/version: Add __cpp_lib_syncbuf:
libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc: New test.
libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.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 |   2 +-
 libstdc++-v3/include/std/syncstream   | 333 ++
 libstdc++-v3/include/std/version  |   4 +
 .../testsuite/27_io/basic_syncbuf/1.cc|  28 ++
 .../testsuite/27_io/basic_syncbuf/2.cc|  28 ++
 .../27_io/basic_syncbuf/basic_ops/1.cc| 137 +++
 .../27_io/basic_syncbuf/requirements/types.cc |  42 +++
 .../27_io/basic_syncbuf/sync_ops/1.cc | 130 +++
 .../testsuite/27_io/basic_syncstream/1.cc |  28 ++
 .../testsuite/27_io/basic_syncstream/2.cc |  28 ++
 .../27_io/basic_syncstream/basic_ops/1.cc | 134 +++
 .../basic_syncstream/requirements/types.cc|  43 +++
 15 files changed, 939 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/std/syncstream
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.cc

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in 
b/libstdc++-v3/doc/doxygen/user.cfg.in
index 9b49a15d31b..320f6dea688 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -897,6 +897,7 @@ INPUT  = @srcdir@/doc/doxygen/doxygroups.cc 
\
  include/streambuf \
  include/string \
  include/string_view \
+ include/syncstream \
  include/system_error \
  include/thread \
  include/tuple \
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index c90ac555e15..8652b921274 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -73,6 +73,7 @@ std_headers = \
${std_srcdir}/shared_mutex \
${std_srcdir}/span \
${std_srcdir}/sstream \
+   ${std_srcdir}/syncstream \
${std_srcdir}/stack \
${std_srcdir}/stdexcept \
${std_srcdir}/stop_token \
diff --git a/libstdc++-v3/include/precompiled/stdc++.h 
b/libstdc++-v3/include/precompiled/stdc++.h
index 7518a98c25a..8899c323a28 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -141,6 +141,6 @@
 #include 
 #include 
 #include 
-// #include 
+#include 
 #include 
 #endif
diff --git a/libstdc++-v3/include/std/syncstream 
b/libstdc++-v3/include/std/syncstream
new file mode 100644
index 000..ff96ca6cf59
--- /dev/null
+++ b/libstdc++-v3/include/std/syncstream
@@ -0,0 +1,333 @@
+//  -*- 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

[PATCH] libstdc++: Add c++2a

2020-11-02 Thread Thomas Rodgers
From: Thomas Rodgers 

Changes implementation to use a private __mutex type as discussed on
IRC.

libstdc++/ChangeLog:
libstdc++-v3/doc/doxygen/user.cfg.in (INPUT): Add new header.
libstdc++-v3/include/Makefile.am (std_headers): Add new header.
libstdc++-v3/include/Makefile.in: Regenerate.
libstdc++-v3/include/precompiled/stdc++.h: Include new header.
(basic_streambuf): Befriend __detail::__streambuf_core_access.
libstdc++-v3/include/std/syncstream: New header.
libstdc++-v3/include/std/version: Add __cpp_lib_syncbuf:
libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc: New test.
libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.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 |   2 +-
 libstdc++-v3/include/std/syncstream   | 328 ++
 libstdc++-v3/include/std/version  |   4 +
 .../testsuite/27_io/basic_syncbuf/1.cc|  28 ++
 .../testsuite/27_io/basic_syncbuf/2.cc|  28 ++
 .../27_io/basic_syncbuf/basic_ops/1.cc| 137 
 .../27_io/basic_syncbuf/requirements/types.cc |  42 +++
 .../27_io/basic_syncbuf/sync_ops/1.cc | 130 +++
 .../testsuite/27_io/basic_syncstream/1.cc |  28 ++
 .../testsuite/27_io/basic_syncstream/2.cc |  28 ++
 .../27_io/basic_syncstream/basic_ops/1.cc | 134 +++
 .../basic_syncstream/requirements/types.cc|  43 +++
 15 files changed, 934 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/std/syncstream
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.cc

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in 
b/libstdc++-v3/doc/doxygen/user.cfg.in
index 9b49a15d31b..320f6dea688 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -897,6 +897,7 @@ INPUT  = @srcdir@/doc/doxygen/doxygroups.cc 
\
  include/streambuf \
  include/string \
  include/string_view \
+ include/syncstream \
  include/system_error \
  include/thread \
  include/tuple \
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index c90ac555e15..8652b921274 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -73,6 +73,7 @@ std_headers = \
${std_srcdir}/shared_mutex \
${std_srcdir}/span \
${std_srcdir}/sstream \
+   ${std_srcdir}/syncstream \
${std_srcdir}/stack \
${std_srcdir}/stdexcept \
${std_srcdir}/stop_token \
diff --git a/libstdc++-v3/include/precompiled/stdc++.h 
b/libstdc++-v3/include/precompiled/stdc++.h
index 7518a98c25a..8899c323a28 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -141,6 +141,6 @@
 #include 
 #include 
 #include 
-// #include 
+#include 
 #include 
 #endif
diff --git a/libstdc++-v3/include/std/syncstream 
b/libstdc++-v3/include/std/syncstream
new file mode 100644
index 000..88452c2ed10
--- /dev/null
+++ b/libstdc++-v3/include/std/syncstream
@@ -0,0 +1,328 @@
+//  -*- 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

[PATCH] libstdc++: Add c++2a

2020-10-29 Thread Thomas Rodgers
From: Thomas Rodgers 

Addresses latest patch feedback. Changes  to also work on
single threaded configurations.

libstdc++/ChangeLog:
libstdc++-v3/doc/doxygen/user.cfg.in (INPUT): Add new header.
libstdc++-v3/include/Makefile.am (std_headers): Add new header.
libstdc++-v3/include/Makefile.in: Regenerate.
libstdc++-v3/include/precompiled/stdc++.h: Include new header.
(basic_streambuf): Befriend __detail::__streambuf_core_access.
libstdc++-v3/include/std/syncstream: New header.
libstdc++-v3/include/std/version: Add __cpp_lib_syncbuf:
libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc: New test.
libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc: Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc:
Likewise.
libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.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 |   2 +-
 libstdc++-v3/include/std/syncstream   | 328 ++
 libstdc++-v3/include/std/version  |   4 +
 .../testsuite/27_io/basic_syncbuf/1.cc|  28 ++
 .../testsuite/27_io/basic_syncbuf/2.cc|  28 ++
 .../27_io/basic_syncbuf/basic_ops/1.cc| 137 
 .../27_io/basic_syncbuf/requirements/types.cc |  42 +++
 .../27_io/basic_syncbuf/sync_ops/1.cc | 130 +++
 .../testsuite/27_io/basic_syncstream/1.cc |  28 ++
 .../testsuite/27_io/basic_syncstream/2.cc |  28 ++
 .../27_io/basic_syncstream/basic_ops/1.cc | 134 +++
 .../basic_syncstream/requirements/types.cc|  43 +++
 15 files changed, 934 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/std/syncstream
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/2.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/basic_ops/1.cc
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_syncbuf/requirements/types.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/2.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_syncstream/basic_ops/1.cc
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_syncstream/requirements/types.cc

diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in 
b/libstdc++-v3/doc/doxygen/user.cfg.in
index 9b49a15d31b..320f6dea688 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -897,6 +897,7 @@ INPUT  = @srcdir@/doc/doxygen/doxygroups.cc 
\
  include/streambuf \
  include/string \
  include/string_view \
+ include/syncstream \
  include/system_error \
  include/thread \
  include/tuple \
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index c90ac555e15..8652b921274 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -73,6 +73,7 @@ std_headers = \
${std_srcdir}/shared_mutex \
${std_srcdir}/span \
${std_srcdir}/sstream \
+   ${std_srcdir}/syncstream \
${std_srcdir}/stack \
${std_srcdir}/stdexcept \
${std_srcdir}/stop_token \
diff --git a/libstdc++-v3/include/precompiled/stdc++.h 
b/libstdc++-v3/include/precompiled/stdc++.h
index 7518a98c25a..8899c323a28 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -141,6 +141,6 @@
 #include 
 #include 
 #include 
-// #include 
+#include 
 #include 
 #endif
diff --git a/libstdc++-v3/include/std/syncstream 
b/libstdc++-v3/include/std/syncstream
new file mode 100644
index 000..88452c2ed10
--- /dev/null
+++ b/libstdc++-v3/include/std/syncstream
@@ -0,0 +1,328 @@
+//  -*- 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

[PATCH] libstdc++: Add C++2a synchronization support

2020-10-26 Thread Thomas Rodgers
From: Thomas Rodgers 

Add support for -
  * atomic_flag::wait/notify_one/notify_all
  * atomic::wait/notify_one/notify_all
  * counting_semaphore
  * binary_semaphore
  * latch

libstdc++-v3/ChangeLog:

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_flag::wait): Define.
(__atomic_flag::notify_one): Likewise.
(__atomic_flag::notify_all): Likewise.
(__atomic_base<_Itp>::wait): Likewise.
(__atomic_base<_Itp>::notify_one): Likewise.
(__atomic_base<_Itp>::notify_all): Likewise.
(__atomic_base<_Ptp*>::wait): Likewise.
(__atomic_base<_Ptp*>::notify_one): Likewise.
(__atomic_base<_Ptp*>::notify_all): Likewise.
(__atomic_impl::wait): Likewise.
(__atomic_impl::notify_one): Likewise.
(__atomic_impl::notify_all): Likewise.
(__atomic_float<_Fp>::wait): Likewise.
(__atomic_float<_Fp>::notify_one): Likewise.
(__atomic_float<_Fp>::notify_all): Likewise.
(__atomic_ref<_Tp>::wait): Likewise.
(__atomic_ref<_Tp>::notify_one): Likewise.
(__atomic_ref<_Tp>::notify_all): Likewise.
(atomic_wait<_Tp>): Likewise.
(atomic_wait_explicit<_Tp>): Likewise.
(atomic_notify_one<_Tp>): Likewise.
(atomic_notify_all<_Tp>): Likewise.
* include/bits/atomic_wait.h: New file.
* include/bits/atomic_timed_wait.h: New file.
* include/bits/semaphore_base.h: New file.
* include/std/atomic (atomic::wait): Define.
(atomic::wait_one): Likewise.
(atomic::wait_all): Likewise.
(atomic<_Tp>::wait): Likewise.
(atomic<_Tp>::wait_one): Likewise.
(atomic<_Tp>::wait_all): Likewise.
(atomic<_Tp*>::wait): Likewise.
(atomic<_Tp*>::wait_one): Likewise.
(atomic<_Tp*>::wait_all): Likewise.
* include/std/latch: New file.
* include/std/semaphore: New file.
* include/std/version: Add __cpp_lib_semaphore and
__cpp_lib_latch defines.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
* testsuite/29_atomic/atomic_float/wait_notify.cc: Likewise.
* testsuite/29_atomic/atomic_integral/wait_notify.cc: Likewise.
* testsuite/29_atomic/atomic_ref/wait_notify.cc: Likewise.
* testsuite/30_thread/semaphore/1.cc: New test.
* testsuite/30_thread/semaphore/2.cc: Likewise.
* testsuite/30_thread/semaphore/least_max_value_neg.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_for.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_posix.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_until.cc: Likewise.
* testsuite/30_thread/latch/1.cc: New test.
* testsuite/30_thread/latch/2.cc: New test.
* testsuite/30_thread/latch/3.cc: New test.
* testsuite/util/atomic/wait_notify_util.h: New File.
---
 libstdc++-v3/include/Makefile.am  |   5 +
 libstdc++-v3/include/Makefile.in  |   5 +
 libstdc++-v3/include/bits/atomic_base.h   | 195 ++-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 287 
 libstdc++-v3/include/bits/atomic_wait.h   | 306 ++
 libstdc++-v3/include/bits/semaphore_base.h| 296 +
 libstdc++-v3/include/std/atomic   |  78 +
 libstdc++-v3/include/std/latch|  91 ++
 libstdc++-v3/include/std/semaphore|  92 ++
 libstdc++-v3/include/std/version  |   2 +
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  61 
 .../29_atomics/atomic_float/wait_notify.cc|  32 ++
 .../29_atomics/atomic_integral/wait_notify.cc |  65 
 .../29_atomics/atomic_ref/wait_notify.cc  | 103 ++
 libstdc++-v3/testsuite/30_threads/latch/1.cc  |  27 ++
 libstdc++-v3/testsuite/30_threads/latch/2.cc  |  27 ++
 libstdc++-v3/testsuite/30_threads/latch/3.cc  |  69 
 .../testsuite/30_threads/semaphore/1.cc   |  27 ++
 .../testsuite/30_threads/semaphore/2.cc   |  27 ++
 .../semaphore/least_max_value_neg.cc  |  30 ++
 .../30_threads/semaphore/try_acquire.cc   |  55 
 .../30_threads/semaphore/try_acquire_for.cc   |  85 +
 .../30_threads/semaphore/try_acquire_posix.cc | 153 +
 .../30_threads/semaphore/try_acquire_un

[PATCH] libstdc++: Implement C++20 features for

2020-10-26 Thread Thomas Rodgers
From: Thomas Rodgers 

New ctors and ::view() accessor for -
  * basic_stingbuf
  * basic_istringstream
  * basic_ostringstream
  * basic_stringstreamm

New ::get_allocator() accessor for basic_stringbuf.

libstdc++-v3/ChangeLog:
* acinclude.m4 (glibcxx_SUBDIRS): Add src/c++20.
* config/abi/pre/gnu.ver: Update GLIBCXX_3.4.29 for the addition of -
basic_stringbuf::basic_stringbuf(allocator const&),
basic_stringbuf::basic_stringbuf(openmode, allocator const&),
basic_stringbuf::basic_stringbuf(basic_string&&, openmode),
basic_stringbuf::basic_stringbuf(basic_stringbuf&&, allocator const&),
basic_stringbuf::get_allocator(),
basic_stringbuf::view(),
basic_istringstream::basic_istringstream(basic_string&&, openmode),
basic_istringstream::basic_istringstream(openmode, allocator const&),
basic_istringstream::view(),
basic_ostringstream::basic_ostringstream(basic_string&&, openmode),
basic_ostringstream::basic_ostringstream(openmode, allocator const&),
basic_ostringstream::view(),
basic_stringstream::basic_stringstream(basic_string&&, openmode),
basic_stringstream::basic_stringstream(openmode, allocator const&),
basic_stringstream::view().
* configure: Regenerate.
* include/std/sstream:
(basic_stringbuf::basic_stringbuf(allocator const&)): New constructor.
(basic_stringbuf::basic_stringbuf(openmode, allocator const&)): 
Likewise.
(basic_stringbuf::basic_stringbuf(basic_string&&, openmode)): Likewise.
(basic_stringbuf::basic_stringbuf(basic_stringbuf&&, allocator 
const&)): Likewise.
(basic_stringbuf::get_allocator()): New method.
(basic_stringbuf::view()): Likewise.
(basic_istringstream::basic_istringstream(basic_string&&, openmode)):
New constructor.
(basic_istringstream::basic_istringstream(openmode, allocator const&)):
Likewise
(basic_istringstream::view()): New method.
(basic_ostringstream::basic_ostringstream(basic_string&&, openmode)):
New constructor.
(basic_ostringstream::basic_ostringstream(openmode, allocator const&)):
Likewise
(basic_ostringstream::view()): New method.
(basic_stringstream::basic_stringstream(basic_string&&, openmode)):
New constructor.
(basic_stringstream::basic_stringstream(openmode, allocator const&)):
Likewise
(basic_stringstream::view()): New method.
* src/Makefile.in: Add c++20 directory.
* src/Makefile.am: Regenerate.
* src/c++20/Makefile.am: Add makefile for new sub-directory.
* src/c++20/Makefile.in: Generate.
* src/c++20/sstream-inst.cc: New file defining explicit
instantiations for basic_stringbuf, basic_istringstream,
basic_ostringstream, and basic_stringstream member functions
added in C++20.
* testsuite/27_io/basic_stringbuf/cons/char/2.cc: New test.
* testsuite/27_io/basic_stringbuf/cons/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_stringbuf/view/char/2.cc: Likewise.
* testsuite/27_io/basic_stringbuf/view/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_istringstream/cons/char/2.cc: Likewise.
* testsuite/27_io/basic_istringstream/cons/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_istringstream/view/char/2.cc: Likewise.
* testsuite/27_io/basic_istringstream/view/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_ostringstream/cons/char/2.cc: Likewise.
* testsuite/27_io/basic_ostringstream/cons/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_ostringstream/view/char/2.cc: Likewise.
* testsuite/27_io/basic_ostringstream/view/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_stringstream/cons/char/2.cc: Likewise.
* testsuite/27_io/basic_stringstream/cons/wchar_t/2.cc: Likewise.
* testsuite/27_io/basic_stringstream/view/char/2.cc: Likewise.
* testsuite/27_io/basic_stringstream/view/wchar_t/2.cc: Likewise.
---
 libstdc++-v3/acinclude.m4 |   2 +-
 libstdc++-v3/config/abi/pre/gnu.ver   |  45 ++
 libstdc++-v3/configure|  16 +-
 libstdc++-v3/include/std/sstream  | 190 +
 libstdc++-v3/src/Makefile.am  |  12 +-
 libstdc++-v3/src/Makefile.in  |  14 +-
 libstdc++-v3/src/c++20/Makefile.am| 105 +++
 libstdc++-v3/src/c++20/Makefile.in| 735 ++
 libstdc++-v3/src/c++20/sstream-inst.cc| 108 +++
 .../27_io/basic_istringstream/cons/char/1.cc  |  85 ++
 .../basic_istringstream/cons/wchar_t/1.cc |  85 ++
 .../27_io/basic_istringstream/view/char/1.cc  |  35 +
 .../basic_istringstream/view/wchar_t/1.cc | 

  1   2   3   >