[cfe-commits] [libcxxabi] r135586 - in /libcxxabi/trunk: src/cxa_exception.hpp src/cxa_exception_storage.cpp test/test_exception_storage.cpp
Marshall Clow
mclow at qualcomm.com
Wed Jul 20 07:53:53 PDT 2011
Author: marshall
Date: Wed Jul 20 09:53:53 2011
New Revision: 135586
URL: http://llvm.org/viewvc/llvm-project?rev=135586&view=rev
Log:
Exception handling stuctures, and thread-local variables for exception handling
Added:
libcxxabi/trunk/src/cxa_exception.hpp
libcxxabi/trunk/src/cxa_exception_storage.cpp
libcxxabi/trunk/test/test_exception_storage.cpp
Added: libcxxabi/trunk/src/cxa_exception.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception.hpp?rev=135586&view=auto
==============================================================================
--- libcxxabi/trunk/src/cxa_exception.hpp (added)
+++ libcxxabi/trunk/src/cxa_exception.hpp Wed Jul 20 09:53:53 2011
@@ -0,0 +1,95 @@
+#include <exception> // for std::unexpected_handler and std::terminate_handler
+#include <cxxabi.h>
+#include "unwind.h"
+
+namespace __cxxabiv1 {
+
+ struct __cxa_exception {
+#if __LP64__
+ // This is a new field to support C++ 0x exception_ptr.
+ // For binary compatibility it is at the start of this
+ // struct which is prepended to the object thrown in
+ // __cxa_allocate_exception.
+ size_t referenceCount;
+#endif
+
+ // Manage the exception object itself.
+ std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+ std::unexpected_handler unexpectedHandler;
+ std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+#ifdef __ARM_EABI_UNWINDER__
+ __cxa_exception* nextPropagatingException;
+ int propagationCount;
+#else
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+#endif
+
+#if !__LP64__
+ // This is a new field to support C++ 0x exception_ptr.
+ // For binary compatibility it is placed where the compiler
+ // previously adding padded to 64-bit align unwindHeader.
+ size_t referenceCount;
+#endif
+
+ _Unwind_Exception unwindHeader;
+ };
+
+ struct __cxa_dependent_exception {
+#if __LP64__
+ void* primaryException;
+#endif
+
+ // Unused dummy data (should be set to null)
+ std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ std::unexpected_handler unexpectedHandler;
+ std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+#ifdef __ARM_EABI_UNWINDER__
+ __cxa_exception* nextPropagatingException;
+ int propagationCount;
+#else
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void * catchTemp;
+ void *adjustedPtr;
+#endif
+
+#if !__LP64__
+ void* primaryException;
+#endif
+
+ _Unwind_Exception unwindHeader;
+ };
+
+ struct __cxa_eh_globals {
+ __cxa_exception * caughtExceptions;
+ unsigned int uncaughtExceptions;
+#ifdef __ARM_EABI_UNWINDER__
+ __cxa_exception* propagatingExceptions;
+#endif
+ };
+
+ extern "C" __cxa_eh_globals * __cxa_get_globals () throw();
+ extern "C" __cxa_eh_globals * __cxa_get_globals_fast () throw();
+
+ extern "C" void * __cxa_allocate_dependent_exception () throw();
+ extern "C" void __cxa_free_dependent_exception (void * dependent_exception) throw();
+
+}
\ No newline at end of file
Added: libcxxabi/trunk/src/cxa_exception_storage.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception_storage.cpp?rev=135586&view=auto
==============================================================================
--- libcxxabi/trunk/src/cxa_exception_storage.cpp (added)
+++ libcxxabi/trunk/src/cxa_exception_storage.cpp Wed Jul 20 09:53:53 2011
@@ -0,0 +1,81 @@
+//===--------------------- cxa_exception_storage.cpp ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//
+// This file implements the storage for the "Caught Exception Stack"
+// http://www.codesourcery.com/public/cxx-abi/abi-eh.html (section 2.2.2)
+//
+//===----------------------------------------------------------------------===//
+
+#include "cxa_exception.hpp"
+
+#ifdef HAS_THREAD_LOCAL
+
+namespace __cxxabiv1 {
+
+namespace {
+ __cxa_eh_globals * __globals () throw () {
+ static thread_local __cxa_eh_globals eh_globals;
+ return &eh_globals;
+ }
+ }
+
+extern "C" {
+ __cxa_eh_globals * __cxa_get_globals () throw() { return __globals (); }
+ __cxa_eh_globals * __cxa_get_globals_fast () throw() { return __globals (); }
+ }
+}
+
+#else
+
+#include <pthread.h>
+#include <cstdlib> // for calloc, free
+#include <exception> // for std::terminate
+
+// In general, we treat all pthread errors as fatal - our error
+// reporting mechanism is std::terminate.
+
+namespace __cxxabiv1 {
+namespace {
+ pthread_once_t flag_ = PTHREAD_ONCE_INIT;
+ pthread_key_t key_;
+
+ void destruct_ (void *p) throw () {
+ std::free ( p );
+ if ( 0 != ::pthread_setspecific ( key_, NULL )) std::terminate ();
+ }
+
+ void construct_ () throw () {
+ if ( 0 != pthread_key_create ( &key_, destruct_ )) std::terminate ();
+ }
+}
+
+extern "C" {
+ __cxa_eh_globals * __cxa_get_globals () throw () {
+ // First time through, create the key.
+ if ( 0 != pthread_once ( &flag_, construct_ )) std::terminate ();
+
+ // Try to get the globals for this thread
+ __cxa_eh_globals* retVal = __cxa_get_globals_fast ();
+
+ // If this is the first time we've been asked for these globals, create them
+ if ( NULL == retVal ) {
+ retVal = static_cast<__cxa_eh_globals*>
+ (std::calloc (1, sizeof (__cxa_eh_globals)));
+ if ( NULL == retVal ) std::terminate ();
+ if ( 0 != pthread_setspecific ( key_, retVal )) std::terminate ();
+ }
+ return retVal;
+ }
+
+ __cxa_eh_globals * __cxa_get_globals_fast () throw () {
+ return static_cast<__cxa_eh_globals*>(::pthread_getspecific(key_));
+ }
+
+}
+}
+#endif
Added: libcxxabi/trunk/test/test_exception_storage.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_exception_storage.cpp?rev=135586&view=auto
==============================================================================
--- libcxxabi/trunk/test/test_exception_storage.cpp (added)
+++ libcxxabi/trunk/test/test_exception_storage.cpp Wed Jul 20 09:53:53 2011
@@ -0,0 +1,64 @@
+#include <cstdlib>
+#include <algorithm>
+#include <iostream>
+#include <pthread.h>
+
+#include "cxa_exception.hpp"
+
+typedef __cxxabiv1::__cxa_eh_globals globals_t ;
+
+void *thread_code (void *parm) {
+ size_t *result = (size_t *) parm;
+ globals_t *glob1, *glob2;
+
+ glob1 = __cxxabiv1::__cxa_get_globals ();
+ if ( NULL == glob1 )
+ std::cerr << "Got null result from __cxa_get_globals" << std::endl;
+
+ glob2 = __cxxabiv1::__cxa_get_globals_fast ();
+ if ( glob1 != glob2 )
+ std::cerr << "Got different globals!" << std::endl;
+
+ *result = (size_t) glob1;
+ sleep ( 1 );
+ return parm;
+ }
+
+
+#define NUMTHREADS 10
+size_t thread_globals [ NUMTHREADS ] = { 0 };
+pthread_t threads [ NUMTHREADS ];
+
+void print_sizes ( size_t *first, size_t *last ) {
+ std::cout << "{ " << std::hex;
+ for ( size_t *iter = first; iter != last; ++iter )
+ std::cout << *iter << " ";
+ std::cout << "}" << std::dec << std::endl;
+ }
+
+int main ( int argc, char *argv [] ) {
+ int retVal = 0;
+
+// Make the threads, let them run, and wait for them to finish
+ for ( int i = 0; i < NUMTHREADS; ++i )
+ pthread_create( threads + i, NULL, thread_code, (void *) (thread_globals + i));
+ for ( int i = 0; i < NUMTHREADS; ++i )
+ pthread_join ( threads [ i ], NULL );
+
+ for ( int i = 0; i < NUMTHREADS; ++i )
+ if ( 0 == thread_globals [ i ] ) {
+ std::cerr << "Thread #" << i << " had a zero global" << std::endl;
+ retVal = 1;
+ }
+
+// print_sizes ( thread_globals, thread_globals + NUMTHREADS );
+ std::sort ( thread_globals, thread_globals + NUMTHREADS );
+ for ( int i = 1; i < NUMTHREADS; ++i ) {
+ if ( thread_globals [ i - 1 ] == thread_globals [ i ] )
+ std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl;
+ retVal = 2;
+ }
+// print_sizes ( thread_globals, thread_globals + NUMTHREADS );
+
+ return retVal;
+ }
More information about the cfe-commits
mailing list