test_exception_storage.cpp revision b9f2cc816dc3e5369507db9509bea6d10b524a94
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
1061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <cstdlib>
1161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <algorithm>
1261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <iostream>
1361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <pthread.h>
1461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
1561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include "cxa_exception.hpp"
1661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
1761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowtypedef __cxxabiv1::__cxa_eh_globals globals_t ;
1861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
1961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowvoid *thread_code (void *parm) {
2061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    size_t *result = (size_t *) parm;
2161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    globals_t *glob1, *glob2;
2261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
2361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    glob1 = __cxxabiv1::__cxa_get_globals ();
2461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    if ( NULL == glob1 )
2561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        std::cerr << "Got null result from __cxa_get_globals" << std::endl;
2661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
2761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    glob2 = __cxxabiv1::__cxa_get_globals_fast ();
2861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    if ( glob1 != glob2 )
2961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        std::cerr << "Got different globals!" << std::endl;
3061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
3161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    *result = (size_t) glob1;
3261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    sleep ( 1 );
3361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    return parm;
3461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    }
3561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
3661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
3761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#define NUMTHREADS  10
3861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowsize_t      thread_globals [ NUMTHREADS ] = { 0 };
3961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowpthread_t   threads        [ NUMTHREADS ];
4061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
4161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowvoid print_sizes ( size_t *first, size_t *last ) {
4261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    std::cout << "{ " << std::hex;
4361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( size_t *iter = first; iter != last; ++iter )
4461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        std::cout << *iter << " ";
4561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    std::cout << "}" << std::dec << std::endl;
4661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    }
4761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
4861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowint main ( int argc, char *argv [] ) {
4961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    int retVal = 0;
5061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
5161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow//  Make the threads, let them run, and wait for them to finish
5261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 0; i < NUMTHREADS; ++i )
5361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        pthread_create( threads + i, NULL, thread_code, (void *) (thread_globals + i));
5461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 0; i < NUMTHREADS; ++i )
5561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        pthread_join ( threads [ i ], NULL );
5661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
5761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 0; i < NUMTHREADS; ++i )
5861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        if ( 0 == thread_globals [ i ] ) {
5961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            std::cerr << "Thread #" << i << " had a zero global" << std::endl;
6061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            retVal = 1;
6161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            }
6261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
6361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow//  print_sizes ( thread_globals, thread_globals + NUMTHREADS );
6461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    std::sort ( thread_globals, thread_globals + NUMTHREADS );
6561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 1; i < NUMTHREADS; ++i ) {
6661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        if ( thread_globals [ i - 1 ] == thread_globals [ i ] )
6761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl;
6861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            retVal = 2;
6961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            }
7061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow//  print_sizes ( thread_globals, thread_globals + NUMTHREADS );
7161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
7261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    return retVal;
7361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    }
74