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