[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