test_exception_storage.cpp revision e45805f0d3f8dafef1297cc7dc49e610713f023b
1b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant//===-------------------- test_exception_storage.cpp ----------------------===// 2b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// 3b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// The LLVM Compiler Infrastructure 4b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// 5b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// 8b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant//===----------------------------------------------------------------------===// 9b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant 10e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include "../src/config.h" 11e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 1261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <cstdlib> 1361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <algorithm> 1461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <iostream> 15e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if !LIBCXXABI_SINGLE_THREADED 16e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert# include <pthread.h> 17e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 1827b00d862a71566e4d6e5fef5fd29bf8280a2f4aHoward Hinnant#include <unistd.h> 1961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 2027b00d862a71566e4d6e5fef5fd29bf8280a2f4aHoward Hinnant#include "../src/cxa_exception.hpp" 2161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 2261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowtypedef __cxxabiv1::__cxa_eh_globals globals_t ; 2361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 2461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowvoid *thread_code (void *parm) { 2561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow size_t *result = (size_t *) parm; 2661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow globals_t *glob1, *glob2; 2761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 2861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow glob1 = __cxxabiv1::__cxa_get_globals (); 2961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow if ( NULL == glob1 ) 3061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cerr << "Got null result from __cxa_get_globals" << std::endl; 3161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 3261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow glob2 = __cxxabiv1::__cxa_get_globals_fast (); 3361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow if ( glob1 != glob2 ) 3461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cerr << "Got different globals!" << std::endl; 3561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 3661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow *result = (size_t) glob1; 3761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow sleep ( 1 ); 3861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow return parm; 3961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow } 4061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 41e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if !LIBCXXABI_SINGLE_THREADED 4261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#define NUMTHREADS 10 4361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowsize_t thread_globals [ NUMTHREADS ] = { 0 }; 4461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowpthread_t threads [ NUMTHREADS ]; 45e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 4661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 4761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowvoid print_sizes ( size_t *first, size_t *last ) { 4861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cout << "{ " << std::hex; 4961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow for ( size_t *iter = first; iter != last; ++iter ) 5061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cout << *iter << " "; 5161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cout << "}" << std::dec << std::endl; 5261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow } 5361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 5461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowint main ( int argc, char *argv [] ) { 5561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow int retVal = 0; 5661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 57e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_SINGLE_THREADED 58e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert size_t thread_globals; 59e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert retVal = thread_code(&thread_globals) != 0; 60e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else 6161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow// Make the threads, let them run, and wait for them to finish 6261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow for ( int i = 0; i < NUMTHREADS; ++i ) 6361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow pthread_create( threads + i, NULL, thread_code, (void *) (thread_globals + i)); 6461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow for ( int i = 0; i < NUMTHREADS; ++i ) 6561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow pthread_join ( threads [ i ], NULL ); 6661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 6761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow for ( int i = 0; i < NUMTHREADS; ++i ) 6861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow if ( 0 == thread_globals [ i ] ) { 6961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cerr << "Thread #" << i << " had a zero global" << std::endl; 7061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow retVal = 1; 7161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow } 7261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow 7361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow// print_sizes ( thread_globals, thread_globals + NUMTHREADS ); 7461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::sort ( thread_globals, thread_globals + NUMTHREADS ); 756953d901c3fd95e27241b305f35a0fc97bd881e6Howard Hinnant for ( int i = 1; i < NUMTHREADS; ++i ) 766953d901c3fd95e27241b305f35a0fc97bd881e6Howard Hinnant if ( thread_globals [ i - 1 ] == thread_globals [ i ] ) { 7761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl; 7861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow retVal = 2; 7961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow } 8061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow// print_sizes ( thread_globals, thread_globals + NUMTHREADS ); 81e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 82e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 8361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow return retVal; 8461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow } 85