rmaprath created this revision.
rmaprath added reviewers: mclow.lists, EricWF, bcraig.
rmaprath added a subscriber: cfe-commits.
Herald added a subscriber: mgorny.

This is more-or-less a mirror image of https://reviews.llvm.org/D21968, 
repeated for libcxxabi.

I will soon upload a dependent patch for libcxx which makes it possible to run 
the libcxx test suite with the externally-threaded libcxxabi variant.


https://reviews.llvm.org/D27204

Files:
  CMakeLists.txt
  src/CMakeLists.txt
  src/config.h
  src/threading_support.h
  test/CMakeLists.txt
  test/libcxxabi/test/config.py
  test/lit.cfg
  test/lit.site.cfg.in
  test/support/external_threads.cpp

Index: test/support/external_threads.cpp
===================================================================
--- /dev/null
+++ test/support/external_threads.cpp
@@ -0,0 +1,10 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#define _LIBCXXABI_BUILDING_EXTERNAL_THREADS
+#include <threading_support.h>
Index: test/lit.site.cfg.in
===================================================================
--- test/lit.site.cfg.in
+++ test/lit.site.cfg.in
@@ -19,6 +19,8 @@
 config.host_triple              = "@LLVM_HOST_TRIPLE@"
 config.target_triple            = "@TARGET_TRIPLE@"
 config.use_target               = len("@LIBCXXABI_TARGET_TRIPLE@") > 0
+config.cxx_ext_threads          = "@LIBCXX_HAS_EXTERNAL_THREAD_API@"
+config.cxxabi_ext_threads       = "@LIBCXXABI_HAS_EXTERNAL_THREAD_API@"
 
 # Let the main config do the real work.
 lit_config.load_config(config, "@LIBCXXABI_SOURCE_DIR@/test/lit.cfg")
Index: test/lit.cfg
===================================================================
--- test/lit.cfg
+++ test/lit.cfg
@@ -18,7 +18,7 @@
 config.name = 'libc++abi'
 
 # suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.cpp', '.s']
+config.suffixes = ['.pass.cpp', '.sh.s', '.sh.cpp']
 
 # test_source_root: The root path where tests are located.
 config.test_source_root = os.path.dirname(__file__)
Index: test/libcxxabi/test/config.py
===================================================================
--- test/libcxxabi/test/config.py
+++ test/libcxxabi/test/config.py
@@ -39,6 +39,9 @@
             self.config.available_features.add('libcxxabi-no-exceptions')
         if not self.cxx.addCompileFlagIfSupported(['-Xclang', '-mqualified-function-type-info']):
             self.config.available_features.add("libcxxabi-no-qualified-function-types")
+        # test_exception_storage_nodynmem.pass.cpp fails under this specific configuration
+        if self.get_lit_bool('cxxabi_ext_threads', False) and self.get_lit_bool('libcxxabi_shared', False):
+            self.config.available_features.add('libcxxabi-shared-externally-threaded')
 
     def configure_compile_flags(self):
         self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER']
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
@@ -17,6 +17,9 @@
 pythonize_bool(LIBCXXABI_ENABLE_THREADS)
 pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS)
 pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
