Boost logo

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