Remove __platform_semaphore. Replace __atomic_semaphore with
__semaphore_base<bool> and change its counter to be ptrdiff_t when the
count doesn't fit in __platform_wait_t (PR 118494).

Make the std::counting_semaphore constructor constexpr to support
constant initialization (PR 110854).

Add precondition checks to the constructor and release member functions
(PR 98749).

libstdc++-v3/ChangeLog:

        PR libstdc++/118494
        PR libstdc++/110854
        PR libstdc++/98749
        * acinclude.m4 (GLIBCXX_CHECK_GTHREADS): Remove checks for
        sem_timedwait. Do not define _GLIBCXX_HAVE_POSIX_SEMAPHORE.
        * config.h.in: Regenerate.
        * configure: Regenerate.
        * include/bits/semaphore_base.h (__platform_semaphore): Remove.
        (__atomic_semaphore): Replace with __semaphore_base<bool> and
        make type of _M_count depend on template parameter. Fix _S_max
        constant to use correct type.
        (__semaphore_base::_M_try_acquire): Qualify to avoid ADL.
        (__semaphore_base::_M_release): Return old value. Remove FIXME
        comment.
        (__semaphore_impl): Replace typedef with alias template.
        * include/bits/version.def (semaphore): Do not depend on
        _GLIBCXX_HAVE_POSIX_SEMAPHORE.
        * include/bits/version.h: Regenerate.
        * include/std/semaphore (semaphore): Adjust type of _M_sem
        member. Add constexpr to constructor. Add assertions to
        (semaphore::semaphore(ptrdiff_t)): Add constexpr. Add assertion
        for precondition.
        (semaphore::release): Add assertion using value returned from
        _M_release.
        * testsuite/30_threads/semaphore/100806.cc: Increase template
        argument for std::counting_semaphore, so constructor
        precondition is met.
        * testsuite/30_threads/semaphore/cons.cc: New test.
        * testsuite/30_threads/semaphore/try_acquire_posix.cc: Remove.
        * testsuite/30_threads/semaphore/platform_try_acquire_for.cc:
        Removed.
---
 libstdc++-v3/acinclude.m4                     |  37 ---
 libstdc++-v3/config.h.in                      |   4 -
 libstdc++-v3/configure                        |  60 +----
 libstdc++-v3/include/bits/semaphore_base.h    | 224 ++++--------------
 libstdc++-v3/include/bits/version.def         |   2 +-
 libstdc++-v3/include/bits/version.h           |   2 +-
 libstdc++-v3/include/std/semaphore            |  32 ++-
 .../testsuite/30_threads/semaphore/100806.cc  |   2 +-
 .../testsuite/30_threads/semaphore/cons.cc    |   7 +
 .../semaphore/platform_try_acquire_for.cc     |   9 -
 .../30_threads/semaphore/try_acquire_posix.cc | 153 ------------
 11 files changed, 82 insertions(+), 450 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/cons.cc
 delete mode 100644 
libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
 delete mode 100644 
libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index d1ecb1ad9566..080a4fca9b57 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4293,43 +4293,6 @@ AC_DEFUN([GLIBCXX_CHECK_GTHREADS], [
     fi
   fi
 
-  AC_CHECK_HEADER(semaphore.h, [
-    AC_MSG_CHECKING([for POSIX Semaphores and sem_timedwait])
-    AC_TRY_COMPILE([
-       #include <unistd.h>
-       #include <semaphore.h>
-       #include <limits.h>
-      ],
-      [
-       #if !defined _POSIX_TIMEOUTS || _POSIX_TIMEOUTS <= 0
-       # error "POSIX Timeouts option not supported"
-       #elif !defined _POSIX_SEMAPHORES || _POSIX_SEMAPHORES <= 0
-       # error "POSIX Semaphores option not supported"
-       #else
-       #if defined SEM_VALUE_MAX
-       constexpr int sem_value_max = SEM_VALUE_MAX;
-       #elif defined _POSIX_SEM_VALUE_MAX
-       constexpr int sem_value_max = _POSIX_SEM_VALUE_MAX;
-       #else
-       # error "SEM_VALUE_MAX not available"
-       #endif
-       sem_t sem;
-       sem_init(&sem, 0, sem_value_max);
-       struct timespec ts = { 0 };
-       sem_timedwait(&sem, &ts);
-       #endif
-      ],
-      [ac_have_posix_semaphore=yes],
-      [ac_have_posix_semaphore=no])],
-      [ac_have_posix_semaphore=no])
-
-  if test $ac_have_posix_semaphore = yes ; then
-    AC_DEFINE(HAVE_POSIX_SEMAPHORE,
-             1,
-             [Define to 1 if POSIX Semaphores with sem_timedwait are available 
in <semaphore.h>.])
-  fi
-  AC_MSG_RESULT([$ac_have_posix_semaphore])
-
   CXXFLAGS="$ac_save_CXXFLAGS"
   AC_LANG_RESTORE
 ])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 3dbe00bae508..ffacdabac854 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -314,10 +314,6 @@
 /* Define to 1 if you have the `posix_memalign' function. */
 #undef HAVE_POSIX_MEMALIGN
 
-/* Define to 1 if POSIX Semaphores with sem_timedwait are available in
-   <semaphore.h>. */
-#undef HAVE_POSIX_SEMAPHORE
-
 /* Define to 1 if you have the `powf' function. */
 #undef HAVE_POWF
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index d6891e544cfe..69aa246ec7fb 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -51990,64 +51990,6 @@ fi
     fi
   fi
 
-  ac_fn_cxx_check_header_mongrel "$LINENO" "semaphore.h" 
"ac_cv_header_semaphore_h" "$ac_includes_default"
-if test "x$ac_cv_header_semaphore_h" = xyes; then :
-
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for POSIX Semaphores and 
sem_timedwait" >&5
-$as_echo_n "checking for POSIX Semaphores and sem_timedwait... " >&6; }
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-       #include <unistd.h>
-       #include <semaphore.h>
-       #include <limits.h>
-
-int
-main ()
-{
-
-       #if !defined _POSIX_TIMEOUTS || _POSIX_TIMEOUTS <= 0
-       # error "POSIX Timeouts option not supported"
-       #elif !defined _POSIX_SEMAPHORES || _POSIX_SEMAPHORES <= 0
-       # error "POSIX Semaphores option not supported"
-       #else
-       #if defined SEM_VALUE_MAX
-       constexpr int sem_value_max = SEM_VALUE_MAX;
-       #elif defined _POSIX_SEM_VALUE_MAX
-       constexpr int sem_value_max = _POSIX_SEM_VALUE_MAX;
-       #else
-       # error "SEM_VALUE_MAX not available"
-       #endif
-       sem_t sem;
-       sem_init(&sem, 0, sem_value_max);
-       struct timespec ts = { 0 };
-       sem_timedwait(&sem, &ts);
-       #endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_have_posix_semaphore=yes
-else
-  ac_have_posix_semaphore=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
-  ac_have_posix_semaphore=no
-fi
-
-
-
-  if test $ac_have_posix_semaphore = yes ; then
-
-$as_echo "#define HAVE_POSIX_SEMAPHORE 1" >>confdefs.h
-
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_have_posix_semaphore" 
>&5
-$as_echo "$ac_have_posix_semaphore" >&6; }
-
   CXXFLAGS="$ac_save_CXXFLAGS"
   ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -53601,7 +53543,7 @@ $as_echo "$glibcxx_cv_libbacktrace_atomics" >&6; }
     CXXFLAGS='-O0 -S'
 
     cat > conftest.$ac_ext << EOF
