blob: ef2524f4784c58bf1952b4b63da20cd67f866d8d [file] [log] [blame]
Howard Hinnant987afbe2011-12-06 18:01:47 +00001//===-------------------- 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
Marshall Clow1df50ca2011-07-20 14:53:53 +000010#include <cstdlib>
11#include <algorithm>
12#include <iostream>
Asiri Rathnayake97ba9fa2017-01-03 12:58:34 +000013#include <__threading_support>
Howard Hinnant805036c2012-01-28 00:30:38 +000014#include <unistd.h>
Marshall Clow1df50ca2011-07-20 14:53:53 +000015
Howard Hinnant805036c2012-01-28 00:30:38 +000016#include "../src/cxa_exception.hpp"
Marshall Clow1df50ca2011-07-20 14:53:53 +000017
18typedef __cxxabiv1::__cxa_eh_globals globals_t ;
19
20void *thread_code (void *parm) {
21 size_t *result = (size_t *) parm;
22 globals_t *glob1, *glob2;
23
24 glob1 = __cxxabiv1::__cxa_get_globals ();
25 if ( NULL == glob1 )
26 std::cerr << "Got null result from __cxa_get_globals" << std::endl;
27
28 glob2 = __cxxabiv1::__cxa_get_globals_fast ();
29 if ( glob1 != glob2 )
30 std::cerr << "Got different globals!" << std::endl;
31
32 *result = (size_t) glob1;
33 sleep ( 1 );
34 return parm;
35 }
36
Asiri Rathnayake7c98baa2016-09-21 09:09:32 +000037#ifndef _LIBCXXABI_HAS_NO_THREADS
Marshall Clow1df50ca2011-07-20 14:53:53 +000038#define NUMTHREADS 10
Asiri Rathnayake6d3ea682016-10-13 15:05:19 +000039size_t thread_globals [ NUMTHREADS ] = { 0 };
Asiri Rathnayake97ba9fa2017-01-03 12:58:34 +000040std::__libcpp_thread_t threads [ NUMTHREADS ];
Jonathan Roelofs40e98422014-05-06 21:30:56 +000041#endif
Marshall Clow1df50ca2011-07-20 14:53:53 +000042
Eric Fiseliera140cba2016-12-24 00:37:13 +000043int main () {
Marshall Clow1df50ca2011-07-20 14:53:53 +000044 int retVal = 0;
45
Asiri Rathnayake7c98baa2016-09-21 09:09:32 +000046#ifndef _LIBCXXABI_HAS_NO_THREADS
Marshall Clow1df50ca2011-07-20 14:53:53 +000047// Make the threads, let them run, and wait for them to finish
48 for ( int i = 0; i < NUMTHREADS; ++i )
Asiri Rathnayake97ba9fa2017-01-03 12:58:34 +000049 std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i));
Marshall Clow1df50ca2011-07-20 14:53:53 +000050 for ( int i = 0; i < NUMTHREADS; ++i )
Asiri Rathnayake97ba9fa2017-01-03 12:58:34 +000051 std::__libcpp_thread_join ( &threads [ i ] );
Marshall Clow1df50ca2011-07-20 14:53:53 +000052
53 for ( int i = 0; i < NUMTHREADS; ++i )
54 if ( 0 == thread_globals [ i ] ) {
55 std::cerr << "Thread #" << i << " had a zero global" << std::endl;
56 retVal = 1;
57 }
58
Marshall Clow1df50ca2011-07-20 14:53:53 +000059 std::sort ( thread_globals, thread_globals + NUMTHREADS );
Howard Hinnantf8d292e2012-01-31 20:01:06 +000060 for ( int i = 1; i < NUMTHREADS; ++i )
61 if ( thread_globals [ i - 1 ] == thread_globals [ i ] ) {
Marshall Clow1df50ca2011-07-20 14:53:53 +000062 std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl;
63 retVal = 2;
64 }
Asiri Rathnayake7c98baa2016-09-21 09:09:32 +000065#else // _LIBCXXABI_HAS_NO_THREADS
66 size_t thread_globals;
67 // Check that __cxa_get_globals() is not NULL.
68 if (thread_code(&thread_globals) == 0) {
69 retVal = 1;
Marshall Clow1df50ca2011-07-20 14:53:53 +000070 }
Asiri Rathnayake7c98baa2016-09-21 09:09:32 +000071#endif // !_LIBCXXABI_HAS_NO_THREADS
72 return retVal;
73}