+pythonize_bool(LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
+pythonize_bool(LIBCXX_HAS_EXTERNAL_THREAD_API)
+pythonize_bool(LIBCXXABI_HAS_EXTERNAL_THREAD_API)
 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
@@ -34,6 +37,14 @@
   set(LIBCXXABI_TEST_DEPS cxxabi_static)
 endif()
 
+if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+  list(APPEND LIBCXXABI_TEST_DEPS "cxxabi_external_threads")
+endif()
+
+if (LIBCXX_HAS_EXTERNAL_THREAD_API)
+  list(APPEND LIBCXXABI_TEST_DEPS "cxx_external_threads")
+endif()
+
 if (NOT LIBCXXABI_STANDALONE_BUILD)
   list(APPEND LIBCXXABI_TEST_DEPS cxx)
   if (LIBCXXABI_USE_LLVM_UNWINDER)
Index: src/threading_support.h
===================================================================
--- src/threading_support.h
+++ src/threading_support.h
@@ -15,93 +15,149 @@
 
 #ifndef _LIBCXXABI_HAS_NO_THREADS
 
-#if defined(_LIBCXXABI_USE_THREAD_API_PTHREAD)
+#ifndef __libcxxabi_has_include
+  #ifndef __has_include
+    #define __libcxxabi_has_include(x) 0
+  #else
+    #define __libcxxabi_has_include(x) __has_include(x)
+  #endif
+#endif
+
+#if defined(_LIBCXXABI_HAS_THREAD_API_EXTERNAL) && \
+    __libcxxabi_has_include(<external_threading.h>)
+#include <external_threading.h>
+#else
 #include <pthread.h>
 
+#if defined(_LIBCXXABI_HAS_THREAD_API_EXTERNAL)
+#define _LIBCXXABI_THREAD_ABI_VISIBILITY _LIBCXXABI_FUNC_VIS
+#else
 #define _LIBCXXABI_THREAD_ABI_VISIBILITY inline _LIBCXXABI_INLINE_VISIBILITY
+#endif
 
 // Mutex
 typedef pthread_mutex_t __libcxxabi_mutex_t;
 #define _LIBCXXABI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
 
 _LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_mutex_lock(__libcxxabi_mutex_t *mutex);
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_mutex_unlock(__libcxxabi_mutex_t *mutex);
+
+// Condition variable
+typedef pthread_cond_t __libcxxabi_condvar_t;
+#define _LIBCXXABI_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_condvar_wait(__libcxxabi_condvar_t *cv,
+                             __libcxxabi_mutex_t *mutex);
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_condvar_broadcast(__libcxxabi_condvar_t *cv);
+
+// Execute once
+typedef pthread_once_t __libcxxabi_exec_once_flag;
+#define _LIBCXXABI_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_execute_once(__libcxxabi_exec_once_flag *flag,
+                             void (*init_routine)(void));
+
+// Thread id
+#if defined(__APPLE__) && !defined(__arm__)
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+mach_port_t __libcxxabi_thread_get_port();
+#endif
+
+// Thread
+typedef pthread_t __libcxxabi_thread_t;
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_thread_create(__libcxxabi_thread_t* __t,
+                           void* (*__func)(void*), void* __arg);
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_thread_join(__libcxxabi_thread_t* __t);
+
+// TLS
+typedef pthread_key_t __libcxxabi_tls_key;
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_tls_create(__libcxxabi_tls_key *key,
+                           void (*destructor)(void *));
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+void *__libcxxabi_tls_get(__libcxxabi_tls_key key);
+
+_LIBCXXABI_THREAD_ABI_VISIBILITY
+int __libcxxabi_tls_set(__libcxxabi_tls_key key, void *value);
+
+// Implementation of the above thread API. Used both by the pthread based
+// libc++abi build and the proof-of-concept externally threaded (i.e. no
+// external_threading.h header) libc++abi build (below implementation built
+// into a separate library for linking against the test suite).
+#if defined(_LIBCXXABI_USE_THREAD_API_PTHREAD) || \
+    defined(_LIBCXXABI_BUILDING_EXTERNAL_THREADS)
+// Mutex
 int __libcxxabi_mutex_lock(__libcxxabi_mutex_t *mutex) {
   return pthread_mutex_lock(mutex);
 }
 
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_mutex_unlock(__libcxxabi_mutex_t *mutex) {
   return pthread_mutex_unlock(mutex);
 }
 
 // Condition variable
-typedef pthread_cond_t __libcxxabi_condvar_t;
-#define _LIBCXXABI_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_condvar_wait(__libcxxabi_condvar_t *cv,
                              __libcxxabi_mutex_t *mutex) {
   return pthread_cond_wait(cv, mutex);
 }
 
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_condvar_broadcast(__libcxxabi_condvar_t *cv) {
   return pthread_cond_broadcast(cv);
 }
 
 // Execute once
