1*c05d8e5dSAndroid Build Coastguard Worker //===-------------------- test_exception_storage.cpp ----------------------===// 2*c05d8e5dSAndroid Build Coastguard Worker // 3*c05d8e5dSAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*c05d8e5dSAndroid Build Coastguard Worker // 5*c05d8e5dSAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open 6*c05d8e5dSAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details. 7*c05d8e5dSAndroid Build Coastguard Worker // 8*c05d8e5dSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*c05d8e5dSAndroid Build Coastguard Worker 10*c05d8e5dSAndroid Build Coastguard Worker // XFAIL: c++17 11*c05d8e5dSAndroid Build Coastguard Worker 12*c05d8e5dSAndroid Build Coastguard Worker #include <cstdlib> 13*c05d8e5dSAndroid Build Coastguard Worker #include <algorithm> 14*c05d8e5dSAndroid Build Coastguard Worker #include <iostream> 15*c05d8e5dSAndroid Build Coastguard Worker #include <__threading_support> 16*c05d8e5dSAndroid Build Coastguard Worker #include <unistd.h> 17*c05d8e5dSAndroid Build Coastguard Worker 18*c05d8e5dSAndroid Build Coastguard Worker #include "../src/cxa_exception.hpp" 19*c05d8e5dSAndroid Build Coastguard Worker 20*c05d8e5dSAndroid Build Coastguard Worker typedef __cxxabiv1::__cxa_eh_globals globals_t ; 21*c05d8e5dSAndroid Build Coastguard Worker thread_code(void * parm)22*c05d8e5dSAndroid Build Coastguard Workervoid *thread_code (void *parm) { 23*c05d8e5dSAndroid Build Coastguard Worker size_t *result = (size_t *) parm; 24*c05d8e5dSAndroid Build Coastguard Worker globals_t *glob1, *glob2; 25*c05d8e5dSAndroid Build Coastguard Worker 26*c05d8e5dSAndroid Build Coastguard Worker glob1 = __cxxabiv1::__cxa_get_globals (); 27*c05d8e5dSAndroid Build Coastguard Worker if ( NULL == glob1 ) 28*c05d8e5dSAndroid Build Coastguard Worker std::cerr << "Got null result from __cxa_get_globals" << std::endl; 29*c05d8e5dSAndroid Build Coastguard Worker 30*c05d8e5dSAndroid Build Coastguard Worker glob2 = __cxxabiv1::__cxa_get_globals_fast (); 31*c05d8e5dSAndroid Build Coastguard Worker if ( glob1 != glob2 ) 32*c05d8e5dSAndroid Build Coastguard Worker std::cerr << "Got different globals!" << std::endl; 33*c05d8e5dSAndroid Build Coastguard Worker 34*c05d8e5dSAndroid Build Coastguard Worker *result = (size_t) glob1; 35*c05d8e5dSAndroid Build Coastguard Worker sleep ( 1 ); 36*c05d8e5dSAndroid Build Coastguard Worker return parm; 37*c05d8e5dSAndroid Build Coastguard Worker } 38*c05d8e5dSAndroid Build Coastguard Worker 39*c05d8e5dSAndroid Build Coastguard Worker #ifndef _LIBCXXABI_HAS_NO_THREADS 40*c05d8e5dSAndroid Build Coastguard Worker #define NUMTHREADS 10 41*c05d8e5dSAndroid Build Coastguard Worker size_t thread_globals [ NUMTHREADS ] = { 0 }; 42*c05d8e5dSAndroid Build Coastguard Worker std::__libcpp_thread_t threads [ NUMTHREADS ]; 43*c05d8e5dSAndroid Build Coastguard Worker #endif 44*c05d8e5dSAndroid Build Coastguard Worker main()45*c05d8e5dSAndroid Build Coastguard Workerint main () { 46*c05d8e5dSAndroid Build Coastguard Worker int retVal = 0; 47*c05d8e5dSAndroid Build Coastguard Worker 48*c05d8e5dSAndroid Build Coastguard Worker #ifndef _LIBCXXABI_HAS_NO_THREADS 49*c05d8e5dSAndroid Build Coastguard Worker // Make the threads, let them run, and wait for them to finish 50*c05d8e5dSAndroid Build Coastguard Worker for ( int i = 0; i < NUMTHREADS; ++i ) 51*c05d8e5dSAndroid Build Coastguard Worker std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i)); 52*c05d8e5dSAndroid Build Coastguard Worker for ( int i = 0; i < NUMTHREADS; ++i ) 53*c05d8e5dSAndroid Build Coastguard Worker std::__libcpp_thread_join ( &threads [ i ] ); 54*c05d8e5dSAndroid Build Coastguard Worker 55*c05d8e5dSAndroid Build Coastguard Worker for ( int i = 0; i < NUMTHREADS; ++i ) 56*c05d8e5dSAndroid Build Coastguard Worker if ( 0 == thread_globals [ i ] ) { 57*c05d8e5dSAndroid Build Coastguard Worker std::cerr << "Thread #" << i << " had a zero global" << std::endl; 58*c05d8e5dSAndroid Build Coastguard Worker retVal = 1; 59*c05d8e5dSAndroid Build Coastguard Worker } 60*c05d8e5dSAndroid Build Coastguard Worker 61*c05d8e5dSAndroid Build Coastguard Worker std::sort ( thread_globals, thread_globals + NUMTHREADS ); 62*c05d8e5dSAndroid Build Coastguard Worker for ( int i = 1; i < NUMTHREADS; ++i ) 63*c05d8e5dSAndroid Build Coastguard Worker if ( thread_globals [ i - 1 ] == thread_globals [ i ] ) { 64*c05d8e5dSAndroid Build Coastguard Worker std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl; 65*c05d8e5dSAndroid Build Coastguard Worker retVal = 2; 66*c05d8e5dSAndroid Build Coastguard Worker } 67*c05d8e5dSAndroid Build Coastguard Worker #else // _LIBCXXABI_HAS_NO_THREADS 68*c05d8e5dSAndroid Build Coastguard Worker size_t thread_globals; 69*c05d8e5dSAndroid Build Coastguard Worker // Check that __cxa_get_globals() is not NULL. 70*c05d8e5dSAndroid Build Coastguard Worker if (thread_code(&thread_globals) == 0) { 71*c05d8e5dSAndroid Build Coastguard Worker retVal = 1; 72*c05d8e5dSAndroid Build Coastguard Worker } 73*c05d8e5dSAndroid Build Coastguard Worker #endif // !_LIBCXXABI_HAS_NO_THREADS 74*c05d8e5dSAndroid Build Coastguard Worker return retVal; 75*c05d8e5dSAndroid Build Coastguard Worker } 76