[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/Makef

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

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


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

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


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

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

This patch supercedes both the Add C++2a synchronization support patch
being replied to *and* the patch adding wait/notify_* to atomic_flag.

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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: New test.
* 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.
---
 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 | 281 
 libstdc++-v3/include/bits/atomic_wait.h   | 301 ++
 libstdc++-v3/include/bits/semaphore_base.h| 283 
 libstdc++-v3/include/std/atomic   |  73 +
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  92 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 ++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
 .../29_atomics/atomic/wait_notify/generic.h   | 160 ++
 .../atomic/wait_notify/integrals.cc   |  65 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  61 
 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  |  50 +++
 .../testsuite/30_threads/semaphore/1.cc   |  27 ++
 .../testsuite/30_threads/semaphore/2.cc   |  27 ++
 .../semaphore/least_max_value_neg.cc  |  30 ++

[PATCH] libstdc++: only pull in bits/align.h if C++11 or later

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

libstdc++-v3/ChangeLog:

* include/std/memory: Move #include  inside C++11
conditional includes.

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

---
 libstdc++-v3/include/std/memory | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index a56952fb114..aee7b050bd7 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -61,7 +61,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -75,6 +74,7 @@
 #  include   // std::basic_ostream
 #  include 
 #  include 
+#  include 
 #  include 
 #  include   // std::less
 #  include 
-- 
2.26.2



Re: [PATCH] Fix overflow handling in std::align

2020-09-14 Thread Thomas Rodgers



> On Sep 14, 2020, at 7:30 AM, Ville Voutilainen via Libstdc++ 
>  wrote:
> 
> On Mon, 14 Sep 2020 at 15:49, Glen Fernandes  wrote:
>> 
>> On Mon, Sep 14, 2020 at 5:52 AM Ville Voutilainen wrote:
>>> On Mon, 14 Sep 2020 at 12:51, Ville Voutilainen
>>> wrote:
 On Mon, 14 Sep 2020 at 09:18, Glen Fernandes
>>> wrote:
> Edit; Correct patch this time.
> 
> Fix overflow handling in align
 
 Should the test verify that space is unmodified when nullptr is returned?
>>> 
>>> ..and same for ptr.
>> 
>> Sounds like a good idea. Updated patch attached.
> 
> Looks good to me.

Agree.

Re: [PATCH] libstdc++: Rebase include/pstl to current upstream

2020-09-21 Thread Thomas Rodgers



> On Sep 21, 2020, at 7:40 AM, Jonathan Wakely  wrote:
> 
> On 15/09/20 20:35 -0700, Thomas Rodgers wrote:
>> From: Thomas Rodgers 
>> 
>> From llvm-project/pstl @ 0b2e0e80d96
>> 
>> libstdc++-v3/ChangeLog:
>> 
>>  * include/pstl/algorithm_impl.h: Update file.
>>  * include/pstl/execution_impl.h: Likewise.
>>  * include/pstl/glue_algorithm_impl.h: Likewise.
>>  * include/pstl/glue_memory_impl.h: Likewise.
>>  * include/pstl/glue_numeric_impl.h: Likewise.
>>  * include/pstl/memory_impl.h: Likewise.
>>  * include/pstl/numeric_impl.h: Likewise.
>>  * include/pstl/parallel_backend.h: Likewise.
>>  * include/pstl/parallel_backend_serial.h: Likewise.
>>  * include/pstl/parallel_backend_tbb.h: Likewise.
>>  * include/pstl/parallel_backend_utils.h: Likewise.
>>  * include/pstl/pstl_config.h: Likewise.
>>  * include/pstl/unseq_backend_simd.h: Likewise.
>> ---
>> libstdc++-v3/include/pstl/algorithm_impl.h| 181 ++--
>> libstdc++-v3/include/pstl/execution_impl.h|   4 +-
>> .../include/pstl/glue_algorithm_impl.h| 543 +--
>> libstdc++-v3/include/pstl/glue_memory_impl.h  | 264 ++---
>> libstdc++-v3/include/pstl/glue_numeric_impl.h |  68 +-
>> libstdc++-v3/include/pstl/memory_impl.h   |  67 +-
>> libstdc++-v3/include/pstl/numeric_impl.h  |   8 +-
>> libstdc++-v3/include/pstl/parallel_backend.h  |   8 +
>> .../include/pstl/parallel_backend_serial.h|   8 +-
>> .../include/pstl/parallel_backend_tbb.h   | 903 +++---
>> .../include/pstl/parallel_backend_utils.h | 248 +++--
>> libstdc++-v3/include/pstl/pstl_config.h   |  24 +-
>> .../include/pstl/unseq_backend_simd.h |  39 +-
>> 13 files changed, 1586 insertions(+), 779 deletions(-)
>> 
>> diff --git a/libstdc++-v3/include/pstl/glue_algorithm_impl.h 
>> b/libstdc++-v3/include/pstl/glue_algorithm_impl.h
>> index 379de4033ec..d2e30529f78 100644
>> --- a/libstdc++-v3/include/pstl/glue_algorithm_impl.h
>> +++ b/libstdc++-v3/include/pstl/glue_algorithm_impl.h
>> @@ -757,8 +743,7 @@ 
>> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
>> equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, 
>> _ForwardIterator1 __last1, _ForwardIterator2 __first2,
>>  _ForwardIterator2 __last2)
>> {
>> -return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, 
>> __last1, __first2, __last2,
>> -  __pstl::__internal::__pstl_equal());
>> +return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, 
>> __first2, __last2, std::equal_to<>());
> 
> Any idea why this is now called unqualified? I don't think we want ADL
> here.
> 
I’m sure it is related to ... 
> 
>> diff --git a/libstdc++-v3/include/pstl/parallel_backend_tbb.h 
>> b/libstdc++-v3/include/pstl/parallel_backend_tbb.h
>> index 9c05ade0532..4476486d548 100644
>> --- a/libstdc++-v3/include/pstl/parallel_backend_tbb.h
>> +++ b/libstdc++-v3/include/pstl/parallel_backend_tbb.h
> 
> This file is full of non-reserved names, like _root and _x_orig and
> move_y_range.
> 

The upstream authors not being sufficiently versed in thinking in terms of 
writing things up front to avoid the sort of issues that a stdlib requires of 
the code.
 
> Fixing those upstream might take a while though.

I have already started accumulating a set of patches for upstream which I’ll 
manage as independently of getting this rebase into gcc.

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

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

Updated patch incorporating latest feedback.

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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: New test.
* 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.
---
 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 | 281 
 libstdc++-v3/include/bits/atomic_wait.h   | 301 ++
 libstdc++-v3/include/bits/semaphore_base.h| 283 
 libstdc++-v3/include/std/atomic   |  73 +
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  92 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 ++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
 .../29_atomics/atomic/wait_notify/generic.h   | 160 ++
 .../atomic/wait_notify/integrals.cc   |  65 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  61 
 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  |  50 +++
 .../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.

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

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

Updated patch incorporating latest feedback (revised).

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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: New test.
* 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.
---
 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 | 281 
 libstdc++-v3/include/bits/atomic_wait.h   | 301 ++
 libstdc++-v3/include/bits/semaphore_base.h| 283 
 libstdc++-v3/include/std/atomic   |  73 +
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  92 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 ++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
 .../29_atomics/atomic/wait_notify/generic.h   | 160 ++
 .../atomic/wait_notify/integrals.cc   |  65 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 .../29_atomics/atomic_flag/wait_notify/1.cc   |  61 
 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  |  50 +++
 .../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

[PATCH] t/trodgers/c2a_synchronization

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

This *should* be the correct patch this time.

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  | 288 +++
 libstdc++-v3/include/bits/atomic_wait.h| 306 +
 libstdc++-v3/include/bits/semaphore_base.h | 298 
 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 +
 .../testsuite/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 +
 libstdc++-v3/testsuite/30_threads/semaphore/1.cc   |  27 ++
 libstdc++-v3/testsuite/30_threads/semaphore/2.cc   |  27 ++
 .../30_threads/semaphore/least_max_value_neg.cc|  30 ++
 .../testsuite/30_threads/semaphore/try_ac

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

2020-10-07 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.
---
 .topdeps  |   1 +
 .topmsg   |   2 +
 libstdc++-v3/acinclude.m4 |   2 +-
 libstdc++-v3/config/abi/pre/gnu.ver   |  60 ++
 libstdc++-v3/configure|  16 +-
 libstdc++-v3/include/std/sstream  | 198 +
 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| 110 +++
 .../27_io/basic_istringstream/cons/char/1.cc  |  84 ++
 .../basic_istringstream/cons/wchar_t/1.cc |

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

2020-10-07 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.
---
 .topdeps  |   1 +
 .topmsg   |   2 +
 libstdc++-v3/acinclude.m4 |   2 +-
 libstdc++-v3/config/abi/pre/gnu.ver   |  45 ++
 libstdc++-v3/configure|  16 +-
 libstdc++-v3/include/std/sstream  | 196 +
 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| 110 +++
 .../27_io/basic_istringstream/cons/char/1.cc  |  85 ++
 .../basic_istringstream/cons/wchar_t/1.cc |

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