-typedef pthread_once_t __libcxxabi_exec_once_flag;
-#define _LIBCXXABI_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_execute_once(__libcxxabi_exec_once_flag *flag,
                              void (*init_routine)(void)) {
   return pthread_once(flag, init_routine);
 }
 
 // Thread id
 #if defined(__APPLE__) && !defined(__arm__)
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-mach_port_t __libcxxabi_thread_get_port()
-{
+mach_port_t __libcxxabi_thread_get_port() {
     return pthread_mach_thread_np(pthread_self());
 }
 #endif
 
 // Thread
-typedef pthread_t __libcxxabi_thread_t;
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_thread_create(__libcxxabi_thread_t* __t,
-                           void* (*__func)(void*), void* __arg)
-{
+                           void* (*__func)(void*), void* __arg) {
     return pthread_create(__t, 0, __func, __arg);
 }
 
-_LIBCXXABI_THREAD_ABI_VISIBILITY
-int __libcxxabi_thread_join(__libcxxabi_thread_t* __t)
-{
+int __libcxxabi_thread_join(__libcxxabi_thread_t* __t) {
     return pthread_join(*__t, 0);
 }
 
 // TLS
-typedef pthread_key_t __libcxxabi_tls_key;
-
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_tls_create(__libcxxabi_tls_key *key,
                            void (*destructor)(void *)) {
   return pthread_key_create(key, destructor);
 }
 
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 void *__libcxxabi_tls_get(__libcxxabi_tls_key key) {
   return pthread_getspecific(key);
 }
 
-_LIBCXXABI_THREAD_ABI_VISIBILITY
 int __libcxxabi_tls_set(__libcxxabi_tls_key key, void *value) {
   return pthread_setspecific(key, value);
 }
 #endif // _LIBCXXABI_USE_THREAD_API_PTHREAD
+
+#endif // !_LIBCXXABI_HAS_THREAD_API_EXTERNAL || !__libcxxabi_has_include(<external_threading.h>)
+
 #endif // !_LIBCXXABI_HAS_NO_THREADS
+
 #endif // _LIBCXXABI_THREADING_SUPPORT_H
Index: src/config.h
===================================================================
--- src/config.h
+++ src/config.h
@@ -42,6 +42,7 @@
 
 // Try and deduce a threading api if one has not been explicitly set.
 #if !defined(_LIBCXXABI_HAS_NO_THREADS) && \
+    !defined(_LIBCXXABI_HAS_THREAD_API_EXTERNAL) && \
     !defined(_LIBCXXABI_USE_THREAD_API_PTHREAD)
   #if defined(_POSIX_THREADS) && _POSIX_THREADS >= 0
     #define _LIBCXXABI_USE_THREAD_API_PTHREAD
Index: src/CMakeLists.txt
===================================================================
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -128,6 +128,23 @@
   list(APPEND LIBCXXABI_TARGETS "cxxabi_shared")
 endif()
 
+if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+  file(GLOB LIBCXXABI_EXTERNAL_THREADING_SUPPORT_SOURCES ../test/support/external_threads.cpp)
+
+  if (LIBCXXABI_ENABLE_SHARED)
+    add_library(cxxabi_external_threads SHARED ${LIBCXXABI_EXTERNAL_THREADING_SUPPORT_SOURCES})
+  else()
+    add_library(cxxabi_external_threads STATIC ${LIBCXXABI_EXTERNAL_THREADING_SUPPORT_SOURCES})
+  endif()
+
+  set_target_properties(cxxabi_external_threads
+    PROPERTIES
+      LINK_FLAGS    "${LIBCXXABI_LINK_FLAGS}"
+      COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
+      OUTPUT_NAME   "cxxabi_external_threads"
+  )
+endif()
+
 # Build the static library.
 if (LIBCXXABI_ENABLE_STATIC)
   add_library(cxxabi_static STATIC $<TARGET_OBJECTS:cxxabi_objects>)
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -118,6 +118,12 @@
 option(LIBCXXABI_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
 option(LIBCXXABI_ENABLE_THREADS "Build with threads enabled" ON)
 option(LIBCXXABI_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
+option(LIBCXXABI_HAS_EXTERNAL_THREAD_API
+  "Build libc++abi with an externalized threading API.
+  This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON." OFF)
+option(LIBCXX_HAS_EXTERNAL_THREAD_API
+  "Build libc++ with an externalized threading API.
+  This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF)
 option(LIBCXXABI_BUILD_32_BITS "Build 32 bit libc++abi." ${LLVM_BUILD_32_BITS})
 set(LIBCXXABI_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.")
 set(LIBCXXABI_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
@@ -347,20 +353,46 @@
   list(APPEND LIBCXXABI_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC)
 endif()
 
+# Threading
 if (NOT LIBCXXABI_ENABLE_THREADS)
   if (LIBCXXABI_HAS_PTHREAD_API)
     message(FATAL_ERROR "LIBCXXABI_HAS_PTHREAD_API can only"
                         " be set to ON when LIBCXXABI_ENABLE_THREADS"
                         " is also set to ON.")
   endif()
+  if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+    message(FATAL_ERROR "LIBCXXABI_HAS_EXTERNAL_THREAD_API can only"
+                        " be set to ON when LIBCXXABI_ENABLE_THREADS"
+                        " is also set to ON.")
+  endif()
   add_definitions(-D_LIBCXXABI_HAS_NO_THREADS)
 endif()
 
+if (LIBCXXABI_HAS_PTHREAD_API AND LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+  message(FATAL_ERROR "The options LIBCXXABI_HAS_EXTERNAL_THREAD_API"
+                      "and LIBCXXABI_HAS_PTHREAD_API cannot be both"
+                      "set to ON at the same time.")
+endif()
+
+if (LIBCXXABI_HAS_EXTERNAL_THREAD_API AND LIBCXXABI_ENABLE_SHARED)
+  # Need to allow unresolved symbols if this is to work with shared library builds
+  if (APPLE)
+    add_link_flags("-undefined dynamic_lookup")
+  else()
+    # Relax this restriction from HandleLLVMOptions
+    string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+  endif()
+endif()
+
 if (LIBCXXABI_HAS_PTHREAD_API)
   add_definitions(-D_LIBCPP_HAS_THREAD_API_PTHREAD)
   add_definitions(-D_LIBCXXABI_USE_THREAD_API_PTHREAD)
 endif()
 
+if (LIBCXXABI_HAS_EXTERNAL_THREAD_API)
+  add_definitions(-D_LIBCXXABI_HAS_THREAD_API_EXTERNAL)
+endif()
+
 if (MSVC)
   add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 endif()
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to