I would really like to write the handlers in terms of C++11 atomics. This would give us the best performance, portablity, and safety tradeoff. Unfortunately I can not yet do that. So I've put the desired code in comments, and reverted the handler getters to the slower but safer legacy atomic intrinsics.
llvm-svn: 153041
This commit is contained in:
		
							parent
							
								
									c58dc9fcd2
								
							
						
					
					
						commit
						e59dbd7b82
					
				| 
						 | 
				
			
			@ -94,6 +94,10 @@ static void default_unexpected_handler()
 | 
			
		|||
std::terminate_handler  __cxa_terminate_handler = default_terminate_handler;
 | 
			
		||||
std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler;
 | 
			
		||||
 | 
			
		||||
// In the future these will become:
 | 
			
		||||
// std::atomic<std::terminate_handler>  __cxa_terminate_handler(default_terminate_handler);
 | 
			
		||||
// std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler);
 | 
			
		||||
 | 
			
		||||
namespace std
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +107,8 @@ set_unexpected(unexpected_handler func) _NOEXCEPT
 | 
			
		|||
	if (func == 0)
 | 
			
		||||
		func = default_unexpected_handler;
 | 
			
		||||
	return __sync_swap(&__cxa_unexpected_handler, func);
 | 
			
		||||
//  Using of C++11 atomics this should be rewritten
 | 
			
		||||
//  return __cxa_unexpected_handler.exchange(func, memory_order_acq_rel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
terminate_handler
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +117,8 @@ set_terminate(terminate_handler func) _NOEXCEPT
 | 
			
		|||
	if (func == 0)
 | 
			
		||||
		func = default_terminate_handler;
 | 
			
		||||
	return __sync_swap(&__cxa_terminate_handler, func);
 | 
			
		||||
//  Using of C++11 atomics this should be rewritten
 | 
			
		||||
//  return __cxa_terminate_handler.exchange(func, memory_order_acq_rel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,10 @@ namespace std
 | 
			
		|||
unexpected_handler
 | 
			
		||||
get_unexpected() _NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return __cxa_unexpected_handler;
 | 
			
		||||
    return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0);
 | 
			
		||||
//  The above is safe but overkill on x86
 | 
			
		||||
//  Using of C++11 atomics this should be rewritten
 | 
			
		||||
//  return __cxa_unexpected_handler.load(memory_order_acq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((visibility("hidden"), noreturn))
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +50,10 @@ unexpected()
 | 
			
		|||
terminate_handler
 | 
			
		||||
get_terminate() _NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return __cxa_terminate_handler;
 | 
			
		||||
    return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0);
 | 
			
		||||
//  The above is safe but overkill on x86
 | 
			
		||||
//  Using of C++11 atomics this should be rewritten
 | 
			
		||||
//  return __cxa_terminate_handler.load(memory_order_acq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((visibility("hidden"), noreturn))
 | 
			
		||||
| 
						 | 
				
			
			@ -96,17 +102,24 @@ terminate() _NOEXCEPT
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
new_handler __cxa_new_handler = 0;
 | 
			
		||||
// In the future these will become:
 | 
			
		||||
// std::atomic<std::new_handler>  __cxa_new_handler(0);
 | 
			
		||||
 | 
			
		||||
new_handler
 | 
			
		||||
set_new_handler(new_handler handler) _NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return __sync_swap(&__cxa_new_handler, handler);
 | 
			
		||||
//  Using of C++11 atomics this should be rewritten
 | 
			
		||||
//  return __cxa_new_handler.exchange(handler, memory_order_acq_rel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
new_handler
 | 
			
		||||
get_new_handler() _NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return __cxa_new_handler;
 | 
			
		||||
    return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0);
 | 
			
		||||
//  The above is safe but overkill on x86
 | 
			
		||||
//  Using of C++11 atomics this should be rewritten
 | 
			
		||||
//  return __cxa_new_handler.load(memory_order_acq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // std
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,20 @@ extern void (*__cxa_terminate_handler)();
 | 
			
		|||
extern void (*__cxa_unexpected_handler)();
 | 
			
		||||
extern void (*__cxa_new_handler)();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
    At some point in the future these three symbols will become
 | 
			
		||||
    C++11 atomic variables:
 | 
			
		||||
 | 
			
		||||
    extern std::atomic<std::terminate_handler>  __cxa_terminate_handler;
 | 
			
		||||
    extern std::atomic<std::unexpected_handler> __cxa_unexpected_handler;
 | 
			
		||||
    extern std::atomic<std::new_handler>        __cxa_new_handler;
 | 
			
		||||
 | 
			
		||||
    This change will not impact their ABI.  But it will allow for a
 | 
			
		||||
    portible performance optimization.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
} // extern "C"
 | 
			
		||||
 | 
			
		||||
#endif  // _CXA_HANDLERS_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue