From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx.kolabnow.com (mx.kolabnow.com [95.128.36.41]) by sourceware.org (Postfix) with ESMTPS id E1D663851C15; Sat, 23 May 2020 22:52:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E1D663851C15 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=appliantology.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=rodgert@appliantology.com Received: from localhost (unknown [127.0.0.1]) by ext-mx-out002.mykolab.com (Postfix) with ESMTP id C8A209FF; Sun, 24 May 2020 00:52:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolabnow.com; h= references:in-reply-to:date:date:subject:subject:mime-version :content-type:content-type:message-id:from:from:received :received:received; s=dkim20160331; t=1590274341; x=1592088742; bh=YHeQUfEUCWnh1YtSTsquC0/K3ylMzdKlXm16w55HJNo=; b=qQ75GzuzOf61 5SLpPHFr3RExhusdR5HeriYJDVsdmdpiR6rL4Zd/Xdke8vFF07tqZEZe1m9CAEPR MQJiqFXl9AKhhQLZ4ostU/aYNQgsKc7CWPDR47TbQpPyyGCiRLZI/HU5mp1itDo+ lNiCeFWjAfSp0c73+qZIVd936hJd/zWDR3ZnDpRGLBmdnMe0FnbuGhcS82WKqFps MTPkG3DrAKZrLvryGcz8BAfPz03/QjKiDW73zR6HHfHXeza89E34Z6r2cuen3O9Q aldVD63OAixpaVT8070esDsnV5uv6cArPr7p13EQ+4vTCWLjJ2n78I9iigKWiAN3 yJxwr0cuy48Vnjq3+Esj4ifeXwZ6bcGyzmwpBy6h0qOI4OQUTVJz4IWW+cxzmEwV SuxukWwJ8KEFGgCkLPjpMieJsUKY5zDj1w5OrwqcpkXM0bLTT/uli/XsdL5fKOdP OMGjuqfyglCXKRkQ5O0uxGnPoboKPZZ6YF0OPlFnYCIQuH0Q6udrBG+MLAoEKlix Tk9VJY8T5JU73uC4Qj6xuRO2FPeIyM4eoHeWbTreDLpfeCJLXly48AnuwDDa7Sz0 CBz3l9Z8Dr+RxOZfp1xu8+cq5sQcMp5euwMEJz74QnszY1J4V/5TcqFAudXq2PyT SGSLK096s6Vi0YIA55jJM+wJtaz9WfA= X-Virus-Scanned: amavisd-new at mykolab.com X-Spam-Score: -1.9 X-Spam-Level: X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 Received: from mx.kolabnow.com ([127.0.0.1]) by localhost (ext-mx-out002.mykolab.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id usqtR-RPf46o; Sun, 24 May 2020 00:52:21 +0200 (CEST) Received: from int-mx002.mykolab.com (unknown [10.9.13.2]) by ext-mx-out002.mykolab.com (Postfix) with ESMTPS id B126B6F4; Sun, 24 May 2020 00:52:21 +0200 (CEST) Received: from ext-subm003.mykolab.com (unknown [10.9.6.3]) by int-mx002.mykolab.com (Postfix) with ESMTPS id 4536935D9; Sun, 24 May 2020 00:52:21 +0200 (CEST) From: Thomas Rodgers Message-Id: <6F58268B-FA3E-48EC-8108-E16E4A8324ED@appliantology.com> Content-Type: multipart/mixed; boundary="Apple-Mail=_35F1270A-E967-48E3-9355-C77AF697D593" Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: [PATCH] Add C++2a synchronization support Date: Sat, 23 May 2020 15:52:16 -0700 In-Reply-To: Cc: Jonathan Wakely , Thomas Rodgers To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org References: <20200511140504.GL2678@redhat.com> X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 May 2020 22:52:31 -0000 --Apple-Mail=_35F1270A-E967-48E3-9355-C77AF697D593 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii Updated patch. --Apple-Mail=_35F1270A-E967-48E3-9355-C77AF697D593 Content-Disposition: attachment; filename=0001-Add-C-2a-synchronization-support.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Add-C-2a-synchronization-support.patch" Content-Transfer-Encoding: quoted-printable =46rom=20a3decdc503fbaa0805358946ac5646bfa17840e4=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Thomas=20Rodgers=20=0A= Date:=20Mon,=206=20Apr=202020=2017:58:47=20-0700=0ASubject:=20[PATCH]=20= Add=20C++2a=20synchronization=20support=0A=0AAdd=20support=20for=20-=0A=20= =20=20=20=20=20=20=20atomic=20wait/notify_one/notify_all=0A=20=20=20=20=20= =20=20=20counting_semaphore=0A=20=20=20=20=20=20=20=20binary_semaphore=0A= =20=20=20=20=20=20=20=20latch=0A=0A=20=20=20=20=20=20=20=20*=20= include/Makefile.am=20(bits_headers):=20Add=20new=20header.=0A=09*=20= include/Makefile.in:=20Regenerate.=0A=09*=20include/bits/atomic_base.h=20= (__atomic_base<_Itp>::wait):=20Define.=0A=09= (__atomic_base<_Itp>::notify_one):=20Likewise.=0A=09= (__atomic_base<_Itp>::notify_all):=20Likewise.=0A=09= (__atomic_base<_Ptp*>::wait):=20Likewise.=0A=09= (__atomic_base<_Ptp*>::notify_one):=20Likewise.=0A=09= (__atomic_base<_Ptp*>::notify_all):=20Likewise.=0A=09= (__atomic_impl::wait):=20Likewise.=0A=09(__atomic_impl::notify_one):=20= Likewise.=0A=09(__atomic_impl::notify_all):=20Likewise.=0A=09= (__atomic_float<_Fp>::wait):=20Likewise.=0A=09= (__atomic_float<_Fp>::notify_one):=20Likewise.=0A=09= (__atomic_float<_Fp>::notify_all):=20Likewise.=0A=09= (__atomic_ref<_Tp>::wait):=20Likewise.=0A=09= (__atomic_ref<_Tp>::notify_one):=20Likewise.=0A=09= (__atomic_ref<_Tp>::notify_all):=20Likewise.=0A=09(atomic_wait<_Tp>):=20= Likewise.=0A=09(atomic_wait_explicit<_Tp>):=20Likewise.=0A=09= (atomic_notify_one<_Tp>):=20Likewise.=0A=09(atomic_notify_all<_Tp>):=20= Likewise.=0A=09*=20include/bits/atomic_wait.h:=20New=20file.=0A=20=20=20=20= =20=20=20=20*=20include/bits/atomic_timed_wait.h:=20New=20file.=0A=20=20=20= =20=20=20=20=20*=20include/bits/semaphore_base.h:=20New=20file.=0A=09*=20= include/std/atomic=20(atomic::wait):=20Define.=0A=09= (atomic::wait_one):=20Likewise.=0A=09(atomic::wait_all):=20= Likewise.=0A=09(atomic<_Tp>::wait):=20Likewise.=0A=09= (atomic<_Tp>::wait_one):=20Likewise.=0A=09(atomic<_Tp>::wait_all):=20= Likewise.=0A=09(atomic<_Tp*>::wait):=20Likewise.=0A=09= (atomic<_Tp*>::wait_one):=20Likewise.=0A=09(atomic<_Tp*>::wait_all):=20= Likewise.=0A=20=20=20=20=20=20=20=20*=20include/std/latch:=20New=20file.=0A= =20=20=20=20=20=20=20=20*=20include/std/semaphore:=20New=20file.=0A=20=20= =20=20=20=20=20=20*=20include/std/version:=20Add=20__cpp_lib_semaphore=20= and=0A=20=20=20=20=20=20=20=20__cpp_lib_latch=20defines.=0A=09*=20= testsuite/29_atomic/atomic/wait_notify/atomic_refs.cc:=20New=20test.=0A=09= *=20testsuite/29_atomic/atomic/wait_notify/bool.cc:=20Likewise.=0A=09*=20= testsuite/29_atomic/atomic/wait_notify/integrals.cc:=20Likewise.=0A=09*=20= testsuite/29_atomic/atomic/wait_notify/floats.cc:=20Likewise.=0A=09*=20= testsuite/29_atomic/atomic/wait_notify/pointers.cc:=20Likewise.=0A=09*=20= testsuite/29_atomic/atomic/wait_notify/generic.h:=20New=20File.=0A=20=20=20= =20=20=20=20=20*=20testsuite/30_thread/semaphore/1.cc:=20New=20test.=0A=20= =20=20=20=20=20=20=20*=20testsuite/30_thread/semaphore/2.cc:=20Likewise.=0A= =20=20=20=20=20=20=20=20*=20= testsuite/30_thread/semaphore/least_max_value_neg.cc:=20Likewise.=0A=20=20= =20=20=20=20=20=20*=20testsuite/30_thread/semaphore/try_acquire.cc:=20= Likewise.=0A=20=20=20=20=20=20=20=20*=20= testsuite/30_thread/semaphore/try_acquire_for.cc:=20Likewise.=0A=20=20=20= =20=20=20=20=20*=20testsuite/30_thread/semaphore/try_acquire_futex.cc:=20= Likewise.=0A=20=20=20=20=20=20=20=20*=20= testsuite/30_thread/semaphore/try_acquire_posix.cc:=20Likewise.=0A=20=20=20= =20=20=20=20=20*=20testsuite/30_thread/semaphore/try_acquire_until.cc:=20= Likewise.=0A=20=20=20=20=20=20=20=20*=20testsuite/30_thread/latch/1.cc:=20= New=20test.=0A=20=20=20=20=20=20=20=20*=20= testsuite/30_thread/latch/2.cc:=20New=20test.=0A=20=20=20=20=20=20=20=20= *=20testsuite/30_thread/latch/3.cc:=20New=20test.=0A---=0A=20= libstdc++-v3/include/Makefile.am=20=20=20=20=20=20=20=20=20=20=20=20=20=20= |=20=20=205=20+=0A=20libstdc++-v3/include/Makefile.in=20=20=20=20=20=20=20= =20=20=20=20=20=20=20|=20=20=205=20+=0A=20= libstdc++-v3/include/bits/atomic_base.h=20=20=20=20=20=20=20|=20161=20= +++++++++-=0A=20libstdc++-v3/include/bits/atomic_timed_wait.h=20|=20282=20= +++++++++++++++++=0A=20libstdc++-v3/include/bits/atomic_wait.h=20=20=20=20= =20=20=20|=20291=20++++++++++++++++++=0A=20= libstdc++-v3/include/bits/semaphore_base.h=20=20=20=20|=20272=20= ++++++++++++++++=0A=20libstdc++-v3/include/std/atomic=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20|=20=2061=20++++=0A=20= libstdc++-v3/include/std/latch=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20|=20=2090=20++++++=0A=20libstdc++-v3/include/std/semaphore=20=20=20=20= =20=20=20=20=20=20=20=20|=20=2086=20++++++=0A=20= libstdc++-v3/include/std/version=20=20=20=20=20=20=20=20=20=20=20=20=20=20= |=20=20=202=20+=0A=20.../atomic/wait_notify/atomic_refs.cc=20=20=20=20=20= =20=20=20=20|=20103=20+++++++=0A=20= .../29_atomics/atomic/wait_notify/bool.cc=20=20=20=20=20|=20=2059=20++++=0A= =20.../29_atomics/atomic/wait_notify/floats.cc=20=20=20|=20=2032=20++=0A=20= .../29_atomics/atomic/wait_notify/generic.h=20=20=20|=20=2088=20++++++=0A= =20.../atomic/wait_notify/integrals.cc=20=20=20=20=20=20=20=20=20=20=20|=20= =2056=20++++=0A=20.../29_atomics/atomic/wait_notify/pointers.cc=20|=20=20= 59=20++++=0A=20libstdc++-v3/testsuite/30_threads/latch/1.cc=20=20|=20=20= 27=20++=0A=20libstdc++-v3/testsuite/30_threads/latch/2.cc=20=20|=20=2027=20= ++=0A=20libstdc++-v3/testsuite/30_threads/latch/3.cc=20=20|=20=2050=20= +++=0A=20.../testsuite/30_threads/semaphore/1.cc=20=20=20=20=20=20=20|=20= =2027=20++=0A=20.../testsuite/30_threads/semaphore/2.cc=20=20=20=20=20=20= =20|=20=2027=20++=0A=20.../semaphore/least_max_value_neg.cc=20=20=20=20=20= =20=20=20=20=20|=20=2028=20++=0A=20= .../30_threads/semaphore/try_acquire.cc=20=20=20=20=20=20=20|=20=2055=20= ++++=0A=20.../30_threads/semaphore/try_acquire_for.cc=20=20=20|=20=2085=20= +++++=0A=20.../30_threads/semaphore/try_acquire_futex.cc=20|=20=2051=20= +++=0A=20.../30_threads/semaphore/try_acquire_posix.cc=20|=20169=20= ++++++++++=0A=20.../30_threads/semaphore/try_acquire_until.cc=20|=20=20= 94=20++++++=0A=2027=20files=20changed,=202291=20insertions(+),=201=20= deletion(-)=0A=20create=20mode=20100644=20= libstdc++-v3/include/bits/atomic_timed_wait.h=0A=20create=20mode=20= 100644=20libstdc++-v3/include/bits/atomic_wait.h=0A=20create=20mode=20= 100644=20libstdc++-v3/include/bits/semaphore_base.h=0A=20create=20mode=20= 100644=20libstdc++-v3/include/std/latch=0A=20create=20mode=20100644=20= libstdc++-v3/include/std/semaphore=0A=20create=20mode=20100644=20= libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc=0A=20create=20= mode=20100644=20= libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/floats.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.h=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/integrals.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc=0A=20= create=20mode=20100644=20libstdc++-v3/testsuite/30_threads/latch/1.cc=0A=20= create=20mode=20100644=20libstdc++-v3/testsuite/30_threads/latch/2.cc=0A=20= create=20mode=20100644=20libstdc++-v3/testsuite/30_threads/latch/3.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/1.cc=0A=20create=20mode=20= 100644=20libstdc++-v3/testsuite/30_threads/semaphore/2.cc=0A=20create=20= mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc=0A=20create=20= mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_futex.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc=0A=20= create=20mode=20100644=20= libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc=0A=0A= diff=20--git=20a/libstdc++-v3/include/Makefile.am=20= b/libstdc++-v3/include/Makefile.am=0Aindex=2080aeb3f8959..b3ac1a3365f=20= 100644=0A---=20a/libstdc++-v3/include/Makefile.am=0A+++=20= b/libstdc++-v3/include/Makefile.am=0A@@=20-52,6=20+52,7=20@@=20= std_headers=20=3D=20\=0A=20=09${std_srcdir}/iostream=20\=0A=20=09= ${std_srcdir}/istream=20\=0A=20=09${std_srcdir}/iterator=20\=0A+=09= ${std_srcdir}/latch\=0A=20=09${std_srcdir}/limits=20\=0A=20=09= ${std_srcdir}/list=20\=0A=20=09${std_srcdir}/locale=20\=0A@@=20-69,6=20= +70,7=20@@=20std_headers=20=3D=20\=0A=20=09${std_srcdir}/ratio=20\=0A=20=09= ${std_srcdir}/regex=20\=0A=20=09${std_srcdir}/scoped_allocator=20\=0A+=09= ${std_srcdir}/semaphore=20\=0A=20=09${std_srcdir}/set=20\=0A=20=09= ${std_srcdir}/shared_mutex=20\=0A=20=09${std_srcdir}/span=20\=0A@@=20= -100,6=20+102,8=20@@=20bits_headers=20=3D=20\=0A=20=09= ${bits_srcdir}/allocated_ptr.h=20\=0A=20=09${bits_srcdir}/allocator.h=20= \=0A=20=09${bits_srcdir}/atomic_base.h=20\=0A+=09= ${bits_srcdir}/atomic_wait.h=20\=0A+=09= ${bits_srcdir}/atomic_timed_wait.h=20\=0A=20=09= ${bits_srcdir}/atomic_futex.h=20\=0A=20=09${bits_srcdir}/basic_ios.h=20\=0A= =20=09${bits_srcdir}/basic_ios.tcc=20\=0A@@=20-174,6=20+178,7=20@@=20= bits_headers=20=3D=20\=0A=20=09${bits_srcdir}/regex_compiler.tcc=20\=0A=20= =09${bits_srcdir}/regex_executor.h=20\=0A=20=09= ${bits_srcdir}/regex_executor.tcc=20\=0A+=09= ${bits_srcdir}/semaphore_base.h=20\=0A=20=09${bits_srcdir}/shared_ptr.h=20= \=0A=20=09${bits_srcdir}/shared_ptr_atomic.h=20\=0A=20=09= ${bits_srcdir}/shared_ptr_base.h=20\=0Adiff=20--git=20= a/libstdc++-v3/include/Makefile.in=20b/libstdc++-v3/include/Makefile.in=0A= index=20eb437ad8d8d..e73ff8b3e64=20100644=0A---=20= a/libstdc++-v3/include/Makefile.in=0A+++=20= b/libstdc++-v3/include/Makefile.in=0A@@=20-397,6=20+397,7=20@@=20= std_headers=20=3D=20\=0A=20=09${std_srcdir}/iostream=20\=0A=20=09= ${std_srcdir}/istream=20\=0A=20=09${std_srcdir}/iterator=20\=0A+=09= ${std_srcdir}/latch\=0A=20=09${std_srcdir}/limits=20\=0A=20=09= ${std_srcdir}/list=20\=0A=20=09${std_srcdir}/locale=20\=0A@@=20-414,6=20= +415,7=20@@=20std_headers=20=3D=20\=0A=20=09${std_srcdir}/ratio=20\=0A=20= =09${std_srcdir}/regex=20\=0A=20=09${std_srcdir}/scoped_allocator=20\=0A= +=09${std_srcdir}/semaphore=20\=0A=20=09${std_srcdir}/set=20\=0A=20=09= ${std_srcdir}/shared_mutex=20\=0A=20=09${std_srcdir}/span=20\=0A@@=20= -445,6=20+447,8=20@@=20bits_headers=20=3D=20\=0A=20=09= ${bits_srcdir}/allocated_ptr.h=20\=0A=20=09${bits_srcdir}/allocator.h=20= \=0A=20=09${bits_srcdir}/atomic_base.h=20\=0A+=09= ${bits_srcdir}/atomic_wait.h=20\=0A+=09= ${bits_srcdir}/atomic_timed_wait.h=20\=0A=20=09= ${bits_srcdir}/atomic_futex.h=20\=0A=20=09${bits_srcdir}/basic_ios.h=20\=0A= =20=09${bits_srcdir}/basic_ios.tcc=20\=0A@@=20-519,6=20+523,7=20@@=20= bits_headers=20=3D=20\=0A=20=09${bits_srcdir}/regex_compiler.tcc=20\=0A=20= =09${bits_srcdir}/regex_executor.h=20\=0A=20=09= ${bits_srcdir}/regex_executor.tcc=20\=0A+=09= ${bits_srcdir}/semaphore_base.h=20\=0A=20=09${bits_srcdir}/shared_ptr.h=20= \=0A=20=09${bits_srcdir}/shared_ptr_atomic.h=20\=0A=20=09= ${bits_srcdir}/shared_ptr_base.h=20\=0Adiff=20--git=20= a/libstdc++-v3/include/bits/atomic_base.h=20= b/libstdc++-v3/include/bits/atomic_base.h=0Aindex=20= 3b66b040976..68d9e7e3756=20100644=0A---=20= a/libstdc++-v3/include/bits/atomic_base.h=0A+++=20= b/libstdc++-v3/include/bits/atomic_base.h=0A@@=20-37,6=20+37,10=20@@=0A=20= #include=20=0A=20#include=20= =0A=20=0A+#if=20__cplusplus=20>=20201703L=0A+#include=20= =0A+#endif=0A+=0A=20#ifndef=20_GLIBCXX_ALWAYS_INLINE=0A= =20#define=20_GLIBCXX_ALWAYS_INLINE=20inline=20= __attribute__((__always_inline__))=0A=20#endif=0A@@=20-134,7=20+138,6=20= @@=20_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=20=20=20=20=20=20return=20= __ret;=0A=20=20=20=20=20}=0A=20=0A-=0A=20=20=20//=20Base=20types=20for=20= atomics.=0A=20=20=20template=0A=20=20=20=20=20struct=20= __atomic_base;=0A@@=20-562,6=20+565,31=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=20=20=20=20=20=20=20= __cmpexch_failure_order(__m));=0A=20=20=20=20=20=20=20}=0A=20=0A+#if=20= __cplusplus=20>=20201703L=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20= void=0A+=20=20=20=20=20=20wait(__int_type=20__old,=0A+=09=20=20= memory_order=20__m=20=3D=20memory_order_seq_cst)=20const=20noexcept=0A+=20= =20=20=20=20=20{=0A+=09std::__atomic_wait(&_M_i,=20__old,=0A+=09=09=09=20= =20=20[__m,=20this,=20__old]()=0A+=09=09=09=20=20=20{=20return=20= this->load(__m)=20!=3D=20__old;=20});=0A+=20=20=20=20=20=20}=0A+=0A+=20=20= =20=20=20=20//=20TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20= =20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_one()=20= const=20noexcept=0A+=20=20=20=20=20=20{=20std::__atomic_notify(&_M_i,=20= false);=20}=0A+=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20= overload=0A+=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20= =20=20=20=20notify_all()=20const=20noexcept=0A+=20=20=20=20=20=20{=20= std::__atomic_notify(&_M_i,=20true);=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+#endif=20//=20C++2a=0A+=0A=20= =20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20__int_type=0A=20=20=20=20=20=20= =20fetch_add(__int_type=20__i,=0A=20=09=09memory_order=20__m=20=3D=20= memory_order_seq_cst)=20noexcept=0A@@=20-823,6=20+851,30=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=09=20=20=20int(__m1),=20= int(__m2));=0A=20=20=20=20=20=20=20}=0A=20=0A+#if=20__cplusplus=20>=20= 201703L=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20= =20=20wait(__pointer_type=20__old,=20memory_order=20__m=20=3D=20= memory_order_seq_cst)=20noexcept=0A+=20=20=20=20=20=20{=0A+=09= std::__atomic_wait(&_M_p,=20__old,=0A+=09=09=20=20=20=20=20=20[__m,=20= this,=20__old]()=0A+=09=09=20=20=20=20=20=20{=20return=20this->load(__m)=20= !=3D=20__old;=20});=0A+=20=20=20=20=20=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_one()=20const=20= noexcept=0A+=20=20=20=20=20=20{=20std::__atomic_notify(&_M_p,=20false);=20= }=0A+=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20overload=0A= +=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20= notify_all()=20const=20noexcept=0A+=20=20=20=20=20=20{=20= std::__atomic_notify(&_M_p,=20true);=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+#endif=20//=20C++2a=0A+=0A=20= =20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20__pointer_type=0A=20=20=20=20=20= =20=20fetch_add(ptrdiff_t=20__d,=0A=20=09=09memory_order=20__m=20=3D=20= memory_order_seq_cst)=20noexcept=0A@@=20-911,6=20+963,32=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=09=20int(__success),=20= int(__failure));=0A=20=20=20=20=20=20=20}=0A=20=0A+#if=20__cplusplus=20>=20= 201703L=0A+=20=20=20=20template=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20wait(const=20_Tp*=20= __ptr,=20_Val<_Tp>=20__old,=20memory_order=20__m=20=3D=20= memory_order_seq_cst)=20noexcept=0A+=20=20=20=20=20=20{=0A+=09= std::__atomic_wait(__ptr,=20__old,=0A+=09=20=20=20=20[=3D]()=20{=20= return=20load(__ptr,=20__m)=20=3D=3D=20__old;=20});=0A+=20=20=20=20=20=20= }=0A+=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20overload=0A= +=0A+=20=20=20=20template=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_one(const=20= _Tp*=20__ptr)=20noexcept=0A+=20=20=20=20=20=20{=20= std::__atomic_notify(__ptr,=20false);=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20= template=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20= void=0A+=20=20=20=20=20=20notify_all(const=20_Tp*=20__ptr)=20noexcept=0A= +=20=20=20=20=20=20{=20std::__atomic_notify(__ptr,=20true);=20}=0A+=0A+=20= =20=20=20=20=20//=20TODO=20add=20const=20volatile=20overload=0A+#endif=20= //=20C++2a=0A+=0A=20=20=20=20=20template=0A=20=20=20=20=20= =20=20_GLIBCXX_ALWAYS_INLINE=20_Tp=0A=20=20=20=20=20=20=20fetch_add(_Tp*=20= __ptr,=20_Diff<_Tp>=20__i,=20memory_order=20__m)=20noexcept=0A@@=20= -1164,6=20+1242,23=20@@=20_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09= =09=20=20=20=20=20=20=20__cmpexch_failure_order(__order));=0A=20=20=20=20= =20=20=20}=0A=20=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20= =20=20=20=20=20wait(_Fp=20__old,=20memory_order=20__m=20=3D=20= memory_order_seq_cst)=20const=20noexcept=0A+=20=20=20=20=20=20{=20= __atomic_impl::wait(&_M_fp,=20__old,=20__m);=20}=0A+=0A+=20=20=20=20=20=20= //=20TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_one()=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::notify_one(&_M_fp);=20}=0A= +=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20overload=0A+=0A= +=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20= notify_all()=20const=20noexcept=0A+=20=20=20=20=20=20{=20= __atomic_impl::notify_all(&_M_fp);=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A=20=20=20=20=20=20=20= value_type=0A=20=20=20=20=20=20=20fetch_add(value_type=20__i,=0A=20=09=09= memory_order=20__m=20=3D=20memory_order_seq_cst)=20noexcept=0A@@=20= -1301,6=20+1396,22=20@@=20_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09= =09=20=20=20=20=20=20=20__cmpexch_failure_order(__order));=0A=20=20=20=20= =20=20=20}=0A=20=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20= =20=20=20=20=20wait(_Tp=20__old,=20memory_order=20__m=20=3D=20= memory_order_seq_cst)=20const=20noexcept=0A+=20=20=20=20=20=20{=20= __atomic_impl::wait(_M_ptr,=20__old,=20__m);=20}=0A+=0A+=20=20=20=20=20=20= //=20TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_one()=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::notify_one(_M_ptr);=20}=0A= +=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20overload=0A+=0A= +=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20= notify_all()=20const=20noexcept=0A+=20=20=20=20=20=20{=20= __atomic_impl::notify_all(_M_ptr);=20}=0A+=0A=20=20=20=20=20private:=0A=20= =20=20=20=20=20=20_Tp*=20_M_ptr;=0A=20=20=20=20=20};=0A@@=20-1396,6=20= +1507,22=20@@=20_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=20=20=20= =20=20=20=20__cmpexch_failure_order(__order));=0A=20=20=20=20=20=20=20}=0A= =20=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20= =20wait(_Tp=20__old,=20memory_order=20__m=20=3D=20memory_order_seq_cst)=20= const=20noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::wait(_M_ptr,=20= __old,=20__m);=20}=0A+=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20= volatile=20overload=0A+=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20= void=0A+=20=20=20=20=20=20notify_one()=20const=20noexcept=0A+=20=20=20=20= =20=20{=20__atomic_impl::notify_one(_M_ptr);=20}=0A+=0A+=20=20=20=20=20=20= //=20TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_all()=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::notify_all(_M_ptr);=20}=0A= +=0A=20=20=20=20=20=20=20value_type=0A=20=20=20=20=20=20=20= fetch_add(value_type=20__i,=0A=20=09=09memory_order=20__m=20=3D=20= memory_order_seq_cst)=20const=20noexcept=0A@@=20-1551,6=20+1678,22=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=20=20=20=20=20=20=20= __cmpexch_failure_order(__order));=0A=20=20=20=20=20=20=20}=0A=20=0A+=20=20= =20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20wait(_Fp=20= __old,=20memory_order=20__m=20=3D=20memory_order_seq_cst)=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::wait(_M_ptr,=20__old,=20= __m);=20}=0A+=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20= overload=0A+=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20= =20=20=20=20notify_one()=20const=20noexcept=0A+=20=20=20=20=20=20{=20= __atomic_impl::notify_one(_M_ptr);=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_all()=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::notify_all(_M_ptr);=20}=0A= +=0A=20=20=20=20=20=20=20value_type=0A=20=20=20=20=20=20=20= fetch_add(value_type=20__i,=0A=20=09=09memory_order=20__m=20=3D=20= memory_order_seq_cst)=20const=20noexcept=0A@@=20-1660,6=20+1803,22=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=20=20=20=20=20=20=20= __cmpexch_failure_order(__order));=0A=20=20=20=20=20=20=20}=0A=20=0A+=20=20= =20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20wait(_Tp=20= __old,=20memory_order=20__m=20=3D=20memory_order_seq_cst)=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::wait(_M_ptr,=20__old,=20= __m);=20}=0A+=0A+=20=20=20=20=20=20//=20TODO=20add=20const=20volatile=20= overload=0A+=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20= =20=20=20=20notify_one()=20const=20noexcept=0A+=20=20=20=20=20=20{=20= __atomic_impl::notify_one(_M_ptr);=20}=0A+=0A+=20=20=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20notify_all()=20const=20= noexcept=0A+=20=20=20=20=20=20{=20__atomic_impl::notify_all(_M_ptr);=20}=0A= +=0A=20=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20value_type=0A=20=20=20=20= =20=20=20fetch_add(difference_type=20__d,=0A=20=09=09memory_order=20__m=20= =3D=20memory_order_seq_cst)=20const=20noexcept=0Adiff=20--git=20= a/libstdc++-v3/include/bits/atomic_timed_wait.h=20= b/libstdc++-v3/include/bits/atomic_timed_wait.h=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..adef80aca61=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/include/bits/atomic_timed_wait.h=0A@@=20-0,0=20+1,282=20= @@=0A+//=20-*-=20C++=20-*-=20header.=0A+=0A+//=20Copyright=20(C)=202020=20= Free=20Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20= part=20of=20the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20= free=0A+//=20software;=20you=20can=20redistribute=20it=20and/or=20modify=20= it=20under=20the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20= License=20as=20published=20by=20the=0A+//=20Free=20Software=20= Foundation;=20either=20version=203,=20or=20(at=20your=20option)=0A+//=20= any=20later=20version.=0A+=0A+//=20This=20library=20is=20distributed=20= in=20the=20hope=20that=20it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20= ANY=20WARRANTY;=20without=20even=20the=20implied=20warranty=20of=0A+//=20= MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20= See=20the=0A+//=20GNU=20General=20Public=20License=20for=20more=20= details.=0A+=0A+//=20Under=20Section=207=20of=20GPL=20version=203,=20you=20= are=20granted=20additional=0A+//=20permissions=20described=20in=20the=20= GCC=20Runtime=20Library=20Exception,=20version=0A+//=203.1,=20as=20= published=20by=20the=20Free=20Software=20Foundation.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20and=0A+//=20a=20copy=20of=20the=20GCC=20Runtime=20Library=20= Exception=20along=20with=20this=20program;=0A+//=20see=20the=20files=20= COPYING3=20and=20COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A= +//=20.=0A+=0A+/**=20@file=20= bits/atomic_timed_wait.h=0A+=20*=20=20This=20is=20an=20internal=20header=20= file,=20included=20by=20other=20library=20headers.=0A+=20*=20=20Do=20not=20= attempt=20to=20use=20it=20directly.=20@headername{atomic}=0A+=20*/=0A+=0A= +#ifndef=20_GLIBCXX_ATOMIC_TIMED_WAIT_H=0A+#define=20= _GLIBCXX_ATOMIC_TIMED_WAIT_H=201=0A+=0A+#pragma=20GCC=20system_header=0A= +=0A+#include=20=0A+#include=20= =0A+#include=20=0A+=0A= +#include=20=0A+=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A= +#include=20=0A+#endif=0A+=0A+namespace=20std=20= _GLIBCXX_VISIBILITY(default)=0A+{=0A+=20=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A+=0A+=20=20enum=20class=20= __atomic_wait_status=20{=20__no_timeout,=20__timeout=20};=0A+=0A+=20=20= namespace=20__detail=0A+=20=20{=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A= +=20=20=20=20enum=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= __futex_wait_bitset_private=20=3D=20__futex_wait_bitset=20|=20= __futex_private_flag,=0A+=20=20=20=20=20=20__futex_wake_bitset_private=20= =3D=20__futex_wake_bitset=20|=20__futex_private_flag,=0A+=20=20=20=20=20=20= __futex_bitset_match_any=20=3D=200xffffffff=0A+=20=20=20=20};=0A+=0A+=20=20= =20=20using=20__platform_wait_clock_t=20=3D=20chrono::steady_clock;=0A+=0A= +=20=20=20=20template=0A+=20=20=20=20=20=20= __atomic_wait_status=0A+=20=20=20=20=20=20= __platform_wait_until_impl(__platform_wait_t*=20__addr,=20= __platform_wait_t=20__val,=0A+=09=09=09=09=20const=20= chrono::time_point<__platform_wait_clock_t,=20_Duration>&=20__atime)=20= noexcept=0A+=20=20=20=20=20=20{=0A+=09auto=20__s=20=3D=20= chrono::time_point_cast(__atime);=0A+=09auto=20__ns=20=3D= =20chrono::duration_cast(__atime=20-=20__s);=0A+=0A= +=09struct=20timespec=20__rt=20=3D=0A+=09{=0A+=09=20=20= static_cast(__s.time_since_epoch().count()),=0A+=09=20=20= static_cast(__ns.count())=0A+=09};=0A+=0A+=09auto=20__e=20=3D=20= syscall=20(SYS_futex,=20__addr,=20__futex_wait_bitset_private,=20__val,=20= &__rt,=0A+=09=09=09=20=20=20=20nullptr,=20__futex_bitset_match_any);=0A+=09= if=20(__e=20&&=20!(errno=20=3D=3D=20EINTR=20||=20errno=20=3D=3D=20EAGAIN=20= ||=20errno=20=3D=3D=20ETIMEDOUT))=0A+=09=20=20=20=20std::terminate();=0A= +=09return=20(__platform_wait_clock_t::now()=20<=20__atime)=0A+=09=20=20=20= =20=20=20=20?=20__atomic_wait_status::__no_timeout=20:=20= __atomic_wait_status::__timeout;=0A+=20=20=20=20=20=20}=0A+=0A+=20=20=20=20= template=0A+=20=20=20=20=20=20= __atomic_wait_status=0A+=20=20=20=20=20=20= __platform_wait_until(__platform_wait_t*=20__addr,=20__platform_wait_t=20= __val,=0A+=09=09=09=20=20=20=20const=20chrono::time_point<_Clock,=20= _Duration>&=20__atime)=0A+=20=20=20=20=20=20{=0A+=09if=20constexpr=20= (std::is_same_v<__platform_wait_clock_t,=20_Clock>)=0A+=09=20=20{=0A+=09=20= =20=20=20return=20__platform_wait_until_impl(__addr,=20__val,=20= __atime);=0A+=09=20=20}=0A+=09else=0A+=09=20=20{=0A+=09=20=20=20=20const=20= typename=20_Clock::time_point=20__c_entry=20=3D=20_Clock::now();=0A+=09=20= =20=20=20const=20__platform_wait_clock_t::time_point=20__s_entry=20=3D=0A= +=09=09=20=20=20=20__platform_wait_clock_t::now();=0A+=09=20=20=20=20= const=20auto=20__delta=20=3D=20__atime=20-=20__c_entry;=0A+=09=20=20=20=20= const=20auto=20__s_atime=20=3D=20__s_entry=20+=20__delta;=0A+=09=20=20=20= =20if=20(__platform_wait_until_impl(__addr,=20__val,=20__s_atime)=20=3D=3D= =20__atomic_wait_status::__no_timeout)=0A+=09=20=20=20=20=20=20return=20= __atomic_wait_status::__no_timeout;=0A+=0A+=09=20=20=20=20//=20We=20got=20= a=20timeout=20when=20measured=20against=20__clock_t=20but=0A+=09=20=20=20= =20//=20we=20need=20to=20check=20against=20the=20caller-supplied=20clock=0A= +=09=20=20=20=20//=20to=20tell=20whether=20we=20should=20return=20a=20= timeout.=0A+=09=20=20=20=20if=20(_Clock::now()=20<=20__atime)=0A+=09=20=20= =20=20=20=20return=20__atomic_wait_status::__no_timeout;=0A+=09=20=20=20=20= return=20__atomic_wait_status::__timeout;=0A+=09=20=20}=0A+=20=20=20=20=20= =20}=0A+#endif=0A+=0A+#ifdef=20_GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT=0A+=20= =20=20=20template=0A+=20=20=20=20=20=20= __atomic_wait_status=0A+=20=20=20=20=20=20= __cond_wait_until_impl(__gthread_cond_t*=20__cv,=0A+=09=20=20= unique_lock&=20__lock,=0A+=09=20=20const=20= chrono::time_point&=20__atime)=0A+=20=20= =20=20=20=20{=0A+=09auto=20__s=20=3D=20= chrono::time_point_cast(__atime);=0A+=09auto=20__ns=20=3D= =20chrono::duration_cast(__atime=20-=20__s);=0A+=0A= +=09__gthread_time_t=20__ts=20=3D=0A+=09=20=20{=0A+=09=20=20=20=20= static_cast(__s.time_since_epoch().count()),=0A+=09=20=20=20= =20static_cast(__ns.count())=0A+=09=20=20};=0A+=0A+=09= pthread_cond_clockwait(__cv,=20__lock.mutex()->native_handle(),=0A+=09=09= =09=20=20=20=20=20=20=20CLOCK_MONOTONIC,=0A+=09=09=09=20=20=20=20=20=20=20= &__ts);=0A+=09return=20(chrono::steady_clock::now()=20<=20__atime)=0A+=09= =20=20=20=20=20=20=20?=20__atomic_wait_status::__no_timeout=20:=20= __atomic_wait_status::__timeout;=0A+=20=20=20=20=20=20}=0A+#endif=0A+=0A= +=20=20=20=20=20=20template=0A+=09= __atomic_wait_status=0A+=09__cond_wait_until_impl(__gthread_cond_t*=20= __cv,=0A+=09=20=20=20=20unique_lock&=20__lock,=0A+=09=20=20=20= =20const=20chrono::time_point&=20= __atime)=0A+=09{=0A+=09=20=20auto=20__s=20=3D=20= chrono::time_point_cast(__atime);=0A+=09=20=20auto=20= __ns=20=3D=20chrono::duration_cast(__atime=20-=20= __s);=0A+=0A+=09=20=20__gthread_time_t=20__ts=20=3D=0A+=09=20=20{=0A+=09=20= =20=20=20static_cast(__s.time_since_epoch().count()),=0A+=09= =20=20=20=20static_cast(__ns.count())=0A+=09=20=20};=0A+=0A+=09=20=20= __gthread_cond_timedwait(__cv,=20__lock.mutex()->native_handle(),=0A+=09=09= =09=09=20=20=20&__ts);=0A+=09=20=20return=20(chrono::system_clock::now()=20= <=20__atime)=0A+=09=09=20?=20__atomic_wait_status::__no_timeout=0A+=09=09= =20:=20__atomic_wait_status::__timeout;=0A+=09}=0A+=0A+=20=20=20=20=20=20= //=20return=20true=20if=20timeout=0A+=20=20=20=20=20=20template=0A+=09__atomic_wait_status=0A+=09= __cond_wait_until(__gthread_cond_t*=20__cv,=0A+=09=20=20=20=20= unique_lock&=20__lock,=0A+=09=20=20=20=20const=20= chrono::time_point<_Clock,=20_Duration>&=20__atime)=0A+=09{=0A+#ifdef=20= _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT=0A+=09=20=20using=20__clock_t=20=3D=20= chrono::steady_clock;=0A+#else=0A+=09=20=20using=20__clock_t=20=3D=20= chrono::system_clock;=0A+#endif=0A+=09=20=20const=20typename=20= _Clock::time_point=20__c_entry=20=3D=20_Clock::now();=0A+=09=20=20const=20= __clock_t::time_point=20__s_entry=20=3D=20__clock_t::now();=0A+=09=20=20= const=20auto=20__delta=20=3D=20__atime=20-=20__c_entry;=0A+=09=20=20= const=20auto=20__s_atime=20=3D=20__s_entry=20+=20__delta;=0A+=09=20=20if=20= (__cond_wait_until_impl(__cv,=20__lock,=20__s_atime))=0A+=09=20=20=20=20= return=20__atomic_wait_status::__no_timeout;=0A+=09=20=20//=20We=20got=20= a=20timeout=20when=20measured=20against=20__clock_t=20but=0A+=09=20=20//=20= we=20need=20to=20check=20against=20the=20caller-supplied=20clock=0A+=09=20= =20//=20to=20tell=20whether=20we=20should=20return=20a=20timeout.=0A+=09=20= =20if=20(_Clock::now()=20<=20__atime)=0A+=09=20=20=20=20return=20= __atomic_wait_status::__no_timeout;=0A+=09=20=20return=20= __atomic_wait_status::__timeout;=0A+=09}=0A+=0A+=20=20=20=20struct=20= __timed_waiters=20:=20__waiters=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= template=0A+=09= __atomic_wait_status=0A+=09_M_do_wait_until(__platform_wait_t=20= __version,=0A+=09=09=09=20const=20chrono::time_point<_Clock,=20= _Duration>&=20__atime)=0A+=09{=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=09= =20=20return=20__platform_wait_until(&_M_ver,=20__version,=20__atime);=0A= +#else=0A+=09=20=20__platform_wait_t=20__cur=20=3D=200;=0A+=09=20=20= __waiters::__lock_t=20__l(_M_mtx);=0A+=09=20=20while=20(__cur=20<=3D=20= __version)=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20=20if=20= (__cond_wait_until(&_M_cv,=20__l,=20__atime)=20=3D=3D=20= __atomic_wait_status::__timeout)=0A+=09=09return=20= __atomic_wait_status::__timeout;=0A+=0A+=09=20=20=20=20=20=20= __platform_wait_t=20__last=20=3D=20__cur;=0A+=09=20=20=20=20=20=20= __atomic_load(&_M_ver,=20&__cur,=20__ATOMIC_ACQUIRE);=0A+=09=20=20=20=20=20= =20if=20(__cur=20<=20__last)=0A+=09=09break;=20//=20break=20the=20loop=20= if=20version=20overflows=0A+=09=20=20=20=20}=0A+=09=20=20return=20= __atomic_wait_status::__no_timeout;=0A+#endif=0A+=09}=0A+=0A+=20=20=20=20= =20=20static=20__timed_waiters&=0A+=20=20=20=20=20=20_S_timed_for(void*=20= __t)=0A+=20=20=20=20=20=20{=0A+=09static_assert(sizeof(__timed_waiters)=20= =3D=3D=20sizeof(__waiters));=0A+=09return=20(__timed_waiters&)=20= __waiters::_S_for(__t);=0A+=20=20=20=20=20=20}=0A+=20=20=20=20};=0A+=20=20= }=20//=20namespace=20__detail=0A+=0A+=20=20template=0A+=20=20=20=20bool=0A+=20=20=20=20__atomic_wait_until(const=20= _Tp*=20__addr,=20_Tp=20__old,=20_Pred=20__pred,=0A+=09=09=09const=20= chrono::time_point<_Clock,=20_Duration>&=20__atime)=20noexcept=0A+=20=20=20= =20{=0A+=20=20=20=20=20=20using=20namespace=20__detail;=0A+=0A+=20=20=20=20= =20=20if=20(std::__atomic_spin(__pred))=0A+=09return=20true;=0A+=0A+=20=20= =20=20=20=20auto&=20__w=20=3D=20= __timed_waiters::_S_timed_for((void*)__addr);=0A+=20=20=20=20=20=20auto=20= __version=20=3D=20__w._M_enter_wait();=0A+=20=20=20=20=20=20do=0A+=09{=0A= +=09=20=20__atomic_wait_status=20__res;=0A+=09=20=20if=20constexpr=20= (__platform_wait_uses_type<_Tp>)=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20= =20__res=20=3D=20__platform_wait_until((__platform_wait_t*)(void*)=20= __addr,=0A+=09=09=09=09=09=20=20=20=20__old,=0A+=09=09=09=09=09=20=20=20=20= __atime);=0A+=09=20=20=20=20}=0A+=09=20=20else=0A+=09=20=20=20=20{=0A+=09= =20=20=20=20=20=20__res=20=3D=20__w._M_do_wait_until(__version,=20= __atime);=0A+=09=20=20=20=20}=0A+=09=20=20if=20(__res=20=3D=3D=20= __atomic_wait_status::__timeout)=0A+=09=20=20=20=20return=20false;=0A+=09= }=0A+=20=20=20=20=20=20while=20(!__pred()=20&&=20__atime=20<=20= _Clock::now());=0A+=20=20=20=20=20=20__w._M_leave_wait();=0A+=0A+=20=20=20= =20=20=20//=20if=20timed=20out,=20return=20false=0A+=20=20=20=20=20=20= return=20(_Clock::now()=20<=20__atime);=0A+=20=20=20=20}=0A+=0A+=20=20= template=0A+=20=20=20=20bool=0A+=20=20=20=20= __atomic_wait_for(const=20_Tp*=20__addr,=20_Tp=20__old,=20_Pred=20= __pred,=0A+=09=09=20=20=20=20=20=20const=20chrono::duration<_Rep,=20= _Period>&=20__rtime)=20noexcept=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= using=20namespace=20__detail;=0A+=0A+=20=20=20=20=20=20if=20= (std::__atomic_spin(__pred))=0A+=09return=20true;=0A+=0A+=20=20=20=20=20=20= if=20(!__rtime.count())=0A+=09return=20false;=20//=20no=20rtime=20= supplied,=20and=20spin=20did=20not=20acquire=0A+=0A+=20=20=20=20=20=20= using=20__dur=20=3D=20chrono::steady_clock::duration;=0A+=20=20=20=20=20=20= auto=20__reltime=20=3D=20chrono::duration_cast<__dur>(__rtime);=0A+=20=20= =20=20=20=20if=20(__reltime=20<=20__rtime)=0A+=09++__reltime;=0A+=0A+=0A= +=20=20=20=20=20=20return=20__atomic_wait_until(__addr,=20__old,=20= std::move(__pred),=0A+=09=09=09=09=20chrono::steady_clock::now()=20+=20= __reltime);=0A+=20=20=20=20}=0A+_GLIBCXX_END_NAMESPACE_VERSION=0A+}=20//=20= namespace=20std=0A+#endif=0Adiff=20--git=20= a/libstdc++-v3/include/bits/atomic_wait.h=20= b/libstdc++-v3/include/bits/atomic_wait.h=0Anew=20file=20mode=20100644=0A= index=2000000000000..92c1e2526ed=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/include/bits/atomic_wait.h=0A@@=20-0,0=20+1,291=20@@=0A= +//=20-*-=20C++=20-*-=20header.=0A+=0A+//=20Copyright=20(C)=202020=20= Free=20Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20= part=20of=20the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20= free=0A+//=20software;=20you=20can=20redistribute=20it=20and/or=20modify=20= it=20under=20the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20= License=20as=20published=20by=20the=0A+//=20Free=20Software=20= Foundation;=20either=20version=203,=20or=20(at=20your=20option)=0A+//=20= any=20later=20version.=0A+=0A+//=20This=20library=20is=20distributed=20= in=20the=20hope=20that=20it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20= ANY=20WARRANTY;=20without=20even=20the=20implied=20warranty=20of=0A+//=20= MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20= See=20the=0A+//=20GNU=20General=20Public=20License=20for=20more=20= details.=0A+=0A+//=20Under=20Section=207=20of=20GPL=20version=203,=20you=20= are=20granted=20additional=0A+//=20permissions=20described=20in=20the=20= GCC=20Runtime=20Library=20Exception,=20version=0A+//=203.1,=20as=20= published=20by=20the=20Free=20Software=20Foundation.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20and=0A+//=20a=20copy=20of=20the=20GCC=20Runtime=20Library=20= Exception=20along=20with=20this=20program;=0A+//=20see=20the=20files=20= COPYING3=20and=20COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A= +//=20.=0A+=0A+/**=20@file=20= bits/atomic_wait.h=0A+=20*=20=20This=20is=20an=20internal=20header=20= file,=20included=20by=20other=20library=20headers.=0A+=20*=20=20Do=20not=20= attempt=20to=20use=20it=20directly.=20@headername{atomic}=0A+=20*/=0A+=0A= +#ifndef=20_GLIBCXX_ATOMIC_WAIT_H=0A+#define=20_GLIBCXX_ATOMIC_WAIT_H=20= 1=0A+=0A+#pragma=20GCC=20system_header=0A+=0A+#include=20= =0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20= =0A+#include=20=0A+=0A+#ifdef=20= _GLIBCXX_HAVE_LINUX_FUTEX=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#endif=0A+=0A+#define=20= _GLIBCXX_SPIN_COUNT_1=2016=0A+#define=20_GLIBCXX_SPIN_COUNT_2=2012=0A+=0A= +//=20TODO=20get=20this=20from=20Autoconf=0A+#define=20= _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE=201=0A+=0A+namespace=20std=20= _GLIBCXX_VISIBILITY(default)=0A+{=0A+_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A= +=20=20namespace=20__detail=0A+=20=20{=0A+=20=20=20=20using=20= __platform_wait_t=20=3D=20int;=0A+=0A+=20=20=20=20inline=20constexpr=0A+=20= =20=20=20auto=20__platform_wait_max_value=20=3D=0A+=09=09= __gnu_cxx::__numeric_traits<__platform_wait_t>::__max;=0A+=0A+=20=20=20=20= template=0A+=20=20=20=20=20=20inline=20constexpr=20bool=20= __platform_wait_uses_type=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=09=3D=20= is_same_v,=20__platform_wait_t>;=0A+#else=0A+=09=3D=20= false;=0A+#endif=0A+=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=20=20=20=20= enum=0A+=20=20=20=20{=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE=0A+=20= =20=20=20=20=20__futex_private_flag=20=3D=20128,=0A+#else=0A+=20=20=20=20= =20=20__futex_private_flag=20=3D=200,=0A+#endif=0A+=20=20=20=20=20=20= __futex_wait=20=3D=200,=0A+=20=20=20=20=20=20__futex_wake=20=3D=201,=0A+=20= =20=20=20=20=20__futex_wait_bitset=20=3D=209,=0A+=20=20=20=20=20=20= __futex_wake_bitset=20=3D=2010,=0A+=20=20=20=20=20=20= __futex_wait_private=20=3D=20__futex_wait=20|=20__futex_private_flag,=0A= +=20=20=20=20=20=20__futex_wake_private=20=3D=20__futex_wake=20|=20= __futex_private_flag=0A+=20=20=20=20};=0A+=0A+=20=20=20=20void=0A+=20=20=20= =20__platform_wait(__platform_wait_t*=20__addr,=20__platform_wait_t=20= __val)=20noexcept=0A+=20=20=20=20{=0A+=20=20=20=20=20=20=20auto=20__e=20= =3D=20syscall=20(SYS_futex,=20__addr,=20__futex_wait_private,=20__val,=20= nullptr);=0A+=20=20=20=20=20=20=20if=20(__e=20&&=20!(errno=20=3D=3D=20= EINTR=20||=20errno=20=3D=3D=20EAGAIN))=0A+=09=20std::terminate();=0A+=20=20= =20=20}=0A+=0A+=20=20=20=20void=0A+=20=20=20=20= __platform_notify(__platform_wait_t*=20__addr,=20bool=20__all)=20= noexcept=0A+=20=20=20=20{=0A+=20=20=20=20=20=20syscall=20(SYS_futex,=20= __addr,=20__futex_wake_private,=20__all=20?=20INT_MAX=20:=201);=0A+=20=20= =20=20}=0A+#endif=0A+=0A+=20=20=20=20struct=20__waiters=0A+=20=20=20=20{=0A= +=20=20=20=20=20=20__platform_wait_t=20alignas(64)=20_M_ver=20=3D=200;=0A= +=20=20=20=20=20=20__platform_wait_t=20alignas(64)=20_M_wait=20=3D=200;=0A= +=0A+#ifndef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=20=20=20=20=20=20using=20= __lock_t=20=3D=20std::unique_lock;=0A+=20=20=20=20=20=20= mutable=20__lock_t::mutex_type=20_M_mtx;=0A+=0A+#=20=20ifdef=20= __GTHREAD_COND_INIT=0A+=20=20=20=20=20=20mutable=20__gthread_cond_t=20= _M_cv=20=3D=20__GTHREAD_COND_INIT;=0A+=20=20=20=20=20=20__waiters()=20= noexcept=20=3D=20default;=0A+#=20=20else=0A+=20=20=20=20=20=20mutable=20= __gthread_cond_t=20_M_cv;=0A+=20=20=20=20=20=20__waiters()=20noexcept=0A= +=20=20=20=20=20=20{=0A+=09__GTHREAD_COND_INIT_FUNCTION(&_M_cond);=0A+=20= =20=20=20=20=20}=0A+#=20=20endif=0A+#endif=0A+=0A+=20=20=20=20=20=20= __platform_wait_t=0A+=20=20=20=20=20=20_M_enter_wait()=20noexcept=0A+=20=20= =20=20=20=20{=0A+=09__platform_wait_t=20__res;=0A+=09= __atomic_load(&_M_ver,=20&__res,=20__ATOMIC_ACQUIRE);=0A+=09= __atomic_fetch_add(&_M_wait,=201,=20__ATOMIC_ACQ_REL);=0A+=09return=20= __res;=0A+=20=20=20=20=20=20}=0A+=0A+=20=20=20=20=20=20void=0A+=20=20=20=20= =20=20_M_leave_wait()=20noexcept=0A+=20=20=20=20=20=20{=0A+=09= __atomic_fetch_sub(&_M_wait,=201,=20__ATOMIC_ACQ_REL);=0A+=20=20=20=20=20= =20}=0A+=0A+=20=20=20=20=20=20void=0A+=20=20=20=20=20=20= _M_do_wait(__platform_wait_t=20__version)=20noexcept=0A+=20=20=20=20=20=20= {=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=09__platform_wait(&_M_ver,=20= __version);=0A+#else=0A+=09__platform_wait_t=20__cur=20=3D=200;=0A+=09= while=20(__cur=20<=3D=20__version)=0A+=09=20=20{=0A+=09=20=20=20=20= __waiters::__lock_t=20__l(_M_mtx);=0A+=09=20=20=20=20auto=20__e=20=3D=20= __gthread_cond_wait(&_M_cv,=20__l.mutex()->native_handle());=0A+=09=20=20= =20=20if=20(__e)=0A+=09=20=20=20=20=20=20std::terminate();=0A+=09=20=20=20= =20__platform_wait_t=20__last=20=3D=20__cur;=0A+=09=20=20=20=20= __atomic_load(&_M_ver,=20&__cur,=20__ATOMIC_ACQUIRE);=0A+=09=20=20=20=20= if=20(__cur=20<=20__last)=0A+=09=20=20=20=20=20=20break;=20//=20break=20= the=20loop=20if=20version=20overflows=0A+=09=20=20}=0A+#endif=0A+=20=20=20= =20=20=20}=0A+=0A+=20=20=20=20=20=20__platform_wait_t=0A+=20=20=20=20=20=20= _M_waiting()=20const=20noexcept=0A+=09{=0A+=09=20=20__platform_wait_t=20= __res;=0A+=09=20=20__atomic_load(&_M_wait,=20&__res,=20= __ATOMIC_ACQUIRE);=0A+=09=20=20return=20__res;=0A+=09}=0A+=0A+=20=20=20=20= =20=20void=0A+=20=20=20=20=20=20_M_notify(bool=20__all)=20noexcept=0A+=20= =20=20=20=20=20{=0A+=09__atomic_fetch_add(&_M_ver,=201,=20= __ATOMIC_ACQ_REL);=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=09= __platform_notify(&_M_ver,=20__all);=0A+#else=0A+=09auto=20__e=20=3D=20= __gthread_cond_broadcast(&_M_cv);=0A+=09if=20(__e)=0A+=09=20=20= __throw_system_error(__e);=0A+#endif=0A+=20=20=20=20=20=20}=0A+=0A+=20=20= =20=20=20=20static=20__waiters&=0A+=20=20=20=20=20=20_S_for(void*=20__t)=0A= +=20=20=20=20=20=20{=0A+=09const=20unsigned=20char=20__mask=20=3D=200xf;=0A= +=09static=20__waiters=20__w[__mask=20+=201];=0A+=0A+=09auto=20__key=20=3D= =20_Hash_impl::hash(__t)=20&=20__mask;=0A+=09return=20__w[__key];=0A+=20=20= =20=20=20=20}=0A+=20=20=20=20};=0A+=0A+=20=20=20=20struct=20__waiter=0A+=20= =20=20=20{=0A+=20=20=20=20=20=20__waiters&=20_M_w;=0A+=20=20=20=20=20=20= __platform_wait_t=20_M_version;=0A+=0A+=20=20=20=20=20=20= template=0A+=09__waiter(const=20_Tp*=20__addr)=20= noexcept=0A+=09=20=20:=20_M_w(__waiters::_S_for((void*)=20__addr))=0A+=09= =20=20,=20_M_version(_M_w._M_enter_wait())=0A+=09{=20}=0A+=0A+=20=20=20=20= =20=20~__waiter()=0A+=20=20=20=20=20=20{=20_M_w._M_leave_wait();=20}=0A+=0A= +=20=20=20=20=20=20void=20_M_do_wait()=20noexcept=0A+=20=20=20=20=20=20{=20= _M_w._M_do_wait(_M_version);=20}=0A+=20=20=20=20};=0A+=0A+=20=20=20=20= void=0A+=20=20=20=20__thread_relax()=20noexcept=0A+=20=20=20=20{=0A+#if=20= defined=20__i386__=20||=20defined=20__x86_64__=0A+=20=20=20=20=20=20= __builtin_ia32_pause();=0A+#elif=20defined=20_GLIBCXX_USE_SCHED_YIELD=0A= +=20=20=20=20=20=20__gthread_yield();=0A+#endif=0A+=20=20=20=20}=0A+=0A+=20= =20=20=20void=0A+=20=20=20=20__thread_yield()=20noexcept=0A+=20=20=20{=0A= +#if=20defined=20_GLIBCXX_USE_SCHED_YIELD=0A+=20=20=20=20=20= __gthread_yield();=0A+#endif=0A+=20=20=20=20}=0A+=0A+=20=20}=20//=20= namespace=20__detail=0A+=0A+=20=20template=0A+=20=20=20= =20bool=0A+=20=20=20=20__atomic_spin(_Pred=20__pred)=20noexcept=0A+=20=20= =20=20{=0A+=20=20=20=20=20=20for=20(auto=20__i=20=3D=200;=20__i=20<=20= _GLIBCXX_SPIN_COUNT_1;=20++__i)=0A+=09{=0A+=09=20=20if=20(__pred())=0A+=09= =20=20=20=20return=20true;=0A+=0A+=09=20=20if=20(__i=20<=20= _GLIBCXX_SPIN_COUNT_2)=0A+=09=20=20=20=20__detail::__thread_relax();=0A+=09= =20=20else=0A+=09=20=20=20=20__detail::__thread_yield();=0A+=09}=0A+=20=20= =20=20=20=20return=20false;=0A+=20=20=20=20}=0A+=0A+=20=20= template=0A+=20=20=20=20void=0A+=20=20= =20=20__atomic_wait(const=20_Tp*=20__addr,=20_Tp=20__old,=20_Pred=20= __pred)=20noexcept=0A+=20=20=20=20{=0A+=20=20=20=20=20=20using=20= namespace=20__detail;=0A+=20=20=20=20=20=20if=20(__atomic_spin(__pred))=0A= +=09return;=0A+=0A+=20=20=20=20=20=20__waiter=20__w(__addr);=0A+=20=20=20= =20=20=20while=20(!__pred())=0A+=09{=0A+=09=20=20if=20constexpr=20= (__platform_wait_uses_type<_Tp>)=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20= =20__platform_wait((__platform_wait_t*)(void*)=20__addr,=20__old);=0A+=09= =20=20=20=20}=0A+=09=20=20else=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20=20= //=20TODO=20support=20timed=20backoff=20when=20this=20can=20be=20moved=20= into=20the=20lib=0A+=09=20=20=20=20=20=20__w._M_do_wait();=0A+=09=20=20=20= =20}=0A+=09}=0A+=20=20=20=20}=0A+=0A+=20=20template=0A+=20= =20=20=20void=0A+=20=20=20=20__atomic_notify(const=20_Tp*=20__addr,=20= bool=20__all)=20noexcept=0A+=20=20=20=20{=0A+=20=20=20=20=20=20using=20= namespace=20__detail;=0A+=20=20=20=20=20=20auto&=20__w=20=3D=20= __waiters::_S_for((void*)__addr);=0A+=20=20=20=20=20=20if=20= (!__w._M_waiting())=0A+=09return;=0A+=0A+=20=20=20=20=20=20if=20= constexpr=20(__platform_wait_uses_type<_Tp>)=0A+=09{=0A+=09=20=20= __platform_notify((__platform_wait_t*)(void*)=20__addr,=20__all);=0A+=09= }=0A+=20=20=20=20=20=20else=0A+=09{=0A+=09=20=20__w._M_notify(__all);=0A= +=09}=0A+=20=20=20=20}=0A+_GLIBCXX_END_NAMESPACE_VERSION=0A+}=20//=20= namespace=20std=0A+#endif=0Adiff=20--git=20= a/libstdc++-v3/include/bits/semaphore_base.h=20= b/libstdc++-v3/include/bits/semaphore_base.h=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..f0c4235d91c=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/include/bits/semaphore_base.h=0A@@=20-0,0=20+1,272=20@@=0A= +//=20-*-=20C++=20-*-=20header.=0A+=0A+//=20Copyright=20(C)=202020=20= Free=20Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20= part=20of=20the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20= free=0A+//=20software;=20you=20can=20redistribute=20it=20and/or=20modify=20= it=20under=20the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20= License=20as=20published=20by=20the=0A+//=20Free=20Software=20= Foundation;=20either=20version=203,=20or=20(at=20your=20option)=0A+//=20= any=20later=20version.=0A+=0A+//=20This=20library=20is=20distributed=20= in=20the=20hope=20that=20it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20= ANY=20WARRANTY;=20without=20even=20the=20implied=20warranty=20of=0A+//=20= MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20= See=20the=0A+//=20GNU=20General=20Public=20License=20for=20more=20= details.=0A+=0A+//=20Under=20Section=207=20of=20GPL=20version=203,=20you=20= are=20granted=20additional=0A+//=20permissions=20described=20in=20the=20= GCC=20Runtime=20Library=20Exception,=20version=0A+//=203.1,=20as=20= published=20by=20the=20Free=20Software=20Foundation.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20and=0A+//=20a=20copy=20of=20the=20GCC=20Runtime=20Library=20= Exception=20along=20with=20this=20program;=0A+//=20see=20the=20files=20= COPYING3=20and=20COPYING.RUNTIME=20respectively.=20=20If=20not,=20see=0A= +//=20.=0A+=0A+/**=20@file=20= bits/semaphore_base.h=0A+=20*=20=20This=20is=20an=20internal=20header=20= file,=20included=20by=20other=20library=20headers.=0A+=20*=20=20Do=20not=20= attempt=20to=20use=20it=20directly.=20@headername{semaphore}=0A+=20*/=0A= +=0A+#ifndef=20_GLIBCXX_SEMAPHORE_BASE_H=0A+#define=20= _GLIBCXX_SEMAPHORE_BASE_H=201=0A+=0A+#pragma=20GCC=20system_header=0A+=0A= +#include=20=0A+#include=20=0A= +#include=20=0A+=0A+#if=20defined=20= _POSIX_SEMAPHORES=20=20&&=20__has_include()=0A+#define=20= _GLIBCXX_HAVE_POSIX_SEMAPHORE=201=0A+#include=20=0A+#endif=0A= +=0A+#include=20=0A+#include=20=0A+=0A+namespace=20= std=20_GLIBCXX_VISIBILITY(default)=0A+{=0A= +_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A+=0A+#ifdef=20= _GLIBCXX_HAVE_POSIX_SEMAPHORE=0A+=20=20template=0A+=20=20=20=20struct=20__platform_semaphore=0A+=20=20= =20=20{=0A+=20=20=20=20=20=20using=20__clock_t=20=3D=20= chrono::system_clock;=0A+=0A+=20=20=20=20=20=20explicit=20= __platform_semaphore(ptrdiff_t=20__count)=20noexcept=0A+=20=20=20=20=20=20= {=0A+=09static_assert(=20__least_max_value=20<=3D=20SEM_VALUE_MAX,=20= "");=0A+=09auto=20__e=20=3D=20sem_init(&_M_semaphore,=200,=20__count);=0A= +=09if=20(__e)=0A+=09=20=20std::terminate();=0A+=20=20=20=20=20=20}=0A+=0A= +=20=20=20=20=20=20~__platform_semaphore()=0A+=20=20=20=20=20=20{=0A+=09= auto=20__e=20=3D=20sem_destroy(&_M_semaphore);=0A+=09if=20(__e)=0A+=09=20= =20std::terminate();=0A+=20=20=20=20=20=20}=0A+=0A+=20=20=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20=20acquire()=20noexcept=0A= +=20=20=20=20=20=20{=0A+=09auto=20__err=20=3D=20sem_wait(&_M_semaphore);=0A= +=09if=20(__err)=0A+=09=20=20std::terminate();=0A+=20=20=20=20=20=20}=0A= +=0A+=20=20=20=20=20=20template=0A+=09bool=0A+=09= __try_acquire_until_impl(const=20chrono::time_point<__clock_t>&=20= __atime)=20noexcept=0A+=09{=0A+=09=20=20auto=20__s=20=3D=20= chrono::time_point_cast(__atime);=0A+=09=20=20auto=20= __ns=20=3D=20chrono::duration_cast(__atime=20-=20= __s);=0A+=0A+=09=20=20struct=20timespec=20__ts=20=3D=0A+=09=20=20{=0A+=09= =20=20=20=20static_cast(__s.time_since_epoch().count()),=0A= +=09=20=20=20=20static_cast(__ns.count())=0A+=09=20=20};=0A+=0A+=09= =20=20auto=20__err=20=3D=20sem_timedwait(&_M_semaphore,=20&__ts);=0A+=09=20= =20if=20(__err=20&&=20(errno=20=3D=3D=20ETIMEDOUT))=0A+=09=20=20=20=20=20= =20return=20false;=0A+=09=20=20else=20if=20(__err)=0A+=09=20=20=20=20=20=20= std::terminate();=0A+=09=20=20return=20true;=0A+=09}=0A+=0A+=20=20=20=20=20= =20template=0A+=09bool=0A+=09= try_acquire_until(const=20chrono::time_point<_Clock,=20_Duration>&=20= __atime)=20noexcept=0A+=09{=0A+=09=20=20if=20constexpr=20= (std::is_same<__clock_t,=20_Clock>::value)=0A+=09=20=20=20=20{=0A+=09=20=20= =20=20=20=20return=20__try_acquire_until_impl(__atime);=0A+=09=20=20=20=20= }=0A+=09=20=20else=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20=20const=20= typename=20_Clock::time_point=20__c_entry=20=3D=20_Clock::now();=0A+=09=20= =20=20=20=20=20const=20__clock_t=20__s_entry=20=3D=20__clock_t::now();=0A= +=09=20=20=20=20=20=20const=20auto=20__delta=20=3D=20__atime=20-=20= __c_entry;=0A+=09=20=20=20=20=20=20const=20auto=20__s_atime=20=3D=20= __s_entry=20+=20__delta;=0A+=09=20=20=20=20=20=20if=20= (__try_acquire_until_impl(__s_atime))=0A+=09=09return=20true;=0A+=0A+=09=20= =20=20=20=20=20//=20We=20got=20a=20timeout=20when=20measured=20against=20= __clock_t=20but=0A+=09=20=20=20=20=20=20//=20we=20need=20to=20check=20= against=20the=20caller-supplied=20clock=0A+=09=20=20=20=20=20=20//=20to=20= tell=20whether=20we=20should=20return=20a=20timeout.=0A+=09=20=20=20=20=20= =20return=20(_Clock::now()=20<=20__atime);=0A+=09=20=20=20=20}=0A+=09}=0A= +=0A+=20=20=20=20=20=20template=0A= +=09_GLIBCXX_ALWAYS_INLINE=20bool=0A+=09try_acquire_for(const=20= chrono::duration<_Rep,=20_Period>&=20__rtime)=20noexcept=0A+=09{=20= return=20try_acquire_until(__clock_t::now()=20+=20__rtime);=20}=0A+=0A+=20= =20=20=20=20=20template=0A+=09= _GLIBCXX_ALWAYS_INLINE=20void=0A+=09release(ptrdiff_t=20__update)=20= noexcept=0A+=09{=0A+=09=20=20do=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20= =20auto=20__err=20=3D=20sem_post(&_M_semaphore);=0A+=09=20=20=20=20=20=20= if=20(__err)=0A+=09=09std::terminate();=0A+=09=20=20=20=20}=20while=20= (--__update);=0A+=09}=0A+=0A+=20=20=20=20=20=20private:=0A+=09sem_t=20= _M_semaphore;=0A+=20=20=20=20=20=20};=0A+#endif=20//=20= _GLIBCXX_HAVE_POSIX_SEMAPHORE=0A+=0A+=20=20=20=20template=0A+=20=20=20=20=20=20struct=20__atomic_semaphore=0A+=20=20=20=20=20=20= {=0A+=09explicit=20__atomic_semaphore(_Tp=20__count)=0A+=09=20=20:=20= _M_a(__count)=0A+=09{=20}=0A+=0A+=09_GLIBCXX_ALWAYS_INLINE=20void=0A+=09= acquire()=20noexcept=0A+=09{=0A+=09=20=20auto=20const=20__pred=20=3D=20= [this]=0A+=09=20=20=20=20{=0A+=09=20=20=20=20=20=20auto=20__old=20=3D=20= __atomic_impl::load(&this->_M_a,=0A+=09=09=09=20=20=20=20=20=20= memory_order::acquire);=0A+=09=20=20=20=20=20=20if=20(__old=20=3D=3D=20= 0)=0A+=09=09return=20false;=0A+=09=20=20=20=20=20=20return=20= __atomic_impl::compare_exchange_strong(&this->_M_a,=0A+=09=09=09__old,=20= __old=20-=201,=0A+=09=09=09memory_order::acquire,=0A+=09=09=09= memory_order::release);=0A+=09=20=20=20=20};=0A+=09=20=20auto=20__old=20= =3D=20__atomic_impl::load(&_M_a,=20memory_order_relaxed);=0A+=09=20=20= __atomic_wait(&_M_a,=20__old,=20__pred);=0A+=09}=0A+=0A+=09bool=0A+=09= try_acquire()=20noexcept=0A+=09{=0A+=09=20=20auto=20__old=20=3D=20= __atomic_impl::load(&_M_a,=20memory_order::acquire);=0A+=09=20=20if=20= (__old=20=3D=3D=200)=0A+=09=20=20=20=20return=20false;=0A+=0A+=09=20=20= return=20__atomic_spin([this,=20&__old]=0A+=09=20=20=20=20{=0A+=09=20=20=20= =20=20=20return=20__atomic_impl::compare_exchange_weak(&this->_M_a,=0A+=09= =09=09__old,=20__old=20-=201,=0A+=09=09=09memory_order::acquire,=0A+=09=09= =09memory_order::release);=0A+=09=20=20=20=20});=0A+=09}=0A+=0A+=09= template=0A+=09=20=20= _GLIBCXX_ALWAYS_INLINE=20bool=0A+=09=20=20try_acquire_until(const=20= chrono::time_point<_Clock,=20_Duration>&=20__atime)=20noexcept=0A+=09=20=20= {=0A+=09=20=20=20=20auto=20const=20__pred=20=3D=20[this]=0A+=09=20=20=20=20= =20=20{=0A+=09=09auto=20__old=20=3D=20__atomic_impl::load(&this->_M_a,=0A= +=09=09=09=09memory_order::acquire);=0A+=09=09if=20(__old=20=3D=3D=200)=0A= +=09=09=20=20return=20false;=0A+=09=09return=20= __atomic_impl::compare_exchange_strong(&this->_M_a,=0A+=09=09=09=09= __old,=20__old=20-=201,=0A+=09=09=09=09memory_order::acquire,=0A+=09=09=09= =09memory_order::release);=0A+=09=20=20=20=20=20=20};=0A+=0A+=09=20=20=20= =20auto=20__old=20=3D=20__atomic_impl::load(&_M_a,=20= memory_order_relaxed);=0A+=09=20=20=20=20return=20= __atomic_wait_until(&_M_a,=20__old,=20__pred,=20__atime);=0A+=09}=0A+=0A= +=20=20=20=20=20=20template=0A+=09= _GLIBCXX_ALWAYS_INLINE=20bool=0A+=09try_acquire_for(const=20= chrono::duration<_Rep,=20_Period>&=20__rtime)=20noexcept=0A+=09{=0A+=09=20= =20auto=20const=20__pred=20=3D=20[this]=0A+=09=20=20=20=20{=0A+=09=20=20=20= =20=20=20auto=20__old=20=3D=20__atomic_impl::load(&this->_M_a,=0A+=09=09=09= =20=20=20=20=20=20memory_order::acquire);=0A+=09=20=20=20=20=20=20if=20= (__old=20=3D=3D=200)=0A+=09=09return=20false;=0A+=09=20=20=20=20=20=20= return=20=20__atomic_impl::compare_exchange_strong(&this->_M_a,=0A+=09=09= =09=20=20=20=20=20=20__old,=20__old=20-=201,=0A+=09=09=09=20=20=20=20=20=20= memory_order::acquire,=0A+=09=09=09=20=20=20=20=20=20= memory_order::release);=0A+=09=20=20=20=20};=0A+=0A+=09=20=20auto=20= __old=20=3D=20__atomic_impl::load(&_M_a,=20memory_order_relaxed);=0A+=09=20= =20return=20__atomic_wait_for(&_M_a,=20__old,=20__pred,=20__rtime);=0A+=09= }=0A+=0A+=20=20=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20=20= =20release(ptrdiff_t=20__update)=20noexcept=0A+=20=20=20=20=20=20{=0A+=09= if=20(0=20<=20__atomic_impl::fetch_add(&_M_a,=20__update,=20= memory_order_release))=0A+=09=20=20return;=0A+=09if=20(__update=20>=201)=0A= +=09=20=20__atomic_impl::notify_all(&_M_a);=0A+=09else=0A+=09=20=20= __atomic_impl::notify_one(&_M_a);=0A+=20=20=20=20=20=20}=0A+=0A+=20=20=20= =20private:=0A+=20=20=20=20=20=20alignas(__alignof__(_Tp))=20_Tp=20_M_a;=0A= +=20=20=20=20};=0A+=0A+#ifdef=20_GLIBCXX_REQUIRE_POSIX_SEMAPHORE=0A+=20=20= template=0A+=20=20=20=20using=20= __semaphore_base=20=3D=20__platform_semaphore<__least_max_value>;=0A= +#else=0A+#=20=20ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=20=20= template=0A+=20=20=20=20using=20= __semaphore_base=20=3D=20conditional_t<(=0A+=09=09=09=20=20=20=20=20=20= __least_max_value=20>=3D=200=0A+=09=09=09=09&&=20__least_max_value=20<=3D=20= __detail::__platform_wait_max_value),=0A+=09=09=09=20=20=20=20=20=20= __atomic_semaphore<__detail::__platform_wait_t>,=0A+=09=09=09=20=20=20=20= =20=20__atomic_semaphore>;=0A+=0A+//=20__platform_semaphore=0A= +#=20=20elif=20defined=20_GLIBCXX_HAVE_POSIX_SEMAPHORE=0A+=20=20= template=0A+=20=20=20=20using=20= __semaphore_base=20=3D=20conditional_t<(=0A+=09=09=09=20=20=20=20=20=20= __least_max_value=20>=3D=200=0A+=09=09=09=09&&=20__least_max_value=20<=3D=20= SEM_VALUE_MAX),=0A+=09=09=09=20=20=20=20=20=20= __platform_semaphore<__least_max_value>,=0A+=09=09=09=20=20=20=20=20=20= __atomic_semaphore>;=0A+#=20=20else=0A+=20=20= template=0A+=20=20=20=20using=20= __semaphore_base=20=3D=20__atomic_semaphore;=0A+#=20=20endif=0A= +#endif=0A+=0A+_GLIBCXX_END_NAMESPACE_VERSION=0A+}=20//=20namespace=20= std=0A+=0A+#endif=0Adiff=20--git=20a/libstdc++-v3/include/std/atomic=20= b/libstdc++-v3/include/std/atomic=0Aindex=20a455286a784..3f18774031d=20= 100644=0A---=20a/libstdc++-v3/include/std/atomic=0A+++=20= b/libstdc++-v3/include/std/atomic=0A@@=20-163,6=20+163,19=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=20=20=20=20= compare_exchange_strong(bool&=20__i1,=20bool=20__i2,=0A=20=09=09=20=20=20= =20memory_order=20__m=20=3D=20memory_order_seq_cst)=20volatile=20= noexcept=0A=20=20=20=20=20{=20return=20= _M_base.compare_exchange_strong(__i1,=20__i2,=20__m);=20}=0A+=0A+#if=20= __cplusplus=20>=20201703L=0A+=20=20=20=20void=20wait(bool=20__old,=20= memory_order=20__m=20=3D=20memory_order_seq_cst)=20const=20noexcept=0A+=20= =20=20=20{=20_M_base.wait(__old,=20__m);=20}=0A+=0A+=20=20=20=20//=20= TODO=20add=20const=20volatile=20overload=0A+=0A+=20=20=20=20void=20= notify_one()=20const=20noexcept=0A+=20=20=20=20{=20_M_base.notify_one();=20= }=0A+=0A+=20=20=20=20void=20notify_all()=20const=20noexcept=0A+=20=20=20=20= {=20_M_base.notify_all();=20}=0A+#endif=0A=20=20=20};=0A=20=0A=20#if=20= __cplusplus=20<=3D=20201703L=0A@@=20-352,6=20+365,19=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=20=20=20=20=20memory_order=20= __m=20=3D=20memory_order_seq_cst)=20volatile=20noexcept=0A=20=20=20=20=20= =20=20{=20return=20compare_exchange_strong(__e,=20__i,=20__m,=0A=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20__cmpexch_failure_order(__m));=20}=0A= +#if=20__cplusplus=20>=20201703L=0A+=20=20=20=20void=20wait(_Tp=20__old,=20= memory_order=20__m=20=3D=20memory_order_seq_cst)=20noexcept=0A+=20=20=20=20= {=20_M_i.wait(__old,=20__m);=20}=0A+=0A+=20=20=20=20//=20TODO=20add=20= const=20volatile=20overload=0A+=0A+=20=20=20=20void=20notify_one()=20= const=20noexcept=0A+=20=20=20=20{=20_M_i.notify_one();=20}=0A+=0A+=20=20=20= =20void=20notify_all()=20const=20noexcept=0A+=20=20=20=20{=20= _M_i.notify_all();=20}=0A+#endif=0A+=0A=20=20=20=20=20};=0A=20#undef=20= _GLIBCXX20_INIT=0A=20=0A@@=20-590,6=20+616,18=20@@=20= _GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=09=20=20=20=20= __cmpexch_failure_order(__m));=0A=20=20=20=20=20=20=20}=0A=20=0A+#if=20= __cplusplus=20>=20201703L=0A+=20=20=20=20void=20wait(__pointer_type=20= __old,=20memory_order=20__m=20=3D=20memory_order_seq_cst)=20noexcept=0A+=20= =20=20=20{=20_M_b.wait(__old,=20__m);=20}=0A+=0A+=20=20=20=20//=20TODO=20= add=20const=20volatile=20overload=0A+=0A+=20=20=20=20void=20notify_one()=20= const=20noexcept=0A+=20=20=20=20{=20_M_b.notify_one();=20}=0A+=0A+=20=20=20= =20void=20notify_all()=20const=20noexcept=0A+=20=20=20=20{=20= _M_b.notify_all();=20}=0A+#endif=0A=20=20=20=20=20=20=20__pointer_type=0A= =20=20=20=20=20=20=20fetch_add(ptrdiff_t=20__d,=0A=20=09=09memory_order=20= __m=20=3D=20memory_order_seq_cst)=20noexcept=0A@@=20-1342,6=20+1380,29=20= @@=20_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A=20=09=09=09=09=09=09=20=20=20=20= =20memory_order_seq_cst);=0A=20=20=20=20=20}=0A=20=0A+=0A+#if=20= __cplusplus=20>=20201703L=0A+=20=20template=0A+=20=20=20=20= inline=20void=20atomic_wait(const=20atomic<_Tp>*=20__a,=0A+=09=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20typename=20= std::atomic<_Tp>::value_type=20__old)=20noexcept=0A+=20=20=20=20{=20= __a->wait(__old);=20}=0A+=0A+=20=20template=0A+=20=20=20=20= inline=20void=20atomic_wait_explicit(const=20atomic<_Tp>*=20__a,=0A+=09=09= =09=09=20=20=20=20=20typename=20std::atomic<_Tp>::value_type=20__old,=0A= +=09=09=09=09=20=20=20=20=20std::memory_order=20__m)=20noexcept=0A+=20=20= =20=20{=20__a->wait(__old,=20__m);=20}=0A+=0A+=20=20template=0A+=20=20=20=20inline=20void=20atomic_notify_one(atomic<_Tp>*=20= __a)=20noexcept=0A+=20=20=20=20{=20__a->notify_one();=20}=0A+=0A+=20=20= template=0A+=20=20=20=20inline=20void=20= atomic_notify_all(atomic<_Tp>*=20__a)=20noexcept=0A+=20=20=20=20{=20= __a->notify_all();=20}=0A+=0A+#endif=20//=20C++2a=0A+=0A=20=20=20//=20= Function=20templates=20for=20atomic_integral=20and=20atomic_pointer=20= operations=20only.=0A=20=20=20//=20Some=20operations=20(and,=20or,=20= xor)=20are=20only=20available=20for=20atomic=20integrals,=0A=20=20=20//=20= which=20is=20implemented=20by=20taking=20a=20parameter=20of=20type=20= __atomic_base<_ITp>*.=0Adiff=20--git=20a/libstdc++-v3/include/std/latch=20= b/libstdc++-v3/include/std/latch=0Anew=20file=20mode=20100644=0Aindex=20= 00000000000..aa5299d9fdd=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/include/std/latch=0A@@=20-0,0=20+1,90=20@@=0A+//=20= =20-*-=20C++=20-*-=0A+=0A+//=20Copyright=20(C)=202020=20Free=20= Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20= the=20GNU=20ISO=20C++=20Library.=09This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=09=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20= Under=20Section=207=20of=20GPL=20version=203,=20you=20are=20granted=20= additional=0A+//=20permissions=20described=20in=20the=20GCC=20Runtime=20= Library=20Exception,=20version=0A+//=203.1,=20as=20published=20by=20the=20= Free=20Software=20Foundation.=0A+=0A+//=20You=20should=20have=20received=20= a=20copy=20of=20the=20GNU=20General=20Public=20License=20and=0A+//=20a=20= copy=20of=20the=20GCC=20Runtime=20Library=20Exception=20along=20with=20= this=20program;=0A+//=20see=20the=20files=20COPYING3=20and=20= COPYING.RUNTIME=20respectively.=09=20If=20not,=20see=0A+//=20= .=0A+=0A+/**=20@file=20include/latch=0A+=20= *=20=20This=20is=20a=20Standard=20C++=20Library=20header.=0A+=20*/=0A+=0A= +#ifndef=20_GLIBCXX_LATCH=0A+#define=20_GLIBCXX_LATCH=0A+=0A+#pragma=20= GCC=20system_header=0A+=0A+#if=20__cplusplus=20>=20201703L=0A+#define=20= __cpp_lib_latch=20201907L=0A+=0A+#include=20=0A= +#include=20=0A+=0A+namespace=20std=20= _GLIBCXX_VISIBILITY(default)=0A+{=0A+_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A= +=0A+=20=20class=20latch=0A+=20=20{=0A+=20=20public:=0A+=20=20=20=20= static=20constexpr=0A+=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20ptrdiff_t=0A+=20= =20=20=20max()=20noexcept=0A+=20=20=20=20{=20return=20= __gnu_cxx::__numeric_traits::__max;=20}=0A+=0A+=20=20=20=20= constexpr=20explicit=20latch(ptrdiff_t=20__expected)=20:=20= _M_a(__expected)=20{=20}=0A+=0A+=20=20=20=20~latch()=20=3D=20default;=0A= +=20=20=20=20latch(const=20latch&)=20=3D=20delete;=0A+=20=20=20=20latch&=20= operator=3D(const=20latch&)=20=3D=20delete;=0A+=0A+=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20count_down(ptrdiff_t=20= __update=20=3D=201)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20auto=20const=20= __old=20=3D=20__atomic_impl::fetch_sub(&_M_a,=20__update,=20= memory_order::release);=0A+=20=20=20=20=20=20if=20(__old=20=3D=3D=20= __update)=0A+=09__atomic_impl::notify_all(&_M_a);=0A+=20=20=20=20}=0A+=0A= +=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20bool=0A+=20=20=20=20try_wait()=20= const=20noexcept=0A+=20=20=20=20{=20return=20__atomic_impl::load(&_M_a,=20= memory_order::acquire)=20=3D=3D=200;=20}=0A+=0A+=20=20=20=20= _GLIBCXX_ALWAYS_INLINE=20void=0A+=20=20=20=20wait()=20const=0A+=20=20=20=20= {=0A+=20=20=20=20=20=20auto=20const=20__old=20=3D=20= __atomic_impl::load(&_M_a,=20memory_order::acquire);=0A+=20=20=20=20=20=20= __atomic_wait(&_M_a,=20__old,=20[this]=20{=20return=20this->try_wait();=20= });=0A+=20=20=20=20}=0A+=0A+=20=20=20=20_GLIBCXX_ALWAYS_INLINE=20void=0A= +=20=20=20=20arrive_and_wait(ptrdiff_t=20__update=20=3D=201)=0A+=20=20=20= =20{=0A+=20=20=20=20=20=20count_down();=0A+=20=20=20=20=20=20wait();=0A+=20= =20=20=20}=0A+=0A+=20=20private:=0A+=20=20=20=20= alignas(__alignof__(ptrdiff_t))=20ptrdiff_t=20_M_a;=0A+=20=20};=0A= +_GLIBCXX_END_NAMESPACE_VERSION=0A+}=20//=20namespace=0A+#endif=20//=20= __cplusplus=20>=20201703L=0A+#endif=20//=20_GLIBCXX_LATCH=0Adiff=20--git=20= a/libstdc++-v3/include/std/semaphore=20= b/libstdc++-v3/include/std/semaphore=0Anew=20file=20mode=20100644=0A= index=2000000000000..90cf3244647=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/include/std/semaphore=0A@@=20-0,0=20+1,86=20@@=0A+//=20= =20-*-=20C++=20-*-=0A+=0A+//=20Copyright=20(C)=202020=20Free=20= Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20= the=20GNU=20ISO=20C++=20Library.=09This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=09=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20= Under=20Section=207=20of=20GPL=20version=203,=20you=20are=20granted=20= additional=0A+//=20permissions=20described=20in=20the=20GCC=20Runtime=20= Library=20Exception,=20version=0A+//=203.1,=20as=20published=20by=20the=20= Free=20Software=20Foundation.=0A+=0A+//=20You=20should=20have=20received=20= a=20copy=20of=20the=20GNU=20General=20Public=20License=20and=0A+//=20a=20= copy=20of=20the=20GCC=20Runtime=20Library=20Exception=20along=20with=20= this=20program;=0A+//=20see=20the=20files=20COPYING3=20and=20= COPYING.RUNTIME=20respectively.=09=20If=20not,=20see=0A+//=20= .=0A+=0A+/**=20@file=20include/semaphore=0A= +=20*=20=20This=20is=20a=20Standard=20C++=20Library=20header.=0A+=20*/=0A= +=0A+#ifndef=20_GLIBCXX_SEMAPHORE=0A+#define=20_GLIBCXX_SEMAPHORE=0A+=0A= +#pragma=20GCC=20system_header=0A+=0A+#if=20__cplusplus=20>=20201703L=0A= +#define=20__cpp_lib_semaphore=20201907L=0A+#include=20= =0A+#include=20=0A+=0A= +namespace=20std=20_GLIBCXX_VISIBILITY(default)=0A+{=0A= +_GLIBCXX_BEGIN_NAMESPACE_VERSION=0A+=0A+=20=20template::__max>=0A+=20=20=20=20class=20= counting_semaphore=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= static_assert(__least_max_value=20>=3D0,=20"");=0A+=0A+=20=20=20=20=20=20= __semaphore_base<__least_max_value>=20_M_sem;=0A+=0A+=20=20=20=20public:=0A= +=20=20=20=20=20=20explicit=20counting_semaphore(ptrdiff_t=20__desired)=20= noexcept=0A+=09:=20_M_sem(__desired)=0A+=20=20=20=20=20=20{=20}=0A+=0A+=20= =20=20=20=20=20~counting_semaphore()=20=3D=20default;=0A+=0A+=20=20=20=20= =20=20counting_semaphore(const=20counting_semaphore&)=20=3D=20delete;=0A= +=20=20=20=20=20=20counting_semaphore&=20operator=3D(const=20= counting_semaphore&)=20=3D=20delete;=0A+=0A+=20=20=20=20=20=20static=20= constexpr=20ptrdiff_t=20max()=20noexcept=0A+=20=20=20=20=20=20{=20return=20= __least_max_value;=20}=0A+=0A+=20=20=20=20=20=20void=20release(ptrdiff_t=20= __update=20=3D=201)=0A+=20=20=20=20=20=20{=20_M_sem.release(__update);=20= }=0A+=0A+=20=20=20=20=20=20void=20acquire()=0A+=20=20=20=20=20=20{=20= _M_sem.acquire();=20}=0A+=0A+=20=20=20=20=20=20bool=20try_acquire()=20= noexcept=0A+=20=20=20=20=20=20{=20return=20_M_sem.try_acquire();=20}=0A+=0A= +=20=20=20=20=20=20template=0A+=09bool=20= try_acquire_for(const=20std::chrono::duration<_Rep,=20_Period>&=20= __rel_time)=0A+=09{=20return=20_M_sem.try_acquire_for(__rel_time);=20}=0A= +=0A+=20=20=20=20=20=20template=0A+=09= bool=20try_acquire_until(const=20std::chrono::time_point<_Clock,=20= _Duration>&=20__abs_time)=0A+=09{=20return=20= _M_sem.try_acquire_until(__abs_time);=20}=0A+=20=20=20=20};=0A+=0A+=20= using=20binary_semaphore=20=3D=20std::counting_semaphore<1>;=0A= +_GLIBCXX_END_NAMESPACE_VERSION=0A+}=20//=20namespace=0A+#endif=20//=20= __cplusplus=20>=20201703L=0A+#endif=20//=20_GLIBCXX_SEMAPHORE=0Adiff=20= --git=20a/libstdc++-v3/include/std/version=20= b/libstdc++-v3/include/std/version=0Aindex=20c6bde2cfbda..f09da3344f7=20= 100644=0A---=20a/libstdc++-v3/include/std/version=0A+++=20= b/libstdc++-v3/include/std/version=0A@@=20-189,6=20+189,8=20@@=0A=20= #endif=0A=20#define=20__cpp_lib_type_identity=20201806L=0A=20#define=20= __cpp_lib_unwrap_ref=20201811L=0A+#define=20__cpp_lib_semaphore=20= 201907L=0A+#define=20__cpp_lib_latch=20201907L=0A=20=0A=20#if=20= _GLIBCXX_HOSTED=0A=20#undef=20__cpp_lib_array_constexpr=0Adiff=20--git=20= a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc=0A= new=20file=20mode=20100644=0Aindex=2000000000000..1ced9d44b20=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc=0A= @@=20-0,0=20+1,103=20@@=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20= -pthread=20-latomic=20-L../../libatomic/.libs"=20}=0A+//=20{=20dg-do=20= run=20{=20target=20c++2a=20}=20}=0A+//=20{=20dg-require-effective-target=20= pthread=20}=0A+//=20{=20dg-require-gthreads=20""=20}=0A+=0A+//=20= Copyright=20(C)=202020=20Free=20Software=20Foundation,=20Inc.=0A+//=0A= +//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20Library.=20=20= This=20library=20is=20free=0A+//=20software;=20you=20can=20redistribute=20= it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20of=20the=20GNU=20= General=20Public=20License=20as=20published=20by=20the=0A+//=20Free=20= Software=20Foundation;=20either=20version=203,=20or=20(at=20your=20= option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20is=20= distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A+//=20= but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+#include=20= =0A+#include=20=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20=0A= +=0A+#include=20=0A+=0A+template=0A+Tp=20= check_wait_notify(Tp=20val1,=20Tp=20val2)=0A+{=0A+=20=20using=20= namespace=20std::literals::chrono_literals;=0A+=0A+=20=20std::mutex=20m;=0A= +=20=20std::condition_variable=20cv;=0A+=0A+=20=20Tp=20aa=20=3D=20val1;=0A= +=20=20std::atomic_ref=20a(aa);=0A+=20=20std::thread=20t([&]=0A+=09=09= {=0A+=09=09=20=20cv.notify_one();=0A+=09=09=20=20a.wait(val1);=0A+=09=09=20= =20if=20(a.load()=20!=3D=20val2)=0A+=09=09=20=20=20=20a=20=3D=20val1;=0A= +=09=09});=0A+=20=20std::unique_lock=20l(m);=0A+=20=20= cv.wait(l);=0A+=20=20std::this_thread::sleep_for(100ms);=0A+=20=20= a.store(val2);=0A+=20=20a.notify_one();=0A+=20=20t.join();=0A+=20=20= return=20a.load();=0A+}=0A+=0A+template=0A+=09=20||=20std::is_floating_point_v>=0A= +struct=20check;=0A+=0A+template=0A+struct=20check=0A+{=0A+=20=20check()=0A+=20=20{=0A+=20=20=20=20Tp=20a=20=3D=200;=0A= +=20=20=20=20Tp=20b=20=3D=2042;=0A+=20=20=20=20= VERIFY(check_wait_notify(a,=20b)=20=3D=3D=20b);=0A+=20=20}=0A+};=0A+=0A= +template=0A+struct=20check=0A+{=0A+=20=20= check(Tp=20b)=0A+=20=20{=0A+=20=20=20=20Tp=20a;=0A+=20=20=20=20= VERIFY(check_wait_notify(a,=20b)=20=3D=3D=20b);=0A+=20=20}=0A+};=0A+=0A= +struct=20foo=0A+{=0A+=20=20long=20a=20=3D=200;=0A+=20=20long=20b=20=3D=20= 0;=0A+=0A+=20=20foo&=20operator=3D(foo=20const&)=20=3D=20default;=0A+=0A= +=20=20friend=20bool=0A+=20=20operator=3D=3D(foo=20const&=20rhs,=20foo=20= const&=20lhs)=0A+=20=20{=20return=20rhs.a=20=3D=3D=20lhs.a=20&&=20rhs.b=20= =3D=3D=20lhs.b;=20}=0A+};=0A+=0A+int=0A+main=20()=0A+{=0A+=20=20= check();=0A+=20=20check();=0A+=20=20check({42,=20= 48});=0A+=20=20return=200;=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..b9fc063c66f=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc=0A@@=20= -0,0=20+1,59=20@@=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20= }=0A+//=20{=20dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+//=20Copyright=20(C)=202020=20Free=20= Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20= the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+#include=20=0A+#include=20=0A+#include=20=0A= +#include=20=0A+#include=20=0A+#include=20= =0A+=0A+#include=20=0A+=0A+int=0A+main=20()=0A= +{=0A+=20=20using=20namespace=20std::literals::chrono_literals;=0A+=0A+=20= =20std::mutex=20m;=0A+=20=20std::condition_variable=20cv;=0A+=0A+=20=20= std::atomic=20a(false);=0A+=20=20std::atomic=20b(false);=0A+=20= =20std::thread=20t([&]=0A+=09=09{=0A+=09=09=20=20cv.notify_one();=0A+=09=09= =20=20a.wait(false);=0A+=09=09=20=20if=20(a.load())=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20{=0A+=09=09=20=20=20=20= b.store(true);=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= }=0A+=09=09});=0A+=20=20std::unique_lock=20l(m);=0A+=20=20= cv.wait(l);=0A+=20=20std::this_thread::sleep_for(100ms);=0A+=20=20= a.store(true);=0A+=20=20a.notify_one();=0A+=20=20t.join();=0A+=20=20= VERIFY(=20b.load()=20);=0A+=20=20return=200;=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/floats.cc=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/floats.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..1d032085752=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/floats.cc=0A@@=20= -0,0=20+1,32=20@@=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread=20= -latomic=20-L../../libatomic/.libs"=20}=0A+//=20{=20dg-do=20run=20{=20= target=20c++2a=20}=20}=0A+//=20{=20dg-require-effective-target=20pthread=20= }=0A+//=20{=20dg-require-gthreads=20""=20}=0A+=0A+//=20Copyright=20(C)=20= 2020=20Free=20Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20= is=20part=20of=20the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20= is=20free=0A+//=20software;=20you=20can=20redistribute=20it=20and/or=20= modify=20it=20under=20the=0A+//=20terms=20of=20the=20GNU=20General=20= Public=20License=20as=20published=20by=20the=0A+//=20Free=20Software=20= Foundation;=20either=20version=203,=20or=20(at=20your=20option)=0A+//=20= any=20later=20version.=0A+=0A+//=20This=20library=20is=20distributed=20= in=20the=20hope=20that=20it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20= ANY=20WARRANTY;=20without=20even=20the=20implied=20warranty=20of=0A+//=20= MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20= See=20the=0A+//=20GNU=20General=20Public=20License=20for=20more=20= details.=0A+=0A+//=20You=20should=20have=20received=20a=20copy=20of=20= the=20GNU=20General=20Public=20License=20along=0A+//=20with=20this=20= library;=20see=20the=20file=20COPYING3.=20=20If=20not=20see=0A+//=20= .=0A+=0A+#include=20"generic.h"=0A+=0A+int=0A= +main=20()=0A+{=0A+=20=20check=20f;=0A+=20=20check=20d;=0A= +=20=20check=20l;=0A+=20=20return=200;=0A+}=0Adiff=20= --git=20a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.h=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.h=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..0da374ece87=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.h=0A@@=20= -0,0=20+1,88=20@@=0A+//=20-*-=20C++=20-*-=20header.=0A+=0A+//=20= Copyright=20(C)=202020=20Free=20Software=20Foundation,=20Inc.=0A+//=0A= +//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20Library.=20=20= This=20library=20is=20free=0A+//=20software;=20you=20can=20redistribute=20= it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20of=20the=20GNU=20= General=20Public=20License=20as=20published=20by=20the=0A+//=20Free=20= Software=20Foundation;=20either=20version=203,=20or=20(at=20your=20= option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20is=20= distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A+//=20= but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+#include=20= =0A+#include=20=0A+#include=20=0A+#include=20= =0A+#include=20=0A+=0A+#include=20= =0A+=0A+template=0A+Tp=20= check_wait_notify(Tp=20val1,=20Tp=20val2)=0A+{=0A+=20=20using=20= namespace=20std::literals::chrono_literals;=0A+=0A+=20=20std::mutex=20m;=0A= +=20=20std::condition_variable=20cv;=0A+=0A+=20=20std::atomic=20= a(val1);=0A+=20=20std::thread=20t([&]=0A+=09=09{=0A+=09=09=20=20= cv.notify_one();=0A+=09=09=20=20a.wait(val1);=0A+=09=09=20=20if=20= (a.load()=20!=3D=20val2)=0A+=09=09=20=20=20=20a=20=3D=20val1;=0A+=09=09= });=0A+=20=20std::unique_lock=20l(m);=0A+=20=20cv.wait(l);=0A= +=20=20std::this_thread::sleep_for(100ms);=0A+=20=20a.store(val2);=0A+=20= =20a.notify_one();=0A+=20=20t.join();=0A+=20=20return=20a.load();=0A+}=0A= +=0A+template=0A+Tp=20check_atomic_wait_notify(Tp=20val1,=20= Tp=20val2)=0A+{=0A+=20=20using=20namespace=20= std::literals::chrono_literals;=0A+=0A+=20=20std::mutex=20m;=0A+=20=20= std::condition_variable=20cv;=0A+=0A+=20=20std::atomic=20a(val1);=0A= +=20=20std::thread=20t([&]=0A+=09=09{=0A+=09=09=20=20cv.notify_one();=0A= +=09=09=20=20std::atomic_wait(&a,=20val1);=0A+=09=09=20=20if=20(a.load()=20= !=3D=20val2)=0A+=09=09=20=20=20=20a=20=3D=20val1;=0A+=09=09});=0A+=20=20= std::unique_lock=20l(m);=0A+=20=20cv.wait(l);=0A+=20=20= std::this_thread::sleep_for(100ms);=0A+=20=20a.store(val2);=0A+=20=20= std::atomic_notify_one(&a);=0A+=20=20t.join();=0A+=20=20return=20= a.load();=0A+}=0A+=0A+template=0A+struct=20check=0A+{=0A+=20= =20check()=0A+=20=20{=0A+=20=20=20=20Tp=20a=20=3D=200;=0A+=20=20=20=20Tp=20= b=20=3D=2042;=0A+=20=20=20=20VERIFY(check_wait_notify(a,=20b)=20=3D=3D=20= b);=0A+=20=20=20=20VERIFY(check_atomic_wait_notify(a,=20b)=20=3D=3D=20= b);=0A+=20=20}=0A+};=0Adiff=20--git=20= a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/integrals.cc=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/integrals.cc=0A= new=20file=20mode=20100644=0Aindex=2000000000000..2afd19a7d14=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/integrals.cc=0A@@=20= -0,0=20+1,56=20@@=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20= }=0A+//=20{=20dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+//=20Copyright=20(C)=202020=20Free=20= Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20= the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+#include=20"generic.h"=0A+=0A+int=0A+main=20()=0A+{=0A+=20=20//=20= check=20bb;=0A+=20=20check=20ch;=0A+=20=20check=20sch;=0A+=20=20check=20uch;=0A+=20=20= check=20s;=0A+=20=20check=20us;=0A+=20=20= check=20i;=0A+=20=20check=20ui;=0A+=20=20= check=20l;=0A+=20=20check=20ul;=0A+=20=20= check=20ll;=0A+=20=20check=20ull;=0A= +=0A+=20=20check=20wch;=0A+=20=20check=20ch8;=0A+=20=20= check=20ch16;=0A+=20=20check=20ch32;=0A+=0A+=20=20= check=20i8;=0A+=20=20check=20i16;=0A+=20=20= check=20i32;=0A+=20=20check=20i64;=0A+=0A+=20=20= check=20u8;=0A+=20=20check=20u16;=0A+=20=20= check=20u32;=0A+=20=20check=20u64;=0A+=20=20return=20= 0;=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..8531bb2e788=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc=0A@@=20= -0,0=20+1,59=20@@=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20= }=0A+//=20{=20dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+//=20Copyright=20(C)=202020=20Free=20= Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20= the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+#include=20=0A+#include=20=0A+#include=20=0A= +#include=20=0A+#include=20=0A+#include=20= =0A+=0A+#include=20=0A+=0A+int=0A+main=20()=0A= +{=0A+=20=20using=20namespace=20std::literals::chrono_literals;=0A+=0A+=20= =20std::mutex=20m;=0A+=20=20std::condition_variable=20cv;=0A+=0A+=20=20= long=20aa;=0A+=20=20long=20bb;=0A+=0A+=20=20std::atomic=20= a(nullptr);=0A+=20=20std::thread=20t([&]=0A+=09=09{=0A+=09=09=20=20= cv.notify_one();=0A+=09=09=20=20a.wait(nullptr);=0A+=09=09=20=20if=20= (a.load()=20=3D=3D=20&aa)=0A+=09=09=20=20=20=20a.store(&bb);=0A+=09=09= });=0A+=20=20std::unique_lock=20l(m);=0A+=20=20cv.wait(l);=0A= +=20=20std::this_thread::sleep_for(100ms);=0A+=20=20a.store(&aa);=0A+=20=20= a.notify_one();=0A+=20=20t.join();=0A+=20=20VERIFY(=20a.load()=20=3D=3D=20= &bb);=0A+=20=20return=200;=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/latch/1.cc=20= b/libstdc++-v3/testsuite/30_threads/latch/1.cc=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..aa203cdf525=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/latch/1.cc=0A@@=20-0,0=20+1,27=20@@=0A= +//=20Copyright=20(C)=202020=20Free=20Software=20Foundation,=20Inc.=0A= +//=0A+//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20= Library.=20=20This=20library=20is=20free=0A+//=20software;=20you=20can=20= redistribute=20it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=20by=20the=0A= +//=20Free=20Software=20Foundation;=20either=20version=203,=20or=20(at=20= your=20option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= +//=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+//=20{=20= dg-options=20"-std=3Dgnu++2a"=20}=0A+//=20{=20dg-do=20compile=20{=20= target=20c++2a=20}=20}=0A+=0A+#include=20=0A+=0A+#ifndef=20= __cpp_lib_latch=0A+#=20error=20"Feature-test=20macro=20for=20latch=20= missing=20in=20"=0A+#elif=20__cpp_lib_latch!=3D=20201907L=0A+#=20= error=20"Feature-test=20macro=20for=20latch=20has=20wrong=20value=20in=20= "=0A+#endif=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/latch/2.cc=20= b/libstdc++-v3/testsuite/30_threads/latch/2.cc=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..756727f33b3=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/latch/2.cc=0A@@=20-0,0=20+1,27=20@@=0A= +//=20Copyright=20(C)=202019-2020=20Free=20Software=20Foundation,=20Inc.=0A= +//=0A+//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20= Library.=20=20This=20library=20is=20free=0A+//=20software;=20you=20can=20= redistribute=20it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=20by=20the=0A= +//=20Free=20Software=20Foundation;=20either=20version=203,=20or=20(at=20= your=20option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= +//=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+//=20{=20= dg-options=20"-std=3Dgnu++2a"=20}=0A+//=20{=20dg-do=20compile=20{=20= target=20c++2a=20}=20}=0A+=0A+#include=20=0A+=0A+#ifndef=20= __cpp_lib_latch=0A+#=20error=20"Feature-test=20macro=20for=20latch=20= missing=20in=20"=0A+#elif=20__cpp_lib_latch=20!=3D=20201907L=0A= +#=20error=20"Feature-test=20macro=20for=20latch=20has=20wrong=20value=20= in=20"=0A+#endif=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/latch/3.cc=20= b/libstdc++-v3/testsuite/30_threads/latch/3.cc=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..10bb500d261=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/latch/3.cc=0A@@=20-0,0=20+1,50=20@@=0A= +//=20Copyright=20(C)=202019-2020=20Free=20Software=20Foundation,=20Inc.=0A= +//=0A+//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20= Library.=20=20This=20library=20is=20free=0A+//=20software;=20you=20can=20= redistribute=20it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=20by=20the=0A= +//=20Free=20Software=20Foundation;=20either=20version=203,=20or=20(at=20= your=20option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= +//=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+//=20{=20= dg-options=20"-std=3Dgnu++2a=20-pthread"=20}=0A+//=20{=20dg-do=20run=20{=20= target=20c++2a=20}=20}=0A+//=20{=20dg-require-effective-target=20pthread=20= }=0A+//=20{=20dg-require-gthreads=20""=20}=0A+//=0A+#include=20=0A= +#include=20=0A+#include=20=0A+#include=20= =0A+=0A+int=20main()=0A+{=0A+=20=20std::atomic=20= a(0);=0A+=0A+=20=20std::latch=20l(3);=0A+=0A+=20=20VERIFY(=20= !l.try_wait()=20);=0A+=0A+=20=20auto=20fn=20=3D=20[&]=0A+=20=20{=0A+=20=20= =20=20++a;=0A+=20=20=20=20l.count_down();=0A+=20=20};=0A+=0A+=20=20= std::thread=20t0(fn);=0A+=20=20std::thread=20t1(fn);=0A+=0A+=20=20= l.arrive_and_wait();=0A+=20=20t0.join();=0A+=20=20t1.join();=0A+=0A+=20=20= VERIFY(=20l.try_wait()=20);=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/1.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..1bbca687fc3=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/1.cc=0A@@=20-0,0=20+1,27=20= @@=0A+//=20Copyright=20(C)=202020=20Free=20Software=20Foundation,=20Inc.=0A= +//=0A+//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20= Library.=20=20This=20library=20is=20free=0A+//=20software;=20you=20can=20= redistribute=20it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=20by=20the=0A= +//=20Free=20Software=20Foundation;=20either=20version=203,=20or=20(at=20= your=20option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= +//=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+//=20{=20= dg-options=20"-std=3Dgnu++2a"=20}=0A+//=20{=20dg-do=20compile=20{=20= target=20c++2a=20}=20}=0A+=0A+#include=20=0A+=0A+#ifndef=20= __cpp_lib_semaphore=0A+#=20error=20"Feature-test=20macro=20for=20= semaphore=20missing=20in=20"=0A+#elif=20__cpp_lib_semaphore=20= !=3D=20201907L=0A+#=20error=20"Feature-test=20macro=20for=20semaphore=20= has=20wrong=20value=20in=20"=0A+#endif=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/2.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..b96b8a59c64=0A---=20/dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/2.cc=0A@@=20-0,0=20+1,27=20= @@=0A+//=20Copyright=20(C)=202019-2020=20Free=20Software=20Foundation,=20= Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20the=20GNU=20ISO=20C++=20= Library.=20=20This=20library=20is=20free=0A+//=20software;=20you=20can=20= redistribute=20it=20and/or=20modify=20it=20under=20the=0A+//=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=20by=20the=0A= +//=20Free=20Software=20Foundation;=20either=20version=203,=20or=20(at=20= your=20option)=0A+//=20any=20later=20version.=0A+=0A+//=20This=20library=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= +//=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+//=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+//=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=20= along=0A+//=20with=20this=20library;=20see=20the=20file=20COPYING3.=20=20= If=20not=20see=0A+//=20.=0A+=0A+//=20{=20= dg-options=20"-std=3Dgnu++2a"=20}=0A+//=20{=20dg-do=20compile=20{=20= target=20c++2a=20}=20}=0A+=0A+#include=20=0A+=0A+#ifndef=20= __cpp_lib_semaphore=0A+#=20error=20"Feature-test=20macro=20for=20= semaphore=20missing=20in=20"=0A+#elif=20__cpp_lib_semaphore=20= !=3D=20201907L=0A+#=20error=20"Feature-test=20macro=20for=20semaphore=20= has=20wrong=20value=20in=20"=0A+#endif=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc=0A= new=20file=20mode=20100644=0Aindex=2000000000000..1ac9d261ca5=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc=0A= @@=20-0,0=20+1,28=20@@=0A+//=20Copyright=20(C)=202019-2020=20Free=20= Software=20Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20= the=20GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+//=20{=20dg-options=20"-std=3Dgnu++2a"=20}=0A+//=20{=20dg-do=20= compile=20{=20target=20c++2a=20}=20}=0A+=0A+#include=20=0A+=0A= +int=20main()=0A+{=0A+=20=20std::counting_semaphore<-1>=20sem(2);=0A+=20=20= return=200;=0A+}=0A+//=20{=20dg-error=20"static=20assertion=20failed"=20= ""=20{=20=20target=20*-*-*=20}=200=20}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..d38cef86cfc=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc=0A@@=20-0,0=20= +1,55=20@@=0A+//=20Copyright=20(C)=202019-2020=20Free=20Software=20= Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20the=20= GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20}=0A+//=20{=20= dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20=0A+=0A= +void=20test01()=0A+{=0A+=20=20std::counting_semaphore<10>=20s(3);=0A+=0A= +=20=20s.acquire();=0A+=20=20VERIFY(=20s.try_acquire()=20);=0A+=20=20= VERIFY(=20s.try_acquire()=20);=0A+=20=20VERIFY(=20!s.try_acquire()=20);=0A= +=20=20s.release();=0A+=20=20VERIFY(=20s.try_acquire()=20);=0A+}=0A+=0A= +void=20test02()=0A+{=0A+=20=20std::binary_semaphore=20s(1);=0A+=0A+=20=20= s.acquire();=0A+=20=20VERIFY(=20!s.try_acquire()=20);=0A+=20=20= s.release();=0A+=20=20VERIFY(=20s.try_acquire()=20);=0A+}=0A+=0A+=0A+int=20= main()=0A+{=0A+=20=20test01();=0A+=20=20test02();=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..965554a3c28=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc=0A@@=20= -0,0=20+1,85=20@@=0A+//=20Copyright=20(C)=202019-2020=20Free=20Software=20= Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20the=20= GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20}=0A+//=20{=20= dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20=0A+#include=20= =0A+=0A+void=20test01()=0A+{=0A+=20=20using=20= namespace=20std::chrono_literals;=0A+=20=20std::counting_semaphore<10>=20= s(2);=0A+=20=20s.acquire();=0A+=0A+=20=20auto=20const=20dur=20=3D=20= 250ms;=0A+=20=20{=0A+=20=20=20=20auto=20const=20t0=20=3D=20= std::chrono::steady_clock::now();=0A+=20=20=20=20VERIFY(=20= s.try_acquire_for(dur)=20);=0A+=20=20=20=20auto=20const=20diff=20=3D=20= std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20VERIFY(=20diff=20= <=20dur=20);=0A+=20=20}=0A+=0A+=20=20{=0A+=20=20=20=20auto=20const=20t0=20= =3D=20std::chrono::steady_clock::now();=0A+=20=20=20=20VERIFY(=20= !s.try_acquire_for(dur)=20);=0A+=20=20=20=20auto=20const=20diff=20=3D=20= std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20VERIFY(=20diff=20= >=3D=20dur=20);=0A+=20=20}=0A+}=0A+=0A+void=20test02()=0A+{=0A+=20=20= using=20namespace=20std::chrono_literals;=0A+=20=20std::binary_semaphore=20= s(1);=0A+=20=20std::atomic=20a(0),=20b(0);=0A+=20=20std::thread=20= t([&]=20{=0A+=20=20=20=20a.wait(0);=0A+=20=20=20=20auto=20const=20dur=20= =3D=20250ms;=0A+=20=20=20=20VERIFY(=20!s.try_acquire_for(dur)=20);=0A+=20= =20=20=20b++;=0A+=20=20=20=20b.notify_one();=0A+=0A+=20=20=20=20= a.wait(1);=0A+=20=20=20=20VERIFY(=20s.try_acquire_for(dur)=20);=0A+=20=20= =20=20b++;=0A+=20=20=20=20b.notify_one();=0A+=20=20});=0A+=20=20= t.detach();=0A+=0A+=20=20s.acquire();=0A+=20=20a++;=0A+=20=20= a.notify_one();=0A+=20=20b.wait(0);=0A+=20=20s.release();=0A+=20=20a++;=0A= +=20=20a.notify_one();=0A+=0A+=20=20b.wait(1);=0A+}=0A+=0A+int=20main()=0A= +{=0A+=20=20test01();=0A+=20=20test02();=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_futex.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_futex.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..5e05606e97f=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_futex.cc=0A@@=20= -0,0=20+1,51=20@@=0A+//=20Copyright=20(C)=202019-2020=20Free=20Software=20= Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20the=20= GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20}=0A+//=20{=20= dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20=0A+=0A= +#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+void=20test01()=0A+{=0A+=20=20//=20= the=20implementation=20optimizes=20for=20values=20of=20least_max_t=20= that=20can=20fit=0A+=20=20//=20in=20a=20futex,=20make=20sure=20we=20= cover=20the=20case=20where=20least_max_t=20doesn't=0A+=20=20auto=20= constexpr=20least_max_t=20=3D=20= std::numeric_limits::max();=0A+=20=20= std::counting_semaphore=20s(3);=0A+=0A+=20=20s.acquire();=0A= +=20=20VERIFY(=20s.try_acquire()=20);=0A+=20=20VERIFY(=20s.try_acquire()=20= );=0A+=20=20VERIFY(=20!s.try_acquire()=20);=0A+=20=20s.release();=0A+=20=20= VERIFY(=20s.try_acquire()=20);=0A+}=0A+=0A+#endif=0A+=0A+int=20main()=0A= +{=0A+#ifdef=20_GLIBCXX_HAVE_LINUX_FUTEX=0A+=20=20test01();=0A+#endif=0A= +}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..bf99fd3cf8f=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc=0A@@=20= -0,0=20+1,169=20@@=0A+//=20Copyright=20(C)=202019-2020=20Free=20Software=20= Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20the=20= GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20}=0A+//=20{=20= dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20=0A+#include=20= =0A+=0A+#ifdef=20_GLIBCXX_HAVE_POSIX_SEMAPHORE=0A+=20=20= //=20The=20implementation=20supports=20posix=20as=20an=20implementation=20= strategy=0A+=20=20//=20make=20sure=20we=20cover=20that=20case=0A+#define=20= _GLIBCXX_REQUIRE_POSIX_SEMAPHORE=0A+=0A+void=20test01()=0A+{=0A+=20=20= std::counting_semaphore<10>=20s(3);=0A+=0A+=20=20s.acquire();=0A+=20=20= VERIFY(=20s.try_acquire()=20);=0A+=20=20VERIFY(=20s.try_acquire()=20);=0A= +=20=20VERIFY(=20!s.try_acquire()=20);=0A+=20=20s.release();=0A+=20=20= VERIFY(=20s.try_acquire()=20);=0A+}=0A+=0A+void=20test02()=0A+{=0A+=20=20= using=20namespace=20std::chrono_literals;=0A+=20=20= std::counting_semaphore<10>=20s(2);=0A+=20=20s.acquire();=0A+=0A+=20=20= auto=20const=20dur=20=3D=20250ms;=0A+=20=20{=0A+=20=20=20=20auto=20const=20= t0=20=3D=20std::chrono::steady_clock::now();=0A+=20=20=20=20VERIFY(=20= s.try_acquire_for(dur)=20);=0A+=20=20=20=20auto=20const=20diff=20=3D=20= std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20VERIFY(=20diff=20= <=20dur=20);=0A+=20=20}=0A+=0A+=20=20{=0A+=20=20=20=20auto=20const=20t0=20= =3D=20std::chrono::steady_clock::now();=0A+=20=20=20=20VERIFY(=20= !s.try_acquire_for(dur)=20);=0A+=20=20=20=20auto=20const=20diff=20=3D=20= std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20VERIFY(=20diff=20= >=3D=20dur=20);=0A+=20=20}=0A+}=0A+=0A+void=20test03()=0A+{=0A+=20=20= using=20namespace=20std::chrono_literals;=0A+=20=20std::binary_semaphore=20= s(1);=0A+=20=20std::atomic=20a(0),=20b(0);=0A+=20=20std::thread=20= t([&]=20{=0A+=20=20=20=20a.wait(0);=0A+=20=20=20=20auto=20const=20dur=20= =3D=20250ms;=0A+=20=20=20=20VERIFY(=20!s.try_acquire_for(dur)=20);=0A+=20= =20=20=20b++;=0A+=20=20=20=20b.notify_one();=0A+=0A+=20=20=20=20= a.wait(1);=0A+=20=20=20=20VERIFY(=20s.try_acquire_for(dur)=20);=0A+=20=20= =20=20b++;=0A+=20=20=20=20b.notify_one();=0A+=20=20});=0A+=20=20= t.detach();=0A+=0A+=20=20s.acquire();=0A+=20=20a++;=0A+=20=20= a.notify_one();=0A+=20=20b.wait(0);=0A+=20=20s.release();=0A+=20=20a++;=0A= +=20=20a.notify_one();=0A+=0A+=20=20b.wait(1);=0A+}=0A+=0A+void=20= test04()=0A+{=0A+=20=20using=20namespace=20std::chrono_literals;=0A+=20=20= std::counting_semaphore<10>=20s(2);=0A+=20=20s.acquire();=0A+=0A+=20=20= auto=20const=20dur=20=3D=20250ms;=0A+=20=20{=0A+=20=20=20=20auto=20const=20= at=20=3D=20std::chrono::system_clock::now()=20+=20dur;=0A+=20=20=20=20= auto=20const=20t0=20=3D=20std::chrono::steady_clock::now();=0A+=20=20=20=20= VERIFY(=20s.try_acquire_until(at)=20);=0A+=20=20=20=20auto=20const=20= diff=20=3D=20std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20= VERIFY(=20diff=20<=20dur=20);=0A+=20=20}=0A+=0A+=20=20{=0A+=20=20=20=20= auto=20const=20at=20=3D=20std::chrono::system_clock::now()=20+=20dur;=0A= +=20=20=20=20auto=20const=20t0=20=3D=20std::chrono::steady_clock::now();=0A= +=20=20=20=20VERIFY(=20!s.try_acquire_until(at)=20);=0A+=20=20=20=20auto=20= const=20diff=20=3D=20std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20= =20=20VERIFY(=20diff=20>=3D=20dur=20);=0A+=20=20}=0A+}=0A+=0A+void=20= test05()=0A+{=0A+=20=20using=20namespace=20std::chrono_literals;=0A+=20=20= std::binary_semaphore=20s(1);=0A+=20=20std::atomic=20a(0),=20b(0);=0A= +=20=20std::thread=20t([&]=20{=0A+=20=20=20=20a.wait(0);=0A+=20=20=20=20= auto=20const=20dur=20=3D=20250ms;=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= auto=20const=20at=20=3D=20std::chrono::system_clock::now()=20+=20dur;=0A= +=20=20=20=20=20=20VERIFY(=20!s.try_acquire_until(at)=20);=0A+=0A+=20=20=20= =20=20=20b++;=0A+=20=20=20=20=20=20b.notify_one();=0A+=20=20=20=20}=0A+=0A= +=20=20=20=20a.wait(1);=0A+=20=20=20=20{=0A+=20=20=20=20=20=20auto=20= const=20at=20=3D=20std::chrono::system_clock::now()=20+=20dur;=0A+=20=20=20= =20=20=20VERIFY(=20s.try_acquire_until(at)=20);=0A+=20=20=20=20}=0A+=20=20= =20=20b++;=0A+=20=20=20=20b.notify_one();=0A+=20=20});=0A+=20=20= t.detach();=0A+=0A+=20=20s.acquire();=0A+=20=20a++;=0A+=20=20= a.notify_one();=0A+=20=20b.wait(0);=0A+=20=20s.release();=0A+=20=20a++;=0A= +=20=20a.notify_one();=0A+=0A+=20=20b.wait(1);=0A+}=0A+#endif=0A+=0A+int=20= main()=0A+{=0A+#ifdef=20_GLIBCXX_HAVE_POSIX_SEMAPHORE=0A+=20=20test01();=0A= +=20=20test02();=0A+=20=20test03();=0A+=20=20test04();=0A+=20=20= test05();=0A+#endif=0A+}=0Adiff=20--git=20= a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc=0Anew=20= file=20mode=20100644=0Aindex=2000000000000..cc67c5c0bf0=0A---=20= /dev/null=0A+++=20= b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc=0A@@=20= -0,0=20+1,94=20@@=0A+//=20Copyright=20(C)=202019-2020=20Free=20Software=20= Foundation,=20Inc.=0A+//=0A+//=20This=20file=20is=20part=20of=20the=20= GNU=20ISO=20C++=20Library.=20=20This=20library=20is=20free=0A+//=20= software;=20you=20can=20redistribute=20it=20and/or=20modify=20it=20under=20= the=0A+//=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=20the=0A+//=20Free=20Software=20Foundation;=20either=20= version=203,=20or=20(at=20your=20option)=0A+//=20any=20later=20version.=0A= +=0A+//=20This=20library=20is=20distributed=20in=20the=20hope=20that=20= it=20will=20be=20useful,=0A+//=20but=20WITHOUT=20ANY=20WARRANTY;=20= without=20even=20the=20implied=20warranty=20of=0A+//=20MERCHANTABILITY=20= or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+//=20= GNU=20General=20Public=20License=20for=20more=20details.=0A+=0A+//=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=20along=0A+//=20with=20this=20library;=20see=20the=20file=20= COPYING3.=20=20If=20not=20see=0A+//=20.=0A= +=0A+//=20{=20dg-options=20"-std=3Dgnu++2a=20-pthread"=20}=0A+//=20{=20= dg-do=20run=20{=20target=20c++2a=20}=20}=0A+//=20{=20= dg-require-effective-target=20pthread=20}=0A+//=20{=20= dg-require-gthreads=20""=20}=0A+=0A+#include=20=0A+#include=20= =0A+#include=20=0A+#include=20=0A+#include=20= =0A+=0A+void=20test01()=0A+{=0A+=20=20using=20= namespace=20std::chrono_literals;=0A+=20=20std::counting_semaphore<10>=20= s(2);=0A+=20=20s.acquire();=0A+=0A+=20=20auto=20const=20dur=20=3D=20= 250ms;=0A+=20=20{=0A+=20=20=20=20auto=20const=20at=20=3D=20= std::chrono::system_clock::now()=20+=20dur;=0A+=20=20=20=20auto=20const=20= t0=20=3D=20std::chrono::steady_clock::now();=0A+=20=20=20=20VERIFY(=20= s.try_acquire_until(at)=20);=0A+=20=20=20=20auto=20const=20diff=20=3D=20= std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20VERIFY(=20diff=20= <=20dur=20);=0A+=20=20}=0A+=0A+=20=20{=0A+=20=20=20=20auto=20const=20at=20= =3D=20std::chrono::system_clock::now()=20+=20dur;=0A+=20=20=20=20auto=20= const=20t0=20=3D=20std::chrono::steady_clock::now();=0A+=20=20=20=20= VERIFY(=20!s.try_acquire_until(at)=20);=0A+=20=20=20=20auto=20const=20= diff=20=3D=20std::chrono::steady_clock::now()=20-=20t0;=0A+=20=20=20=20= VERIFY(=20diff=20>=3D=20dur=20);=0A+=20=20}=0A+}=0A+=0A+void=20test02()=0A= +{=0A+=20=20using=20namespace=20std::chrono_literals;=0A+=20=20= std::binary_semaphore=20s(1);=0A+=20=20std::atomic=20a(0),=20b(0);=0A= +=20=20std::thread=20t([&]=20{=0A+=20=20=20=20a.wait(0);=0A+=20=20=20=20= auto=20const=20dur=20=3D=20250ms;=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= auto=20const=20at=20=3D=20std::chrono::system_clock::now()=20+=20dur;=0A= +=20=20=20=20=20=20VERIFY(=20!s.try_acquire_until(at)=20);=0A+=0A+=20=20=20= =20=20=20b++;=0A+=20=20=20=20=20=20b.notify_one();=0A+=20=20=20=20}=0A+=0A= +=20=20=20=20a.wait(1);=0A+=20=20=20=20{=0A+=20=20=20=20=20=20auto=20= const=20at=20=3D=20std::chrono::system_clock::now()=20+=20dur;=0A+=20=20=20= =20=20=20VERIFY(=20s.try_acquire_until(at)=20);=0A+=20=20=20=20}=0A+=20=20= =20=20b++;=0A+=20=20=20=20b.notify_one();=0A+=20=20});=0A+=20=20= t.detach();=0A+=0A+=20=20s.acquire();=0A+=20=20a++;=0A+=20=20= a.notify_one();=0A+=20=20b.wait(0);=0A+=20=20s.release();=0A+=20=20a++;=0A= +=20=20a.notify_one();=0A+=0A+=20=20b.wait(1);=0A+}=0A+=0A+int=20main()=0A= +{=0A+=20=20test01();=0A+=20=20test02();=0A+}=0A--=20=0A2.26.2=0A=0A= --Apple-Mail=_35F1270A-E967-48E3-9355-C77AF697D593 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On May 11, 2020, at 1:59 PM, Thomas Rodgers via Libstdc++ = wrote: >=20 > I *think* I have addressed everything in the attached patch. > <0001-Add-C-2a-synchronization-support.patch> > Jonathan Wakely writes: >=20 >> On 09/05/20 17:01 -0700, Thomas Rodgers via Libstdc++ wrote: >>> * Note, this patch supersedes my previous atomic wait and semaphore >>> patches. >>>=20 >>> Add support for - >>> atomic wait/notify_one/notify_all >>> counting_semaphore >>> binary_semaphore >>> latch >>>=20 >>> * include/Makefile.am (bits_headers): Add new header. >>> * include/Makefile.in: Regenerate. >>> * include/bits/atomic_base.h (__atomic_base<_Itp>:wait): = Define. >>=20 >> Should be two colons before wait. >>=20 >>> diff --git a/libstdc++-v3/include/Makefile.in = b/libstdc++-v3/include/Makefile.in >>> index eb437ad8d8d..e73ff8b3e64 100644 >>> --- a/libstdc++-v3/include/Makefile.in >>> +++ b/libstdc++-v3/include/Makefile.in >>=20 >> Generated files don't need to be in the patch. >>=20 >>> diff --git a/libstdc++-v3/include/bits/atomic_base.h = b/libstdc++-v3/include/bits/atomic_base.h >>> index 87fe0bd6000..b2cec0f1722 100644 >>> --- a/libstdc++-v3/include/bits/atomic_base.h >>> +++ b/libstdc++-v3/include/bits/atomic_base.h >>> @@ -37,6 +37,11 @@ >>> #include >>> #include >>>=20 >>> +#if __cplusplus > 201703L >>> +#include >>> +#include >>=20 >> shouldn't be here (it adds runtime cost, as well as >> compile-time). >>=20 >>> @@ -542,6 +546,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> __cmpexch_failure_order(__m)); >>> } >>>=20 >>> +#if __cplusplus > 201703L >>> + _GLIBCXX_ALWAYS_INLINE void >>> + wait(__int_type __old, memory_order __m =3D = memory_order_seq_cst) const noexcept >>=20 >> Please format everything to <=3D 80 columns (ideally < 80). >>=20 >>> + wait(__pointer_type __old, memory_order __m =3D = memory_order_seq_cst) noexcept >>> + { >>> + __atomic_wait(&_M_p, __old, >>=20 >> This should be qualified to prevent ADL. >>=20 >>> + [__m, this, __old]() >>> + { return this->load(__m) !=3D __old; }); >>> + } >>> + >>> + // TODO add const volatile overload >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + notify_one() const noexcept >>> + { __atomic_notify(&_M_p, false); } >>=20 >> Qualify to prevent ADL here too, and all similar calls. >>=20 >>> +#if __cplusplus > 201703L >>> + template >>> + _GLIBCXX_ALWAYS_INLINE void >>> + wait(const _Tp* __ptr, _Val<_Tp> __old, memory_order __m =3D = memory_order_seq_cst) noexcept >>> + { >>> + __atomic_wait(__ptr, *std::__addressof(__old), >>=20 >> Can't this just be __old instead of *std::__addressof(__old) ? >>=20 >>> + [=3D]() >>> + { return load(__ptr, __m) =3D=3D = *std::__addressof(__old); }); >>=20 >> Same here? >>=20 >>> diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h = b/libstdc++-v3/include/bits/atomic_timed_wait.h >>> new file mode 100644 >>> index 00000000000..10f0fe50ed9 >>> --- /dev/null >>> +++ b/libstdc++-v3/include/bits/atomic_timed_wait.h >>> @@ -0,0 +1,270 @@ >>> +// -*- C++ -*- header. >>> + >>> +// 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. >>> + >>> +// 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/atomic_timed_wait.h >>> + * This is an internal header file, included by other library = headers. >>> + * Do not attempt to use it directly. @headername{atomic} >>> + */ >>> + >>> +#ifndef _GLIBCXX_ATOMIC_TIMED_WAIT_H >>> +#define _GLIBCXX_ATOMIC_TIMED_WAIT_H 1 >>> + >>> +#pragma GCC system_header >>> + >>> +#include >>> +#include >>> +#include >>> + >>> +#include >>> + >>> +#ifdef _GLIBCXX_HAVE_LINUX_FUTEX >>> +#include >>> +#endif >>> + >>> +namespace std _GLIBCXX_VISIBILITY(default) >>> +{ >>> + _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> + enum class __atomic_wait_status { __no_timeout, __timeout }; >>=20 >> Blank line before and after this enum definition please. >>=20 >>> + namespace __detail >>> + { >>> +#ifdef _GLIBCXX_HAVE_LINUX_FUTEX >>> + enum >>> + { >>> + __futex_wait_bitset_private =3D __futex_wait_bitset | = __futex_private_flag, >>> + __futex_wake_bitset_private =3D __futex_wake_bitset | = __futex_private_flag, >>> + __futex_bitset_match_any =3D 0xffffffff >>> + }; >>> + >>> + using __platform_wait_clock_t =3D chrono::steady_clock; >>=20 >> Blank line after this using-decl please. >>=20 >>> + template >>> + __atomic_wait_status >>> + __platform_wait_until_impl(__platform_wait_t* __addr, = __platform_wait_t __val, >>> + const = chrono::time_point<__platform_wait_clock_t, _Duration>& __atime) = noexcept >>> + { >>> + auto __s =3D chrono::time_point_cast(__atime); >>> + auto __ns =3D chrono::duration_cast(__atime = - __s); >>> + >>=20 >> Eventually we'll want to move the rest of this function (which = doesn't >> depend on the template argument) into the compiled library, but it's >> better to be header-only for now. >>=20 >>> + struct timespec __rt =3D >>> + { >>> + static_cast(__s.time_since_epoch().count()), >>> + static_cast(__ns.count()) >>> + }; >>> + >>> + auto __e =3D syscall (SYS_futex, __addr, = __futex_wait_bitset_private, __val, &__rt, >>> + nullptr, __futex_bitset_match_any); >>> + if (__e && !(errno =3D=3D EINTR || errno =3D=3D EAGAIN || errno = =3D=3D ETIMEDOUT)) >>> + std::terminate(); >>> + return (__platform_wait_clock_t::now() < __atime) >>> + ? __atomic_wait_status::__no_timeout : = __atomic_wait_status::__timeout; >>> + } >>> + >>> + template >>> + __atomic_wait_status >>> + __platform_wait_until(__platform_wait_t* __addr, = __platform_wait_t __val, >>> + const chrono::time_point<_Clock, _Duration>& = __atime) >>> + { >>> + if constexpr (std::is_same<__platform_wait_clock_t, = _Clock>::value) >>=20 >> This is C++20 so you can use is_same_v here, which uses the intrinsic >> directly and avoids instantiating the is_same class template. >>=20 >>> + { >>> + return __platform_wait_until_impl(__addr, __val, __atime); >>> + } >>> + else >>> + { >>> + const typename _Clock::time_point __c_entry =3D = _Clock::now(); >>> + const __platform_wait_clock_t::time_point __s_entry =3D >>> + __platform_wait_clock_t::now(); >>> + const auto __delta =3D __atime - __c_entry; >>> + const auto __s_atime =3D __s_entry + __delta; >>> + if (__platform_wait_until_impl(__addr, __val, __s_atime) =3D=3D= __atomic_wait_status::__no_timeout) >>> + return __atomic_wait_status::__no_timeout; >>> + >>> + // We got a timeout when measured against __clock_t but >>> + // we need to check against the caller-supplied clock >>> + // to tell whether we should return a timeout. >>> + if (_Clock::now() < __atime) >>> + return __atomic_wait_status::__no_timeout; >>> + return __atomic_wait_status::__timeout; >>> + } >>> + } >>> +#endif >>> + >>> +#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT >>> + template >>> + __atomic_wait_status >>> + __cond_wait_until_impl(__gthread_cond_t* __cv, = std::unique_lock& __lock, >>> + const = chrono::time_point& __atime) >>=20 >> The std:: qualification here isn't needed (and doesn't help with >> keeping the line below 80 cols). >>=20 >>> + { >>> + auto __s =3D chrono::time_point_cast(__atime); >>> + auto __ns =3D chrono::duration_cast(__atime = - __s); >>> + >>> + __gthread_time_t __ts =3D >>> + { >>> + static_cast(__s.time_since_epoch().count()), >>> + static_cast(__ns.count()) >>> + }; >>> + >>> + pthread_cond_clockwait(__cv, __lock.mutex()->native_handle(), >>> + CLOCK_MONOTONIC, >>> + &__ts); >>> + return (chrono::steady_clock::now() < __atime) >>> + ? __atomic_wait_status::__no_timeout : = __atomic_wait_status::__timeout; >>> + } >>> +#endif >>> + >>> + template >>> + __atomic_wait_status >>> + __cond_wait_until_impl(__gthread_cond_t* __cv, = std::unique_lock& __lock, >>> + const = chrono::time_point& __atime) >>> + { >>> + auto __s =3D = chrono::time_point_cast(__atime); >>> + auto __ns =3D = chrono::duration_cast(__atime - __s); >>> + >>> + __gthread_time_t __ts =3D >>> + { >>> + static_cast(__s.time_since_epoch().count()), >>> + static_cast(__ns.count()) >>> + }; >>> + >>> + __gthread_cond_timedwait(__cv, = __lock.mutex()->native_handle(), >>> + &__ts); >>> + return (chrono::system_clock::now() < __atime) >>> + ? __atomic_wait_status::__no_timeout : = __atomic_wait_status::__timeout; >>> + } >>> + >>> + // return true if timeout >>> + template >>> + __atomic_wait_status >>> + __cond_wait_until(__gthread_cond_t* __cv, = std::unique_lock& __lock, >>> + const chrono::time_point<_Clock, _Duration>& = __atime) >>> + { >>> +#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT >>> + using __clock_t =3D chrono::steady_clock; >>> +#else >>> + using __clock_t =3D chrono::system_clock; >>> +#endif >>> + const typename _Clock::time_point __c_entry =3D _Clock::now(); >>> + const __clock_t::time_point __s_entry =3D __clock_t::now(); >>> + const auto __delta =3D __atime - __c_entry; >>> + const auto __s_atime =3D __s_entry + __delta; >>> + if (__cond_wait_until_impl(__cv, __lock, __s_atime)) >>> + return __atomic_wait_status::__no_timeout; >>> + // We got a timeout when measured against __clock_t but >>> + // we need to check against the caller-supplied clock >>> + // to tell whether we should return a timeout. >>> + if (_Clock::now() < __atime) >>> + return __atomic_wait_status::__no_timeout; >>> + return __atomic_wait_status::__timeout; >>> + } >>> + >>> + struct __timed_waiters : __waiters >>> + { >>> + template >>> + __atomic_wait_status >>> + _M_do_wait_until(int32_t __version, >>> + const chrono::time_point<_Clock, _Duration>& = __atime) >>> + { >>> + int32_t __cur =3D 0; >>> + __waiters::__lock_t __l(_M_mtx); >>> + while (__cur <=3D __version) >>> + { >>> + if (__cond_wait_until(&_M_cv, __l, __atime) =3D=3D = __atomic_wait_status::__timeout) >>> + return __atomic_wait_status::__timeout; >>> + >>> + int32_t __last =3D __cur; >>> + __atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE); >>> + if (__cur < __last) >>> + break; // break the loop if version overflows >>> + } >>> + return __atomic_wait_status::__no_timeout; >>> + } >>> + >>> + static __timed_waiters& >>> + _S_timed_for(void* __t) >>> + { >>> + static_assert(sizeof(__timed_waiters) =3D=3D sizeof(__waiters)); >>> + return (__timed_waiters&) __waiters::_S_for(__t); >>> + } >>> + }; >>> + } // namespace __detail >>> + >>> + template>> + typename _Clock, typename _Duration> >>> + bool >>> + __atomic_wait_until(const _Tp* __addr, _Tp __old, _Pred __pred, >>> + const chrono::time_point<_Clock, _Duration>& = __atime) noexcept >>> + { >>> + using namespace __detail; >>> + >>> + if (__atomic_spin(__pred)) >>=20 >> Qualify to prevent ADL. >>=20 >>> + return true; >>> + >>> + auto& __w =3D __timed_waiters::_S_timed_for((void*)__addr); >>> + auto __version =3D __w._M_enter_wait(); >>> + do >>> + { >>> + __atomic_wait_status __res; >>> + if constexpr (__platform_wait_uses_type<_Tp>::__value) >>> + { >>> + __res =3D = __platform_wait_until((__platform_wait_t*)(void*) __addr, __old, >>> + __atime); >>> + } >>> + else >>> + { >>> + __res =3D __w._M_do_wait_until(__version, __atime); >>> + } >>> + if (__res =3D=3D __atomic_wait_status::__timeout) >>> + return false; >>> + } >>> + while (!__pred() && __atime < _Clock::now()); >>> + __w._M_leave_wait(); >>> + >>> + // if timed out, return false >>> + return (_Clock::now() < __atime); >>> + } >>> + >>> + template>> + typename _Rep, typename _Period> >>> + bool >>> + __atomic_wait_for(const _Tp* __addr, _Tp __old, _Pred __pred, >>> + const chrono::duration<_Rep, _Period>& __rtime) = noexcept >>> + { >>> + using namespace __detail; >>> + >>> + if (__atomic_spin(__pred)) >>> + return true; >>> + >>> + if (!__rtime.count()) >>> + return false; // no rtime supplied, and spin did not acquire >>> + >>> + using __dur =3D chrono::steady_clock::duration; >>> + auto __reltime =3D chrono::duration_cast<__dur>(__rtime); >>> + if (__reltime < __rtime) >>> + ++__reltime; >>> + >>> + >>> + return __atomic_wait_until(__addr, __old, std::move(__pred), >>> + chrono::steady_clock::now() + = __reltime); >>> + } >>> +_GLIBCXX_END_NAMESPACE_VERSION >>> +} // namespace std >>> +#endif >>> diff --git a/libstdc++-v3/include/bits/atomic_wait.h = b/libstdc++-v3/include/bits/atomic_wait.h >>> new file mode 100644 >>> index 00000000000..32070a54f40 >>> --- /dev/null >>> +++ b/libstdc++-v3/include/bits/atomic_wait.h >>> @@ -0,0 +1,280 @@ >>> +// -*- C++ -*- header. >>> + >>> +// 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. >>> + >>> +// 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/atomic_wait.h >>> + * This is an internal header file, included by other library = headers. >>> + * Do not attempt to use it directly. @headername{atomic} >>> + */ >>> + >>> +#ifndef _GLIBCXX_ATOMIC_WAIT_H >>> +#define _GLIBCXX_ATOMIC_WAIT_H 1 >>> + >>> +#pragma GCC system_header >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#ifdef _GLIBCXX_HAVE_LINUX_FUTEX >>> +#include >>> +#include >>> +#include >>> +#endif >>> + >>> +#define _GLIBCXX_SPIN_COUNT_1 16 >>> +#define _GLIBCXX_SPIN_COUNT_2 12 >>> + >>> +// TODO get this from Autoconf >>> +#define _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE 1 >>> + >>> +namespace std _GLIBCXX_VISIBILITY(default) >>> +{ >>> +_GLIBCXX_BEGIN_NAMESPACE_VERSION >>> + namespace __detail >>> + { >>> + using __platform_wait_t =3D int; >>> + >>> + template >>=20 >> This should be typename not class. >>=20 >>> + struct __platform_wait_uses_type >>> + { >>> +#ifdef _GLIBCXX_HAVE_LINUX_FUTEX >>> + enum { __value =3D std::is_same::type, >>=20 >> This should be remove_cv_t. >>=20 >>> + __platform_wait_t>::value }; >>> +#else >>> + enum { __value =3D std::false_type::value }; >>> +#endif >>=20 >> There's no need to use the C++03 enum hack here, it should just = derive >> from true_type or false_type. >>=20 >> template >> struct __platform_wait_uses_type >> #ifdef _GLIBCXX_HAVE_LINUX_FUTEX >> : is_same, __platform_wait_t> >> #else >> : false_type >> #endif >> { }; >>=20 >> Or better yet, just use a variable template: >>=20 >> template >> inline constexpr bool __platform_wait_uses_type >> #ifdef _GLIBCXX_HAVE_LINUX_FUTEX >> =3D is_same_v, __platform_wait_t>; >> #else >> =3D false; >> #endif >>=20 >>=20 >>=20 >>> + }; >>> + >>> +#ifdef _GLIBCXX_HAVE_LINUX_FUTEX >>> + enum >>> + { >>> +#ifdef _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE >>> + __futex_private_flag =3D 128, >>> +#else >>> + __futex_private_flag =3D 0, >>> +#endif >>> + __futex_wait =3D 0, >>> + __futex_wake =3D 1, >>> + __futex_wait_bitset =3D 9, >>> + __futex_wake_bitset =3D 10, >>> + __futex_wait_private =3D __futex_wait | __futex_private_flag, >>> + __futex_wake_private =3D __futex_wake | __futex_private_flag >>> + }; >>> + >>> + void >>> + __platform_wait(__platform_wait_t* __addr, __platform_wait_t = __val) noexcept >>> + { >>> + auto __e =3D syscall (SYS_futex, __addr, = __futex_wait_private, __val, nullptr); >>> + if (__e && !(errno =3D=3D EINTR || errno =3D=3D EAGAIN)) >>> + std::terminate(); >>> + } >>> + >>> + void >>> + __platform_notify(__platform_wait_t* __addr, bool __all) = noexcept >>> + { >>> + syscall (SYS_futex, __addr, __futex_wake_private, __all ? = INT_MAX : 1); >>> + } >>> +#endif >>> + >>> + struct alignas(64) __waiters >>=20 >> Isn't alignas(64) already implied by the first data member? >>=20 >>> + { >>> + int32_t alignas(64) _M_ver =3D 0; >>> + int32_t alignas(64) _M_wait =3D 0; >>> + >>> + // TODO make this used only where we don't have futexes >>=20 >> Don't we always need these even with futexes, for the types that = don't >> use a futex? >>=20 >>> + using __lock_t =3D std::unique_lock; >>> + mutable __lock_t::mutex_type _M_mtx; >>> + >>> +#ifdef __GTHREAD_COND_INIT >>> + mutable __gthread_cond_t _M_cv =3D __GTHREAD_COND_INIT; >>> + __waiters() noexcept =3D default; >>=20 >> If we moved std::condition_variable into its own header (or >> , could we reuse that here instead of using >> __gthread_cond_t directly? >>=20 >>> +#else >>> + mutable __gthread_cond_t _M_cv; >>> + __waiters() noexcept >>> + { >>> + __GTHREAD_COND_INIT_FUNCTION(&_M_cond); >>> + } >>> +#endif >>> + >>> + int32_t >>> + _M_enter_wait() noexcept >>> + { >>> + int32_t __res; >>> + __atomic_load(&_M_ver, &__res, __ATOMIC_ACQUIRE); >>> + __atomic_fetch_add(&_M_wait, 1, __ATOMIC_ACQ_REL); >>> + return __res; >>> + } >>> + >>> + void >>> + _M_leave_wait() noexcept >>> + { >>> + __atomic_fetch_sub(&_M_wait, 1, __ATOMIC_ACQ_REL); >>> + } >>> + >>> + void >>> + _M_do_wait(int32_t __version) const noexcept >>> + { >>> + int32_t __cur =3D 0; >>> + while (__cur <=3D __version) >>> + { >>> + __waiters::__lock_t __l(_M_mtx); >>> + auto __e =3D __gthread_cond_wait(&_M_cv, = __l.mutex()->native_handle()); >>> + if (__e) >>> + std::terminate(); >>> + int32_t __last =3D __cur; >>> + __atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE); >>> + if (__cur < __last) >>> + break; // break the loop if version overflows >>> + } >>> + } >>> + >>> + int32_t >>> + _M_waiting() const noexcept >>> + { >>> + int32_t __res; >>> + __atomic_load(&_M_wait, &__res, __ATOMIC_ACQUIRE); >>> + return __res; >>> + } >>> + >>> + void >>> + _M_notify(bool __all) noexcept >>> + { >>> + __atomic_fetch_add(&_M_ver, 1, __ATOMIC_ACQ_REL); >>> + auto __e =3D __gthread_cond_broadcast(&_M_cv); >>> + if (__e) >>> + __throw_system_error(__e); >>> + } >>> + >>> + static __waiters& >>> + _S_for(void* __t) >>> + { >>> + const unsigned char __mask =3D 0xf; >>> + static __waiters __w[__mask + 1]; >>> + >>> + auto __key =3D _Hash_impl::hash(__t) & __mask; >>> + return __w[__key]; >>> + } >>> + }; >>> + >>> + struct __waiter >>> + { >>> + __waiters& _M_w; >>> + int32_t _M_version; >>> + >>> + template >>> + __waiter(const _Tp* __addr) noexcept >>> + : _M_w(__waiters::_S_for((void*) __addr)) >>> + , _M_version(_M_w._M_enter_wait()) >>> + { } >>> + >>> + ~__waiter() >>> + { _M_w._M_leave_wait(); } >>> + >>> + void _M_do_wait() noexcept >>> + { _M_w._M_do_wait(_M_version); } >>> + }; >>> + >>> + void >>> + __thread_relax() noexcept >>> + { >>> +#if defined __i386__ || defined __x86_64__ >>> + __builtin_ia32_pause(); >>> +#elif defined _GLIBCXX_USE_SCHED_YIELD >>> + __gthread_yield(); >>> +#endif >>> + } >>> + >>> + void >>> + __thread_yield() noexcept >>> + { >>> +#if defined _GLIBCXX_USE_SCHED_YIELD >>> + __gthread_yield(); >>> +#endif >>> + } >>> + >>> + } // namespace __detail >>> + >>> + template >>=20 >> s/class/template/ >>=20 >>> + bool >>> + __atomic_spin(_Pred __pred) noexcept >>> + { >>> + for (auto __i =3D 0; __i < _GLIBCXX_SPIN_COUNT_1; ++__i) >>> + { >>> + if (__pred()) >>> + return true; >>> + >>> + if (__i < _GLIBCXX_SPIN_COUNT_2) >>> + __detail::__thread_relax(); >>> + else >>> + __detail::__thread_yield(); >>> + } >>> + return false; >>> + } >>> + >>> + template >>=20 >> s/class/template/ >>=20 >>> + void >>> + __atomic_wait(const _Tp* __addr, _Tp __old, _Pred __pred) = noexcept >>> + { >>> + using namespace __detail; >>> + if (__atomic_spin(__pred)) >>> + return; >>> + >>> + __waiter __w(__addr); >>> + while (!__pred()) >>> + { >>> + if constexpr (__platform_wait_uses_type<_Tp>::__value) >>> + { >>> + __platform_wait((__platform_wait_t*)(void*) __addr, = __old); >>> + } >>> + else >>> + { >>> + // TODO support timed backoff when this can be moved into = the lib >>> + __w._M_do_wait(); >>> + } >>> + } >>> + } >>> + >>> + template >>=20 >> s/class/template/ >>=20 >>> + void >>> + __atomic_notify(const _Tp* __addr, bool __all) noexcept >>> + { >>> + using namespace __detail; >>> + auto& __w =3D __waiters::_S_for((void*)__addr); >>> + if (!__w._M_waiting()) >>=20 >> When __platform_wait_uses_type<_Tp> is true, will __w._M_waiting() >> ever be true? Won't this always return before notifying? >>=20 >> Is there meant to be a __waiter constructed here? >>=20 >>> + return; >>> + >>> + if constexpr (__platform_wait_uses_type<_Tp>::__value) >>> + { >>> + __platform_notify((__platform_wait_t*)(void*) __addr, __all); >>> + } >>> + else >>> + { >>> + __w._M_notify(__all); >>> + } >>> + } >>> +_GLIBCXX_END_NAMESPACE_VERSION >>> +} // namespace std >>> +#endif >>> diff --git a/libstdc++-v3/include/bits/semaphore_base.h = b/libstdc++-v3/include/bits/semaphore_base.h >>> new file mode 100644 >>> index 00000000000..b3c83bbc70b >>> --- /dev/null >>> +++ b/libstdc++-v3/include/bits/semaphore_base.h >>> @@ -0,0 +1,270 @@ >>> +// -*- C++ -*- header. >>> + >>> +// 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. >>> + >>> +// 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/semaphore.h >>=20 >> Should be bits/semaphore_base.h >>=20 >>> + * This is an internal header file, included by other library = headers. >>> + * Do not attempt to use it directly. @headername{atomic} >>=20 >> Should be @headername{semaphore} >>=20 >>> + */ >>> + >>> +#ifndef _GLIBCXX_SEMAPHORE_BASE_H >>> +#define _GLIBCXX_SEMAPHORE_BASE_H 1 >>> + >>> +#pragma GCC system_header >>> + >>> +#include >>> +#include >>> +#include >>> + >>> +#if defined _POSIX_SEMAPHORES && __has_include() >>> +#define _GLIBCXX_HAVE_POSIX_SEMAPHORE 1 >>> +#include >>> +#endif >>> + >>> +#include >>> +#include >>> +#include >>=20 >> is much smaller than and should be >> used for limits of integer types. (I recently added >> too but that was a mistake that I need to fix). >>=20 >>=20 >>> +namespace std _GLIBCXX_VISIBILITY(default) >>> +{ >>> +_GLIBCXX_BEGIN_NAMESPACE_VERSION >>> + >>> +#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE >>> + template >>=20 >> __least_max_t isn't a type so shouldn't have the _t suffix. >>=20 >>> + struct __platform_semaphore >>> + { >>> + using __clock_t =3D chrono::system_clock; >>> + >>> + __platform_semaphore(ptrdiff_t __count) noexcept >>=20 >> Should this constructor be explicit? >>=20 >>> + { >>> + static_assert( __least_max_t <=3D SEM_VALUE_MAX, "__least_max_t = > SEM_VALUE_MAX"); >>=20 >> Our static_assert messages should state the positive condition, not >> the negative one. So it should be "__least_max_t <=3D SEM_VALUE_MAX", >> which is what the real condition is anyway, so you might as well omit >> the string literal. >>=20 >>> + auto __e =3D sem_init(&_M_semaphore, 0, __count); >>> + if (__e) >>> + std::terminate(); >>> + } >>> + >>> + ~__platform_semaphore() >>> + { >>> + auto __e =3D sem_destroy(&_M_semaphore); >>> + if (__e) >>> + std::terminate(); >>> + } >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + acquire() noexcept >>> + { >>> + auto __err =3D sem_wait(&_M_semaphore); >>> + if (__err) >>> + std::terminate(); >>> + } >>> + >>> + template >>> + _GLIBCXX_ALWAYS_INLINE bool >>=20 >> Do we really need this to be always_inline? >>=20 >>> + __try_acquire_until_impl(const chrono::time_point<__clock_t>& = __atime) noexcept >>> + { >>> + auto __s =3D = chrono::time_point_cast(__atime); >>> + auto __ns =3D = chrono::duration_cast(__atime - __s); >>> + >>> + struct timespec __ts =3D >>> + { >>> + static_cast(__s.time_since_epoch().count()), >>> + static_cast(__ns.count()) >>> + }; >>> + >>> + auto __err =3D sem_timedwait(&_M_semaphore, &__ts); >>> + if (__err && (errno =3D=3D ETIMEDOUT)) >>> + return false; >>> + else if (__err) >>> + std::terminate(); >>> + return true; >>> + } >>> + >>> + template >>> + _GLIBCXX_ALWAYS_INLINE bool >>=20 >> always_inline? >>=20 >>> + try_acquire_until(const chrono::time_point<_Clock, _Duration>& = __atime) noexcept >>> + { >>> + if constexpr (std::is_same<__clock_t, _Clock>::value) >>=20 >> is_same_v >>=20 >>> + { >>> + return __try_acquire_until_impl(__atime); >>> + } >>> + else >>> + { >>> + const typename _Clock::time_point __c_entry =3D = _Clock::now(); >>> + const __clock_t __s_entry =3D __clock_t::now(); >>> + const auto __delta =3D __atime - __c_entry; >>> + const auto __s_atime =3D __s_entry + __delta; >>> + if (__try_acquire_until_impl(__s_atime)) >>> + return true; >>> + >>> + // We got a timeout when measured against __clock_t but >>> + // we need to check against the caller-supplied clock >>> + // to tell whether we should return a timeout. >>> + return (_Clock::now() < __atime); >>> + } >>> + } >>> + >>> + template >>> + _GLIBCXX_ALWAYS_INLINE bool >>> + try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime) = noexcept >>> + { return try_acquire_until(__clock_t::now() + __rtime); } >>> + >>> + template >>> + _GLIBCXX_ALWAYS_INLINE void >>> + release(ptrdiff_t __update) noexcept >>> + { >>> + do >>> + { >>> + auto __err =3D sem_post(&_M_semaphore); >>> + if (__err) >>> + std::terminate(); >>> + } while (--__update); >>> + } >>> + >>> + private: >>> + sem_t _M_semaphore; >>> + }; >>> +#endif // _GLIBCXX_HAVE_POSIX_SEMAPHORE >>> + >>> + template >>> + struct __atomic_semaphore >>> + { >>> + static constexpr size_t _S_alignment =3D __alignof__(_Tp); >>> + >>> + __atomic_semaphore(_Tp __count) >>=20 >> Should this be explicit? >>=20 >>> + : _M_a(__count) >>> + { } >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + acquire() noexcept >>> + { >>> + auto const __pred =3D [this] >>> + { >>> + auto __old =3D __atomic_impl::load(&this->_M_a, = memory_order::acquire); >>> + if (__old =3D=3D 0) >>> + return false; >>> + return __atomic_impl::compare_exchange_strong(&this->_M_a, >>> + __old, __old = - 1, >>> + = memory_order::acquire, >>> + = memory_order::release); >>> + }; >>> + auto __old =3D __atomic_impl::load(&_M_a, = memory_order_relaxed); >>> + __atomic_wait(&_M_a, __old, __pred); >>> + } >>> + >>> + bool >>> + try_acquire() noexcept >>> + { >>> + auto __old =3D __atomic_impl::load(&_M_a, = memory_order::acquire); >>> + if (__old =3D=3D 0) >>> + return false; >>> + >>> + return __atomic_spin([this, &__old] >>> + { >>> + return __atomic_impl::compare_exchange_weak(&this->_M_a, >>> + __old, __old - = 1, >>> + = memory_order::acquire, >>> + = memory_order::release); >>> + }); >>> + } >>> + >>> + template >>> + _GLIBCXX_ALWAYS_INLINE bool >>> + try_acquire_until(const chrono::time_point<_Clock, _Duration>& = __atime) noexcept >>> + { >>> + auto const __pred =3D [this] >>> + { >>> + auto __old =3D __atomic_impl::load(&this->_M_a, = memory_order::acquire); >>> + if (__old =3D=3D 0) >>> + return false; >>> + return = __atomic_impl::compare_exchange_strong(&this->_M_a, >>> + __old, = __old - 1, >>> + = memory_order::acquire, >>> + = memory_order::release); >>> + }; >>> + >>> + auto __old =3D __atomic_impl::load(&_M_a, = memory_order_relaxed); >>> + return __atomic_wait_until(&_M_a, __old, __pred, __atime); >>> + } >>> + >>> + template >>> + _GLIBCXX_ALWAYS_INLINE bool >>> + try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime) = noexcept >>> + { >>> + auto const __pred =3D [this] >>> + { >>> + auto __old =3D __atomic_impl::load(&this->_M_a, = memory_order::acquire); >>> + if (__old =3D=3D 0) >>> + return false; >>> + return = __atomic_impl::compare_exchange_strong(&this->_M_a, >>> + __old, = __old - 1, >>> + = memory_order::acquire, >>> + = memory_order::release); >>> + }; >>> + >>> + auto __old =3D __atomic_impl::load(&_M_a, = memory_order_relaxed); >>> + return __atomic_wait_for(&_M_a, __old, __pred, __rtime); >>> + } >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + release(ptrdiff_t __update) noexcept >>> + { >>> + if (0 < __atomic_impl::fetch_add(&_M_a, __update, = memory_order_release)) >>> + return; >>> + if (__update > 1) >>> + __atomic_impl::notify_all(&_M_a); >>> + else >>> + __atomic_impl::notify_one(&_M_a); >>> + } >>> + >>> + private: >>> + alignas(_S_alignment) _Tp _M_a; >>=20 >> Could this just use alignas(__alignof__(_Tp)) _Tp here? There's no >> need for the _S_alignment constant if it's only used in one place. >>=20 >>> + }; >>> + >>> +#ifdef _GLIBCXX_REQUIRE_POSIX_SEMAPHORE >>> + template >>=20 >> Rename __least_max_t here too. >>=20 >>> + using __semaphore_base =3D __platform_semaphore<__least_max_t>; >>> +#else >>> +# ifdef _GLIBCXX_HAVE_LINUX_FUTEX >>> + template >>> + using __semaphore_base =3D std::conditional<(__least_max_t > 0 >>=20 >> This should use conditional_t<> not conditional<>::type. >>=20 >> The least-max_value can't be negative. If it's zero, can't we use a >> futex or semaphore? So the '__least_max_t > 0' condition is wrong? >>=20 >>> + && __least_max_t < = std::numeric_limits<__detail::__platform_wait_t>::max()), >>=20 >> Should that be <=3D rather than < ? >>=20 >>> + = __atomic_semaphore<__detail::__platform_wait_t>, >>> + = __atomic_semaphore>::type; >>> + // __platform_semaphore >>> +# else >>> +# ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE >>=20 >> Please use '#elif defined _GLIBCXX_HAVE_POSIX_SEMAPHORE' here to = avoid >> an extra level of #if nesting. >>=20 >>> + template >>> + using __semaphore_base =3D std::conditional<(__least_max_t > 0 = && __least_max_t <=3D SEM_VALUE_MAX), >>> + = __platform_semaphore<__least_max_t>, >>> + = __atomic_semaphore>::type; >>> +# else >>> + template >>> + using __semaphore_base =3D __atomic_semaphore; >>> +# endif >>> +# endif >>> +#endif >>> + >>> +_GLIBCXX_END_NAMESPACE_VERSION >>> +} // namespace std >>> + >>> +#endif >>> diff --git a/libstdc++-v3/include/std/atomic = b/libstdc++-v3/include/std/atomic >>> index a455286a784..3f18774031d 100644 >>> --- a/libstdc++-v3/include/std/atomic >>> +++ b/libstdc++-v3/include/std/atomic >>> @@ -163,6 +163,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> compare_exchange_strong(bool& __i1, bool __i2, >>> memory_order __m =3D memory_order_seq_cst) volatile = noexcept >>> { return _M_base.compare_exchange_strong(__i1, __i2, __m); } >>> + >>> +#if __cplusplus > 201703L >>> + void wait(bool __old, memory_order __m =3D = memory_order_seq_cst) const noexcept >>> + { _M_base.wait(__old, __m); } >>> + >>> + // TODO add const volatile overload >>> + >>> + void notify_one() const noexcept >>> + { _M_base.notify_one(); } >>> + >>> + void notify_all() const noexcept >>> + { _M_base.notify_all(); } >>> +#endif >>> }; >>>=20 >>> #if __cplusplus <=3D 201703L >>> @@ -352,6 +365,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> memory_order __m =3D memory_order_seq_cst) volatile = noexcept >>> { return compare_exchange_strong(__e, __i, __m, >>> __cmpexch_failure_order(__m)); = } >>> +#if __cplusplus > 201703L >>> + void wait(_Tp __old, memory_order __m =3D memory_order_seq_cst) = noexcept >>> + { _M_i.wait(__old, __m); } >>> + >>> + // TODO add const volatile overload >>> + >>> + void notify_one() const noexcept >>> + { _M_i.notify_one(); } >>> + >>> + void notify_all() const noexcept >>> + { _M_i.notify_all(); } >>> +#endif >>> + >>> }; >>> #undef _GLIBCXX20_INIT >>>=20 >>> @@ -590,6 +616,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> = __cmpexch_failure_order(__m)); >>> } >>>=20 >>> +#if __cplusplus > 201703L >>> + void wait(__pointer_type __old, memory_order __m =3D = memory_order_seq_cst) noexcept >>> + { _M_b.wait(__old, __m); } >>> + >>> + // TODO add const volatile overload >>> + >>> + void notify_one() const noexcept >>> + { _M_b.notify_one(); } >>> + >>> + void notify_all() const noexcept >>> + { _M_b.notify_all(); } >>> +#endif >>> __pointer_type >>> fetch_add(ptrdiff_t __d, >>> memory_order __m =3D memory_order_seq_cst) noexcept >>> @@ -1342,6 +1380,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> = memory_order_seq_cst); >>> } >>>=20 >>> + >>> +#if __cplusplus > 201703L >>> + template >>> + inline void atomic_wait(const atomic<_Tp>* __a, >>> + typename std::atomic<_Tp>::value_type __old) = noexcept >>> + { __a->wait(__old); } >>> + >>> + template >>> + inline void atomic_wait_explicit(const atomic<_Tp>* __a, >>> + typename = std::atomic<_Tp>::value_type __old, >>> + std::memory_order __m) noexcept >>> + { __a->wait(__old, __m); } >>> + >>> + template >>> + inline void atomic_notify_one(atomic<_Tp>* __a) noexcept >>> + { __a->notify_one(); } >>> + >>> + template >>> + inline void atomic_notify_all(atomic<_Tp>* __a) noexcept >>> + { __a->notify_all(); } >>> + >>> +#endif // C++2a >>> + >>> // Function templates for atomic_integral and atomic_pointer = operations only. >>> // Some operations (and, or, xor) are only available for atomic = integrals, >>> // which is implemented by taking a parameter of type = __atomic_base<_ITp>*. >>> diff --git a/libstdc++-v3/include/std/latch = b/libstdc++-v3/include/std/latch >>> new file mode 100644 >>> index 00000000000..0099877416e >>> --- /dev/null >>> +++ b/libstdc++-v3/include/std/latch >>> @@ -0,0 +1,91 @@ >>> +// -*- C++ -*- >>=20 >> A space before . >>=20 >>> + >>> +// 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. >>> + >>> +// 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 include/latch >>> + * This is a Standard C++ Library header. >>=20 >> Align "This" with "@file" here. >>=20 >>> + */ >>> + >>> +#ifndef _GLIBCXX_LATCH >>> +#define _GLIBCXX_LATCH >>> + >>> +#pragma GCC system_header >>> + >>> +#if __cplusplus > 201703L >>> +#define __cpp_lib_latch 201907L >>> + >>> +#include >>> +#include >>=20 >> Use here too. >>=20 >>> +namespace std _GLIBCXX_VISIBILITY(default) >>> +{ >>> +_GLIBCXX_BEGIN_NAMESPACE_VERSION >>> + >>> + class latch >>> + { >>> + static constexpr size_t _S_alignment =3D = __alignof__(ptrdiff_t); >>> + public: >>> + static constexpr >>> + _GLIBCXX_ALWAYS_INLINE ptrdiff_t >>> + max() noexcept >>> + { return numeric_limits::max(); } >>> + >>> + constexpr explicit latch(ptrdiff_t __expected) : = _M_a(__expected) { } >>> + >>> + ~latch() =3D default; >>> + latch(const latch&) =3D delete; >>> + latch& operator=3D(const latch&) =3D delete; >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + count_down(ptrdiff_t __update =3D 1) >>> + { >>> + auto const __old =3D __atomic_impl::fetch_sub(&_M_a, = __update, memory_order::release); >>> + if (__old =3D=3D __update) >>> + __atomic_impl::notify_all(&_M_a); >>> + } >>> + >>> + _GLIBCXX_ALWAYS_INLINE bool >>> + try_wait() const noexcept >>> + { return __atomic_impl::load(&_M_a, memory_order::acquire) =3D=3D= 0; } >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + wait() const >>> + { >>> + auto const __old =3D __atomic_impl::load(&_M_a, = memory_order::acquire); >>> + __atomic_wait(&_M_a, __old, [this] { return this->try_wait(); = }); >>> + } >>> + >>> + _GLIBCXX_ALWAYS_INLINE void >>> + arrive_and_wait(ptrdiff_t __update =3D 1) >>> + { >>> + count_down(); >>> + wait(); >>> + } >>> + >>> + private: >>> + alignas(_S_alignment) ptrdiff_t _M_a; >>=20 >> Just use __alignof__ directly here and get rid of _S_alignment? >>=20 >>> + }; >>> +_GLIBCXX_END_NAMESPACE_VERSION >>> +} // namespace >>> +#endif // __cplusplus > 201703L >>> +#endif // _GLIBCXX_LATCH >>> diff --git a/libstdc++-v3/include/std/semaphore = b/libstdc++-v3/include/std/semaphore >>> new file mode 100644 >>> index 00000000000..b51940b46ac >>> --- /dev/null >>> +++ b/libstdc++-v3/include/std/semaphore >>> @@ -0,0 +1,81 @@ >>> +// -*- C++ -*- >>=20 >> A space before . >>=20 >>> + >>> +// 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. >>> + >>> +// 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 include/semaphore >>> + * This is a Standard C++ Library header. >>=20 >> Align "This" with "@file" here. >>=20 >>> + */ >>> + >>> +#ifndef _GLIBCXX_SEMAPHORE >>> +#define _GLIBCXX_SEMAPHORE >>> + >>> +#pragma GCC system_header >>> + >>> +#if __cplusplus > 201703L >>> +#define __cpp_lib_semaphore 201907L >>> +#include >>> + >>> +namespace std _GLIBCXX_VISIBILITY(default) >>> +{ >>> +_GLIBCXX_BEGIN_NAMESPACE_VERSION >>> + >>> + template::max()> >>> + class counting_semaphore >>> + { >>=20 >> I don't see a static_assert making it ill-formed to use a negative >> value for __least_max_value. Is that enforced somewhere else? >>=20 >> The standard says it's ill-formed, so we should also have a _neg.cc >> test checking that we reject it. >>=20 >>> + __semaphore_base<__least_max_value> _M_sem; >>=20 >> Blank line after this please. >>=20 >>> + public: >>> + explicit counting_semaphore(ptrdiff_t __desired) noexcept >>> + : _M_sem(__desired) >>> + { } >>> + >>> + ~counting_semaphore() =3D default; >>> + >>> + counting_semaphore(const counting_semaphore&) =3D delete; >>> + counting_semaphore& operator=3D(const counting_semaphore&) =3D = delete; >>> + >>> + static constexpr ptrdiff_t max() noexcept >>> + { return __least_max_value; } >>> + >>> + void release(ptrdiff_t __update =3D 1) >>> + { _M_sem.release(__update); } >>> + >>> + void acquire() >>> + { _M_sem.acquire(); } >>> + >>> + bool try_acquire() noexcept >>> + { return _M_sem.try_acquire(); } >>> + >>> + template >>=20 >> s/class/template/ >>=20 >>> + bool try_acquire_for(const std::chrono::duration<_Rep, _Period>& = __rel_time) >>> + { return _M_sem.try_acquire_for(__rel_time); } >>> + >>> + template >>=20 >> s/class/template/ >>=20 >>> + bool try_acquire_until(const std::chrono::time_point<_Clock, = _Duration>& __abs_time) >>> + { return _M_sem.try_acquire_until(__abs_time); } >>> + }; >>> + >>> + using binary_semaphore =3D std::counting_semaphore<1>; >>> +_GLIBCXX_END_NAMESPACE_VERSION >>> +} // namespace >>> +#endif // __cplusplus > 201703L >>> +#endif // _GLIBCXX_SEMAPHORE >>> diff --git a/libstdc++-v3/include/std/version = b/libstdc++-v3/include/std/version >>> index c3a5bd26e63..390990282b0 100644 >>> --- a/libstdc++-v3/include/std/version >>> +++ b/libstdc++-v3/include/std/version >>> @@ -188,6 +188,8 @@ >>> #endif >>> #define __cpp_lib_type_identity 201806L >>> #define __cpp_lib_unwrap_ref 201811L >>> +#define __cpp_lib_semaphore 201907L >>> +#define __cpp_lib_latch 201907L >>=20 >> These features aren't supported in a freestanding implementation, so >> should be in the #if _GLIBCXX_HOSTED block (and the macros should be >> in alphabetical order). >>=20 >>>=20 >>> #if _GLIBCXX_HOSTED >>> #undef __cpp_lib_array_constexpr >>> diff --git = a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc = b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc >>> new file mode 100644 >>> index 00000000000..1ced9d44b20 >>> --- /dev/null >>> +++ = b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc >>> @@ -0,0 +1,103 @@ >>> +// { dg-options "-std=3Dgnu++2a -pthread -latomic = -L../../libatomic/.libs" } >>=20 >> Use { dg-add-options libatomic } instead of adding -latomic -L... >=20 --Apple-Mail=_35F1270A-E967-48E3-9355-C77AF697D593--