{"id":2225760,"url":"http://patchwork.ozlabs.org/api/patches/2225760/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/patch/20260421144257.1000552-1-jwakely@redhat.com/","project":{"id":17,"url":"http://patchwork.ozlabs.org/api/projects/17/?format=json","name":"GNU Compiler Collection","link_name":"gcc","list_id":"gcc-patches.gcc.gnu.org","list_email":"gcc-patches@gcc.gnu.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260421144257.1000552-1-jwakely@redhat.com>","list_archive_url":null,"date":"2026-04-21T14:42:18","name":"libstdc++: Add platform wait functions for Darwin [PR120527]","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"99ecdae2154587c7600880fb32c3976cadad7572","submitter":{"id":48004,"url":"http://patchwork.ozlabs.org/api/people/48004/?format=json","name":"Jonathan Wakely","email":"jwakely@redhat.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/gcc/patch/20260421144257.1000552-1-jwakely@redhat.com/mbox/","series":[{"id":500827,"url":"http://patchwork.ozlabs.org/api/series/500827/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/list/?series=500827","date":"2026-04-21T14:42:18","name":"libstdc++: Add platform wait functions for Darwin [PR120527]","version":1,"mbox":"http://patchwork.ozlabs.org/series/500827/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2225760/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2225760/checks/","tags":{},"related":[],"headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=XA+OwyDS;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=XA+OwyDS","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0Q8R1xX1z1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 00:43:33 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 1D9EA4BA901C\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 14:43:32 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id CC6E84BA2E09\n for <gcc-patches@gcc.gnu.org>; Tue, 21 Apr 2026 14:43:03 +0000 (GMT)","from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-259-DLK4BsftMWuREG-iNzyLpw-1; Tue,\n 21 Apr 2026 10:43:01 -0400","from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 4D9D61800366; Tue, 21 Apr 2026 14:43:00 +0000 (UTC)","from zen.kayari.org (unknown [10.44.50.46])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 9B43F3000C21; Tue, 21 Apr 2026 14:42:58 +0000 (UTC)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 1D9EA4BA901C","OpenDKIM Filter v2.11.0 sourceware.org CC6E84BA2E09"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org CC6E84BA2E09","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org CC6E84BA2E09","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776782583; cv=none;\n b=xU1u8yJJzCtB1+RE4mT5qae9UNzN1ckhiNkZ/F3gYjKvvlUP2FfrkTUjOq4Wq9rHbfEs7vCd0jXZz1slJX7pB8gx0q8RJYarkHmV0UCgZ+dkMBQ5pQilD6bpBj94hmWlRx194dBNsNhz9HddU3G7hddfb4/myF2f2F5QkzoTl8M=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776782583; c=relaxed/simple;\n bh=36RMx7S3MWmt/zx4eV01MuGOIRrpyPP5NPYXWglT0Ys=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=oPJlTTY/9iIL+g11e1ZoyZgmI/KDXh5tFFk8joT2RfeTuVwV0I7CIgrRHYn6Uz1gVpFoInVHg4WoWnKrCumSog34GLN37m7S1rro6Je+yB9sf9fGw+WJX5nR3pzaoGh19mnwX0iituQfGtvvn7Wb7JrhhIomp4oWsLuCdvXRbyw=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776782583;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=wNpWHxruiMcHJFKEioyhf30HWzV5bBZ/E28hS1NIqJk=;\n b=XA+OwyDSle+aSyUXmju0CJcR6QT7AcNoZHEaF3nXOEYyy1rTRV0/Np0soEBJ7sjpERqR8a\n m05OS32GtmMLu8VCHVniXrTDEsP+mo9kDMdgr6Do82mPaGe1z8IMdphL/GG3lXL7suDpz6\n /7JzptkOZ5Lo31kefRjKrXdIehJMqhY=","X-MC-Unique":"DLK4BsftMWuREG-iNzyLpw-1","X-Mimecast-MFC-AGG-ID":"DLK4BsftMWuREG-iNzyLpw_1776782581","From":"Jonathan Wakely <jwakely@redhat.com>","To":"gcc-patches@gcc.gnu.org,\n\tlibstdc++@gcc.gnu.org","Cc":"Iain Sandoe <iain@sandoe.co.uk>","Subject":"[PATCH] libstdc++: Add platform wait functions for Darwin [PR120527]","Date":"Tue, 21 Apr 2026 15:42:18 +0100","Message-ID":"<20260421144257.1000552-1-jwakely@redhat.com>","MIME-Version":"1.0","X-Scanned-By":"MIMEDefang 3.4.1 on 10.30.177.4","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"TcZiEkRS-AEE9BSIZPjx0DWMNLLJJE9XnrTuKY0Zvxc_1776782581","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","Content-Transfer-Encoding":"8bit","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"},"content":"Darwin has kernel support for this facility from 10.12 (macOS Sierra).\n\nFrom 10.15 (macOS Catalina) 64bit qualitities are supported.\n\nWhen the library is built for 10.12+ both 32b and 64b quantities will be\nsupported by the DSO which means it can be installed on 10.12+ with support\nfor 64bit available when the instalation is >= 10.15.\n\nThe header will only recognise 64b quantities when the deployment version\nis >= 10.15.\n\nIf the library is built for <= 10.11, the support will be missing and attempts\nto use it wlll result in link errors.\n\nThe platform wait type is unconditionally set to 32bits, since this is compatible\nacross supported OS editions.\n\n\tPR libstdc++/120527\n\nlibstdc++-v3/ChangeLog:\n\n\t* include/bits/atomic_wait.h:\n\t* src/c++20/atomic.cc (__ulock_wait): Enable supported Darwin versions.\n\t(__ulock_wake): Likewise.\n\t(UL_COMPARE_AND_WAIT): New.\n\t(UL_COMPARE_AND_WAIT64): New.\n\t(ULF_WAKE_ALL): New.\n\t(_GLIBCXX_HAVE_PLATFORM_WAIT): Enable for suppported Darwin versions.\n\nCo-authored-by: Iain Sandoe <iain@sandoe.co.uk>\nSigned-off-by: Iain Sandoe <iain@sandoe.co.uk>\n---\n\nTested x86_64-linux and various darwin systems (by Iain).\n\nPushed to trunk.\n\n libstdc++-v3/include/bits/atomic_wait.h | 21 +++++++\n libstdc++-v3/src/c++20/atomic.cc        | 74 +++++++++++++++++++++++++\n 2 files changed, 95 insertions(+)","diff":"diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h\nindex 47bd1073f881..704c10d5f382 100644\n--- a/libstdc++-v3/include/bits/atomic_wait.h\n+++ b/libstdc++-v3/include/bits/atomic_wait.h\n@@ -69,6 +69,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n     inline constexpr bool __platform_wait_uses_type\n       = __detail::__waitable<_Tp>\n \t  && sizeof(_Tp) == sizeof(int) && alignof(_Tp) >= 4;\n+#elif defined __APPLE__ \\\n+      && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200\n+  namespace __detail\n+  {\n+    using __platform_wait_t = __INT32_TYPE__;\n+    inline constexpr size_t __platform_wait_alignment = 4;\n+  }\n+  // Defined to true for a subset of __waitable types which are statically\n+  // known to definitely be able to use __ulock_wait, not a proxy wait.\n+  // We know that OS Versions later than 10.15 support 64b wait types even\n+  // though we must make the __platform_wait_t 32b for compatibility with\n+  // earlier versions of __ulock_xxxx.\n+  template<typename _Tp>\n+    inline constexpr bool __platform_wait_uses_type\n+      = __detail::__waitable<_Tp>\n+#  if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500\n+\t  && sizeof(_Tp) == 4 && alignof(_Tp) >= 4;\n+#  else\n+\t  && ((sizeof(_Tp) == 4 && alignof(_Tp) >= 4)\n+\t\t|| (sizeof(_Tp) == 8 && alignof(_Tp) >= 8));\n+#  endif\n #elif defined __FreeBSD__ && __SIZEOF_LONG__ == 8\n   namespace __detail\n   {\ndiff --git a/libstdc++-v3/src/c++20/atomic.cc b/libstdc++-v3/src/c++20/atomic.cc\nindex 177c503330d5..3e02f437db3c 100644\n--- a/libstdc++-v3/src/c++20/atomic.cc\n+++ b/libstdc++-v3/src/c++20/atomic.cc\n@@ -27,6 +27,7 @@\n #if __glibcxx_atomic_wait\n #include <atomic>\n #include <bits/atomic_timed_wait.h>\n+#include <utility> // cmp_less\n #include <cstdint> // uint32_t, uint64_t, uintptr_t\n #include <climits> // INT_MAX\n #include <cerrno>  // errno, ETIMEDOUT, etc.\n@@ -39,6 +40,19 @@\n # include <unistd.h>\n # include <sys/time.h> // timespec\n # define _GLIBCXX_HAVE_PLATFORM_WAIT 1\n+#elif defined __APPLE__ \\\n+      && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200\n+// These are thin wrappers over the underlying syscall, they exist on\n+// earlier versions of the OS, however those versions do not support the\n+// UL_COMPARE_AND_WAIT64 operation.\n+extern \"C\" int\n+__ulock_wait(uint32_t operation, void* addr, uint64_t value, uint32_t timeout);\n+extern \"C\" int\n+__ulock_wake(uint32_t operation, void* addr, uint64_t wake_value);\n+# define UL_COMPARE_AND_WAIT             1\n+# define UL_COMPARE_AND_WAIT64          5\n+# define ULF_WAKE_ALL                    0x00000100\n+# define _GLIBCXX_HAVE_PLATFORM_WAIT 1\n #elif defined __FreeBSD__ && __FreeBSD__ >= 11 && __SIZEOF_LONG__ == 8\n # include <sys/types.h>\n # include <sys/umtx.h>\n@@ -154,6 +168,66 @@ namespace\n   __platform_load(const int* addr, int order, int /* obj_sz */) noexcept\n   { return __atomic_load_n(addr, order); }\n \n+#elif defined __APPLE__ \\\n+      && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200\n+\n+  [[gnu::always_inline]]\n+  inline uint32_t\n+  wait_op(int obj_sz) noexcept\n+  {\n+    __glibcxx_assert(obj_sz == 4 || obj_sz == 8);\n+    return obj_sz == 4 ? UL_COMPARE_AND_WAIT : UL_COMPARE_AND_WAIT64;\n+  }\n+\n+  void\n+  __platform_wait(const void* addr, uint64_t val, int obj_sz) noexcept\n+  {\n+    if (0 > __ulock_wait(wait_op(obj_sz), const_cast<void*>(addr), val, 0))\n+      if (errno != EINTR && errno != EFAULT)\n+\t__throw_system_error(errno);\n+  }\n+\n+  void\n+  __platform_notify(const void* addr, bool all, int obj_sz) noexcept\n+  {\n+    uint32_t op = wait_op (obj_sz);\n+    if (all)\n+      op |= ULF_WAKE_ALL;\n+    __ulock_wake(op, const_cast<void*>(addr), 0);\n+  }\n+\n+  // returns true if wait ended before timeout\n+  bool\n+  __platform_wait_until(const void* addr, uint64_t val,\n+\t\t\tconst __wait_clock_t::time_point& atime,\n+\t\t\tint obj_sz) noexcept\n+  {\n+    auto reltime\n+      = chrono::ceil<chrono::microseconds>(atime - __wait_clock_t::now());\n+    if (reltime <= reltime.zero())\n+      return false;\n+    uint32_t timeout = numeric_limits<uint32_t>::max();\n+    if (std::cmp_less(reltime.count(), timeout))\n+       timeout = reltime.count();\n+\n+    if (0 > __ulock_wait(wait_op(obj_sz), const_cast<void*>(addr), val,\n+\t\t\t timeout))\n+      {\n+\tif (errno == ETIMEDOUT)\n+\t  return timeout == numeric_limits<uint32_t>::max();\n+\tif (errno != EINTR && errno != EFAULT)\n+\t  __throw_system_error(errno);\n+      }\n+    return true;\n+  }\n+\n+  // ??? CHECKME: this could likely be more efficient.\n+  [[gnu::always_inline]]\n+  inline __wait_value_type\n+  __platform_load(const __platform_wait_t* addr, int memory_order,\n+\t\t  int /* obj_sz */) noexcept\n+  { return __atomic_load_n(addr, memory_order); }\n+\n #elif defined __FreeBSD__ && __SIZEOF_LONG__ == 8\n   [[gnu::always_inline]]\n   inline int\n","prefixes":[]}