Permalink
Browse files

Ensure the correct happens-before relationship between set / get

functions.

Add the C++11 std::get_new_handler().
  • Loading branch information...
1 parent d48277e commit fb8cc3b07be8677604df8df8e7b270edc2000aef David Chisnall committed Mar 27, 2012
Showing with 48 additions and 16 deletions.
  1. +29 −0 src/atomic.h
  2. +6 −4 src/exception.cc
  3. +13 −12 src/memory.cc
View
@@ -0,0 +1,29 @@
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+/**
+ * Swap macro that enforces a happens-before relationship with a corresponding
+ * ATOMIC_LOAD.
+ */
+#if __has_feature(cxx_atomic)
+#define ATOMIC_SWAP(addr, val)\
+ __atomic_exchange(addr, val, __ATOMIC_ACQ_REL)
+#elif __has_builtin(__sync_swap)
+#define ATOMIC_SWAP(addr, val)\
+ __sync_swap(addr, val)
+#else
+#define ATOMIC_SWAP(addr, val)\
+ __sync_lock_test_and_set(addr, val)
+#endif
+
+#if __has_feature(cxx_atomic)
+#define ATOMIC_LOAD(addr)\
+ __atomic_load(addr, __ATOMIC_ACQUIRE)
+#else
+#define ATOMIC_LOAD(addr)\
+ (__sync_synchronize(), *addr)
+#endif
View
@@ -32,6 +32,7 @@
#include <pthread.h>
#include "typeinfo.h"
#include "dwarf_eh.h"
+#include "atomic.h"
#include "cxxabi.h"
#pragma weak pthread_key_create
@@ -1328,15 +1329,16 @@ namespace std
{
if (thread_local_handlers) { return pathscale::set_unexpected(f); }
- return __sync_lock_test_and_set(&unexpectedHandler, f);
+ return ATOMIC_SWAP(&terminateHandler, f);
}
/**
* Sets the function that is called to terminate the program.
*/
terminate_handler set_terminate(terminate_handler f) throw()
{
if (thread_local_handlers) { return pathscale::set_terminate(f); }
- return __sync_lock_test_and_set(&terminateHandler, f);
+
+ return ATOMIC_SWAP(&terminateHandler, f);
}
/**
* Terminates the program, calling a custom terminate implementation if
@@ -1390,7 +1392,7 @@ namespace std
{
return info->unexpectedHandler;
}
- return unexpectedHandler;
+ return ATOMIC_LOAD(&unexpectedHandler);
}
/**
* Returns the current terminate handler.
@@ -1402,7 +1404,7 @@ namespace std
{
return info->terminateHandler;
}
- return terminateHandler;
+ return ATOMIC_LOAD(&terminateHandler);
}
}
#ifdef __arm__
View
@@ -36,14 +36,8 @@
#include <stddef.h>
#include <stdlib.h>
#include "stdexcept.h"
+#include "atomic.h"
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#if !__has_builtin(__sync_swap)
-#define __sync_swap __sync_lock_test_and_set
-#endif
namespace std
{
@@ -67,7 +61,12 @@ namespace std
__attribute__((weak))
new_handler set_new_handler(new_handler handler)
{
- return __sync_swap(&new_handl, handler);
+ return ATOMIC_SWAP(&new_handl, handler);
+ }
+ __attribute__((weak))
+ new_handler get_new_handler(void)
+ {
+ return ATOMIC_LOAD(&new_handl);
}
}
@@ -78,9 +77,10 @@ void* operator new(size_t size)
void * mem = malloc(size);
while (0 == mem)
{
- if (0 != new_handl)
+ new_handler h = std::get_new_handler();
+ if (0 != h)
{
- new_handl();
+ h();
}
else
{
@@ -98,11 +98,12 @@ void* operator new(size_t size, const std::nothrow_t &) throw()
void *mem = malloc(size);
while (0 == mem)
{
- if (0 != new_handl)
+ new_handler h = std::get_new_handler();
+ if (0 != h)
{
try
{
- new_handl();
+ h();
}
catch (...)
{

0 comments on commit fb8cc3b

Please sign in to comment.