2020-10-07 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  | 196 +
 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| 111 +++
 .../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 | 

[PATCH] Add support for C++2a stop_token

2019-10-22 Thread Thomas Rodgers


0001-Add-support-for-C-2a-stop_token.patch
Description: le patch


[PATCH] Add C++20 jthread type to --text follows this line-<#part type="text/x-patch" filename="/home/remote/trodgers/src/oss/gcc/jt/0001-Add-C-20-jthread-type-to-thread.patch" disposition=at

2019-10-23 Thread Thomas Rodgers




[PATCH] Add C++20 jthread type to (2nd attempt)

2019-10-23 Thread Thomas Rodgers
From 56b78956a003b91e538cd5c680d614fdaee9c9eb Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Wed, 23 Oct 2019 12:32:31 -0700
Subject: [PATCH] Add C++20 jthread type to 

---
 libstdc++-v3/ChangeLog|   8 +
 libstdc++-v3/include/std/stop_token   |  14 ++
 libstdc++-v3/include/std/thread   | 125 +++
 .../testsuite/30_threads/jthread/1.cc |  27 +++
 .../testsuite/30_threads/jthread/2.cc |  27 +++
 .../testsuite/30_threads/jthread/jthread.cc   | 198 ++
 6 files changed, 399 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/30_threads/jthread/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/jthread/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/jthread/jthread.cc

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 970c5c2a018..523620da1c3 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2019-10-23  Thomas Rodgers  
+
+	* include/std/stop_token (stop_token): Add operator==(), operator!=().
+	* include/std/thread: Add jthread type.
+	* testsuite/30_threads/jthread/1.cc: New test.
+	* testsuite/30_threads/jthread/2.cc: New test.
+	* testsuite/30_threads/jthread/jthread.cc: New test.
+
 2019-10-22  Thomas Rodgers  
 
 	* include/Makefile.am: Add  header.
diff --git a/libstdc++-v3/include/std/stop_token b/libstdc++-v3/include/std/stop_token
index b3655b85eae..04b9521d24e 100644
--- a/libstdc++-v3/include/std/stop_token
+++ b/libstdc++-v3/include/std/stop_token
@@ -87,6 +87,20 @@ namespace std _GLIBCXX_VISIBILITY(default)
   return stop_possible() && _M_state->_M_stop_requested();
 }
 
+[[nodiscard]]
+friend bool
+operator==(const stop_token& __a, const stop_token& __b)
+{
+  return __a._M_state == __b._M_state;
+}
+
+[[nodiscard]]
+friend bool
+operator!=(const stop_token& __a, const stop_token& __b)
+{
+  return __a._M_state == __b._M_state;
+}
+
   private:
 friend stop_source;
 template
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 90b4be6cd16..93afa766d18 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -39,6 +39,13 @@
 #include 
 #include 
 #include 
+
+#if __cplusplus > 201703L
+#define __cpp_lib_jthread 201907L
+#include 
+#include 
+#endif
+
 #include 
 #include 
 #include 
@@ -409,6 +416,124 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // @} group threads
 
+#ifdef __cpp_lib_jthread
+
+  class jthread
+  {
+  public:
+using id = std::thread::id;
+using native_handle_type = std::thread::native_handle_type;
+
+jthread() noexcept
+: _M_stop_source{ nostopstate_t{ } }
+{ }
+
+template, jthread>>>
+explicit
+jthread(_Callable&& __f, _Args&&... __args)
+  : _M_thread{[](stop_token __token, auto&& __cb, auto&&... __args)
+  {
+if constexpr(std::is_invocable_v<_Callable, stop_token, _Args...>)
+  {
+std::invoke(std::forward(__cb),
+std::move(__token),
+std::forward(__args)...);
+  }
+else
+  {
+std::invoke(std::forward(__cb),
+std::forward(__args)...);
+  }
+  },
+  _M_stop_source.get_token(),
+  std::forward<_Callable>(__f),
+  std::forward<_Args>(__args)...}
+{ }
+
+jthread(const jthread&) = delete;
+jthread(jthread&&) noexcept = default;
+
+~jthread()
+{
+  if (joinable())
+{
+  request_stop();
+  join();
+}
+}
+
+jthread&
+operator=(const jthread&) = delete;
+
+jthread&
+operator=(jthread&&) noexcept = default;
+
+void
+swap(jthread& __other) noexcept
+{
+  std::swap(_M_stop_source, __other._M_stop_source);
+  std::swap(_M_thread, __other._M_thread);
+}
+
+bool
+joinable() const noexcept
+{
+  return _M_thread.joinable();
+}
+
+void
+join()
+{
+  _M_thread.join();
+}
+
+void
+detach()
+{
+  _M_thread.detach();
+}
+
+id
+get_id() const noexcept
+{
+  _M_thread.get_id();
+}
+
+native_handle_type
+native_handle()
+{
+  return _M_thread.native_handle();
+}
+
+static unsigned
+hardware_concurrency() noexcept
+{
+  return std::thread::hardware_concurrency();
+}
+
+[[nodiscard]] stop_source
+get_stop_source() noexcept
+{
+  return _M_stop_source;
+}
+
+[[nodiscard]] stop_token
+get_stop_token() const noexcept
+{
+  return _M_stop_source.get_token();
+}
+
+

Re: [PATCH] Add support for C++2a stop_token

2019-10-23 Thread Thomas Rodgers

Thomas Rodgers writes:

Let's try this again.From 23e1c9402cc15666d099fd61b58a0019181a9115 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Tue, 22 Oct 2019 17:53:00 -0700
Subject: [PATCH] Add support for C++2a stop_token

  * include/Makefile.am: Add  header.
  * include/Makefile.in: Regenerate.
	* include/std/stop_token: New file.
	* include/std/version (__cpp_lib_jthread): New value.
	* testsuite/30_threads/stop_token/1.cc: New test.
	* testsuite/30_threads/stop_token/2.cc: New test.
	* testsuite/30_threads/stop_token/stop_token.cc: New test.
---
 libstdc++-v3/ChangeLog|  10 +
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/std/stop_token   | 338 ++
 libstdc++-v3/include/std/version  |   1 +
 .../testsuite/30_threads/stop_token/1.cc  |  27 ++
 .../testsuite/30_threads/stop_token/2.cc  |  27 ++
 .../30_threads/stop_token/stop_token.cc   |  93 +
 8 files changed, 498 insertions(+)
 create mode 100644 libstdc++-v3/include/std/stop_token
 create mode 100644 libstdc++-v3/testsuite/30_threads/stop_token/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/stop_token/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/stop_token/stop_token.cc

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 2ea0fe4ec40..970c5c2a018 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,13 @@
+2019-10-22  Thomas Rodgers  
+
+	* include/Makefile.am: Add  header.
+* include/Makefile.in: Regenerate.
+	* include/std/stop_token: New file.
+	* include/std/version (__cpp_lib_jthread): New value.
+	* testsuite/30_threads/stop_token/1.cc: New test.
+	* testsuite/30_threads/stop_token/2.cc: New test.
+	* testsuite/30_threads/stop_token/stop_token.cc: New test.
+
 2019-09-05  Jonathan Wakely  
 
 	* doc/xml/manual/status_cxx2020.xml: Update status for P0122R7 and
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index b8b786d9260..fb6777366bd 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -72,6 +72,7 @@ std_headers = \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
 	${std_srcdir}/stdexcept \
+	${std_srcdir}/stop_token \
 	${std_srcdir}/streambuf \
 	${std_srcdir}/string \
 	${std_srcdir}/string_view \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index cd1e9df5482..9b4ab670315 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -416,6 +416,7 @@ std_headers = \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
 	${std_srcdir}/stdexcept \
+	${std_srcdir}/stop_token \
 	${std_srcdir}/streambuf \
 	${std_srcdir}/string \
 	${std_srcdir}/string_view \
diff --git a/libstdc++-v3/include/std/stop_token b/libstdc++-v3/include/std/stop_token
new file mode 100644
index 000..b3655b85eae
--- /dev/null
+++ b/libstdc++-v3/include/std/stop_token
@@ -0,0 +1,338 @@
+//  -*- C++ -*-
+
+// Copyright (C) 2008-2019 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.
+
+// 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
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/stop_token
+ *  This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_STOP_TOKEN
+#define _GLIBCXX_STOP_TOKEN
+
+#include 
+#include 
+#include 
+#include 
+
+#define __cpp_lib_jthread 201907L
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+  _GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  class stop_source;
+  template
+  class stop_callback;
+
+  struct nostopstate_t { explicit nostopstate_t() = default; };
+  inline constexpr nostopstate_t nostopstate();
+
+  class stop_token {
+  public:
+stop_token() noexcept = default;
+
+stop_token(const stop_token& __other) noexcept
+  : _M_state(__other._M_state)
+{ }
+
+stop_token(stop_token&& __other) noexcept
+  : _M_state(std::move(__other._M_state))
+{ }
+
+~stop_token() = default;
+
+stop_token&
+   

Re: [PATCH] Add support for C++2a stop_token

2019-11-13 Thread Thomas Rodgers

The attached patch should be a complete implementation of C++20
stop_token, jthread, and changes to condition_variable_any which also
addresses the comments on the previous patch.
From 2cdaa367ed919b24f3bbb84d6f7391a350dce77b Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Wed, 13 Nov 2019 17:51:11 -0800
Subject: [PATCH] Support for jthread and stop_token

	* include/Makefile.am: Add  header.
  * include/Makefile.in: Regenerate.
	* include/std/condition_variable: Add overloads for stop_token support
	to condition_variable_any.
	* include/std/stop_token: New file.
	* include/std/thread: Add jthread type.
	* include/std/version (__cpp_lib_jthread): New value.
	* testsuite/30_threads/condition_variable_any/stop_token/1.cc: New test.
	* testsuite/30_threads/condition_variable_any/stop_token/2.cc: New test.
	* testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc: New test.
	* testsuite/30_threads/jthread/1.cc: New test.
	* testsuite/30_threads/jthread/2.cc: New test.
	* testsuite/30_threads/jthread/jthread.cc: New test.
	* testsuite/30_threads/stop_token/1.cc: New test.
	* testsuite/30_threads/stop_token/2.cc: New test.
	* testsuite/30_threads/stop_token/stop_token.cc: New test.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/std/condition_variable   |  84 
 libstdc++-v3/include/std/stop_token   | 370 ++
 libstdc++-v3/include/std/thread   | 125 ++
 libstdc++-v3/include/std/version  |   1 +
 .../condition_variable_any/stop_token/1.cc|  27 ++
 .../condition_variable_any/stop_token/2.cc|  27 ++
 .../stop_token/wait_on.cc | 136 +++
 .../testsuite/30_threads/jthread/1.cc |  27 ++
 .../testsuite/30_threads/jthread/2.cc |  27 ++
 .../testsuite/30_threads/jthread/jthread.cc   | 198 ++
 .../testsuite/30_threads/stop_token/1.cc  |  27 ++
 .../testsuite/30_threads/stop_token/2.cc  |  27 ++
 .../30_threads/stop_token/stop_token.cc   | 100 +
 14 files changed, 1177 insertions(+)
 create mode 100644 libstdc++-v3/include/std/stop_token
 create mode 100644 libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/jthread/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/jthread/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/jthread/jthread.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/stop_token/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/stop_token/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/stop_token/stop_token.cc

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 49fd41360bc..6300de9e96d 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -74,6 +74,7 @@ std_headers = \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
 	${std_srcdir}/stdexcept \
+	${std_srcdir}/stop_token \
 	${std_srcdir}/streambuf \
 	${std_srcdir}/string \
 	${std_srcdir}/string_view \
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index cc96661e94c..8887cee29fa 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -36,6 +36,7 @@
 #else
 
 #include 
+
 #include 
 #include 
 #include 
@@ -45,6 +46,11 @@
 #include 
 #include 
 
+#if __cplusplus > 201703L
+#define __cpp_lib_jthread 201907L
+#include 
+#endif
+
 #if defined(_GLIBCXX_HAS_GTHREADS)
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -360,6 +366,84 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   wait_for(_Lock& __lock,
 	   const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p)
   { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
+
+#ifdef __cpp_lib_jthread
+template 
+bool wait_on(_Lock& __lock,
+ stop_token __stoken,
+ _Predicate __p)
+{
+  if (__stoken.stop_requested())
+{
+  return __p();
+}
+ 
+  std::stop_callback __cb(__stoken, [this] { notify_all(); });
+  shared_ptr __mutex = _M_mutex;
+  while (!__p())
+{
+  unique_lock __my_lock(*__mutex);
+  if (__stoken.stop_requested())
+{
+  return false;
+}
+  // *__mutex must be unlocked before re-locking __lock so move
+  // ownership of *__mutex lock to an object with shorter lifetime.
+  _Unlock<_Lock> __unlock(__lock);
+  unique_lock __my_lock2(std::move(__my_lock));
+  _M_cond.wait(__my_lock2);
+}
+  return true;
+}
+
+template 
+bool wait_on_until(_Lock& __lock,
+   

[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 in

[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.
+
+// This

[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

[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

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.


> 



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 lit

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



[PATCH] Suppress deprecation warnings in tbb effective target check

2020-01-23 Thread Thomas Rodgers
From cfd3c2e2a49dd3e29b42baa0f22feffd4b346231 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Thu, 23 Jan 2020 21:54:44 -0800
Subject: [PATCH] Suppress deprecation warnings in tbb effective target check

TBB 2020 added deprecation warnings which produced output not expected by
check_effective_target_tbb-backend
---
 libstdc++-v3/testsuite/lib/libstdc++.exp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 94f3fdb2bc8..f451719bdd4 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1597,7 +1597,8 @@ proc check_effective_target_tbb-backend { } {
 puts $f "}"
 close $f
 
-set lines [v3_target_compile $src $exe executable "additional_flags=-std=c++17 additional_flags=-ltbb"]
+set lines [v3_target_compile $src $exe executable "additional_flags=-std=c++17 additional_flags=-ltbb
+   additional_flags=-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1"]
 file delete $src
 
 if [string match "" $lines] {
-- 
2.21.1



Re: [PATCH] libstdc++: Fix conformance issues in (PR92895)

2020-01-29 Thread Thomas Rodgers
Looks good to me, ok for trunk.

Thanks.

Jonathan Wakely writes:

> Fix synchronization issues in . Replace shared_ptr with
> _Stop_state_ref and a reference count embedded in the shared state.
> Replace std::mutex with spinlock using one bit of a std::atomic<> that
> also tracks whether a stop request has been made and how many
> stop_source objects share ownership of the state.
>
> The synchronization with callbacks being destroyed is based on the
> implementation by Lewis Baker and Nico Josuttis. It allows the
> callback being destroyed to detect whether it's currently running, and
> if so whether on the current thread or a different one.
>
> Tom, please take a look and give a review. As discussed, the
> binary_semaphore is temporary, until we have the real thing.



[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



[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++: 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
@@

[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_

[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

Re: [PATCH] Restore enable_if lost during original import of pstl

2019-12-10 Thread Thomas Rodgers


Tested x86_64-pc-linux-gnu, committed to trunk, backported to
gcc-9-branch.

Jonathan Wakely writes:

> On 18/11/19 20:54 -0800, Thomas Rodgers wrote:
>>
>>  * include/pstl/glue_numeric_defs.h: Restore enable_if lost during 
>> original
>>  import of pstl.
>>  * include/pstl/glue_numeric_impl.h: Likewise.
>
> OK for trunk and gcc-9-branch, thanks.



[PATCH] Rename condition_variable_any::wait_on_* methods

2019-12-10 Thread Thomas Rodgers
User-agent: mu4e 1.3.4; emacs 26.2
* include/std/condition_variable
(condition_variable_any::wait_on(_Lock&, stop_token, _Predicate): Rename
to match current draft standard.
(condition_variable_any::wait_on_until(_Lock&, stop_token,
const chrono::time_point<>&, _Predicate): Likewise.
(condition_variable_any::wait_on_for(_Lock&, stop_token,
const chrono::duration<>&, _Predicate(: Likewise.
* testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc 
(main):
Adjust tests to account for renamed methods.
---
 libstdc++-v3/include/std/condition_variable   | 30 +--
 .../stop_token/wait_on.cc | 22 +++---
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/std/condition_variable 
b/libstdc++-v3/include/std/condition_variable
index 8887cee29fa..3346a28e5dd 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -369,9 +369,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #ifdef __cpp_lib_jthread
 template 
-bool wait_on(_Lock& __lock,
- stop_token __stoken,
- _Predicate __p)
+bool wait(_Lock& __lock,
+  stop_token __stoken,
+  _Predicate __p)
 {
   if (__stoken.stop_requested())
 {
@@ -397,10 +397,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 }
 
 template 
-bool wait_on_until(_Lock& __lock,
-   stop_token __stoken,
-   const chrono::time_point<_Clock, _Duration>& __abs_time,
-   _Predicate __p)
+bool wait_until(_Lock& __lock,
+stop_token __stoken,
+const chrono::time_point<_Clock, _Duration>& __abs_time,
+_Predicate __p)
 {
   if (__stoken.stop_requested())
 {
@@ -432,16 +432,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 }
 
 template 
-bool wait_on_for(_Lock& __lock,
- stop_token __stoken,
- const chrono::duration<_Rep, _Period>& __rel_time,
- _Predicate __p)
+bool wait_for(_Lock& __lock,
+  stop_token __stoken,
+  const chrono::duration<_Rep, _Period>& __rel_time,
+  _Predicate __p)
 {
   auto __abst = std::chrono::steady_clock::now() + __rel_time;
-  return wait_on_until(__lock,
-   std::move(__stoken),
-   __abst,
-   std::move(__p));
+  return wait_until(__lock,
+std::move(__stoken),
+__abst,
+std::move(__p));
 }
 #endif
   };
diff --git 
a/libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc
 
b/libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc
index 212fc949b3f..636425b43fc 100644
--- 
a/libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc
+++ 
b/libstdc++-v3/testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc
@@ -28,7 +28,7 @@
 
 using namespace::std::literals;
 
-void test_wait_on_stop()
+void test_wait_stop()
 {
   bool ready = false;
   std::mutex mtx;
@@ -40,7 +40,7 @@ void test_wait_on_stop()
   std::thread t([&ready, &mtx, &cv, tok]
 {
   std::unique_lock lck(mtx);
-  auto res = cv.wait_on(lck, tok, [&ready] { return ready; });
+  auto res = cv.wait(lck, tok, [&ready] { return ready; });
   if (!res)
 {
   VERIFY(tok.stop_requested());
@@ -54,7 +54,7 @@ void test_wait_on_stop()
   VERIFY(src.stop_requested());
 }
 
-void test_wait_on_until(bool ck = true)
+void test_wait_until(bool ck = true)
 {
   bool ready = false;
   std::mutex mtx;
@@ -67,7 +67,7 @@ void test_wait_on_until(bool ck = true)
   std::thread t([ck, &ready, &mtx, &cv, abst, tok]
 {
   std::unique_lock lck(mtx);
-  auto res = cv.wait_on_until(lck, tok, abst, [&ready] { 
return ready; });
+  auto res = cv.wait_until(lck, tok, abst, [&ready] { return 
ready; });
   if (!res && ck)
 {
   VERIFY(tok.stop_requested());
@@ -90,7 +90,7 @@ void test_wait_on_until(bool ck = true)
 }
 }
 
-void test_wait_on_for(bool ck = true)
+void test_wait_for(bool ck = true)
 {
   bool ready = false;
   std::mutex mtx;
@@ -102,7 +102,7 @@ void test_wait_on_for(bool ck = true)
   std::thread t([ck, &ready, &mtx, &cv, tok]
 {
   std::unique_lock lck(mtx);
-  auto res = cv.wait_on_for(lck, tok, 1.0s, [&ready] { return 
ready; });
+  auto res = cv.wait_for(lck, tok, 1.0s, [&ready] { return 
ready; });
   if (!res && ck)
 {
 

Re: [PATCH] Rename condition_variable_any::wait_on_* methods

2020-01-07 Thread Thomas Rodgers


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

Jonathan Wakely writes:

> On 10/12/19 22:38 -0800, Thomas Rodgers wrote:
>>User-agent: mu4e 1.3.4; emacs 26.2
>>  * include/std/condition_variable
>>  (condition_variable_any::wait_on(_Lock&, stop_token, _Predicate): Rename
>>  to match current draft standard.
>>  (condition_variable_any::wait_on_until(_Lock&, stop_token,
>>  const chrono::time_point<>&, _Predicate): Likewise.
>>  (condition_variable_any::wait_on_for(_Lock&, stop_token,
>>  const chrono::duration<>&, _Predicate(: Likewise.
>
> The closing paren here is an opening one. OK for trunk with that
> fixed.
>
> Optional tweaks ...
>
> Since the names wait_on, wait_on_until and wait_on_for are
> unambiguous, you could just list them without parameters i.e.
>
>   * include/std/condition_variable (condition_variable_any::wait_on)
>(condition_variable_any::wait_on_until)
>(condition_variable_any::wait_on_for): Rename to match current
>draft standard.
>
>>  * testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc 
>> (main):
>
> We don't generally both to say which functions were modified in tests,
> so the (main) isn't needed here, but is harmless.
>
>>  Adjust tests to account for renamed methods.



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


[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



[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] 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 = &i;
   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++] 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] 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-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



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.


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


[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] = {
+  { &tmp[0] },
+  { &tmp[16 * 4] },
+  { &tmp[32 * 4] },
+  { &tmp[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

[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*>

[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] = {
+ 

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.


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


[PATCH] Add C++2a synchronization support

2020-09-02 Thread Thomas Rodgers
Adds support for -
atomic wait/notify_one/notify_all
counting_semaphore
binary_semaphore
latch

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>::wait): Define.
(__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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* 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.
---
 libstdc++-v3/include/Makefile.am  |   5 +
 libstdc++-v3/include/Makefile.in  |   5 +
 libstdc++-v3/include/bits/atomic_base.h   | 172 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 281 
 libstdc++-v3/include/bits/atomic_wait.h   | 301 ++
 libstdc++-v3/include/bits/semaphore_base.h| 283 
 libstdc++-v3/include/std/atomic   |  73 +
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  92 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 ++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
 .../29_atomics/atomic/wait_notify/generic.h   | 160 ++
 .../atomic/wait_notify/integrals.cc   |  65 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 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  |  50 +++
 .../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_until.cc |  94 ++
 27 files changed, 2387 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/bits/atomic_timed_wait.h
 create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
 create mode 100644 libstdc++-v3/include/bits/semaphore_base.h
 create mode 100644 libstdc++-v3/include/std/latch
 create mode 100644 libstdc++-v3/include/std/semaphore
 create mode 100644 
libstdc++-v3

[PATCH] Add C++2a synchronization support

2020-09-02 Thread Thomas Rodgers
Note - ignore previous version of this patch, didn't filter out
Makefile.in

Adds support for -
atomic wait/notify_one/notify_all
counting_semaphore
binary_semaphore
latch

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>::wait): Define.
(__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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* 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.
---
 libstdc++-v3/include/Makefile.am  |   5 +
 libstdc++-v3/include/Makefile.in  |   5 +
 libstdc++-v3/include/bits/atomic_base.h   | 172 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 281 
 libstdc++-v3/include/bits/atomic_wait.h   | 301 ++
 libstdc++-v3/include/bits/semaphore_base.h| 283 
 libstdc++-v3/include/std/atomic   |  73 +
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  92 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 ++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
 .../29_atomics/atomic/wait_notify/generic.h   | 160 ++
 .../atomic/wait_notify/integrals.cc   |  65 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 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  |  50 +++
 .../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_until.cc |  94 ++
 27 files changed, 2387 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/bits/atomic_timed_wait.h
 create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
 create mode 100644 libstdc++-v3/include/bits/semaphore_base.h
 create mode 100644 libstdc++-v3/include/std/latch
 create mod

[PATCH] Add support for C++20 barriers

2020-09-07 Thread Thomas Rodgers
Re-sending

Adds 

* include/Makefile.am (std_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>::_M_wait): Define.
(__atomic_base<_Itp>::wait): Delegate to _M_wait.
* 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  |   3 +-
 libstdc++-v3/include/bits/atomic_base.h   |  16 +-
 libstdc++-v3/include/std/barrier  | 230 ++
 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|  34 +++
 .../30_threads/barrier/arrive_and_drop.cc |  32 +++
 .../30_threads/barrier/arrive_and_wait.cc |  33 +++
 .../30_threads/barrier/completion.cc  |  39 +++
 .../testsuite/30_threads/barrier/max.cc   |  26 ++
 12 files changed, 465 insertions(+), 4 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 ef8acd4a389..bae97852348 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 c121d993fee..98f9941c2d4 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -229,6 +229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __atomic_load(&_M_i, &__v, int(__m));
   return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
 }
+
 #endif // C++20
 
 _GLIBCXX_ALWAYS_INLINE void
@@ -566,13 +567,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 #if __cplusplus > 201703L
+  template
+   _GLIBCXX_ALWAYS_INLINE void
+   _M_wait(__int_type __old, _Pred&& __pred,
+   memory_order __m) const noexcept
+   {
+ std::__atomic_wait(&_M_i, __old,
+std::forward<_Pred&&>(__pred));
+   }
+
   _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; },
+   __m);
   }
 
   // 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..870db7db2ac
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,230 @@
+//  -*- C++ -*-
+// 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 reaso

[PATCH] Add support for atomic_flag::wait/notify_one/notify_all

2020-09-08 Thread Thomas Rodgers
* include/bits/atomic_base.h (__atomic_flag::wait): Define.
(__atomic_flag::notify_one): Likewise.
(__atomic_flag::notify_all): Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: New test.
---
 libstdc++-v3/include/bits/atomic_base.h   | 23 +++
 .../29_atomics/atomic_flag/wait_notify/1.cc   | 61 +++
 2 files changed, 84 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index c121d993fee..a7ddd03d544 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -229,6 +229,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __atomic_load(&_M_i, &__v, int(__m));
   return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
 }
+
+_GLIBCXX_ALWAYS_INLINE void
+wait(bool __old,
+   memory_order __m = memory_order_seq_cst) const noexcept
+{
+  std::__atomic_wait(&_M_i, __old,
+[__m, this, __old]()
+{ return this->test(__m) != __old; });
+}
+
+// TODO add const volatile overload
+
+_GLIBCXX_ALWAYS_INLINE void
+notify_one() const noexcept
+{ std::__atomic_notify(&_M_i, false); }
+
+// TODO add const volatile overload
+
+_GLIBCXX_ALWAYS_INLINE void
+notify_all() const noexcept
+{ std::__atomic_notify(&_M_i, true); }
+
+// TODO add const volatile overload
 #endif // C++20
 
 _GLIBCXX_ALWAYS_INLINE void
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
new file mode 100644
index 000..6de7873ecc2
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
@@ -0,0 +1,61 @@
+// { dg-options "-std=gnu++2a -pthread" }
+// { dg-do run { target c++2a } }
+// { dg-require-effective-target pthread }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+int
+main()
+{
+  using namespace std::literals::chrono_literals;
+
+  std::mutex m;
+  std::condition_variable cv;
+
+  std::atomic_flag a;
+  std::atomic_flag b;
+  std::thread t([&]
+   {
+ cv.notify_one();
+ a.wait(false);
+  b.test_and_set();
+  b.notify_one();
+   });
+
+  std::unique_lock l(m);
+  cv.wait(l);
+  std::this_thread::sleep_for(100ms);
+  a.test_and_set();
+  a.notify_one();
+  b.wait(false);
+  t.join();
+
+  VERIFY( a.test() );
+  VERIFY( b.test() );
+  return 0;
+}
-- 
2.26.2



[PATCH] Split std::align/assume_aligned to bits/align.h

2020-09-09 Thread Thomas Rodgers
We would like to be able to use these things without having to pull in
the whole of .

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/align.h: New file.
* include/std/memory (align): Move definition to bits/align.h.
(assume_aligned): Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/align.h | 104 ++
 libstdc++-v3/include/std/memory   |  60 +
 4 files changed, 107 insertions(+), 59 deletions(-)
 create mode 100644 libstdc++-v3/include/bits/align.h

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index bae97852348..eabec88219d 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -99,6 +99,7 @@ bits_srcdir = ${glibcxx_srcdir}/include/bits
 bits_builddir = ./bits
 bits_headers = \
${bits_srcdir}/algorithmfwd.h \
+   ${bits_srcdir}/align.h \
${bits_srcdir}/alloc_traits.h \
${bits_srcdir}/allocated_ptr.h \
${bits_srcdir}/allocator.h \
diff --git a/libstdc++-v3/include/bits/align.h 
b/libstdc++-v3/include/bits/align.h
new file mode 100644
index 000..593b337f897
--- /dev/null
+++ b/libstdc++-v3/include/bits/align.h
@@ -0,0 +1,104 @@
+// align implementation -*- C++ -*-
+
+// Copyright (C) 2008-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.
+
+// 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
+// .
+
+/** @file bits/align.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{memory}
+ */
+
+#ifndef _ALIGN_H
+#define _ALIGN_H 1
+
+#include 
+
+#include   // std::has_single_bit
+#include  // uintptr_t
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+/**
+ *  @brief Fit aligned storage in buffer.
+ *  @ingroup memory
+ *
+ *  This function tries to fit @a __size bytes of storage with alignment
+ *  @a __align into the buffer @a __ptr of size @a __space bytes.  If such
+ *  a buffer fits then @a __ptr is changed to point to the first byte of the
+ *  aligned storage and @a __space is reduced by the bytes used for alignment.
+ *
+ *  C++11 20.6.5 [ptr.align]
+ *
+ *  @param __align   A fundamental or extended alignment value.
+ *  @param __sizeSize of the aligned storage required.
+ *  @param __ptr Pointer to a buffer of @a __space bytes.
+ *  @param __space   Size of the buffer pointed to by @a __ptr.
+ *  @return the updated pointer if the aligned storage fits, otherwise nullptr.
+ *
+ */
+inline void*
+align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
+{
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+  const auto __intptr = reinterpret_cast(__ptr);
+#else
+  // Cannot use std::uintptr_t so assume that std::size_t can be used instead.
+  static_assert(sizeof(size_t) >= sizeof(void*),
+  "std::size_t must be a suitable substitute for std::uintptr_t");
+  const auto __intptr = reinterpret_cast(__ptr);
+#endif
+  const auto __aligned = (__intptr - 1u + __align) & -__align;
+  const auto __diff = __aligned - __intptr;
+  if ((__size + __diff) > __space)
+return nullptr;
+  else
+{
+  __space -= __diff;
+  return __ptr = reinterpret_cast(__aligned);
+}
+}
+
+#if __cplusplus > 201703L
+#define __cpp_lib_assume_aligned 201811L
+  /** @brief Inform the compiler that a pointer is aligned.
+   *
+   *  @tparam _Align An alignment value (i.e. a power of two)
+   *  @tparam _TpAn object type
+   *  @param  __ptr  A pointer that is aligned to _Align
+   *  @ingroup memory
+   */
+  template
+[[nodiscard,__gnu__::__always_inline__]]
+constexpr _Tp* assume_aligned(_Tp* __ptr)
+{
+  static_assert(std::has_single_bit(_Align));
+  _GLIBCXX_DEBUG_ASSERT((std::uintptr_t)__ptr % _Align == 0);
+  return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
+}
+#endif // C++2a
+
+_GLIBCXX_END_NAMESP

[PATCH] Add c++2a binary_semaphore

2020-02-17 Thread Thomas Rodgers
This patch adds the c++2a semaphore header and binary_semaphore type. The 
implementation is not complete, this patch is just to solicit initial feedback.

* include/std/semaphore: New file.
* include/std/version (__cpp_lib_semaphore): Add feature test macro.
* include/Makefile.am (std_headers): add semaphore.
* include/Makefile.in: Regenerate.
* testsuite/30_threads/semaphore/1.cc: New test.
* testsuite/30_threads/semaphore/2.cc: New test.
* testsuite/30_threads/semaphore/binary_semaphore.cc: New test.
* testsuite/30_threads/semaphore/try_acquire.cc: New test.
* testsuite/30_threads/semaphore/try_acquire_for.cc: New test.
* testsuite/30_threads/semaphore/try_acquire_until.cc: New test.

From 8ce4252605361ed33b389a91fb7e3aeec529d9ac Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Mon, 17 Feb 2020 19:58:57 -0800
Subject: [PATCH] Add c++2a binary_semaphore

* include/std/semaphore: New file.
* include/std/version (__cpp_lib_semaphore): Add feature test macro.
* include/Makefile.am (std_headers): add semaphore.
* include/Makefile.in: Regenerate.
* testsuite/30_threads/semaphore/1.cc: New test.
* testsuite/30_threads/semaphore/2.cc: New test.
* testsuite/30_threads/semaphore/binary_semaphore.cc: New test.
* testsuite/30_threads/semaphore/try_acquire.cc: New test.
* testsuite/30_threads/semaphore/try_acquire_for.cc: New test.
* testsuite/30_threads/semaphore/try_acquire_until.cc: New test.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/std/semaphore| 131 ++
 libstdc++-v3/include/std/version  |   1 +
 .../testsuite/30_threads/semaphore/1.cc   |  27 
 .../testsuite/30_threads/semaphore/2.cc   |  27 
 .../30_threads/semaphore/binary_semaphore.cc  |  47 +++
 .../30_threads/semaphore/try_acquire.cc   |  36 +
 .../30_threads/semaphore/try_acquire_for.cc   |  72 ++
 .../30_threads/semaphore/try_acquire_until.cc |  74 ++
 10 files changed, 417 insertions(+)
 create mode 100644 libstdc++-v3/include/std/semaphore
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/binary_semaphore.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 89835759069..2dbb7d3a6b1 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -69,6 +69,7 @@ std_headers = \
 	${std_srcdir}/ratio \
 	${std_srcdir}/regex \
 	${std_srcdir}/scoped_allocator \
+  ${std_srcdir}/semaphore \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
 	${std_srcdir}/span \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 123d24bb1c6..8f2780c86ce 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -414,6 +414,7 @@ std_headers = \
 	${std_srcdir}/ratio \
 	${std_srcdir}/regex \
 	${std_srcdir}/scoped_allocator \
+  ${std_srcdir}/semaphore \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
 	${std_srcdir}/span \
diff --git a/libstdc++-v3/include/std/semaphore b/libstdc++-v3/include/std/semaphore
new file mode 100644
index 000..e3e88a50eec
--- /dev/null
+++ b/libstdc++-v3/include/std/semaphore
@@ -0,0 +1,131 @@
+//  -*- C++ -*-
+
+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// 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
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/stop_token
+ *  This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_SEMAPHORE
+#define _GLIBCXX_SEMAPHORE
+
+#if __cplusplus >

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

2020-02-24 Thread Thomas Rodgers
Hopefully less borked than the previous one, adds futex support.

- Original Message -
From: "Thomas Rodgers" 
To: gcc-patches@gcc.gnu.org, libstd...@gcc.gnu.org
Sent: Wednesday, February 19, 2020 7:18:36 PM
Subject: Re: [PATCH] Add c++2a binary_semaphore

Should address the previous issues, adds backoff logic.

* include/std/semaphore: New file.
* include/std/version (__cpp_lib_semaphore): Add feature test macro.
* include/Makefile.am (std_headers): add semaphore.
* include/Makefile.in: Regenerate.
* testsuite/30_threads/semaphore/1.cc: New test.
* testsuite/30_threads/semaphore/2.cc: New test.
* testsuite/30_threads/semaphore/binary_semaphore.cc: New test.
* testsuite/30_threads/semaphore/try_acquire.cc: New test.
* testsuite/30_threads/semaphore/try_acquire_for.cc: New test.
* testsuite/30_threads/semaphore/try_acquire_until.cc: New test.

- Original Message -
From: "Jonathan Wakely" 
To: "Thomas Rodgers" 
Cc: gcc-patches@gcc.gnu.org, libstd...@gcc.gnu.org
Sent: Tuesday, February 18, 2020 6:25:41 AM
Subject: Re: [PATCH] Add c++2a binary_semaphore

On 18/02/20 01:46 -0500, Thomas Rodgers wrote:
>This patch adds the c++2a semaphore header and binary_semaphore type. The 
>implementation is not complete, this patch is just to solicit initial feedback.

Here is some initial feedback on comments and whitespace :-)

>diff --git a/libstdc++-v3/include/Makefile.am 
>b/libstdc++-v3/include/Makefile.am
>index 89835759069..2dbb7d3a6b1 100644
>--- a/libstdc++-v3/include/Makefile.am
>+++ b/libstdc++-v3/include/Makefile.am
>@@ -69,6 +69,7 @@ std_headers = \
>   ${std_srcdir}/ratio \
>   ${std_srcdir}/regex \
>   ${std_srcdir}/scoped_allocator \
>+  ${std_srcdir}/semaphore \

Indentation is borked.

>   ${std_srcdir}/set \
>   ${std_srcdir}/shared_mutex \
>   ${std_srcdir}/span \
>diff --git a/libstdc++-v3/include/std/semaphore 
>b/libstdc++-v3/include/std/semaphore
>new file mode 100644
>index 000..e3e88a50eec
>--- /dev/null
>+++ b/libstdc++-v3/include/std/semaphore
>@@ -0,0 +1,131 @@
>+//  -*- C++ -*-

Wrong header name in comment.

>+
>+// Copyright (C) 2019-2020 Free Software Foundation, Inc.
>+//
>+// This file is part of the GNU ISO C++ Library.  This library is free
>+// software; you can redistribute it and/or modify it under the
>+// terms of the GNU General Public License as published by the
>+// Free Software Foundation; either version 3, or (at your option)
>+// any later version.
>+
>+// This library is distributed in the hope that it will be useful,
>+// but WITHOUT ANY WARRANTY; without even the implied warranty of
>+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>+// GNU General Public License for more details.
>+
>+// 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
>+// <http://www.gnu.org/licenses/>.
>+
>+/** @file include/stop_token

Wrong name again.

>+ *  This is a Standard C++ Library header.
>+ */
>+
>+#ifndef _GLIBCXX_SEMAPHORE
>+#define _GLIBCXX_SEMAPHORE
>+
>+#if __cplusplus > 201703L
>+#define __cpp_lib_semaphore 201907L

We shouldn't define this until the file is complete, i.e. when it
provides binary_semaphore and counting_semaphore.

>+
>+#include 

Is this header needed? ptrdiff_t and size_t are both defined in
 which every header already includes.

>+#include 
>+#include 
>+
>+namespace std _GLIBCXX_VISIBILITY(default)
>+{
>+_GLIBCXX_BEGIN_NAMESPACE_VERSION
>+
>+  // TODO: replace this with a real implementation of std::binary_semaphore
>+  struct binary_semaphore
>+{

Indentation is borked here too.

>+  explicit binary_semaphore(int __d) : _M_counter(__d > 0) { }
>+
>+  static constexpr std::ptrdiff_t
>+  max() noexcept
>+  {
>+   return 1;
>+  }
>+
>+  void release() { _M_counter.fetch_add(1, memory_order::release); }
>+
>+  void acquire()
>+  {
>+   while (!_M_try_acquire())
>+ {
>+  _S_yield();
>+ }
>+  }
>+
>+  bool
>+  try_acquire() noexcept
>+  {
>+   return _M_try_acquire(1u);
>+  }
>+
>+  template
>+  bool try_acquire_for(const std::chrono::duration<_Rep, _Period>& __rel_time)
>+  {
>+   auto __abst = std::chrono::steady_clock::now() + __rel_time;
>+   return try_acquire_until(__abst);
>+  }
>+
>+  template
>+  bool try_acquire_until(c

[PATCH] Add C++2a wait/notify_one/notify_all support to std::atomic<>

2020-03-15 Thread Thomas Rodgers
This patch adds support for wait/notify_one/notify_all to std::atomic<>.
Support for the volatile overloads will be added in a subsequent patch.

* include/Makefile.am (bits_headers): Add new header.
* include/Mamefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>:wait): Define.
(__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/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.
* testsuite/29_atomic/atomic/wait_notify/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   2 +
 libstdc++-v3/include/bits/atomic_base.h   | 178 ++-
 libstdc++-v3/include/bits/atomic_wait.h   | 295 ++
 libstdc++-v3/include/std/atomic   |  61 
 .../atomic/wait_notify/atomic_refs.cc | 103 ++
 .../29_atomics/atomic/wait_notify/bool.cc |  57 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.h   |  88 ++
 .../atomic/wait_notify/integrals.cc   |  56 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 11 files changed, 931 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/floats.cc
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.h
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/integrals.cc
 create mode 100644 
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 80aeb3f8959..d195a721fd5 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -100,6 +100,7 @@ bits_headers = \
${bits_srcdir}/allocated_ptr.h \
${bits_srcdir}/allocator.h \
${bits_srcdir}/atomic_base.h \
+   ${bits_srcdir}/atomic_wait.h \
${bits_srcdir}/atomic_futex.h \
${bits_srcdir}/basic_ios.h \
${bits_srcdir}/basic_ios.tcc \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index eb437ad8d8d..4faaac5fb8d 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -445,6 +445,7 @@ bits_headers = \
${bits_srcdir}/allocated_ptr.h \
${bits_srcdir}/allocator.h \
${bits_srcdir}/atomic_base.h \
+   ${bits_srcdir}/atomic_wait.h \
${bits_srcdir}/atomic_futex.h \
${bits_srcdir}/basic_ios.h \
${bits_srcdir}/basic_ios.tcc \
@@ -526,6 +527,7 @@ bits_headers = \
${bits_srcdir}/specfun.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/std_abs.h \
+   ${bits_srcdir}/std_condvar.h \
${bits_srcdir}/std_function.h \
${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 87fe0bd6000..b4fbe2c6eb3 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -37,6 +37,11 @@
 #include 
 #include 
 
+#if __cplusplus > 201703L
+#include 
+#include 
+#endif
+
 #ifndef _GLIBCXX_ALWAYS_INL

Re: [PATCH] Include netinet/in.h in include/experimental/internet

2019-09-30 Thread Thomas Rodgers
Looks good to me.

Andreas Tobler writes:

> Hi all,
>
> I'm going to commit the attached patch to trunk.
> It is preapproved by Jonathan. (via #irc)
>
> On FreeBSD the netinet/in.h header is not included by arpa/inet.h, so do the
> include if we have the _GLIBCXX_HAVE_NETINET_IN_H defined.
>
> This makes all the experimental/net/internet test cases pass here.
>
> Any comments?
>
> TIA,
> Andreas
>
> Commit one-liner:
>
> Include netinet/in.h in include/experimental/internet
>
> 2019-09-30  Andreas Tobler  
>
>   * include/experimental/internet: Include netinet/in.h if we have
>   _GLIBCXX_HAVE_NETINET_IN_H defined.
>
> Index: include/experimental/internet
> ===
> --- include/experimental/internet (revision 276342)
> +++ include/experimental/internet (working copy)
> @@ -51,6 +51,9 @@
>  #ifdef _GLIBCXX_HAVE_ARPA_INET_H
>  # include   // inet_ntop
>  #endif
> +#ifdef _GLIBCXX_HAVE_NETINET_IN_H
> +# include  // IPPROTO_IP
> +#endif
>  #ifdef _GLIBCXX_HAVE_NETINET_TCP_H
>  # include // TCP_NODELAY
>  #endif



[PATCH] Add support for C++20 barriers

2020-05-23 Thread Thomas Rodgers
This patch requires the patch for atomic::wait/notify to be applied first.

This implementation is based on the libc++ implementation, but excludes the 
alternative “central barrier” implementation for now as there is no standard 
way to switch between the two.

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



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

2020-05-24 Thread Thomas Rodgers
This time with 100% more patch…



0001-Add-support-for-C-20-barriers_f.patch
Description: Binary data


> On May 23, 2020, at 3:58 PM, Thomas Rodgers  wrote:
> 
> This patch requires the patch for atomic::wait/notify to be applied first.
> 
> This implementation is based on the libc++ implementation, but excludes the 
> alternative “central barrier” implementation for now as there is no standard 
> way to switch between the two.
> 
>* 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.
> 



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

2020-05-24 Thread Thomas Rodgers



> On May 24, 2020, at 11:11 AM, Jonathan Wakely  wrote:
> 
> On Sun, 24 May 2020 at 18:55, Florian Weimer wrote:
>> 
>> * Thomas Rodgers:
>> 
>>> +  static __gthread_t
>>> +  _S_get_tid() noexcept
>>> +  {
>>> +#ifdef __GLIBC__
>>> + // For the GNU C library pthread_self() is usable without linking to
>>> + // libpthread.so but returns 0, so we cannot use it in single-threaded
>>> + // programs, because this_thread::get_id() != thread::id{} must be 
>>> true.
>>> + // We know that pthread_t is an integral type in the GNU C library.
>>> + if (!__gthread_active_p())
>>> +   return 1;
>>> +#endif
>>> + return __gthread_self();
>>> +  }
>> 
>> This comment seems outdated or incomplete.  pthread_self returns a
>> proper pointer since glibc 2.27, I believe.
> 
> The comment is copied from the  header, and dates from 2015.

Yes, this comes from  to avoid pulling in all of  to just get a 
hash from the current thread identity. I’m now using it in two places, is this 
worth splitting out somewhere?

> 
>> I'm also not sure how the difference is observable for the libstdc++
>> implementation.  Late loading of libpthread isn't quite supported.
> 
> It's nothing to do with late loading. A single threaded program that
> doesn't create any threads and doesn't link to libpthread can still
> expect std::this_thread::get_id() != std::thread::id() to be true in
> the main (and only) thread. If pthread_self() returns 0, and
> thread::id() default constructs with a value of 0, then we can't
> distinguish "the main thread" from "not a thread".
> 
> But I do see a non-zero value from glibc now, which is great. I'll add
> it to my TODO list to remove that workaround from .



[PATCH] Adjust wait logic to limit spurious evalution of wait predicate.

2020-05-24 Thread Thomas Rodgers
* include/bits/atomic_wait.h (__waiters::_M_do_wait): adjust wakeup 
logic.


[PATCH] Remove binary_semaphore implementation from stop_token

2020-05-24 Thread Thomas Rodgers
 * include/std/stop_token: Remove local binary_semaphore implementation.
   (_Stop_state_t::_M_do_try_lock): Use __thread_yield() from
   bits/atomic_wait.h.



0001-Remove-binary_semaphore-implementation-from-stop_tok.patch
Description: Binary data


Re: [PATCH] Adjust wait logic to limit spurious evalution of wait predicate.

2020-05-24 Thread Thomas Rodgers
And this time, with patch.



wake_up_fix.patch
Description: Binary data


> On May 24, 2020, at 3:06 PM, Thomas Rodgers  wrote:
> 
>   * include/bits/atomic_wait.h (__waiters::_M_do_wait): adjust wakeup 
> logic.



[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
+//
+//===---===//
+
+/**

[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] Add C++2a synchronization support

2020-06-05 Thread Thomas Rodgers
Add support for -
atomic wait/notify_one/notify_all
counting_semaphore
binary_semaphore
latch

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>::wait): Define.
(__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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* 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_futex.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.
---
 libstdc++-v3/include/Makefile.am  |   5 +
 libstdc++-v3/include/Makefile.in  |   5 +
 libstdc++-v3/include/bits/atomic_base.h   | 161 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 282 +
 libstdc++-v3/include/bits/atomic_wait.h   | 291 ++
 libstdc++-v3/include/bits/semaphore_base.h| 272 
 libstdc++-v3/include/std/atomic   |  61 
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  86 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 +++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.h   |  88 ++
 .../atomic/wait_notify/integrals.cc   |  56 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 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  |  50 +++
 .../testsuite/30_threads/semaphore/1.cc   |  27 ++
 .../testsuite/30_threads/semaphore/2.cc   |  27 ++
 .../semaphore/least_max_value_neg.cc  |  28 ++
 .../30_threads/semaphore/try_acquire.cc   |  55 
 .../30_threads/semaphore/try_acquire_for.cc   |  85 +
 .../30_threads/semaphore/try_acquire_futex.cc |  51 +++
 .../30_threads/semaphore/try_acquire_posix.cc | 169 ++
 .../30_threads/semaphore/try_acquire_until.cc |  94 ++
 27 files changed, 2291 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/bits/atomic_timed_wait.h
 create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
 create mode 100644 libstdc++-v3/include/bits/semaphore_base.h
 create mode 100644 libstdc++-v3/include/std/latch
 create mode 100644 libstdc++-v3/include/std/semaphore
 create mode 100644 
libstdc++-v3/

[PATCH] Add support for C++20 barriers

2020-06-06 Thread Thomas Rodgers
* 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   |  15 +-
 libstdc++-v3/include/std/barrier  | 230 ++
 libstdc++-v3/include/std/version  |   5 +-
 .../testsuite/30_threads/barrier/1.cc |  27 ++
 .../testsuite/30_threads/barrier/2.cc |  27 ++
 .../testsuite/30_threads/barrier/arrive.cc|  34 +++
 .../30_threads/barrier/arrive_and_drop.cc |  32 +++
 .../30_threads/barrier/arrive_and_wait.cc |  33 +++
 .../30_threads/barrier/completion.cc  |  39 +++
 .../testsuite/30_threads/barrier/max.cc   |  26 ++
 12 files changed, 465 insertions(+), 5 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 b3ac1a3365f..e2cded53779 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/Makefile.in b/libstdc++-v3/include/Makefile.in
index e73ff8b3e64..8e1163e8e18 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -375,6 +375,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 68d9e7e3756..271656c6b37 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -566,13 +566,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 #if __cplusplus > 201703L
+  template
+   _GLIBCXX_ALWAYS_INLINE void
+   _M_wait(__int_type __old, _Pred&& __pred,
+   memory_order __m) const noexcept
+   {
+ std::__atomic_wait(&_M_i, __old,
+std::forward<_Pred&&>(__pred));
+   }
+
   _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; },
+   __m);
   }
 
   // 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..870db7db2ac
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,230 @@
+//  -*- C++ -*-
+// 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 tr

[PATCH] Add C++2a synchronization support

2020-06-06 Thread Thomas Rodgers
Add support for -
atomic wait/notify_one/notify_all
counting_semaphore
binary_semaphore
latch

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>::wait): Define.
(__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/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* 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_futex.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.
---
 libstdc++-v3/include/Makefile.am  |   5 +
 libstdc++-v3/include/Makefile.in  |   5 +
 libstdc++-v3/include/bits/atomic_base.h   | 161 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 282 +
 libstdc++-v3/include/bits/atomic_wait.h   | 291 ++
 libstdc++-v3/include/bits/semaphore_base.h| 272 
 libstdc++-v3/include/std/atomic   |  61 
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  86 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 +++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.h   |  88 ++
 .../atomic/wait_notify/integrals.cc   |  56 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 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  |  50 +++
 .../testsuite/30_threads/semaphore/1.cc   |  27 ++
 .../testsuite/30_threads/semaphore/2.cc   |  27 ++
 .../semaphore/least_max_value_neg.cc  |  28 ++
 .../30_threads/semaphore/try_acquire.cc   |  55 
 .../30_threads/semaphore/try_acquire_for.cc   |  85 +
 .../30_threads/semaphore/try_acquire_futex.cc |  51 +++
 .../30_threads/semaphore/try_acquire_posix.cc | 169 ++
 .../30_threads/semaphore/try_acquire_until.cc |  94 ++
 27 files changed, 2291 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/bits/atomic_timed_wait.h
 create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
 create mode 100644 libstdc++-v3/include/bits/semaphore_base.h
 create mode 100644 libstdc++-v3/include/std/latch
 create mode 100644 libstdc++-v3/include/std/semaphore
 create mode 100644 
libstdc++-v3/

[PATCH 3/4] Adjust wait logic to limit spurious eval of wait predicate.

2020-06-06 Thread Thomas Rodgers
* include/bits/atomic_wait.h (__waiters::_M_do_wait): adjust wakeup
  logic.
---
 libstdc++-v3/include/bits/atomic_wait.h | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 92c1e2526ed..cce11ae1cf5 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -138,24 +138,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
   void
-  _M_do_wait(__platform_wait_t __version) noexcept
+  _M_do_wait(__platform_wait_t __old) noexcept
   {
+   __platform_wait_t __cur;
+   __atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE);
+   while (__cur == __old)
+ {
 #ifdef _GLIBCXX_HAVE_LINUX_FUTEX
-   __platform_wait(&_M_ver, __version);
+   __platform_wait(&_M_ver, __cur);
 #else
-   __platform_wait_t __cur = 0;
-   while (__cur <= __version)
- {
__waiters::__lock_t __l(_M_mtx);
auto __e = __gthread_cond_wait(&_M_cv, 
__l.mutex()->native_handle());
if (__e)
  std::terminate();
-   __platform_wait_t __last = __cur;
+#endif
__atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE);
-   if (__cur < __last)
- break; // break the loop if version overflows
  }
-#endif
   }
 
   __platform_wait_t
-- 
2.26.2



[PATCH] Remove binary_semaphore implementation from stop_token

2020-06-06 Thread Thomas Rodgers
* include/std/stop_token: Remove local binary_semaphore implementation.
  (_Stop_state_t::_M_do_try_lock): Use __thread_yield() from
  bits/atomic_wait.h.
---
 libstdc++-v3/include/std/stop_token | 40 ++---
 1 file changed, 2 insertions(+), 38 deletions(-)

diff --git a/libstdc++-v3/include/std/stop_token 
b/libstdc++-v3/include/std/stop_token
index 847d12f7454..40a71574a7e 100644
--- a/libstdc++-v3/include/std/stop_token
+++ b/libstdc++-v3/include/std/stop_token
@@ -36,9 +36,7 @@
 #ifdef _GLIBCXX_HAS_GTHREADS
 # define __cpp_lib_jthread 201911L
 # include 
-# if __has_include()
-#  include 
-# endif
+# include 
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -100,40 +98,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 template
   friend class stop_callback;
 
-static void
-_S_yield() noexcept
-{
-#if defined __i386__ || defined __x86_64__
-  __builtin_ia32_pause();
-#elif defined _GLIBCXX_USE_SCHED_YIELD
-  __gthread_yield();
-#endif
-}
-
-#ifndef __cpp_lib_semaphore
-// TODO: replace this with a real implementation of std::binary_semaphore
-struct binary_semaphore
-{
-  explicit binary_semaphore(int __d) : _M_counter(__d > 0) { }
-
-  void release() { _M_counter.fetch_add(1, memory_order::release); }
-
-  void acquire()
-  {
-   int __old = 1;
-   while (!_M_counter.compare_exchange_weak(__old, 0,
-memory_order::acquire,
-memory_order::relaxed))
- {
-   __old = 1;
-   _S_yield();
- }
-  }
-
-  atomic _M_counter;
-};
-#endif
-
 struct _Stop_cb
 {
   using __cb_type = void(_Stop_cb*) noexcept;
@@ -389,7 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
if (__curval & _S_locked_bit)
  {
-   _S_yield();
+   __detail::__thread_yield();
__curval = _M_value.load(__failure);
return false;
  }
-- 
2.26.2



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



[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

[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 c++2a

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

* Note: depends on a sufficiently C++20ified basic_stringbuf<>.

libstdc++/Changelog:
libstdc++-v3/include/Makefile.am (std_headers): Add new header.
libstdc++-v3/include/Makefile.in: Regenerate.
libstdc++-v3/include/std/streambuf
(__detail::__streambuf_core_access): Define.
(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/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/std/streambuf|  81 +
 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|  27 ++
 .../27_io/basic_syncbuf/basic_ops/1.cc| 138 
 .../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 |  27 ++
 .../27_io/basic_syncstream/basic_ops/1.cc | 135 +++
 .../basic_syncstream/requirements/types.cc|  43 +++
 14 files changed, 1018 insertions(+)
 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/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 28d273924ee..61aaff7a2f4 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/std/streambuf 
b/libstdc++-v3/include/std/streambuf
index cae35e75bda..d6053e4c1ed 100644
--- a/libstdc++-v3/include/std/streambuf
+++ b/libstdc++-v3/include/std/streambuf
@@ -48,6 +48,84 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #define _IsUnused __attribute__ ((__unused__))
 
+  template
+class basic_streambuf;
+
+#if __cplusplus > 201703L
+  namespace __detail
+  {
+struct __streambuf_core_access
+{
+  template
+   static void
+   _S_imbue(basic_streambuf<_CharT, _Traits>& __b, const locale& __loc)
+   { __b.imbue(__loc); }
+
+  template
+   static basic_streambuf<_CharT, _Traits>*
+   _S_setbuf(basic_streambuf<_CharT, _Traits>& __b,
+ _CharT* __c, streamsize __n)
+   { return __b.setbuf(__c, __n); }
+
+  template
+   static typename _Traits::pos_type
+   _S_seekoff(basic_streambuf<_CharT, _Traits>& __b,
+  typename _Traits::off_type __off, ios_base::seekdir __dir,
+  ios_base::openmode __mode)
+ { return __b.seekoff(__off, __dir, __mode); }
+
+  template
+   static typename _Traits::pos_type
+   _S_seekpos(basic_streambuf<_CharT, _Traits>& __b,
+  typename _Traits::pos_type __pos, ios_base::openmode __mode)
+   { return __b.seekpos(__pos, __mode); }
+
+  template
+   static int
+   _S_sync(basic_streambuf<_CharT, _Traits>& __b)
+   { return __b.sync(); }
+
+  template
+   static streamsize
+   _S_showmanyc(basic_streambuf<_CharT, _Traits>& __b)
+   { return _

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

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

This should address the cumulative comments (modulo the discussion going
on on the reflector about specification issues/questions).

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: Includ new header.
libstdc++-v3/include/std/streambuf
(__detail::__streambuf_core_access): Define.
(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/sstream  |   2 +-
 libstdc++-v3/include/std/syncstream   | 276 ++
 libstdc++-v3/include/std/version  |   4 +
 .../testsuite/27_io/basic_syncbuf/1.cc|  28 ++
 .../testsuite/27_io/basic_syncbuf/2.cc|  27 ++
 .../27_io/basic_syncbuf/basic_ops/1.cc| 138 +
 .../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 |  27 ++
 .../27_io/basic_syncstream/basic_ops/1.cc | 135 +
 .../basic_syncstream/requirements/types.cc|  43 +++
 16 files changed, 883 insertions(+), 2 deletions(-)
 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 28d273924ee..61aaff7a2f4 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/sstream b/libstdc++-v3/include/std/sstream
index b0d1decfe63..5379f025eef 100644
--- a/libstdc++-v3/include/std/sstream
+++ b/libstdc++-v3/include/std/sstream
@@ -137,7 +137,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   // 27.8.2.2 Assign and swap:
 
   basic_stringbuf&
-  operator=(const basic_stringbuf&) = delete;
+ operator=(const basic_s

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

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

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.
libstdc++-v3/include/std/streambuf
(__detail::__streambuf_core_access): Define.
(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   | 279 ++
 libstdc++-v3/include/std/version  |   4 +
 .../testsuite/27_io/basic_syncbuf/1.cc|  28 ++
 .../testsuite/27_io/basic_syncbuf/2.cc|  27 ++
 .../27_io/basic_syncbuf/basic_ops/1.cc| 138 +
 .../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 |  27 ++
 .../27_io/basic_syncstream/basic_ops/1.cc | 135 +
 .../basic_syncstream/requirements/types.cc|  43 +++
 15 files changed, 885 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 28d273924ee..61aaff7a2f4 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..3f78cef1d8d
--- /dev/null
+++ b/libstdc++-v3/include/std/syncstream
@@ -0,0 +1,279 @@
+//  -*- 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

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

2020-10-21 Thread Thomas Rodgers



> On Oct 21, 2020, at 10:34 AM, Jonathan Wakely  wrote:
> 
> On 21/10/20 09:53 -0700, Thomas Rodgers wrote:
>> From: Thomas Rodgers 
>> 
>> 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.
>>  libstdc++-v3/include/std/streambuf
>>   (__detail::__streambuf_core_access): Define.
>>   (basic_streambuf): Befriend __detail::__streambuf_core_access.
> 
> This file is no longer part of the commit, so the server will reject
> this changelog. Please ensure the changelog is accurate (the
> gcc-verify alias created by contrib/gcc-git-customization.sh can do
> that) and push, thanks.
> 

This patch is dependent on the changes to  so I can’t push until that 
patch lands.

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

[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++: 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 is

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.


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

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

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++] 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(&this->_M_counter, __old); };
+   [this] { return _S_do_try_acquire(&this->_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(&this->_M_counter, __old); };
+   [this] { return _S_do_try_acquire(&this->_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(&this->_M_counter, __old); 
};
+ [this] { return _S_do_try_acquire(&this->_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(&this->_M_counter, __old); 
};
+ [this] { return _S_do_try_acquire(&this->_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: [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 "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 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.


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.


[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



[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



Re: [PATCH] Add support for C++2a stop_token

2019-11-14 Thread Thomas Rodgers
Tested x86_64-pc-linux-gnu, committed to trunk.

Jonathan Wakely writes:

> On 13/11/19 17:59 -0800, Thomas Rodgers wrote:
>>+/** @file include/stop_token
>>+ *  This is a Standard C++ Library header.
>>+ */
>>+
>>+#ifndef _GLIBCXX_STOP_TOKEN
>>+#define _GLIBCXX_STOP_TOKEN
>>+
>>+#if __cplusplus >= 201703L
>
> This should be > not >=
>
> OK for trunk with that change.



  1   2   3   >