summaryrefslogtreecommitdiff
path: root/src/memory.cc
diff options
context:
space:
mode:
authorDavid Chisnall <dchisnall@pathscale.com>2012-03-27 19:34:09 +0100
committerDavid Chisnall <dchisnall@pathscale.com>2012-03-27 19:34:09 +0100
commitfb8cc3b07be8677604df8df8e7b270edc2000aef (patch)
tree812f8e4d37b0838e9babb67597cfb6575d3aa816 /src/memory.cc
parentd48277e2a7749bd2555e0b75f30ed33225462429 (diff)
downloadlibcxxrt-fb8cc3b07be8677604df8df8e7b270edc2000aef.tar.gz
libcxxrt-fb8cc3b07be8677604df8df8e7b270edc2000aef.tar.bz2
libcxxrt-fb8cc3b07be8677604df8df8e7b270edc2000aef.tar.xz
Ensure the correct happens-before relationship between set / get
functions. Add the C++11 std::get_new_handler().
Diffstat (limited to 'src/memory.cc')
-rw-r--r--src/memory.cc25
1 files changed, 13 insertions, 12 deletions
diff --git a/src/memory.cc b/src/memory.cc
index bd7fd22..fec861a 100644
--- a/src/memory.cc
+++ b/src/memory.cc
@@ -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 (...)
{