summaryrefslogtreecommitdiff
path: root/ace/Atomic_Op.cpp
diff options
context:
space:
mode:
authorchris <chris@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-02-27 00:49:25 +0000
committerchris <chris@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-02-27 00:49:25 +0000
commit733e2e952b6edba9082e8d34c8b058cfd16fb336 (patch)
tree72d8649c6934b9ff3f76cd25d2440d4c115efbd1 /ace/Atomic_Op.cpp
parent2b4df3b0d7e68751a6ba9d7f718590bc75fddc5e (diff)
downloadATCD-733e2e952b6edba9082e8d34c8b058cfd16fb336.tar.gz
ChangeLogTag:Wed Feb 26 18:42:33 2003 Christopher Kohlhoff <chris@kohlhoff.com>
Diffstat (limited to 'ace/Atomic_Op.cpp')
-rw-r--r--ace/Atomic_Op.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/ace/Atomic_Op.cpp b/ace/Atomic_Op.cpp
index b35d1d7424c..11c075d473d 100644
--- a/ace/Atomic_Op.cpp
+++ b/ace/Atomic_Op.cpp
@@ -13,6 +13,7 @@ ACE_RCSID(ace, Atomic_Op, "$Id$")
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::increment_fn_) (volatile long *) = 0;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::decrement_fn_) (volatile long *) = 0;
+long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::exchange_fn_) (volatile long *, long) = 0;
long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::exchange_add_fn_) (volatile long *, long) = 0;
void
@@ -22,12 +23,14 @@ ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions (void)
{
increment_fn_ = single_cpu_increment;
decrement_fn_ = single_cpu_decrement;
+ exchange_fn_ = single_cpu_exchange;
exchange_add_fn_ = single_cpu_exchange_add;
}
else
{
increment_fn_ = multi_cpu_increment;
decrement_fn_ = multi_cpu_decrement;
+ exchange_fn_ = multi_cpu_exchange;
exchange_add_fn_ = multi_cpu_exchange_add;
}
}
@@ -75,6 +78,20 @@ ACE_Atomic_Op<ACE_Thread_Mutex, long>::single_cpu_decrement (volatile long *valu
}
long
+ACE_Atomic_Op<ACE_Thread_Mutex, long>::single_cpu_exchange (volatile long *value,
+ long rhs)
+{
+#if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
+ unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
+ asm( "xchg %0, (%1)" : "+r"(rhs) : "r"(addr) );
+ return rhs;
+#else /* __GNUC__ && ACE_HAS_PENTIUM */
+ ACE_UNUSED_ARG (value);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* __GNUC__ && ACE_HAS_PENTIUM */
+}
+
+long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::single_cpu_exchange_add (volatile long *value,
long rhs)
{
@@ -137,6 +154,21 @@ ACE_Atomic_Op<ACE_Thread_Mutex, long>::multi_cpu_decrement (volatile long *value
}
long
+ACE_Atomic_Op<ACE_Thread_Mutex, long>::multi_cpu_exchange (volatile long *value,
+ long rhs)
+{
+#if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
+ unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
+ // The XCHG instruction automatically follows LOCK semantics
+ asm( "xchg %0, (%1)" : "+r"(rhs) : "r"(addr) );
+ return rhs;
+#else /* __GNUC__ && ACE_HAS_PENTIUM */
+ ACE_UNUSED_ARG (value);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* __GNUC__ && ACE_HAS_PENTIUM */
+}
+
+long
ACE_Atomic_Op<ACE_Thread_Mutex, long>::multi_cpu_exchange_add (volatile long *value,
long rhs)
{