tavianator created this revision.
tavianator added reviewers: danalbert, jroelofs.
tavianator added a subscriber: cfe-commits.
Herald added subscribers: danalbert, tberghammer.
__cxa_thread_atexit_impl() isn't present on all platforms, for example
Android pre-6.0. This patch uses a weak symbol to detect _impl()
support, falling back to a pthread_key_t-based implementation.
http://reviews.llvm.org/D21803
Files:
cmake/config-ix.cmake
src/CMakeLists.txt
src/cxa_thread_atexit.cpp
test/CMakeLists.txt
test/cxa_thread_atexit_test.pass.cpp
test/libcxxabi/test/config.py
test/lit.site.cfg.in
Index: test/lit.site.cfg.in
===================================================================
--- test/lit.site.cfg.in
+++ test/lit.site.cfg.in
@@ -13,7 +13,6 @@
config.enable_32bit = "@LIBCXXABI_BUILD_32_BITS@"
config.target_info = "@LIBCXXABI_TARGET_INFO@"
config.executor = "@LIBCXXABI_EXECUTOR@"
-config.thread_atexit = "@LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL@"
config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@"
config.enable_shared = "@LIBCXX_ENABLE_SHARED@"
config.enable_exceptions = "@LIBCXXABI_ENABLE_EXCEPTIONS@"
Index: test/libcxxabi/test/config.py
===================================================================
--- test/libcxxabi/test/config.py
+++ test/libcxxabi/test/config.py
@@ -37,8 +37,6 @@
super(Configuration, self).configure_features()
if not self.get_lit_bool('enable_exceptions', True):
self.config.available_features.add('libcxxabi-no-exceptions')
- if self.get_lit_bool('thread_atexit', True):
- self.config.available_features.add('thread_atexit')
def configure_compile_flags(self):
self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER']
Index: test/cxa_thread_atexit_test.pass.cpp
===================================================================
--- test/cxa_thread_atexit_test.pass.cpp
+++ test/cxa_thread_atexit_test.pass.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
// REQUIRES: linux
-// REQUIRES: thread_atexit
#include <assert.h>
#include <cxxabi.h>
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
@@ -16,7 +16,6 @@
pythonize_bool(LIBCXXABI_ENABLE_THREADS)
pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS)
pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
-pythonize_bool(LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
set(LIBCXXABI_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
"TargetInfo to use when setting up test environment.")
set(LIBCXXABI_EXECUTOR "None" CACHE STRING
Index: src/cxa_thread_atexit.cpp
===================================================================
--- src/cxa_thread_atexit.cpp
+++ src/cxa_thread_atexit.cpp
@@ -8,19 +8,77 @@
//===----------------------------------------------------------------------===//
#include "cxxabi.h"
+#include <cstdlib>
+#include <pthread.h>
namespace __cxxabiv1 {
-extern "C" {
+namespace {
+ typedef void (*Dtor)(void *);
+
+ struct DtorList {
+ Dtor dtor;
+ void* obj;
+ DtorList* next;
+ };
+
+ void run_dtors(void* ptr) {
+ auto elem = static_cast<DtorList*>(ptr);
+ while (elem) {
+ auto saved = elem;
+ elem = elem->next;
+ saved->dtor(saved->obj);
+ std::free(saved);
+ }
+ }
+
+ class DtorListHolder {
+ public:
+ DtorListHolder() {
+ pthread_key_create(&key_, run_dtors);
+ }
+
+ ~DtorListHolder() {
+ run_dtors(get());
+ pthread_key_delete(key_);
+ }
+
+ DtorList* get() {
+ return static_cast<DtorList*>(pthread_getspecific(key_));
+ }
+
+ void set(DtorList* list) {
+ pthread_setspecific(key_, list);
+ }
+
+ private:
+ pthread_key_t key_;
+ };
+} // namespace
-#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
+extern "C" {
-_LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*dtor)(void *), void *obj,
+_LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void *obj,
void *dso_symbol) throw() {
- extern int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);
- return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
-}
+ extern int __cxa_thread_atexit_impl(Dtor, void *, void *)
+ __attribute__((__weak__));
-#endif // HAVE__CXA_THREAD_ATEXIT_IMPL
+ if (__cxa_thread_atexit_impl) {
+ return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
+ } else {
+ static DtorListHolder dtors;
+
+ auto head = static_cast<DtorList*>(std::malloc(sizeof(DtorList)));
+ if (!head) {
+ return -1;
+ }
+
+ head->dtor = dtor;
+ head->obj = obj;
+ head->next = dtors.get();
+ dtors.set(head);
+ return 0;
+ }
+}
} // extern "C"
} // namespace __cxxabiv1
Index: src/CMakeLists.txt
===================================================================
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -41,10 +41,6 @@
include_directories("${LIBCXXABI_LIBCXX_INCLUDES}")
-if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
- add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL)
-endif()
-
# Generate library list
set(libraries ${LIBCXXABI_CXX_ABI_LIBRARIES})
Index: cmake/config-ix.cmake
===================================================================
--- cmake/config-ix.cmake
+++ cmake/config-ix.cmake
@@ -43,5 +43,3 @@
check_library_exists(dl dladdr "" LIBCXXABI_HAS_DL_LIB)
check_library_exists(pthread pthread_once "" LIBCXXABI_HAS_PTHREAD_LIB)
check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXXABI_HAS_GCC_S_LIB)
-check_library_exists(c __cxa_thread_atexit_impl ""
- LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits