|
Boost-Commit : |
From: igaztanaga_at_[hidden]
Date: 2007-10-18 12:20:28
Author: igaztanaga
Date: 2007-10-18 12:20:28 EDT (Thu, 18 Oct 2007)
New Revision: 40159
URL: http://svn.boost.org/trac/boost/changeset/40159
Log:
Added atomic operations for alpha processors
Text files modified:
trunk/boost/interprocess/detail/atomic.hpp | 78 +++++++++++++++++++++++++++++++++++++++
1 files changed, 77 insertions(+), 1 deletions(-)
Modified: trunk/boost/interprocess/detail/atomic.hpp
==============================================================================
--- trunk/boost/interprocess/detail/atomic.hpp (original)
+++ trunk/boost/interprocess/detail/atomic.hpp 2007-10-18 12:20:28 EDT (Thu, 18 Oct 2007)
@@ -436,8 +436,84 @@
} //namespace interprocess{
} //namespace boost{
-#else
+#elif defined(__osf__)
+
+#include <machine/builtins.h>
+#include <c_asm.h>
+
+namespace boost{
+namespace interprocess{
+namespace detail{
+
+//! Atomically increment an apr_uint32_t by 1
+//! "mem": pointer to the object
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
+{ return __ATOMIC_INCREMENT_LONG(mem); }
+
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
+//! Returns false if the value becomes zero on decrement, otherwise true
+inline bool atomic_dec32(volatile boost::uint32_t *mem)
+{ return __ATOMIC_DECREMENT_LONG(mem); }
+
+// Rational for the implementation of the atomic read and write functions.
+//
+// 1. The Alpha Architecture Handbook requires that access to a byte,
+// an aligned word, an aligned longword, or an aligned quadword is
+// atomic. (See 'Alpha Architecture Handbook', version 4, chapter 5.2.2.)
+//
+// 2. The CXX User's Guide states that volatile quantities are accessed
+// with single assembler instructions, and that a compilation error
+// occurs when declaring a quantity as volatile which is not properly
+// aligned.
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{ return *mem; }
+//! 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; }
+
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
+//! "mem": pointer to the value
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
+//! Returns the old value of *mem
+inline boost::uint32_t atomic_cas32
+ (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
+{
+ // Notes:
+ //
+ // 1. Branch prediction prefers branches, as we assume that the lock
+ // is not stolen usually, we branch forward conditionally on success
+ // of the store, and not conditionally backwards on failure.
+ //
+ // 2. The memory lock is invalidated when a branch is taken between
+ // load and store. Therefore we can only branch if we don't need a
+ // store.
+
+ return asm("10: ldl_l %v0,(%a0) ;" // load prev value from mem and lock mem
+ " cmpeq %v0,%a2,%t0 ;" // compare with given value
+ " beq %t0,20f ;" // if not equal, we're done
+ " mov %a1,%t0 ;" // load new value into scratch register
+ " stl_c %t0,(%a0) ;" // store new value to locked mem (overwriting scratch)
+ " bne %t0,20f ;" // store succeeded, we're done
+ " br 10b ;" // lock has been stolen, retry
+ "20: ",
+ mem, with, cmp);
+}
+
+} //namespace detail{
+} //namespace interprocess{
+} //namespace boost{
+
+#else
+
#error No atomic operations implemented for this platform, sorry!
#endif
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk