[libcxx-commits] [libcxxabi] bc91104 - Revert "[libcxxabi] Always use thread_local for cxa_exception_storage"

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Nov 24 05:32:47 PST 2022


Author: Louis Dionne
Date: 2022-11-24T08:32:10-05:00
New Revision: bc91104e85b7a233a8966998f387b2222f350f6e

URL: https://github.com/llvm/llvm-project/commit/bc91104e85b7a233a8966998f387b2222f350f6e
DIFF: https://github.com/llvm/llvm-project/commit/bc91104e85b7a233a8966998f387b2222f350f6e.diff

LOG: Revert "[libcxxabi] Always use thread_local for cxa_exception_storage"

This reverts commit 8271aa5335668a1dc62168a4e90b4554bd3a0ca7 since it
broke some downstream builds. See https://reviews.llvm.org/D138461 for
details.

Added: 
    

Modified: 
    libcxxabi/src/cxa_exception_storage.cpp
    libcxxabi/src/fallback_malloc.cpp
    libcxxabi/src/fallback_malloc.h

Removed: 
    


################################################################################
diff  --git a/libcxxabi/src/cxa_exception_storage.cpp b/libcxxabi/src/cxa_exception_storage.cpp
index 1abf6143e59f7..3a3233a1b9272 100644
--- a/libcxxabi/src/cxa_exception_storage.cpp
+++ b/libcxxabi/src/cxa_exception_storage.cpp
@@ -12,18 +12,21 @@
 
 #include "cxa_exception.h"
 
-namespace __cxxabiv1 {
+#include <__threading_support>
 
 #if defined(_LIBCXXABI_HAS_NO_THREADS)
 
+namespace __cxxabiv1 {
 extern "C" {
     static __cxa_eh_globals eh_globals;
     __cxa_eh_globals *__cxa_get_globals() { return &eh_globals; }
     __cxa_eh_globals *__cxa_get_globals_fast() { return &eh_globals; }
 } // extern "C"
+} // namespace __cxxabiv1
 
-#else
+#elif defined(HAS_THREAD_LOCAL)
 
+namespace __cxxabiv1 {
 namespace {
     __cxa_eh_globals *__globals() {
         static thread_local __cxa_eh_globals eh_globals;
@@ -35,7 +38,66 @@ extern "C" {
     __cxa_eh_globals *__cxa_get_globals() { return __globals(); }
     __cxa_eh_globals *__cxa_get_globals_fast() { return __globals(); }
 } // extern "C"
+} // namespace __cxxabiv1
 
+#else
+
+#include "abort_message.h"
+#include "fallback_malloc.h"
+
+#if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
+#pragma comment(lib, "pthread")
 #endif
 
+//  In general, we treat all threading errors as fatal.
+//  We cannot call std::terminate() because that will in turn
+//  call __cxa_get_globals() and cause infinite recursion.
+
+namespace __cxxabiv1 {
+namespace {
+    std::__libcpp_tls_key key_;
+    std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
+
+    void _LIBCPP_TLS_DESTRUCTOR_CC destruct_(void *p) {
+        __free_with_fallback(p);
+        if (0 != std::__libcpp_tls_set(key_, NULL))
+            abort_message("cannot zero out thread value for __cxa_get_globals()");
+    }
+
+    void construct_() {
+        if (0 != std::__libcpp_tls_create(&key_, destruct_))
+            abort_message("cannot create thread specific key for __cxa_get_globals()");
+    }
+} // namespace
+
+extern "C" {
+    __cxa_eh_globals *__cxa_get_globals() {
+        // Try to get the globals for this thread
+        __cxa_eh_globals *retVal = __cxa_get_globals_fast();
+
+        // If this is the first time we've been asked for these globals, create them
+        if (NULL == retVal) {
+            retVal = static_cast<__cxa_eh_globals*>(
+                __calloc_with_fallback(1, sizeof(__cxa_eh_globals)));
+            if (NULL == retVal)
+                abort_message("cannot allocate __cxa_eh_globals");
+            if (0 != std::__libcpp_tls_set(key_, retVal))
+               abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
+        }
+        return retVal;
+    }
+
+    // Note that this implementation will reliably return NULL if not
+    // preceded by a call to __cxa_get_globals().  This is an extension
+    // to the Itanium ABI and is taken advantage of in several places in
+    // libc++abi.
+    __cxa_eh_globals *__cxa_get_globals_fast() {
+        // First time through, create the key.
+        if (0 != std::__libcpp_execute_once(&flag_, construct_))
+            abort_message("execute once failure in __cxa_get_globals_fast()");
+        return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
+    }
+} // extern "C"
 } // namespace __cxxabiv1
+
+#endif

diff  --git a/libcxxabi/src/fallback_malloc.cpp b/libcxxabi/src/fallback_malloc.cpp
index 759bb58f7c308..591efbefc8a52 100644
--- a/libcxxabi/src/fallback_malloc.cpp
+++ b/libcxxabi/src/fallback_malloc.cpp
@@ -270,6 +270,17 @@ void* __aligned_malloc_with_fallback(size_t size) {
   return fallback_malloc(size);
 }
 
+void* __calloc_with_fallback(size_t count, size_t size) {
+  void* ptr = ::calloc(count, size);
+  if (NULL != ptr)
+    return ptr;
+  // if calloc fails, fall back to emergency stash
+  ptr = fallback_malloc(size * count);
+  if (NULL != ptr)
+    ::memset(ptr, 0, size * count);
+  return ptr;
+}
+
 void __aligned_free_with_fallback(void* ptr) {
   if (is_fallback_ptr(ptr))
     fallback_free(ptr);

diff  --git a/libcxxabi/src/fallback_malloc.h b/libcxxabi/src/fallback_malloc.h
index 528014b3456d8..816e691ed2313 100644
--- a/libcxxabi/src/fallback_malloc.h
+++ b/libcxxabi/src/fallback_malloc.h
@@ -17,6 +17,9 @@ namespace __cxxabiv1 {
 // Allocate some memory from _somewhere_
 _LIBCXXABI_HIDDEN void * __aligned_malloc_with_fallback(size_t size);
 
+// Allocate and zero-initialize memory from _somewhere_
+_LIBCXXABI_HIDDEN void * __calloc_with_fallback(size_t count, size_t size);
+
 _LIBCXXABI_HIDDEN void __aligned_free_with_fallback(void *ptr);
 _LIBCXXABI_HIDDEN void __free_with_fallback(void *ptr);
 


        


More information about the libcxx-commits mailing list