1 //===-------------------- test_exception_storage.cpp ----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // TODO(ldionne): This test fails on Ubuntu Focal on our CI nodes (and only there), in 32 bit mode. 10 // UNSUPPORTED: linux && 32bits-on-64bits 11 12 #include <algorithm> 13 #include <cstdio> 14 #include <cstdlib> 15 #include <__threading_support> 16 #include <unistd.h> 17 18 #include "../src/cxa_exception.h" 19 20 typedef __cxxabiv1::__cxa_eh_globals globals_t ; 21 22 void *thread_code (void *parm) { 23 size_t *result = (size_t *) parm; 24 globals_t *glob1, *glob2; 25 26 glob1 = __cxxabiv1::__cxa_get_globals (); 27 if ( NULL == glob1 ) 28 std::printf("Got null result from __cxa_get_globals\n"); 29 30 glob2 = __cxxabiv1::__cxa_get_globals_fast (); 31 if ( glob1 != glob2 ) 32 std::printf("Got different globals!\n"); 33 34 *result = (size_t) glob1; 35 #ifndef _LIBCXXABI_HAS_NO_THREADS 36 sleep ( 1 ); 37 #endif 38 return parm; 39 } 40 41 #ifndef _LIBCXXABI_HAS_NO_THREADS 42 #define NUMTHREADS 10 43 size_t thread_globals [ NUMTHREADS ] = { 0 }; 44 std::__libcpp_thread_t threads [ NUMTHREADS ]; 45 #endif 46 47 int main() { 48 #ifndef _LIBCXXABI_HAS_NO_THREADS 49 // Make the threads, let them run, and wait for them to finish 50 for ( int i = 0; i < NUMTHREADS; ++i ) 51 std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i)); 52 for ( int i = 0; i < NUMTHREADS; ++i ) 53 std::__libcpp_thread_join ( &threads [ i ] ); 54 55 int retVal = 0; 56 for ( int i = 0; i < NUMTHREADS; ++i ) { 57 if ( 0 == thread_globals [ i ] ) { 58 std::printf("Thread #%d had a zero global\n", i); 59 retVal = 1; 60 } 61 } 62 63 std::sort ( thread_globals, thread_globals + NUMTHREADS ); 64 for ( int i = 1; i < NUMTHREADS; ++i ) { 65 if ( thread_globals [ i - 1 ] == thread_globals [ i ] ) { 66 std::printf("Duplicate thread globals (%d and %d)\n", i-1, i); 67 retVal = 2; 68 } 69 } 70 return retVal; 71 #else // _LIBCXXABI_HAS_NO_THREADS 72 size_t thread_globals; 73 thread_code(&thread_globals); 74 // Check that __cxa_get_globals() is not NULL. 75 return (thread_globals == 0) ? 1 : 0; 76 #endif // !_LIBCXXABI_HAS_NO_THREADS 77 } 78