summaryrefslogtreecommitdiff
path: root/ACE/ace/Atomic_Op.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Atomic_Op.h')
-rw-r--r--ACE/ace/Atomic_Op.h382
1 files changed, 382 insertions, 0 deletions
diff --git a/ACE/ace/Atomic_Op.h b/ACE/ace/Atomic_Op.h
new file mode 100644
index 00000000000..77a3b4b89bd
--- /dev/null
+++ b/ACE/ace/Atomic_Op.h
@@ -0,0 +1,382 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Atomic_Op.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@uci.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_ATOMIC_OP_H
+#define ACE_ATOMIC_OP_H
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Thread_Mutex.h"
+
+// Include the templates here.
+#include "ace/Atomic_Op_T.h"
+
+// Determine whether builtin atomic op support is
+// available on this platform.
+#if defined (ACE_HAS_THREADS)
+# if defined (WIN32)
+# if defined (ACE_HAS_INTRINSIC_INTERLOCKED)
+# define ACE_HAS_BUILTIN_ATOMIC_OP
+# endif /* ACE_HAS_INTRINSIC_INTERLOCKED */
+# if defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
+# define ACE_HAS_BUILTIN_ATOMIC_OP
+# else /* ACE_HAS_INTERLOCKED_EXCHANGEADD */
+ // Inline assembly emulation of InterlockedExchangeAdd
+ // is currently only implemented for MSVC (x86 only) and Borland.
+# if (defined (_MSC_VER) && defined (_M_IX86)) || defined (__BORLANDC__)
+# define ACE_HAS_BUILTIN_ATOMIC_OP
+# endif /* _MSC_VER || __BORLANDC__ */
+# endif /* ACE_HAS_INTERLOCKED_EXCHANGEADD */
+# elif defined (ACE_HAS_INTEL_ASSEMBLY)
+# define ACE_HAS_BUILTIN_ATOMIC_OP
+# elif defined (ACE_HAS_VXATOMICLIB)
+# define ACE_HAS_BUILTIN_ATOMIC_OP
+# elif defined (ACE_HAS_SOLARIS_ATOMIC_LIB) && !defined (ACE_HAS_BUILTIN_ATOMIC_OP)
+# define ACE_HAS_BUILTIN_ATOMIC_OP
+# endif /* WIN32 */
+#endif /* ACE_HAS_THREADS */
+
+// If we have the GCC Atomic builtin support, use it
+#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
+# undef ACE_HAS_BUILTIN_ATOMIC_OP
+#endif
+
+// Include the templates here.
+#include "ace/Atomic_Op_GCC_T.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
+
+/**
+ * @brief Specialization of ACE_Atomic_Op for platforms that
+ * support atomic integer operations.
+ *
+ * Specialization of ACE_Atomic_Op for platforms that support atomic
+ * integer operations.
+ */
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long>
+{
+public:
+ /// Initialize @c value_ to 0.
+ ACE_Atomic_Op (void);
+
+ /// Initialize @c value_ to c.
+ ACE_Atomic_Op (long c);
+
+ /// Manage copying...
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c);
+
+ /// Atomically pre-increment @c value_.
+ long operator++ (void);
+
+ /// Atomically post-increment @c value_.
+ long operator++ (int);
+
+ /// Atomically increment @c value_ by rhs.
+ long operator+= (long rhs);
+
+ /// Atomically pre-decrement @c value_.
+ long operator-- (void);
+
+ /// Atomically post-decrement @c value_.
+ long operator-- (int);
+
+ /// Atomically decrement @c value_ by rhs.
+ long operator-= (long rhs);
+
+ /// Atomically compare @c value_ with rhs.
+ bool operator== (long rhs) const;
+
+ /// Atomically compare @c value_ with rhs.
+ bool operator!= (long rhs) const;
+
+ /// Atomically check if @c value_ greater than or equal to rhs.
+ bool operator>= (long rhs) const;
+
+ /// Atomically check if @c value_ greater than rhs.
+ bool operator> (long rhs) const;
+
+ /// Atomically check if @c value_ less than or equal to rhs.
+ bool operator<= (long rhs) const;
+
+ /// Atomically check if @c value_ less than rhs.
+ bool operator< (long rhs) const;
+
+ /// Atomically assign rhs to @c value_.
+ ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (long rhs);
+
+ /// Atomically assign <rhs> to @c value_.
+ ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &rhs);
+
+ /// Exchange value with @a newval.
+ long exchange (long newval);
+
+ /// Explicitly return @c value_.
+ long value (void) const;
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Explicitly return @c value_ (by reference).
+ volatile long &value_i (void);
+
+ // ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+ /// Used during ACE object manager initialization to optimize the fast
+ /// atomic op implementation according to the number of CPUs.
+ static void init_functions (void);
+
+private:
+
+ /// This function cannot be supported by this template specialization.
+ /// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
+ /// template instead.
+ ACE_Thread_Mutex &mutex (void);
+
+private:
+
+ /// Current object decorated by the atomic op.
+ volatile long value_;
+
+ /// Pointers to selected atomic op implementations.
+ static long (*increment_fn_) (volatile long *);
+ static long (*decrement_fn_) (volatile long *);
+ static long (*exchange_fn_) (volatile long *, long);
+ static long (*exchange_add_fn_) (volatile long *, long);
+};
+
+/**
+ * @brief Specialization of ACE_Atomic_Op for platforms that
+ * support atomic integer operations.
+ *
+ * Specialization of ACE_Atomic_Op for platforms that support atomic
+ * integer operations.
+ */
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>
+{
+public:
+ /// Initialize @c value_ to 0.
+ ACE_Atomic_Op (void);
+
+ /// Initialize @c value_ to c.
+ ACE_Atomic_Op (unsigned long c);
+
+ /// Manage copying...
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
+
+ /// Atomically pre-increment @c value_.
+ unsigned long operator++ (void);
+
+ /// Atomically post-increment @c value_.
+ unsigned long operator++ (int);
+
+ /// Atomically increment @c value_ by rhs.
+ unsigned long operator+= (unsigned long rhs);
+
+ /// Atomically pre-decrement @c value_.
+ unsigned long operator-- (void);
+
+ /// Atomically post-decrement @c value_.
+ unsigned long operator-- (int);
+
+ /// Atomically decrement @c value_ by rhs.
+ unsigned long operator-= (unsigned long rhs);
+
+ /// Atomically compare @c value_ with rhs.
+ bool operator== (unsigned long rhs) const;
+
+ /// Atomically compare @c value_ with rhs.
+ bool operator!= (unsigned long rhs) const;
+
+ /// Atomically check if @c value_ greater than or equal to rhs.
+ bool operator>= (unsigned long rhs) const;
+
+ /// Atomically check if @c value_ greater than rhs.
+ bool operator> (unsigned long rhs) const;
+
+ /// Atomically check if @c value_ less than or equal to rhs.
+ bool operator<= (unsigned long rhs) const;
+
+ /// Atomically check if @c value_ less than rhs.
+ bool operator< (unsigned long rhs) const;
+
+ /// Atomically assign rhs to @c value_.
+ ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (unsigned long rhs);
+
+ /// Atomically assign <rhs> to @c value_.
+ ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &rhs);
+
+ /// Exchange value with @a newval.
+ unsigned long exchange (unsigned long newval);
+
+ /// Explicitly return @c value_.
+ unsigned long value (void) const;
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Explicitly return @c value_ (by reference).
+ volatile unsigned long &value_i (void);
+
+ // ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+ /// Used during ACE object manager initialization to optimize the fast
+ /// atomic op implementation according to the number of CPUs.
+ static void init_functions (void);
+
+private:
+
+ /// This function cannot be supported by this template specialization.
+ /// If you need access to an underlying lock, use the ACE_Atomic_Op_Ex
+ /// template instead.
+ ACE_Thread_Mutex &mutex (void);
+
+private:
+
+ /// Current object decorated by the atomic op.
+ volatile unsigned long value_;
+
+ // Pointers to selected atomic op implementations.
+ static long (*increment_fn_) (volatile long *);
+ static long (*decrement_fn_) (volatile long *);
+ static long (*exchange_fn_) (volatile long *, long);
+ static long (*exchange_add_fn_) (volatile long *, long);
+};
+
+#endif /* !ACE_HAS_BUILTIN_ATOMIC_OP */
+
+#if defined (ACE_HAS_GCC_ATOMIC_BUILTINS) && (ACE_HAS_GCC_ATOMIC_BUILTINS == 1)
+
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, int>
+: public ACE_Atomic_Op_GCC<int>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (int c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, int> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, int> &operator= (int rhs);
+};
+
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int>
+: public ACE_Atomic_Op_GCC<unsigned int>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (unsigned int c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, unsigned int> &operator= (unsigned int rhs);
+};
+
+// If we have built in atomic op, use that, the assignment operator
+// is faster for a long/unsinged long
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long>
+: public ACE_Atomic_Op_GCC<long>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (long c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, long> &operator= (long rhs);
+};
+
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>
+: public ACE_Atomic_Op_GCC<unsigned long>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (unsigned long c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long> &operator= (unsigned long rhs);
+};
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, long long>
+: public ACE_Atomic_Op_GCC<long long>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (long long c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, long long> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, long long> &operator= (long long rhs);
+};
+
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long>
+: public ACE_Atomic_Op_GCC<unsigned long long>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (unsigned long long c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long long> &operator= (unsigned long long rhs);
+};
+
+#if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_2)
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, short>
+: public ACE_Atomic_Op_GCC<short>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (short c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, short> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, short> &operator= (short rhs);
+};
+
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short>
+: public ACE_Atomic_Op_GCC<unsigned short>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (unsigned short c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, unsigned short> &operator= (unsigned short rhs);
+};
+#endif
+
+#if !defined (ACE_LACKS_GCC_ATOMIC_BUILTINS_1)
+template<>
+class ACE_Export ACE_Atomic_Op<ACE_Thread_Mutex, bool>
+: public ACE_Atomic_Op_GCC<bool>
+{
+public:
+ ACE_Atomic_Op (void);
+ ACE_Atomic_Op (bool c);
+ ACE_Atomic_Op (const ACE_Atomic_Op<ACE_Thread_Mutex, bool> &c);
+ ACE_Atomic_Op<ACE_Thread_Mutex, bool> &operator= (bool rhs);
+};
+#endif
+
+#endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/Atomic_Op.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+#endif /*ACE_ATOMIC_OP_H*/