-#line 53604 "configure"
+#line 53546 "configure"
 #include <stddef.h>
 int main()
 {
diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 444a1589fb5a..5b5a1c982317 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -34,162 +34,44 @@
 #pragma GCC system_header
 #endif
 
+#include <bits/version.h>
+
+#ifdef __glibcxx_semaphore // C++ >= 20 && hosted && atomic_wait
 #include <bits/atomic_base.h>
 #include <bits/chrono.h>
-#if __glibcxx_atomic_wait
 #include <bits/atomic_timed_wait.h>
 #include <ext/numeric_traits.h>
-#endif // __cpp_lib_atomic_wait
-
-#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
-# include <cerrno>     // errno, EINTR, EAGAIN etc.
-# include <limits.h>   // SEM_VALUE_MAX
-# include <semaphore.h>        // sem_t, sem_init, sem_wait, sem_post etc.
-#elif defined(_GLIBCXX_USE_POSIX_SEMAPHORE)
-# warning "POSIX semaphore not available, ignoring 
_GLIBCXX_USE_POSIX_SEMAPHORE"
-# undef _GLIBCXX_USE_POSIX_SEMAPHORE
-#endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
-  struct __platform_semaphore
+  template<bool _Platform_wait>
+  struct __semaphore_base
   {
-    using __clock_t = chrono::system_clock;
-#ifdef SEM_VALUE_MAX
-    static constexpr ptrdiff_t _S_max = SEM_VALUE_MAX;
-#else
-    static constexpr ptrdiff_t _S_max = _POSIX_SEM_VALUE_MAX;
-#endif
+    using __count_type = __conditional_t<_Platform_wait,
+                                        __detail::__platform_wait_t,
+                                        ptrdiff_t>;
 
-    explicit __platform_semaphore(ptrdiff_t __count) noexcept
-    {
-      sem_init(&_M_semaphore, 0, __count);
-    }
+    static constexpr ptrdiff_t _S_max
+      = __gnu_cxx::__int_traits<__count_type>::__max;
 
-    __platform_semaphore(const __platform_semaphore&) = delete;
-    __platform_semaphore& operator=(const __platform_semaphore&) = delete;
+    constexpr explicit
+    __semaphore_base(__count_type __count) noexcept
+    : _M_counter(__count)
+    { }
 
-    ~__platform_semaphore()
-    { sem_destroy(&_M_semaphore); }
+    __semaphore_base(const __semaphore_base&) = delete;
+    __semaphore_base& operator=(const __semaphore_base&) = delete;
 
-    _GLIBCXX_ALWAYS_INLINE void
-    _M_acquire() noexcept
-    {
-      while (sem_wait(&_M_semaphore))
-       if (errno != EINTR)
-         std::__terminate();
-    }
-
-    _GLIBCXX_ALWAYS_INLINE bool
-    _M_try_acquire() noexcept
-    {
-      while (sem_trywait(&_M_semaphore))
-       {
-         if (errno == EAGAIN) // already locked
-           return false;
-         else if (errno != EINTR)
-           std::__terminate();
-         // else got EINTR so retry
-       }
-      return true;
-    }
-
-    _GLIBCXX_ALWAYS_INLINE void
-    _M_release(ptrdiff_t __update) noexcept
-    {
-      for(; __update != 0; --__update)
-       if (sem_post(&_M_semaphore))
-         std::__terminate();
-    }
-
-    bool
-    _M_try_acquire_until_impl(const chrono::time_point<__clock_t>& __atime)
-      noexcept
-    {
-      auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
-      auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
-
-      struct timespec __ts =
-      {
-       static_cast<std::time_t>(__s.time_since_epoch().count()),
-       static_cast<long>(__ns.count())
-      };
-
-      while (sem_timedwait(&_M_semaphore, &__ts))
-       {
-         if (errno == ETIMEDOUT)
-           return false;
-         else if (errno != EINTR)
-           std::__terminate();
-       }
-      return true;
-    }
-
-    template<typename _Clock, typename _Duration>
-      bool
-      _M_try_acquire_until(const chrono::time_point<_Clock,
-                          _Duration>& __atime) noexcept
-      {
-       if constexpr (std::is_same_v<__clock_t, _Clock>)
-         {
-           using _Dur = __clock_t::duration;
-           return _M_try_acquire_until_impl(chrono::ceil<_Dur>(__atime));
-         }
-       else
-         {
-           // TODO: if _Clock is monotonic_clock we could use
-           // sem_clockwait with CLOCK_MONOTONIC.
-
-           const typename _Clock::time_point __c_entry = _Clock::now();
-           const auto __s_entry = __clock_t::now();
-           const auto __delta = __atime - __c_entry;
-           const auto __s_atime = __s_entry + __delta;
-           if (_M_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<typename _Rep, typename _Period>
-      _GLIBCXX_ALWAYS_INLINE bool
-      _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime)
-       noexcept
-      { return _M_try_acquire_until(__clock_t::now() + __rtime); }
-
-  private:
-    sem_t _M_semaphore;
-  };
-#endif // _GLIBCXX_HAVE_POSIX_SEMAPHORE
-
-#if __glibcxx_atomic_wait
-  struct __atomic_semaphore
-  {
-    static constexpr ptrdiff_t _S_max = __gnu_cxx::__int_traits<int>::__max;
-    explicit __atomic_semaphore(__detail::__platform_wait_t __count) noexcept
-      : _M_counter(__count)
-    {
-      __glibcxx_assert(__count >= 0 && __count <= _S_max);
-    }
-
-    __atomic_semaphore(const __atomic_semaphore&) = delete;
-    __atomic_semaphore& operator=(const __atomic_semaphore&) = delete;
-
-    static _GLIBCXX_ALWAYS_INLINE __detail::__platform_wait_t
-    _S_get_current(__detail::__platform_wait_t* __counter) noexcept
+    static _GLIBCXX_ALWAYS_INLINE __count_type
+    _S_get_current(__count_type* __counter) noexcept
     {
       return __atomic_impl::load(__counter, memory_order::acquire);
     }
 
     static _GLIBCXX_ALWAYS_INLINE bool
-    _S_do_try_acquire(__detail::__platform_wait_t* __counter,
-                     __detail::__platform_wait_t __old) noexcept
+    _S_do_try_acquire(__count_type* __counter, __count_type __old) noexcept
     {
       if (__old == 0)
        return false;
@@ -204,8 +86,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _M_acquire() noexcept
     {
       auto const __vfn = [this]{ return _S_get_current(&this->_M_counter); };
-      auto const __pred = [this](__detail::__platform_wait_t __cur)
-       { return _S_do_try_acquire(&this->_M_counter, __cur); };
+      auto const __pred = [this](__count_type __cur) {
+       return _S_do_try_acquire(&this->_M_counter, __cur);
+      };
       std::__atomic_wait_address(&_M_counter, __pred, __vfn, true);
     }
 
@@ -213,23 +96,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _M_try_acquire() noexcept
     {
       auto const __vfn = [this]{ return _S_get_current(&this->_M_counter); };
-      auto const __pred = [this](__detail::__platform_wait_t __cur)
-       { return _S_do_try_acquire(&this->_M_counter, __cur); };
-      return __atomic_wait_address_for(&_M_counter, __pred, __vfn,
-                                        __detail::__wait_clock_t::duration(),
-                                        true);
+      auto const __pred = [this](__count_type __cur) {
+       return _S_do_try_acquire(&this->_M_counter, __cur);
+      };
+      using __detail::__wait_clock_t;
+      return std::__atomic_wait_address_for(&_M_counter, __pred, __vfn,
+                                           __wait_clock_t::duration(),
+                                           true);
     }
 
     template<typename _Clock, typename _Duration>
       _GLIBCXX_ALWAYS_INLINE bool
-      _M_try_acquire_until(const chrono::time_point<_Clock,
-                          _Duration>& __atime) noexcept
+      _M_try_acquire_until(const chrono::time_point<_Clock, _Duration>& 
__atime) noexcept
       {
        auto const __vfn = [this]{ return _S_get_current(&this->_M_counter); };
-       auto const __pred = [this](__detail::__platform_wait_t __cur)
-        { return _S_do_try_acquire(&this->_M_counter, __cur); };
-       return std::__atomic_wait_address_until(&_M_counter,
-                                               __pred, __vfn, __atime, true);
+       auto const __pred = [this](__count_type __cur) {
+         return _S_do_try_acquire(&this->_M_counter, __cur);
+       };
+       return std::__atomic_wait_address_until(&_M_counter, __pred, __vfn,
+                                               __atime, true);
       }
 
     template<typename _Rep, typename _Period>
@@ -237,39 +122,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_try_acquire_for(const chrono::duration<_Rep, _Period>& __rtime) 
noexcept
       {
        auto const __vfn = [this]{ return _S_get_current(&this->_M_counter); };
-       auto const __pred = [this](__detail::__platform_wait_t __cur)
-        { return _S_do_try_acquire(&this->_M_counter, __cur); };
-       return std::__atomic_wait_address_for(&_M_counter,
-                                             __pred, __vfn, __rtime, true);
+       auto const __pred = [this](__count_type __cur) {
+         return _S_do_try_acquire(&this->_M_counter, __cur);
+       };
+       return std::__atomic_wait_address_for(&_M_counter, __pred, __vfn,
+                                             __rtime, true);
       }
 
-    _GLIBCXX_ALWAYS_INLINE void
+    _GLIBCXX_ALWAYS_INLINE ptrdiff_t
     _M_release(ptrdiff_t __update) noexcept
     {
-      if (0 < __atomic_impl::fetch_add(&_M_counter, __update, 
memory_order_release))
-       return;
-      if (__update > 1)
+      auto __old = __atomic_impl::fetch_add(&_M_counter, __update,
+                                           memory_order::release);
+      if (__old == 0 && __update > 0)
        __atomic_notify_address(&_M_counter, true, true);
-      else
-       __atomic_notify_address(&_M_counter, true, true);
-// FIXME - Figure out why this does not wake a waiting thread
-//     __atomic_notify_address_bare(&_M_counter, false);
+      return __old;
     }
 
   private:
-    alignas(__detail::__platform_wait_alignment)
-    __detail::__platform_wait_t _M_counter;
+    alignas(_Platform_wait ? __detail::__platform_wait_alignment
+                          : __alignof__(__count_type))
+    __count_type _M_counter;
   };
-#endif // __cpp_lib_atomic_wait
 
-// Note: the _GLIBCXX_USE_POSIX_SEMAPHORE macro can be used to force the
-// use of Posix semaphores (sem_t). Doing so however, alters the ABI.
-#if defined __glibcxx_atomic_wait && !_GLIBCXX_USE_POSIX_SEMAPHORE
-  using __semaphore_impl = __atomic_semaphore;
-#elif _GLIBCXX_HAVE_POSIX_SEMAPHORE
-  using __semaphore_impl = __platform_semaphore;
-#endif
+  template<ptrdiff_t _Max>
+    using __semaphore_impl
+      = __semaphore_base<(_Max <= __semaphore_base<true>::_S_max)>;
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
+#endif // __glibcxx_semaphore
 #endif // _GLIBCXX_SEMAPHORE_BASE_H
diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 5a981caffe9b..9ab14a0310ed 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1363,7 +1363,7 @@ ftms = {
     v = 201907;
     cxxmin = 20;
     hosted = yes;
-    extra_cond = "__glibcxx_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE";
+    extra_cond = "__glibcxx_atomic_wait";
   };
 };
 
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 06646110a914..3358e84f1607 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1499,7 +1499,7 @@
 #undef __glibcxx_want_move_iterator_concept
 
 #if !defined(__cpp_lib_semaphore)
-# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED && (__glibcxx_atomic_wait || 
_GLIBCXX_HAVE_POSIX_SEMAPHORE)
+# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED && (__glibcxx_atomic_wait)
 #  define __glibcxx_semaphore 201907L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_semaphore)
 #   define __cpp_lib_semaphore 201907L
diff --git a/libstdc++-v3/include/std/semaphore 
b/libstdc++-v3/include/std/semaphore
index bec5ac301aa2..ca1bffe371a0 100644
--- a/libstdc++-v3/include/std/semaphore
+++ b/libstdc++-v3/include/std/semaphore
@@ -35,29 +35,29 @@
 
 #include <bits/requires_hosted.h> // concurrency
 
-#if __cplusplus > 201703L
-#include <bits/semaphore_base.h>
-
 #define __glibcxx_want_semaphore
 #include <bits/version.h>
 
-#ifdef __cpp_lib_semaphore // C++ >= 20 && hosted && (atomic_wait || posix_sem)
+#ifdef __cpp_lib_semaphore // C++ >= 20 && hosted && atomic_wait
+#include <bits/semaphore_base.h>
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  template<ptrdiff_t __least_max_value = __semaphore_impl::_S_max>
+  template<ptrdiff_t __least_max_value = __semaphore_base<true>::_S_max>
     class counting_semaphore
     {
       static_assert(__least_max_value >= 0);
-      static_assert(__least_max_value <= __semaphore_impl::_S_max);
 
-      __semaphore_impl _M_sem;
+      using _Impl = __semaphore_impl<__least_max_value>;
+      _Impl _M_sem;
 
     public:
-      explicit counting_semaphore(ptrdiff_t __desired) noexcept
-       : _M_sem(__desired)
-      { }
+      constexpr explicit
+      counting_semaphore(ptrdiff_t __desired) noexcept
+      : _M_sem(__desired)
+      { __glibcxx_assert(__desired >= 0 && __desired <= max()); }
 
       ~counting_semaphore() = default;
 
@@ -69,8 +69,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return __least_max_value; }
 
       void
-      release(ptrdiff_t __update = 1) noexcept(noexcept(_M_sem._M_release(1)))
-      { _M_sem._M_release(__update); }
+      release(ptrdiff_t __update = 1) noexcept
+      {
+       [[maybe_unused]] ptrdiff_t __old = _M_sem._M_release(__update);
+       __glibcxx_assert(__update >= 0 && __update <= max() - __old);
+      }
 
       void
       acquire() noexcept(noexcept(_M_sem._M_acquire()))
@@ -91,10 +94,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        { return _M_sem._M_try_acquire_until(__atime); }
     };
 
+  /** @brief A binary semaphore
+   *
+   * @since C++20
+   */
   using binary_semaphore = std::counting_semaphore<1>;
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
-#endif // cpp_lib_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE
 #endif // __cpp_lib_semaphore
 #endif // _GLIBCXX_SEMAPHORE
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
index c770f05be009..4b761cef2024 100644
--- a/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
@@ -12,7 +12,7 @@
 #include <chrono>
 #include <vector>
 
-std::counting_semaphore<4> semaphore{6};
+std::counting_semaphore<6> semaphore{6};
 
 std::mutex mtx;
 std::vector<std::string> results;
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc
new file mode 100644
index 000000000000..920f7423332b
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/cons.cc
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++20 } }
+
+#include <semaphore>
+
+// PR 110854 Constructor of std::counting_semaphore is not constexpr
+constinit std::binary_semaphore b(0);
+constinit std::counting_semaphore<5> c(2);
diff --git 
a/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
deleted file mode 100644
index 6d90564ea8ac..000000000000
--- a/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-// { dg-options "-D_GLIBCXX_USE_POSIX_SEMAPHORE" }
-// { dg-do run { target c++20 } }
-// { dg-additional-options "-pthread" { target pthread } }
-// { dg-require-gthreads "" }
-// { dg-add-options libatomic }
-
-#include "try_acquire_for.cc"
-
-// { dg-prune-output "ignoring _GLIBCXX_USE_POSIX_SEMAPHORE" }
diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
deleted file mode 100644
index cf5745584c8d..000000000000
--- a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-do run { target c++20 } }
-// { dg-additional-options "-pthread" { target pthread } }
-// { dg-require-gthreads "" }
-// { dg-add-options libatomic }
-
-#include <semaphore>
-#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
-#include <chrono>
-#include <thread>
-#include <atomic>
-#include <testsuite_hooks.h>
-
-void test01()
-{
-  using namespace std::chrono_literals;
-  std::__platform_semaphore s(2);
-  s._M_acquire();
-
-  auto const dur = 250ms;
-  {
-    auto const t0 = std::chrono::steady_clock::now();
-    VERIFY( s._M_try_acquire_for(dur) );
-    auto const diff = std::chrono::steady_clock::now() - t0;
-    VERIFY( diff < dur );
-  }
-
-  {
-    auto const t0 = std::chrono::steady_clock::now();
-    VERIFY( !s._M_try_acquire_for(dur) );
-    auto const diff = std::chrono::steady_clock::now() - t0;
-    VERIFY( diff >= dur );
-  }
-}
-
-void test02()
-{
-  using namespace std::chrono_literals;
-  std::__platform_semaphore s(1);
-  std::atomic<int> a(0), b(0);
-  std::thread t([&] {
-    a.wait(0);
-    auto const dur = 250ms;
-    VERIFY( !s._M_try_acquire_for(dur) );
-    b++;
-    b.notify_one();
-
-    a.wait(1);
-    VERIFY( s._M_try_acquire_for(dur) );
-    b++;
-    b.notify_one();
-  });
-  t.detach();
-
-  s._M_acquire();
-  a++;
-  a.notify_one();
-  b.wait(0);
-  s._M_release(1);
-  a++;
-  a.notify_one();
-
-  b.wait(1);
-}
-
-void test03()
-{
-  using namespace std::chrono_literals;
-  std::__platform_semaphore s(2);
-  s._M_acquire();
-
-  auto const dur = 250ms;
-  {
-    auto const at = std::chrono::system_clock::now() + dur;
-    auto const t0 = std::chrono::steady_clock::now();
-    VERIFY( s._M_try_acquire_until(at) );
-    auto const diff = std::chrono::steady_clock::now() - t0;
-    VERIFY( diff < dur );
-  }
-
-  {
-    auto const at = std::chrono::system_clock::now() + dur;
-    auto const t0 = std::chrono::steady_clock::now();
-    VERIFY( !s._M_try_acquire_until(at) );
-    auto const diff = std::chrono::steady_clock::now() - t0;
-    VERIFY( diff >= dur );
-  }
-}
-
-void test04()
-{
-  using namespace std::chrono_literals;
-  std::__platform_semaphore s(1);
-  std::atomic<int> a(0), b(0);
-  std::thread t([&] {
-    a.wait(0);
-    auto const dur = 250ms;
-    {
-      auto const at = std::chrono::system_clock::now() + dur;
-      VERIFY( !s._M_try_acquire_until(at) );
-
-      b++;
-      b.notify_one();
-    }
-
-    a.wait(1);
-    {
-      auto const at = std::chrono::system_clock::now() + dur;
-      VERIFY( s._M_try_acquire_until(at) );
-    }
-    b++;
-    b.notify_one();
-  });
-  t.detach();
-
-  s._M_acquire();
-  a++;
-  a.notify_one();
-  b.wait(0);
-  s._M_release(1);
-  a++;
-  a.notify_one();
-
-  b.wait(1);
-}
-#endif
-
-int main()
-{
-#ifdef _GLIBCXX_HAVE_POSIX_SEMAPHORE
-  test01();
-  test02();
-  test03();
-  test04();
-#endif
-  return 0;
-}
-- 
2.49.0

Reply via email to