|
Boost : |
Subject: Re: [boost] [interprocess] atomic_write32 on GCC/x86/x68_64 lacks memory barrier
From: Lars Hagström (lars_at_[hidden])
Date: 2014-08-12 04:43:28
> Thanks for your time Lars, could you provide a patch with the
modifications you've done? Just in case Boost.Atomic
> port is not in time for Boost 1.57...
Here is my patch. I also sent you a pull request on github, in case that
makes life easier...
I also updated the versions of atomic_read32 and atomic_write32 that use
gcc compiler intrinsics. However, I have not made any changes to the
plaforms that I cannot test.
Cheers
/Lars
diff --git a/include/boost/interprocess/detail/atomic.hpp
b/include/boost/interprocess/detail/atomic.hpp
index 11992d1..60993ae 100644
--- a/include/boost/interprocess/detail/atomic.hpp
+++ b/include/boost/interprocess/detail/atomic.hpp
@@ -53,6 +53,9 @@ inline boost::uint32_t atomic_cas32
#include <boost/interprocess/detail/win32_api.hpp>
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+
namespace boost{
namespace interprocess{
namespace ipcdetail{
@@ -71,7 +74,11 @@ inline boost::uint32_t atomic_inc32(volatile
boost::uint32_t *mem)
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{ return *mem; }
+{
+ const boost::uint32_t val = *mem;
+ _ReadWriteBarrier();
+ return val;
+}
//! Atomically set an boost::uint32_t in memory
//! "mem": pointer to the object
@@ -157,13 +164,24 @@ inline boost::uint32_t atomic_dec32(volatile
boost::uint32_t *mem)
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{ return *mem; }
+{
+ const boost::uint32_t val = *mem;
+ __asm__ __volatile__ ( "" ::: "memory" );
+ return val;
+}
//! Atomically set an boost::uint32_t in memory
//! "mem": pointer to the object
//! "param": val value that the object will assume
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t
val)
-{ *mem = val; }
+{
+ __asm__ __volatile__
+ (
+ "xchgl %0, %1"
+ : "+r" (val), "+m" (*mem)
+ :: "memory"
+ );
+}
} //namespace ipcdetail{
} //namespace interprocess{
@@ -510,7 +528,7 @@ inline boost::uint32_t atomic_dec32(volatile
boost::uint32_t *mem)
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{ return *mem; }
+{ return __atomic_load_n(mem, __ATOMIC_SEQ_CST); }
//! Compare an boost::uint32_t's value with "cmp".
//! If they are the same swap the value with "with"
@@ -526,7 +544,7 @@ inline boost::uint32_t atomic_cas32
//! "mem": pointer to the object
//! "param": val value that the object will assume
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t
val)
-{ *mem = val; }
+{ __atomic_store_n(mem, val, __ATOMIC_SEQ_CST); }
} //namespace ipcdetail{
} //namespace interprocess{
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk