Hopefully less borked than the previous one, adds futex support. ----- Original Message ----- From: "Thomas Rodgers" To: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org Sent: Wednesday, February 19, 2020 7:18:36 PM Subject: Re: [PATCH] Add c++2a binary_semaphore Should address the previous issues, adds backoff logic. * include/std/semaphore: New file. * include/std/version (__cpp_lib_semaphore): Add feature test macro. * include/Makefile.am (std_headers): add semaphore. * include/Makefile.in: Regenerate. * testsuite/30_threads/semaphore/1.cc: New test. * testsuite/30_threads/semaphore/2.cc: New test. * testsuite/30_threads/semaphore/binary_semaphore.cc: New test. * testsuite/30_threads/semaphore/try_acquire.cc: New test. * testsuite/30_threads/semaphore/try_acquire_for.cc: New test. * testsuite/30_threads/semaphore/try_acquire_until.cc: New test. ----- Original Message ----- From: "Jonathan Wakely" To: "Thomas Rodgers" Cc: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org Sent: Tuesday, February 18, 2020 6:25:41 AM Subject: Re: [PATCH] Add c++2a binary_semaphore On 18/02/20 01:46 -0500, Thomas Rodgers wrote: >This patch adds the c++2a semaphore header and binary_semaphore type. The implementation is not complete, this patch is just to solicit initial feedback. Here is some initial feedback on comments and whitespace :-) >diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am >index 89835759069..2dbb7d3a6b1 100644 >--- a/libstdc++-v3/include/Makefile.am >+++ b/libstdc++-v3/include/Makefile.am >@@ -69,6 +69,7 @@ std_headers = \ > ${std_srcdir}/ratio \ > ${std_srcdir}/regex \ > ${std_srcdir}/scoped_allocator \ >+ ${std_srcdir}/semaphore \ Indentation is borked. > ${std_srcdir}/set \ > ${std_srcdir}/shared_mutex \ > ${std_srcdir}/span \ >diff --git a/libstdc++-v3/include/std/semaphore b/libstdc++-v3/include/std/semaphore >new file mode 100644 >index 00000000000..e3e88a50eec >--- /dev/null >+++ b/libstdc++-v3/include/std/semaphore >@@ -0,0 +1,131 @@ >+// -*- C++ -*- Wrong header name in comment. >+ >+// Copyright (C) 2019-2020 Free Software Foundation, Inc. >+// >+// This file is part of the GNU ISO C++ Library. This library is free >+// software; you can redistribute it and/or modify it under the >+// terms of the GNU General Public License as published by the >+// Free Software Foundation; either version 3, or (at your option) >+// any later version. >+ >+// This library is distributed in the hope that it will be useful, >+// but WITHOUT ANY WARRANTY; without even the implied warranty of >+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+// GNU General Public License for more details. >+ >+// Under Section 7 of GPL version 3, you are granted additional >+// permissions described in the GCC Runtime Library Exception, version >+// 3.1, as published by the Free Software Foundation. >+ >+// You should have received a copy of the GNU General Public License and >+// a copy of the GCC Runtime Library Exception along with this program; >+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see >+// . >+ >+/** @file include/stop_token Wrong name again. >+ * This is a Standard C++ Library header. >+ */ >+ >+#ifndef _GLIBCXX_SEMAPHORE >+#define _GLIBCXX_SEMAPHORE >+ >+#if __cplusplus > 201703L >+#define __cpp_lib_semaphore 201907L We shouldn't define this until the file is complete, i.e. when it provides binary_semaphore and counting_semaphore. >+ >+#include Is this header needed? ptrdiff_t and size_t are both defined in which every header already includes. >+#include >+#include >+ >+namespace std _GLIBCXX_VISIBILITY(default) >+{ >+_GLIBCXX_BEGIN_NAMESPACE_VERSION >+ >+ // TODO: replace this with a real implementation of std::binary_semaphore >+ struct binary_semaphore >+{ Indentation is borked here too. >+ explicit binary_semaphore(int __d) : _M_counter(__d > 0) { } >+ >+ static constexpr std::ptrdiff_t >+ max() noexcept >+ { >+ return 1; >+ } >+ >+ void release() { _M_counter.fetch_add(1, memory_order::release); } >+ >+ void acquire() >+ { >+ while (!_M_try_acquire()) >+ { >+ _S_yield(); >+ } >+ } >+ >+ bool >+ try_acquire() noexcept >+ { >+ return _M_try_acquire(1u); >+ } >+ >+ template >+ bool try_acquire_for(const std::chrono::duration<_Rep, _Period>& __rel_time) >+ { >+ auto __abst = std::chrono::steady_clock::now() + __rel_time; >+ return try_acquire_until(__abst); >+ } >+ >+ template >+ bool try_acquire_until(const std::chrono::time_point<_Clock, _Duration>& __abs_time) >+ { >+ do >+ { >+ if (_M_try_acquire()) >+ { >+ return true; >+ } >+ } while (std::chrono::steady_clock::now() < __abs_time); >+ return false; >+ } >+ >+private: >+ static void >+ _S_yield() noexcept >+ { >+#if defined __i386__ || defined __x86_64__ >+ __builtin_ia32_pause(); >+#elif defined _GLIBCXX_USE_SCHED_YIELD >+ __gthread_yield(); >+#endif >+ } >+ >+ bool >+ _M_try_acquire(unsigned __spin_ct) >+ { >+ int __old = 1; >+ while (!_M_counter.compare_exchange_weak(__old, 0, >+ memory_order::acquire, >+ memory_order::relaxed)) >+ { >+ if (--__spin_ct == 0) >+ { >+ return false; >+ } >+ __old = 1; >+ } >+ return true; >+ } >+ >+ static constexpr unsigned _S_spin_ct = 64u; >+ bool >+ _M_try_acquire() >+ { >+ return _M_try_acquire(1); >+ } >+ >+ atomic _M_counter; >+}; >+ >+_GLIBCXX_END_NAMESPACE_VERSION >+} // namespace >+#endif // __cplusplus > 201703L >+#endif // _GLIBCXX_STOP_TOKEN Wrong macro name in comment.