xref: /aosp_15_r20/external/libcxxabi/test/test_exception_storage.pass.cpp (revision c05d8e5dc3e10f6ce4317e8bc22cc4a25f55fa94)
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 Worker void *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 Worker int 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