[libcxx-commits] [libcxx] [libc++] Assume that <atomic> is available (PR #199674)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 5 07:23:06 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/199674

>From 9bc798ea4dbbc5651ff3c7e7c679671092627ab1 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 26 May 2026 15:18:34 +0200
Subject: [PATCH] [libc++] Assume that <atomic> is available

---
 libcxx/include/__atomic/atomic_flag.h     | 30 +++++++++----------
 libcxx/include/__atomic/support.h         |  4 +--
 libcxx/include/__config                   | 19 ------------
 libcxx/include/__memory/shared_ptr.h      |  4 +--
 libcxx/include/atomic                     |  4 ---
 libcxx/modules/std.cppm.in                |  4 +--
 libcxx/src/memory_resource.cpp            | 35 +----------------------
 libcxx/utils/generate_libcxx_cppm_in.py   | 12 +-------
 libcxx/utils/libcxx/header_information.py |  6 ----
 libcxx/utils/libcxx/test/modules.py       | 11 +------
 10 files changed, 21 insertions(+), 108 deletions(-)

diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h
index 7c09870867b70..9c3dd13d132d4 100644
--- a/libcxx/include/__atomic/atomic_flag.h
+++ b/libcxx/include/__atomic/atomic_flag.h
@@ -23,34 +23,34 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct atomic_flag {
-  __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
+  __cxx_atomic_impl<bool> __a_;
 
   _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
-    return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
+    return __cxx_atomic_load(&__a_, __m);
   }
   _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
-    return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
+    return __cxx_atomic_load(&__a_, __m);
   }
 
   _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
-    return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
+    return __cxx_atomic_exchange(&__a_, true, __m);
   }
   _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
-    return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
+    return __cxx_atomic_exchange(&__a_, true, __m);
   }
   _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
-    __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
+    __cxx_atomic_store(&__a_, false, __m);
   }
   _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
-    __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
+    __cxx_atomic_store(&__a_, false, __m);
   }
 
 #if _LIBCPP_STD_VER >= 20
   _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
-    std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
+    std::__atomic_wait(*this, __v, __m);
   }
   _LIBCPP_HIDE_FROM_ABI void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
-    std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
+    std::__atomic_wait(*this, __v, __m);
   }
   _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { std::__atomic_notify_one(*this); }
   _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
