diff options
author | chris <chris@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-02-27 00:49:25 +0000 |
---|---|---|
committer | chris <chris@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-02-27 00:49:25 +0000 |
commit | 733e2e952b6edba9082e8d34c8b058cfd16fb336 (patch) | |
tree | 72d8649c6934b9ff3f76cd25d2440d4c115efbd1 /ace/Atomic_Op.cpp | |
parent | 2b4df3b0d7e68751a6ba9d7f718590bc75fddc5e (diff) | |
download | ATCD-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.cpp | 32 |
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) { |