Index: src/cxa_exception_storage.cpp =================================================================== --- src/cxa_exception_storage.cpp +++ src/cxa_exception_storage.cpp @@ -33,7 +33,7 @@ #else #include -#include // for calloc, free +#include // for calloc, free, atexit #include "abort_message.h" // In general, we treat all pthread errors as fatal. @@ -42,34 +42,56 @@ namespace __cxxabiv1 { namespace { +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 pthread_key_t key_; pthread_once_t flag_ = PTHREAD_ONCE_INIT; +#else + __cxa_eh_globals * eh_globals_ = NULL; +#endif void destruct_ (void *p) { std::free ( p ); - if ( 0 != ::pthread_setspecific ( key_, NULL ) ) +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 + if ( 0 != ::pthread_setspecific ( key_, NULL ) ) abort_message("cannot zero out thread value for __cxa_get_globals()"); +#else + eh_globals_ = NULL; +#endif } +#if !(defined(_POSIX_THREADS) && _POSIX_THREADS > 0) + void do_destruct_ () { + destruct_(eh_globals_); + } +#endif + void construct_ () { +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 if ( 0 != pthread_key_create ( &key_, destruct_ ) ) abort_message("cannot create pthread key for __cxa_get_globals()"); +#else + atexit (do_destruct_); +#endif } -} +} 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*> (std::calloc (1, sizeof (__cxa_eh_globals))); if ( NULL == retVal ) abort_message("cannot allocate __cxa_eh_globals"); +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 if ( 0 != pthread_setspecific ( key_, retVal ) ) abort_message("pthread_setspecific failure in __cxa_get_globals()"); +#else + eh_globals_ = retVal; +#endif } return retVal; } @@ -79,13 +101,16 @@ // to the Itanium ABI and is taken advantage of in several places in // libc++abi. __cxa_eh_globals * __cxa_get_globals_fast () { +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 // First time through, create the key. if (0 != pthread_once(&flag_, construct_)) abort_message("pthread_once failure in __cxa_get_globals_fast()"); // static int init = construct_(); return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_)); +#else + return eh_globals_; +#endif } - } } #endif Index: src/cxa_guard.cpp =================================================================== --- src/cxa_guard.cpp +++ src/cxa_guard.cpp @@ -59,8 +59,10 @@ #endif +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER; +#endif #if defined(__APPLE__) && !defined(__arm__) @@ -163,10 +165,11 @@ int __cxa_guard_acquire(guard_type* guard_object) { +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 char* initialized = (char*)guard_object; if (pthread_mutex_lock(&guard_mut)) abort_message("__cxa_guard_acquire failed to acquire mutex"); - int result = *initialized == 0; + int result = !is_initialized(guard_object); if (result) { #if defined(__APPLE__) && !defined(__arm__) @@ -193,7 +196,7 @@ while (get_lock(*guard_object)) if (pthread_cond_wait(&guard_cv, &guard_mut)) abort_message("__cxa_guard_acquire condition variable wait failed"); - result = *initialized == 0; + result = !is_initialized(guard_object); if (result) set_lock(*guard_object, true); #endif // !__APPLE__ || __arm__ @@ -201,29 +204,41 @@ if (pthread_mutex_unlock(&guard_mut)) abort_message("__cxa_guard_acquire failed to release mutex"); return result; +#else // !_POSIX_THREADS || _POSIX_THREADS <= 0 + int result = !is_initialized(guard_object); + return result; +#endif // !_POSIX_THREADS || _POSIX_THREADS <= 0 } void __cxa_guard_release(guard_type* guard_object) { +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 if (pthread_mutex_lock(&guard_mut)) abort_message("__cxa_guard_release failed to acquire mutex"); +#endif *guard_object = 0; set_initialized(guard_object); +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 if (pthread_mutex_unlock(&guard_mut)) abort_message("__cxa_guard_release failed to release mutex"); if (pthread_cond_broadcast(&guard_cv)) abort_message("__cxa_guard_release failed to broadcast condition variable"); +#endif } void __cxa_guard_abort(guard_type* guard_object) { +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 if (pthread_mutex_lock(&guard_mut)) abort_message("__cxa_guard_abort failed to acquire mutex"); +#endif *guard_object = 0; +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 if (pthread_mutex_unlock(&guard_mut)) abort_message("__cxa_guard_abort failed to release mutex"); if (pthread_cond_broadcast(&guard_cv)) abort_message("__cxa_guard_abort failed to broadcast condition variable"); +#endif } } // extern "C" Index: src/fallback_malloc.ipp =================================================================== --- src/fallback_malloc.ipp +++ src/fallback_malloc.ipp @@ -23,16 +23,28 @@ namespace { +// When POSIX threads are not available, make the mutex operations a nop +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 static pthread_mutex_t heap_mutex = PTHREAD_MUTEX_INITIALIZER; +#else +static void * heap_mutex = 0; +#endif class mutexor { public: +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 mutexor ( pthread_mutex_t *m ) : mtx_(m) { pthread_mutex_lock ( mtx_ ); } ~mutexor () { pthread_mutex_unlock ( mtx_ ); } +#else + mutexor ( void * ) {} + ~mutexor () {} +#endif private: mutexor ( const mutexor &rhs ); mutexor & operator = ( const mutexor &rhs ); +#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0 pthread_mutex_t *mtx_; +#endif }; Index: test/test_exception_storage.cpp =================================================================== --- test/test_exception_storage.cpp +++ test/test_exception_storage.cpp @@ -34,10 +34,11 @@ return parm; } - +#if defined(__POSIX_THREADS) && __POSIX_THREADS > 0 #define NUMTHREADS 10 size_t thread_globals [ NUMTHREADS ] = { 0 }; pthread_t threads [ NUMTHREADS ]; +#endif void print_sizes ( size_t *first, size_t *last ) { std::cout << "{ " << std::hex; @@ -49,6 +50,7 @@ int main ( int argc, char *argv [] ) { int retVal = 0; +#if defined(__POSIX_THREADS) && __POSIX_THREADS > 0 // Make the threads, let them run, and wait for them to finish for ( int i = 0; i < NUMTHREADS; ++i ) pthread_create( threads + i, NULL, thread_code, (void *) (thread_globals + i)); @@ -69,6 +71,9 @@ retVal = 2; } // print_sizes ( thread_globals, thread_globals + NUMTHREADS ); - +#else + size_t thread_globals; + retVal = thread_code(&thread_globals) != 0; +#endif return retVal; }