@@ -74,23 +74,21 @@ struct atomic_flag {
 #if _LIBCPP_STD_VER >= 20
 template <>
 struct __atomic_waitable_traits<atomic_flag> {
-  using __value_type _LIBCPP_NODEBUG = _LIBCPP_ATOMIC_FLAG_TYPE;
+  using __value_type _LIBCPP_NODEBUG = bool;
 
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
+  static _LIBCPP_HIDE_FROM_ABI bool __atomic_load(const atomic_flag& __a, memory_order __order) {
     return std::__cxx_atomic_load(&__a.__a_, __order);
   }
 
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE
-  __atomic_load(const volatile atomic_flag& __a, memory_order __order) {
+  static _LIBCPP_HIDE_FROM_ABI bool __atomic_load(const volatile atomic_flag& __a, memory_order __order) {
     return std::__cxx_atomic_load(&__a.__a_, __order);
   }
 
-  static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
-  __atomic_contention_address(const atomic_flag& __a) {
+  static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<bool>* __atomic_contention_address(const atomic_flag& __a) {
     return std::addressof(__a.__a_);
   }
 
-  static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
+  static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<bool>*
   __atomic_contention_address(const volatile atomic_flag& __a) {
     return std::addressof(__a.__a_);
   }
diff --git a/libcxx/include/__atomic/support.h b/libcxx/include/__atomic/support.h
index 99d0f6aa543ca..053ad54aa6ce5 100644
--- a/libcxx/include/__atomic/support.h
+++ b/libcxx/include/__atomic/support.h
@@ -102,9 +102,9 @@
 // clang-format on
 //
 
-#if _LIBCPP_HAS_GCC_ATOMIC_IMP
+#ifdef _LIBCPP_COMPILER_GCC
 #  include <__atomic/support/gcc.h>
-#elif _LIBCPP_HAS_C_ATOMIC_IMP
+#else
 #  include <__atomic/support/c11.h>
 #endif
 
diff --git a/libcxx/include/__config b/libcxx/include/__config
index a6e94b6ff70ea..9172166b16b87 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -381,25 +381,6 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
 #  endif
 
-#  if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic)
-#    define _LIBCPP_HAS_C_ATOMIC_IMP 1
-#    define _LIBCPP_HAS_GCC_ATOMIC_IMP 0
-#    define _LIBCPP_HAS_EXTERNAL_ATOMIC_IMP 0
-#  elif defined(_LIBCPP_COMPILER_GCC)
-#    define _LIBCPP_HAS_C_ATOMIC_IMP 0
-#    define _LIBCPP_HAS_GCC_ATOMIC_IMP 1
-#    define _LIBCPP_HAS_EXTERNAL_ATOMIC_IMP 0
-#  endif
-
-#  if !_LIBCPP_HAS_C_ATOMIC_IMP && !_LIBCPP_HAS_GCC_ATOMIC_IMP && !_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP
-#    define _LIBCPP_HAS_ATOMIC_HEADER 0
-#  else
-#    define _LIBCPP_HAS_ATOMIC_HEADER 1
-#    ifndef _LIBCPP_ATOMIC_FLAG_TYPE
-#      define _LIBCPP_ATOMIC_FLAG_TYPE bool
-#    endif
-#  endif
-
 // We often repeat things just for handling wide characters in the library.
 // When wide characters are disabled, it can be useful to have a quick way of
 // disabling it without having to resort to #if-#endif, which has a larger
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 66442c8868005..0081752f392db 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -10,6 +10,7 @@
 #ifndef _LIBCPP___MEMORY_SHARED_PTR_H
 #define _LIBCPP___MEMORY_SHARED_PTR_H
 
+#include <__atomic/memory_order.h>
 #include <__compare/compare_three_way.h>
 #include <__compare/ordering.h>
 #include <__config>
@@ -59,9 +60,6 @@
 #include <__utility/swap.h>
 #include <__verbose_abort>
 #include <typeinfo>
-#if _LIBCPP_HAS_ATOMIC_HEADER
-#  include <__atomic/memory_order.h>
-#endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index ec40a0883f152..a6a910c2f380f 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -626,10 +626,6 @@ template <class T>
 #    pragma GCC system_header
 #  endif
 
-#  if !_LIBCPP_HAS_ATOMIC_HEADER
-#    error <atomic> is not implemented
-#  endif
-
 #  if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 20
 #    include <cmath>
 #    include <compare>
diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in
index 984b18321923c..6de6369c3387f 100644
--- a/libcxx/modules/std.cppm.in
+++ b/libcxx/modules/std.cppm.in
@@ -20,9 +20,7 @@ module;
 #include <algorithm>
 #include <any>
 #include <array>
-#if _LIBCPP_HAS_ATOMIC_HEADER
-#  include <atomic>
-#endif
+#include <atomic>
 #include <barrier>
 #include <bit>
 #include <bitset>
diff --git a/libcxx/src/memory_resource.cpp b/libcxx/src/memory_resource.cpp
index 00307e107faa6..c58e4a3790b25 100644
--- a/libcxx/src/memory_resource.cpp
+++ b/libcxx/src/memory_resource.cpp
@@ -6,19 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <atomic>
 #include <cstddef>
 #include <memory>
 #include <memory_resource>
 
-#if _LIBCPP_HAS_ATOMIC_HEADER
-#  include <atomic>
-#elif _LIBCPP_HAS_THREADS
-#  include <mutex>
-#  if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
-#    pragma comment(lib, "pthread")
-#  endif
-#endif
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
@@ -95,7 +87,6 @@ memory_resource* null_memory_resource() noexcept { return &res_init.resources.nu
 // default_memory_resource()
 
 static memory_resource* __default_memory_resource(bool set = false, memory_resource* new_res = nullptr) noexcept {
-#if _LIBCPP_HAS_ATOMIC_HEADER
   static constinit atomic<memory_resource*> __res{&res_init.resources.new_delete_res};
   if (set) {
     new_res = new_res ? new_res : new_delete_resource();
@@ -104,30 +95,6 @@ static memory_resource* __default_memory_resource(bool set = false, memory_resou
   } else {
     return std::atomic_load_explicit(&__res, memory_order_acquire);
   }
-#elif _LIBCPP_HAS_THREADS
-  static constinit memory_resource* res = &res_init.resources.new_delete_res;
-  static mutex res_lock;
-  if (set) {
-    new_res = new_res ? new_res : new_delete_resource();
-    lock_guard<mutex> guard(res_lock);
-    memory_resource* old_res = res;
-    res                      = new_res;
-    return old_res;
-  } else {
-    lock_guard<mutex> guard(res_lock);
-    return res;
-  }
-#else
-  static constinit memory_resource* res = &res_init.resources.new_delete_res;
-  if (set) {
-    new_res                  = new_res ? new_res : new_delete_resource();
-    memory_resource* old_res = res;
-    res                      = new_res;
-    return old_res;
-  } else {
-    return res;
-  }
-#endif
 }
 
 memory_resource* get_default_resource() noexcept { return __default_memory_resource(); }
diff --git a/libcxx/utils/generate_libcxx_cppm_in.py b/libcxx/utils/generate_libcxx_cppm_in.py
index 26d680a0db31f..fac33f74812a7 100644
--- a/libcxx/utils/generate_libcxx_cppm_in.py
+++ b/libcxx/utils/generate_libcxx_cppm_in.py
@@ -12,7 +12,6 @@
 from libcxx.header_information import (
     module_c_headers,
     module_headers,
-    header_restrictions,
     headers_not_available,
     libcxx_root,
 )
@@ -46,16 +45,7 @@ def write_file(module):
 """
         )
         for header in sorted(module_headers if module == "std" else module_c_headers):
-            if header in header_restrictions:
-                module_cpp_in.write(
-                    f"""\
-#if {header_restrictions[header]}
-#  include <{header}>
-#endif
-"""
-                )
-            else:
-                module_cpp_in.write(f"#include <{header}>\n")
+            module_cpp_in.write(f"#include <{header}>\n")
 
         module_cpp_in.write(
             """
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index d06271a7908cc..384ff9f759460 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -175,12 +175,6 @@ def __hash__(self) -> int:
     "text_encoding",
 ]))
 
-header_restrictions = {
-    # headers with #error directives
-    "atomic": "_LIBCPP_HAS_ATOMIC_HEADER",
-    "stdatomic.h": "_LIBCPP_HAS_ATOMIC_HEADER",
-}
-
 lit_header_restrictions = {
     "barrier": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
     "coroutine": "// UNSUPPORTED: c++03, c++11, c++14, c++17",
diff --git a/libcxx/utils/libcxx/test/modules.py b/libcxx/utils/libcxx/test/modules.py
index 4076379c41276..4aff04864e2d1 100644
--- a/libcxx/utils/libcxx/test/modules.py
+++ b/libcxx/utils/libcxx/test/modules.py
@@ -7,7 +7,6 @@
 # ===----------------------------------------------------------------------===##
 
 from libcxx.header_information import module_headers
-from libcxx.header_information import header_restrictions
 from dataclasses import dataclass
 
 ### SkipDeclarations
@@ -141,15 +140,7 @@ def process_module_partition(self, header, is_c_header):
         # Some headers cannot be included when a libc++ feature is disabled.
         # In that case include the header conditionally. The header __config
         # ensures the libc++ feature macros are available.
-        if header in header_restrictions:
-            include = (
-                f"#include <__config>{nl}"
-                f"#if {header_restrictions[header]}{nl}"
-                f"#  include <{header}>{nl}"
-                f"#endif{nl}"
-            )
-        else:
-            include = f"#include <{header}>{nl}"
+        include = f"#include <{header}>{nl}"
 
         module_files = f'#include \\"{self.module_path}/std/{header}.inc\\"{nl}'
         if is_c_header:



More information about the libcxx-commits mailing list