forked from OSchip/llvm-project
[libcxxabi] Introduce an externally threaded libc++abi variant.
r281179 Introduced an externally threaded variant of the libc++ library. This patch adds support for a similar library variant for libc++abi. Differential revision: https://reviews.llvm.org/D27575 Reviewers: EricWF llvm-svn: 290888
This commit is contained in:
parent
b44b4cbae8
commit
97ba9fae1f
|
@ -118,6 +118,9 @@ option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF)
|
|||
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(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 +350,46 @@ if (NOT LIBCXXABI_ENABLE_SHARED)
|
|||
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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "config.h"
|
||||
#include "threading_support.h"
|
||||
#include "cxxabi.h"
|
||||
|
||||
#include <exception> // for std::terminate
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "cxa_exception.hpp"
|
||||
|
||||
#include "config.h"
|
||||
#include "threading_support.h"
|
||||
#include <__threading_support>
|
||||
|
||||
#if defined(_LIBCXXABI_HAS_NO_THREADS)
|
||||
|
||||
|
@ -54,17 +54,17 @@ extern "C" {
|
|||
|
||||
namespace __cxxabiv1 {
|
||||
namespace {
|
||||
__libcxxabi_tls_key key_;
|
||||
__libcxxabi_exec_once_flag flag_ = _LIBCXXABI_EXEC_ONCE_INITIALIZER;
|
||||
std::__libcpp_tls_key key_;
|
||||
std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER;
|
||||
|
||||
void destruct_ (void *p) {
|
||||
__free_with_fallback ( p );
|
||||
if ( 0 != __libcxxabi_tls_set ( key_, NULL ) )
|
||||
if ( 0 != std::__libcpp_tls_set ( key_, NULL ) )
|
||||
abort_message("cannot zero out thread value for __cxa_get_globals()");
|
||||
}
|
||||
|
||||
void construct_ () {
|
||||
if ( 0 != __libcxxabi_tls_create ( &key_, destruct_ ) )
|
||||
if ( 0 != std::__libcpp_tls_create ( &key_, destruct_ ) )
|
||||
abort_message("cannot create thread specific key for __cxa_get_globals()");
|
||||
}
|
||||
}
|
||||
|
@ -80,8 +80,8 @@ extern "C" {
|
|||
(__calloc_with_fallback (1, sizeof (__cxa_eh_globals)));
|
||||
if ( NULL == retVal )
|
||||
abort_message("cannot allocate __cxa_eh_globals");
|
||||
if ( 0 != __libcxxabi_tls_set ( key_, retVal ) )
|
||||
abort_message("__libcxxabi_tls_set failure in __cxa_get_globals()");
|
||||
if ( 0 != std::__libcpp_tls_set ( key_, retVal ) )
|
||||
abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()");
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
@ -92,10 +92,10 @@ extern "C" {
|
|||
// libc++abi.
|
||||
__cxa_eh_globals * __cxa_get_globals_fast () {
|
||||
// First time through, create the key.
|
||||
if (0 != __libcxxabi_execute_once(&flag_, construct_))
|
||||
if (0 != std::__libcpp_execute_once(&flag_, construct_))
|
||||
abort_message("execute once failure in __cxa_get_globals_fast()");
|
||||
// static int init = construct_();
|
||||
return static_cast<__cxa_eh_globals*>(__libcxxabi_tls_get(key_));
|
||||
return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "abort_message.h"
|
||||
#include "config.h"
|
||||
#include "threading_support.h"
|
||||
#include <__threading_support>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
|||
which will turn around and try to call __cxa_guard_acquire reentrantly.
|
||||
For this reason, the headers of this file are as restricted as possible.
|
||||
Previous implementations of this code for __APPLE__ have used
|
||||
__libcxxabi_mutex_lock and the abort_message utility without problem. This
|
||||
implementation also uses __libcxxabi_condvar_wait which has tested
|
||||
std::__libcpp_mutex_lock and the abort_message utility without problem. This
|
||||
implementation also uses std::__libcpp_condvar_wait which has tested
|
||||
to not be a problem.
|
||||
*/
|
||||
|
||||
|
@ -67,8 +67,8 @@ bool is_initialized(guard_type* guard_object) {
|
|||
#endif
|
||||
|
||||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
__libcxxabi_mutex_t guard_mut = _LIBCXXABI_MUTEX_INITIALIZER;
|
||||
__libcxxabi_condvar_t guard_cv = _LIBCXXABI_CONDVAR_INITIALIZER;
|
||||
std::__libcpp_mutex_t guard_mut = _LIBCPP_MUTEX_INITIALIZER;
|
||||
std::__libcpp_condvar_t guard_cv = _LIBCPP_CONDVAR_INITIALIZER;
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && !defined(__arm__)
|
||||
|
@ -173,13 +173,13 @@ extern "C"
|
|||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
_LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) {
|
||||
char* initialized = (char*)guard_object;
|
||||
if (__libcxxabi_mutex_lock(&guard_mut))
|
||||
if (std::__libcpp_mutex_lock(&guard_mut))
|
||||
abort_message("__cxa_guard_acquire failed to acquire mutex");
|
||||
int result = *initialized == 0;
|
||||
if (result)
|
||||
{
|
||||
#if defined(__APPLE__) && !defined(__arm__)
|
||||
const lock_type id = __libcxxabi_thread_get_port();
|
||||
const lock_type id = std::__libcpp_thread_get_port();
|
||||
lock_type lock = get_lock(*guard_object);
|
||||
if (lock)
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) {
|
|||
abort_message("__cxa_guard_acquire detected deadlock");
|
||||
do
|
||||
{
|
||||
if (__libcxxabi_condvar_wait(&guard_cv, &guard_mut))
|
||||
if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut))
|
||||
abort_message("__cxa_guard_acquire condition variable wait failed");
|
||||
lock = get_lock(*guard_object);
|
||||
} while (lock);
|
||||
|
@ -200,36 +200,36 @@ _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) {
|
|||
set_lock(*guard_object, id);
|
||||
#else // !__APPLE__ || __arm__
|
||||
while (get_lock(*guard_object))
|
||||
if (__libcxxabi_condvar_wait(&guard_cv, &guard_mut))
|
||||
if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut))
|
||||
abort_message("__cxa_guard_acquire condition variable wait failed");
|
||||
result = *initialized == 0;
|
||||
if (result)
|
||||
set_lock(*guard_object, true);
|
||||
#endif // !__APPLE__ || __arm__
|
||||
}
|
||||
if (__libcxxabi_mutex_unlock(&guard_mut))
|
||||
if (std::__libcpp_mutex_unlock(&guard_mut))
|
||||
abort_message("__cxa_guard_acquire failed to release mutex");
|
||||
return result;
|
||||
}
|
||||
|
||||
_LIBCXXABI_FUNC_VIS void __cxa_guard_release(guard_type *guard_object) {
|
||||
if (__libcxxabi_mutex_lock(&guard_mut))
|
||||
if (std::__libcpp_mutex_lock(&guard_mut))
|
||||
abort_message("__cxa_guard_release failed to acquire mutex");
|
||||
*guard_object = 0;
|
||||
set_initialized(guard_object);
|
||||
if (__libcxxabi_mutex_unlock(&guard_mut))
|
||||
if (std::__libcpp_mutex_unlock(&guard_mut))
|
||||
abort_message("__cxa_guard_release failed to release mutex");
|
||||
if (__libcxxabi_condvar_broadcast(&guard_cv))
|
||||
if (std::__libcpp_condvar_broadcast(&guard_cv))
|
||||
abort_message("__cxa_guard_release failed to broadcast condition variable");
|
||||
}
|
||||
|
||||
_LIBCXXABI_FUNC_VIS void __cxa_guard_abort(guard_type *guard_object) {
|
||||
if (__libcxxabi_mutex_lock(&guard_mut))
|
||||
if (std::__libcpp_mutex_lock(&guard_mut))
|
||||
abort_message("__cxa_guard_abort failed to acquire mutex");
|
||||
*guard_object = 0;
|
||||
if (__libcxxabi_mutex_unlock(&guard_mut))
|
||||
if (std::__libcpp_mutex_unlock(&guard_mut))
|
||||
abort_message("__cxa_guard_abort failed to release mutex");
|
||||
if (__libcxxabi_condvar_broadcast(&guard_cv))
|
||||
if (std::__libcpp_condvar_broadcast(&guard_cv))
|
||||
abort_message("__cxa_guard_abort failed to broadcast condition variable");
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "abort_message.h"
|
||||
#include "cxxabi.h"
|
||||
#include "threading_support.h"
|
||||
#include <__threading_support>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace __cxxabiv1 {
|
||||
|
@ -39,7 +39,7 @@ namespace {
|
|||
// destructors of any objects with static storage duration.
|
||||
//
|
||||
// - thread_local destructors on non-main threads run on the first iteration
|
||||
// through the __libcxxabi_tls_key destructors.
|
||||
// through the __libccpp_tls_key destructors.
|
||||
// std::notify_all_at_thread_exit() and similar functions must be careful to
|
||||
// wait until the second iteration to provide their intended ordering
|
||||
// guarantees.
|
||||
|
@ -66,7 +66,7 @@ namespace {
|
|||
// True if the destructors are currently scheduled to run on this thread
|
||||
__thread bool dtors_alive = false;
|
||||
// Used to trigger destructors on thread exit; value is ignored
|
||||
__libcxxabi_tls_key dtors_key;
|
||||
std::__libcpp_tls_key dtors_key;
|
||||
|
||||
void run_dtors(void*) {
|
||||
while (auto head = dtors) {
|
||||
|
@ -80,16 +80,16 @@ namespace {
|
|||
|
||||
struct DtorsManager {
|
||||
DtorsManager() {
|
||||
// There is intentionally no matching __libcxxabi_tls_delete call, as
|
||||
// There is intentionally no matching std::__libcpp_tls_delete call, as
|
||||
// __cxa_thread_atexit() may be called arbitrarily late (for example, from
|
||||
// global destructors or atexit() handlers).
|
||||
if (__libcxxabi_tls_create(&dtors_key, run_dtors) != 0) {
|
||||
abort_message("__libcxxabi_tls_create() failed in __cxa_thread_atexit()");
|
||||
if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) {
|
||||
abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()");
|
||||
}
|
||||
}
|
||||
|
||||
~DtorsManager() {
|
||||
// __libcxxabi_tls_key destructors do not run on threads that call exit()
|
||||
// std::__libcpp_tls_key destructors do not run on threads that call exit()
|
||||
// (including when the main thread returns from main()), so we explicitly
|
||||
// call the destructor here. This runs at exit time (potentially earlier
|
||||
// if libc++abi is dlclose()'d). Any thread_locals initialized after this
|
||||
|
@ -110,12 +110,12 @@ extern "C" {
|
|||
if (__cxa_thread_atexit_impl) {
|
||||
return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
|
||||
} else {
|
||||
// Initialize the dtors __libcxxabi_tls_key (uses __cxa_guard_*() for
|
||||
// Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for
|
||||
// one-time initialization and __cxa_atexit() for destruction)
|
||||
static DtorsManager manager;
|
||||
|
||||
if (!dtors_alive) {
|
||||
if (__libcxxabi_tls_set(dtors_key, &dtors_key) != 0) {
|
||||
if (std::__libcpp_tls_set(dtors_key, &dtors_key) != 0) {
|
||||
return -1;
|
||||
}
|
||||
dtors_alive = true;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "fallback_malloc.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "threading_support.h"
|
||||
#include <__threading_support>
|
||||
|
||||
#include <cstdlib> // for malloc, calloc, free
|
||||
#include <cstring> // for memset
|
||||
|
@ -29,7 +29,8 @@ namespace {
|
|||
|
||||
// When POSIX threads are not available, make the mutex operations a nop
|
||||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
static __libcxxabi_mutex_t heap_mutex = _LIBCXXABI_MUTEX_INITIALIZER;
|
||||
_LIBCPP_SAFE_STATIC
|
||||
static std::__libcpp_mutex_t heap_mutex = _LIBCPP_MUTEX_INITIALIZER;
|
||||
#else
|
||||
static void * heap_mutex = 0;
|
||||
#endif
|
||||
|
@ -37,8 +38,10 @@ static void * heap_mutex = 0;
|
|||
class mutexor {
|
||||
public:
|
||||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
mutexor ( __libcxxabi_mutex_t *m ) : mtx_(m) { __libcxxabi_mutex_lock ( mtx_ ); }
|
||||
~mutexor () { __libcxxabi_mutex_unlock ( mtx_ ); }
|
||||
mutexor ( std::__libcpp_mutex_t *m ) : mtx_(m) {
|
||||
std::__libcpp_mutex_lock ( mtx_ );
|
||||
}
|
||||
~mutexor () { std::__libcpp_mutex_unlock ( mtx_ ); }
|
||||
#else
|
||||
mutexor ( void * ) {}
|
||||
~mutexor () {}
|
||||
|
@ -47,9 +50,9 @@ private:
|
|||
mutexor ( const mutexor &rhs );
|
||||
mutexor & operator = ( const mutexor &rhs );
|
||||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
__libcxxabi_mutex_t *mtx_;
|
||||
std::__libcpp_mutex_t *mtx_;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
static const size_t HEAP_SIZE = 512;
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
//===------------------------ threading_support.h -------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCXXABI_THREADING_SUPPORT_H
|
||||
#define _LIBCXXABI_THREADING_SUPPORT_H
|
||||
|
||||
#include "__cxxabi_config.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
|
||||
#if defined(_LIBCXXABI_USE_THREAD_API_PTHREAD)
|
||||
#include <pthread.h>
|
||||
|
||||
#define _LIBCXXABI_THREAD_ABI_VISIBILITY inline _LIBCXXABI_INLINE_VISIBILITY
|
||||
|
||||
// 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) {
|
||||
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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
return pthread_create(__t, 0, __func, __arg);
|
||||
}
|
||||
|
||||
_LIBCXXABI_THREAD_ABI_VISIBILITY
|
||||
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_NO_THREADS
|
||||
#endif // _LIBCXXABI_THREADING_SUPPORT_H
|
|
@ -17,6 +17,7 @@ pythonize_bool(LIBCXXABI_ENABLE_SHARED)
|
|||
pythonize_bool(LIBCXXABI_ENABLE_THREADS)
|
||||
pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS)
|
||||
pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
|
||||
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 +35,10 @@ else()
|
|||
set(LIBCXXABI_TEST_DEPS cxxabi_static)
|
||||
endif()
|
||||
|
||||
if (LIBCXXABI_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)
|
||||
|
|
|
@ -42,6 +42,9 @@ class Configuration(LibcxxConfiguration):
|
|||
self.config.available_features.add('libcxxabi-no-exceptions')
|
||||
if not self.has_cpp_feature('noexcept_function_type', 201510):
|
||||
self.config.available_features.add('libcxxabi-no-noexcept-function-type')
|
||||
# test_exception_storage_nodynmem.pass.cpp fails under this specific configuration
|
||||
if self.get_lit_bool('cxx_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']
|
||||
|
|
|
@ -19,6 +19,7 @@ config.enable_exceptions = "@LIBCXXABI_ENABLE_EXCEPTIONS@"
|
|||
config.host_triple = "@LLVM_HOST_TRIPLE@"
|
||||
config.target_triple = "@TARGET_TRIPLE@"
|
||||
config.use_target = len("@LIBCXXABI_TARGET_TRIPLE@") > 0
|
||||
config.cxx_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")
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include "../src/threading_support.h"
|
||||
#include <__threading_support>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../src/cxa_exception.hpp"
|
||||
|
@ -39,7 +39,7 @@ void *thread_code (void *parm) {
|
|||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
#define NUMTHREADS 10
|
||||
size_t thread_globals [ NUMTHREADS ] = { 0 };
|
||||
__libcxxabi_thread_t threads [ NUMTHREADS ];
|
||||
std::__libcpp_thread_t threads [ NUMTHREADS ];
|
||||
#endif
|
||||
|
||||
int main () {
|
||||
|
@ -48,9 +48,9 @@ int main () {
|
|||
#ifndef _LIBCXXABI_HAS_NO_THREADS
|
||||
// Make the threads, let them run, and wait for them to finish
|
||||
for ( int i = 0; i < NUMTHREADS; ++i )
|
||||
__libcxxabi_thread_create ( threads + i, thread_code, (void *) (thread_globals + i));
|
||||
std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i));
|
||||
for ( int i = 0; i < NUMTHREADS; ++i )
|
||||
__libcxxabi_thread_join ( &threads [ i ] );
|
||||
std::__libcpp_thread_join ( &threads [ i ] );
|
||||
|
||||
for ( int i = 0; i < NUMTHREADS; ++i )
|
||||
if ( 0 == thread_globals [ i ] ) {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <iostream>
|
||||
#include <deque>
|
||||
|
||||
#include "../src/threading_support.h"
|
||||
#include <__threading_support>
|
||||
|
||||
typedef std::deque<void *> container;
|
||||
|
||||
|
|
Loading…
Reference in New Issue