|
Boost : |
From: Markus Schöpflin (markus.schoepflin_at_[hidden])
Date: 2007-10-18 10:35:26
Hello,
attached patch introduces support for the atomic ops needed by interprocess
on Tru64/CXX/Alpha. It currently misses support for atomic add and sub, but
those are not used right now.
There are a few issues I would like to raise regarding the atomic operations:
1) Currently it is not specified whether an atomic operation implies a
memory barrier or not. This should be explicitly stated.
2) atomic_sub32 does not return the old value, but atomic_add32 does. This
seems inconsistent to me.
3) Has the use of the low level atomic ops API as proposed in WG21/N2047
(see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2047.html)
been considered. If yes, why has it been rejected? If no, would it makes
sense to use this API?
4) Is there a need for an atomic ops boost library? I seem to remember that
other libraries need atomic ops as well.
Regards,
Markus
Index: atomic.hpp
===================================================================
--- atomic.hpp (revision 40078)
+++ atomic.hpp (working copy)
@@ -436,6 +436,82 @@
} //namespace interprocess{
} //namespace boost{
+#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!
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk