[libc-commits] [libc] [llvm] [libc] Moves __cxa_thread_atexit_impl into proper entrypoint (PR #229347)
via libc-commits
libc-commits at lists.llvm.org
Tue Oct 6 23:22:14 PDT 2026
https://github.com/shri-acha updated https://github.com/llvm/llvm-project/pull/229347
>From 289b2bd0f907beb3a00aa85698c91116e50097ea Mon Sep 17 00:00:00 2001
From: Shriharsh Acharya <happy.irhs at gmail.com>
Date: Tue, 6 Oct 2026 14:46:39 +0545
Subject: [PATCH 1/3] feat: introduce __cxa_thread_atexit_impl into as a libc
entry point
---
CMakeFiles/Progress/count.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/src/__support/threads/thread.cpp | 8 ++---
libc/src/__support/threads/thread.h | 8 +++--
libc/src/threads/CMakeLists.txt | 10 ++++++
libc/src/threads/__cxa_thread_atexit_impl.cpp | 33 +++++++++++++++++++
libc/src/threads/__cxa_thread_atexit_impl.h | 22 +++++++++++++
7 files changed, 76 insertions(+), 7 deletions(-)
create mode 100644 CMakeFiles/Progress/count.txt
create mode 100644 libc/src/threads/__cxa_thread_atexit_impl.cpp
create mode 100644 libc/src/threads/__cxa_thread_atexit_impl.h
diff --git a/CMakeFiles/Progress/count.txt b/CMakeFiles/Progress/count.txt
new file mode 100644
index 00000000000000..38b10c1b2badd8
--- /dev/null
+++ b/CMakeFiles/Progress/count.txt
@@ -0,0 +1 @@
+68
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 7928a35a6284a5..48326462a1d99f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1592,6 +1592,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.twalk_r
# threads.h entrypoints
+ libc.src.threads.__cxa_thread_atexit_impl
libc.src.threads.call_once
libc.src.threads.cnd_broadcast
libc.src.threads.cnd_destroy
diff --git a/libc/src/__support/threads/thread.cpp b/libc/src/__support/threads/thread.cpp
index 950dea837d0f97..9644c50c9793a5 100644
--- a/libc/src/__support/threads/thread.cpp
+++ b/libc/src/__support/threads/thread.cpp
@@ -139,17 +139,15 @@ class ThreadAtExitCallbackMgr {
static LIBC_THREAD_LOCAL ThreadAtExitCallbackMgr atexit_callback_mgr;
+int add_thread_atexit_callback(AtExitCallback *callback, void *obj) {
+ return atexit_callback_mgr.add_callback(callback, obj);
+}
// The function __cxa_thread_atexit is provided by C++ runtimes like libcxxabi.
// It is used by thread local object runtime to register destructor calls. To
// actually register destructor call with the threading library, it calls
// __cxa_thread_atexit_impl, which is to be provided by the threading library.
// The semantics are very similar to the __cxa_atexit function except for the
// fact that the registered callback is thread specific.
-extern "C" int __cxa_thread_atexit_impl(AtExitCallback *callback, void *obj,
- void *) {
- return atexit_callback_mgr.add_callback(callback, obj);
-}
-
namespace internal {
void call_atexit_callbacks() {
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index 56cca8e3c915cb..746e1dcda13a7f 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -175,11 +175,15 @@ namespace internal {
// implementing the thread_exit function.
void call_atexit_callbacks();
-} // namespace internal
+}//internal namespace
+
+using AtExitCallback = void(void *);
+
+int add_thread_atexit_callback(AtExitCallback *callback, void *obj);
LIBC_INLINE Thread current_thread() {
return Thread(get_current_thread_attrib());
-}
+ }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/threads/CMakeLists.txt b/libc/src/threads/CMakeLists.txt
index 56247204c30f90..90ddbaadd5190e 100644
--- a/libc/src/threads/CMakeLists.txt
+++ b/libc/src/threads/CMakeLists.txt
@@ -179,6 +179,16 @@ add_entrypoint_object(
libc.src.__support.threads.mutex
)
+add_entrypoint_object(
+ __cxa_thread_atexit_impl
+ SRCS
+ __cxa_thread_atexit_impl.cpp
+ HDRS
+ __cxa_thread_atexit_impl.h
+ DEPENDS
+ libc.src.__support.threads.thread
+)
+
add_entrypoint_object(
cnd_init
ALIAS
diff --git a/libc/src/threads/__cxa_thread_atexit_impl.cpp b/libc/src/threads/__cxa_thread_atexit_impl.cpp
new file mode 100644
index 00000000000000..67b387ab76fdb3
--- /dev/null
+++ b/libc/src/threads/__cxa_thread_atexit_impl.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of __cxa_thread_atexit_impl
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/threads/__cxa_thread_atexit_impl.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/thread.h"
+
+#include <threads.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+// The function __cxa_thread_atexit is provided by C++ runtimes like libcxxabi.
+// It is used by thread local object runtime to register destructor calls. To
+// actually register destructor call with the threading library, it calls
+// __cxa_thread_atexit_impl, which is to be provided by the threading library.
+// The semantics are very similar to the __cxa_atexit function except for the
+// fact that the registered callback is thread specific.
+LLVM_LIBC_FUNCTION(int, __cxa_thread_atexit_impl,
+ (AtExitCallback* callback, void *obj, void *)) {
+ return add_thread_atexit_callback(callback, obj);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/threads/__cxa_thread_atexit_impl.h b/libc/src/threads/__cxa_thread_atexit_impl.h
new file mode 100644
index 00000000000000..729498b409a82e
--- /dev/null
+++ b/libc/src/threads/__cxa_thread_atexit_impl.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for __cxa_thread_atexit_impl function ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___THREADS_CXA_THREAD_ATEXIT_IMPL_H
+#define LLVM_LIBC_SRC___THREADS_CXA_THREAD_ATEXIT_IMPL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/thread.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int __cxa_thread_atexit_impl(AtExitCallback *callback, void *obj,
+ void *);
+}// namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_THREADS_CXA_THREAD_ATEXIT_IMPL_H
+
>From e560c23de195facd3afe12b67872f84a24e3a63e Mon Sep 17 00:00:00 2001
From: Shriharsh Acharya <happy.irhs at gmail.com>
Date: Wed, 7 Oct 2026 08:55:37 +0545
Subject: [PATCH 2/3] fix: moved out the implementation and headers from
threads to stdlib
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 2 +-
libc/src/__support/threads/thread.cpp | 6 ------
libc/src/stdlib/CMakeLists.txt | 10 ++++++++++
.../{threads => stdlib}/__cxa_thread_atexit_impl.cpp | 11 ++++-------
.../{threads => stdlib}/__cxa_thread_atexit_impl.h | 11 ++++-------
libc/src/threads/CMakeLists.txt | 10 ----------
8 files changed, 21 insertions(+), 31 deletions(-)
rename libc/src/{threads => stdlib}/__cxa_thread_atexit_impl.cpp (81%)
rename libc/src/{threads => stdlib}/__cxa_thread_atexit_impl.h (58%)
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index c7ded2fade05d9..b31ba2dc55d68c 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -223,6 +223,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdbit.stdc_trailing_zeros_us
# stdlib.h entrypoints
+ libc.src.stdlib.__cxa_thread_atexit_impl
libc.src.stdlib.abs
libc.src.stdlib.atof
libc.src.stdlib.atoi
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 296985eeff937c..8743969bf97537 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1507,6 +1507,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdio.ungetc
# stdlib.h entrypoints
+ libc.src.stdlib.__cxa_thread_atexit_impl
libc.src.stdlib._Exit
libc.src.stdlib.abort
libc.src.stdlib.at_quick_exit
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 48326462a1d99f..fc9ff112d118d2 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1533,6 +1533,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdio.ungetc
# stdlib.h entrypoints
+ libc.src.stdlib.__cxa_thread_atexit_impl
libc.src.stdlib._Exit
libc.src.stdlib.abort
libc.src.stdlib.at_quick_exit
@@ -1592,7 +1593,6 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.search.twalk_r
# threads.h entrypoints
- libc.src.threads.__cxa_thread_atexit_impl
libc.src.threads.call_once
libc.src.threads.cnd_broadcast
libc.src.threads.cnd_destroy
diff --git a/libc/src/__support/threads/thread.cpp b/libc/src/__support/threads/thread.cpp
index 9644c50c9793a5..828014507fee5f 100644
--- a/libc/src/__support/threads/thread.cpp
+++ b/libc/src/__support/threads/thread.cpp
@@ -142,12 +142,6 @@ static LIBC_THREAD_LOCAL ThreadAtExitCallbackMgr atexit_callback_mgr;
int add_thread_atexit_callback(AtExitCallback *callback, void *obj) {
return atexit_callback_mgr.add_callback(callback, obj);
}
-// The function __cxa_thread_atexit is provided by C++ runtimes like libcxxabi.
-// It is used by thread local object runtime to register destructor calls. To
-// actually register destructor call with the threading library, it calls
-// __cxa_thread_atexit_impl, which is to be provided by the threading library.
-// The semantics are very similar to the __cxa_atexit function except for the
-// fact that the registered callback is thread specific.
namespace internal {
void call_atexit_callbacks() {
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index faa31c62d1d8e8..9e16bdfffc9de7 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -1,3 +1,13 @@
+add_entrypoint_object(
+ __cxa_thread_atexit_impl
+ SRCS
+ __cxa_thread_atexit_impl.cpp
+ HDRS
+ __cxa_thread_atexit_impl.h
+ DEPENDS
+ libc.src.__support.threads.thread
+)
+
add_entrypoint_object(
atoi
SRCS
diff --git a/libc/src/threads/__cxa_thread_atexit_impl.cpp b/libc/src/stdlib/__cxa_thread_atexit_impl.cpp
similarity index 81%
rename from libc/src/threads/__cxa_thread_atexit_impl.cpp
rename to libc/src/stdlib/__cxa_thread_atexit_impl.cpp
index 67b387ab76fdb3..040b369e2effff 100644
--- a/libc/src/threads/__cxa_thread_atexit_impl.cpp
+++ b/libc/src/stdlib/__cxa_thread_atexit_impl.cpp
@@ -11,12 +11,9 @@
///
//===----------------------------------------------------------------------===//
-#include "src/threads/__cxa_thread_atexit_impl.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/threads/thread.h"
+#include "src/stdlib/__cxa_thread_atexit_impl.h"
-#include <threads.h>
+#include "src/__support/common.h"
namespace LIBC_NAMESPACE_DECL {
@@ -27,7 +24,7 @@ namespace LIBC_NAMESPACE_DECL {
// The semantics are very similar to the __cxa_atexit function except for the
// fact that the registered callback is thread specific.
LLVM_LIBC_FUNCTION(int, __cxa_thread_atexit_impl,
- (AtExitCallback* callback, void *obj, void *)) {
+ (AtExitCallback * callback, void* obj, void*)) {
return add_thread_atexit_callback(callback, obj);
}
-} // namespace LIBC_NAMESPACE_DECL
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/threads/__cxa_thread_atexit_impl.h b/libc/src/stdlib/__cxa_thread_atexit_impl.h
similarity index 58%
rename from libc/src/threads/__cxa_thread_atexit_impl.h
rename to libc/src/stdlib/__cxa_thread_atexit_impl.h
index 729498b409a82e..32e30d714a08bb 100644
--- a/libc/src/threads/__cxa_thread_atexit_impl.h
+++ b/libc/src/stdlib/__cxa_thread_atexit_impl.h
@@ -1,4 +1,4 @@
-//===-- Implementation header for __cxa_thread_atexit_impl function ------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,14 +9,11 @@
#ifndef LLVM_LIBC_SRC___THREADS_CXA_THREAD_ATEXIT_IMPL_H
#define LLVM_LIBC_SRC___THREADS_CXA_THREAD_ATEXIT_IMPL_H
-#include "src/__support/macros/config.h"
#include "src/__support/threads/thread.h"
namespace LIBC_NAMESPACE_DECL {
-int __cxa_thread_atexit_impl(AtExitCallback *callback, void *obj,
- void *);
-}// namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC_THREADS_CXA_THREAD_ATEXIT_IMPL_H
+int __cxa_thread_atexit_impl(AtExitCallback* callback, void* obj, void*);
+} // namespace LIBC_NAMESPACE_DECL
+#endif // LLVM_LIBC_SRC_THREADS_CXA_THREAD_ATEXIT_IMPL_H
diff --git a/libc/src/threads/CMakeLists.txt b/libc/src/threads/CMakeLists.txt
index 90ddbaadd5190e..56247204c30f90 100644
--- a/libc/src/threads/CMakeLists.txt
+++ b/libc/src/threads/CMakeLists.txt
@@ -179,16 +179,6 @@ add_entrypoint_object(
libc.src.__support.threads.mutex
)
-add_entrypoint_object(
- __cxa_thread_atexit_impl
- SRCS
- __cxa_thread_atexit_impl.cpp
- HDRS
- __cxa_thread_atexit_impl.h
- DEPENDS
- libc.src.__support.threads.thread
-)
-
add_entrypoint_object(
cnd_init
ALIAS
>From ae7c889d69c64709079710a31c2a066a8d8a0776 Mon Sep 17 00:00:00 2001
From: Shriharsh Acharya <happy.irhs at gmail.com>
Date: Wed, 7 Oct 2026 12:06:43 +0545
Subject: [PATCH 3/3] fix: clang-format
---
CMakeFiles/Progress/count.txt | 1 -
libc/src/__support/threads/thread.h | 4 ++--
libc/src/stdlib/__cxa_thread_atexit_impl.cpp | 4 ++--
libc/src/stdlib/__cxa_thread_atexit_impl.h | 6 +++---
4 files changed, 7 insertions(+), 8 deletions(-)
delete mode 100644 CMakeFiles/Progress/count.txt
diff --git a/CMakeFiles/Progress/count.txt b/CMakeFiles/Progress/count.txt
deleted file mode 100644
index 38b10c1b2badd8..00000000000000
--- a/CMakeFiles/Progress/count.txt
+++ /dev/null
@@ -1 +0,0 @@
-68
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index 746e1dcda13a7f..afb18af39cd1c2 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -175,7 +175,7 @@ namespace internal {
// implementing the thread_exit function.
void call_atexit_callbacks();
-}//internal namespace
+} // namespace internal
using AtExitCallback = void(void *);
@@ -183,7 +183,7 @@ int add_thread_atexit_callback(AtExitCallback *callback, void *obj);
LIBC_INLINE Thread current_thread() {
return Thread(get_current_thread_attrib());
- }
+}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/__cxa_thread_atexit_impl.cpp b/libc/src/stdlib/__cxa_thread_atexit_impl.cpp
index 040b369e2effff..c38a6516a6ff09 100644
--- a/libc/src/stdlib/__cxa_thread_atexit_impl.cpp
+++ b/libc/src/stdlib/__cxa_thread_atexit_impl.cpp
@@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE_DECL {
// The semantics are very similar to the __cxa_atexit function except for the
// fact that the registered callback is thread specific.
LLVM_LIBC_FUNCTION(int, __cxa_thread_atexit_impl,
- (AtExitCallback * callback, void* obj, void*)) {
+ (AtExitCallback * callback, void *obj, void *)) {
return add_thread_atexit_callback(callback, obj);
}
-} // namespace LIBC_NAMESPACE_DECL
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/__cxa_thread_atexit_impl.h b/libc/src/stdlib/__cxa_thread_atexit_impl.h
index 32e30d714a08bb..0ee509d63f45c6 100644
--- a/libc/src/stdlib/__cxa_thread_atexit_impl.h
+++ b/libc/src/stdlib/__cxa_thread_atexit_impl.h
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE_DECL {
-int __cxa_thread_atexit_impl(AtExitCallback* callback, void* obj, void*);
-} // namespace LIBC_NAMESPACE_DECL
+int __cxa_thread_atexit_impl(AtExitCallback *callback, void *obj, void *);
+} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_THREADS_CXA_THREAD_ATEXIT_IMPL_H
+#endif // LLVM_LIBC_SRC_THREADS_CXA_THREAD_ATEXIT_IMPL_H
More information about the libc-commits
mailing list