Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Atomic_Op.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Atomic_Op.cpp,v 1.1.1.1.2.1 2003/03/13 19:44:20 chad Exp $
00003 
00004 #include "ace/Atomic_Op.h"
00005 #include "ace/OS.h"
00006 
00007 ACE_RCSID(ace, Atomic_Op, "$Id: Atomic_Op.cpp,v 1.1.1.1.2.1 2003/03/13 19:44:20 chad Exp $")
00008 
00009 #if !defined (__ACE_INLINE__)
00010 #include "ace/Atomic_Op.i"
00011 #endif /* __ACE_INLINE__ */
00012 
00013 #if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
00014 
00015 long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::increment_fn_) (volatile long *) = 0;
00016 long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::decrement_fn_) (volatile long *) = 0;
00017 long (*ACE_Atomic_Op<ACE_Thread_Mutex, long>::exchange_add_fn_) (volatile long *, long) = 0;
00018 
00019 void
00020 ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions (void)
00021 {
00022   if (ACE_OS::num_processors () == 1)
00023     {
00024       increment_fn_ = single_cpu_increment;
00025       decrement_fn_ = single_cpu_decrement;
00026       exchange_add_fn_ = single_cpu_exchange_add;
00027     }
00028   else
00029     {
00030       increment_fn_ = multi_cpu_increment;
00031       decrement_fn_ = multi_cpu_decrement;
00032       exchange_add_fn_ = multi_cpu_exchange_add;
00033     }
00034 }
00035 
00036 void
00037 ACE_Atomic_Op<ACE_Thread_Mutex, long>::dump (void) const
00038 {
00039   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00040   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00041 }
00042 
00043 #if defined (_MSC_VER)
00044 // Disable "no return value" warning, as we will be putting
00045 // the return values directly into the EAX register.
00046 #pragma warning (push)
00047 #pragma warning (disable: 4035)
00048 #endif /* _MSC_VER */
00049 
00050 long
00051 ACE_Atomic_Op<ACE_Thread_Mutex, long>::single_cpu_increment (volatile long *value)
00052 {
00053 #if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
00054   long tmp = 1;
00055   unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
00056   asm( "xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
00057   return tmp + 1;
00058 #else /* __GNUC__ && ACE_HAS_PENTIUM */
00059   ACE_UNUSED_ARG (value);
00060   ACE_NOTSUP_RETURN (-1);
00061 #endif /* __GNUC__ && ACE_HAS_PENTIUM */
00062 }
00063 
00064 long
00065 ACE_Atomic_Op<ACE_Thread_Mutex, long>::single_cpu_decrement (volatile long *value)
00066 {
00067 #if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
00068   long tmp = -1;
00069   unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
00070   asm( "xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
00071   return tmp - 1;
00072 #else /* __GNUC__ && ACE_HAS_PENTIUM */
00073   ACE_UNUSED_ARG (value);
00074   ACE_NOTSUP_RETURN (-1);
00075 #endif /* __GNUC__ && ACE_HAS_PENTIUM */
00076 }
00077 
00078 long
00079 ACE_Atomic_Op<ACE_Thread_Mutex, long>::single_cpu_exchange_add (volatile long *value,
00080                                                                 long rhs)
00081 {
00082 #if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
00083   unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
00084   asm( "xadd %0, (%1)" : "+r"(rhs) : "r"(addr) );
00085   return rhs;
00086 #elif defined (WIN32) && !defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
00087 # if defined (_MSC_VER)
00088   __asm
00089     {
00090       mov eax, rhs
00091       mov edx, value
00092       xadd [edx], eax
00093     }
00094   // Return value is already in EAX register.
00095 # elif defined (__BORLANDC__)
00096   _EAX = rhs;
00097   _EDX = ACE_reinterpret_cast (unsigned long, value);
00098   __emit__(0x0F, 0xC1, 0x02); // xadd [edx], eax
00099   // Return value is already in EAX register.
00100 # else /* _MSC_VER */
00101   ACE_UNUSED_ARG (value);
00102   ACE_UNUSED_ARG (rhs);
00103   ACE_NOTSUP_RETURN (-1);
00104 # endif /* _MSC_VER */
00105 #else /* __GNUC__ && ACE_HAS_PENTIUM */
00106   ACE_UNUSED_ARG (value);
00107   ACE_UNUSED_ARG (rhs);
00108   ACE_NOTSUP_RETURN (-1);
00109 #endif /* __GNUC__ && ACE_HAS_PENTIUM */
00110 }
00111 
00112 long
00113 ACE_Atomic_Op<ACE_Thread_Mutex, long>::multi_cpu_increment (volatile long *value)
00114 {
00115 #if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
00116   long tmp = 1;
00117   unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
00118   asm( "lock ; xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
00119   return tmp + 1;
00120 #else /* __GNUC__ && ACE_HAS_PENTIUM */
00121   ACE_UNUSED_ARG (value);
00122   ACE_NOTSUP_RETURN (-1);
00123 #endif /* __GNUC__ && ACE_HAS_PENTIUM */
00124 }
00125 
00126 long
00127 ACE_Atomic_Op<ACE_Thread_Mutex, long>::multi_cpu_decrement (volatile long *value)
00128 {
00129 #if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
00130   long tmp = -1;
00131   unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
00132   asm( "lock ; xadd %0, (%1)" : "+r"(tmp) : "r"(addr) );
00133   return tmp - 1;
00134 #else /* __GNUC__ && ACE_HAS_PENTIUM */
00135   ACE_UNUSED_ARG (value);
00136   ACE_NOTSUP_RETURN (-1);
00137 #endif /* __GNUC__ && ACE_HAS_PENTIUM */
00138 }
00139 
00140 long
00141 ACE_Atomic_Op<ACE_Thread_Mutex, long>::multi_cpu_exchange_add (volatile long *value,
00142                                                                long rhs)
00143 {
00144 #if defined (__GNUC__) && defined (ACE_HAS_PENTIUM)
00145   unsigned long addr = ACE_reinterpret_cast (unsigned long, value);
00146   asm( "lock ; xadd %0, (%1)" : "+r"(rhs) : "r"(addr) );
00147   return rhs;
00148 #elif defined (WIN32) && !defined (ACE_HAS_INTERLOCKED_EXCHANGEADD)
00149 # if defined (_MSC_VER)
00150   __asm
00151     {
00152       mov eax, rhs
00153       mov edx, value
00154       lock xadd [edx], eax
00155     }
00156   // Return value is already in EAX register.
00157 # elif defined (__BORLANDC__)
00158   _EAX = rhs;
00159   _EDX = ACE_reinterpret_cast (unsigned long, value);
00160   __emit__(0xF0, 0x0F, 0xC1, 0x02); // lock xadd [edx], eax
00161   // Return value is already in EAX register.
00162 # else /* _MSC_VER */
00163   ACE_UNUSED_ARG (value);
00164   ACE_UNUSED_ARG (rhs);
00165   ACE_NOTSUP_RETURN (-1);
00166 # endif /* _MSC_VER */
00167 #else /* __GNUC__ && ACE_HAS_PENTIUM */
00168   ACE_UNUSED_ARG (value);
00169   ACE_UNUSED_ARG (rhs);
00170   ACE_NOTSUP_RETURN (-1);
00171 #endif /* __GNUC__ && ACE_HAS_PENTIUM */
00172 }
00173 
00174 #if defined (_MSC_VER)
00175 #pragma warning (pop)
00176 #endif /* _MSC_VER */
00177 
00178 #endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
00179 
00180 #if defined (ACE_HAS_THREADS)
00181 # if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00182 #  if !defined (ACE_HAS_BUILTIN_ATOMIC_OP)
00183 template class ACE_Atomic_Op<ACE_Thread_Mutex, long>;
00184 #  endif /* !ACE_HAS_BUILTIN_ATOMIC_OP */
00185 template class ACE_Atomic_Op_Ex<ACE_Thread_Mutex, long>;
00186 # elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00187 #  if !defined (ACE_HAS_BUILTIN_ATOMIC_OP)
00188 #   pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, long>
00189 #  endif /* !ACE_HAS_BUILTIN_ATOMIC_OP */
00190 #  pragma instantiate ACE_Atomic_Op_Ex<ACE_Thread_Mutex, long>
00191 # endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
00192 #endif /* ACE_HAS_THREADS */

Generated on Mon Jun 16 11:19:09 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002