Atomic_Op_T.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Atomic_Op_T.h
00006  *
00007  *  $Id: Atomic_Op_T.h 80826 2008-03-04 14:51:23Z wotte $
00008  *
00009  *  @author Douglas C. Schmidt <schmidt@uci.edu>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef ACE_ATOMIC_OP_T_H
00014 #define ACE_ATOMIC_OP_T_H
00015 #include /**/ "ace/pre.h"
00016 
00017 #include /**/ "ace/config-all.h"
00018 
00019 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00020 # pragma once
00021 #endif /* ACE_LACKS_PRAGMA_ONCE */
00022 
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 template<typename TYPE>
00026 struct ACE_Type_Traits
00027 {
00028   typedef TYPE const & parameter_type;
00029 };
00030 
00031 template<>
00032 struct ACE_Type_Traits<bool>
00033 {
00034   typedef bool parameter_type;
00035 };
00036 
00037 template<>
00038 struct ACE_Type_Traits<char>
00039 {
00040   typedef char parameter_type;
00041 };
00042 
00043 template<>
00044 struct ACE_Type_Traits<signed char>
00045 {
00046   typedef signed char parameter_type;
00047 };
00048 
00049 template<>
00050 struct ACE_Type_Traits<unsigned char>
00051 {
00052   typedef unsigned char parameter_type;
00053 };
00054 
00055 template<>
00056 struct ACE_Type_Traits<short>
00057 {
00058   typedef short parameter_type;
00059 };
00060 
00061 template<>
00062 struct ACE_Type_Traits<unsigned short>
00063 {
00064   typedef unsigned short parameter_type;
00065 };
00066 
00067 template<>
00068 struct ACE_Type_Traits<int>
00069 {
00070   typedef int parameter_type;
00071 };
00072 
00073 template<>
00074 struct ACE_Type_Traits<unsigned int>
00075 {
00076   typedef unsigned int parameter_type;
00077 };
00078 
00079 template<>
00080 struct ACE_Type_Traits<long>
00081 {
00082   typedef long parameter_type;
00083 };
00084 
00085 template<>
00086 struct ACE_Type_Traits<unsigned long>
00087 {
00088   typedef unsigned long parameter_type;
00089 };
00090 
00091 #ifndef ACE_LACKS_LONGLONG_T
00092 template<>
00093 struct ACE_Type_Traits<long long>
00094 {
00095   typedef long long parameter_type;
00096 };
00097 #endif  /* !ACE_LACKS_LONGLONG_T */
00098 
00099 #if !defined (ACE_LACKS_LONGLONG_T) \
00100   && !defined (ACE_LACKS_UNSIGNEDLONGLONG_T)
00101 template<>
00102 struct ACE_Type_Traits<unsigned long long>
00103 {
00104   typedef unsigned long long parameter_type;
00105 };
00106 #endif  /* !ACE_LACKS_LONGLONG_T && !ACE_LACKS_UNSIGNEDLONGLONG_T */
00107 
00108 template<>
00109 struct ACE_Type_Traits<float>
00110 {
00111   typedef float parameter_type;
00112 };
00113 
00114 template<>
00115 struct ACE_Type_Traits<double>
00116 {
00117   typedef double parameter_type;
00118 };
00119 
00120 template<>
00121 struct ACE_Type_Traits<long double>
00122 {
00123   typedef long double parameter_type;
00124 };
00125 
00126 template<typename TYPE>
00127 struct ACE_Type_Traits<TYPE*>
00128 {
00129   typedef TYPE* parameter_type;
00130 };
00131 
00132 /**
00133  * @class ACE_Atomic_Op_Ex
00134  *
00135  * @brief Transparently parameterizes synchronization into basic
00136  * arithmetic operations.
00137  *
00138  * This class is described in an article in the July/August 1994
00139  * issue of the C++ Report magazine.  It implements a
00140  * templatized version of the Decorator pattern from the GoF book.
00141  *
00142  * ACE_Atomic_Op_Ex objects must be constructed with a reference
00143  * to an existing lock. A single lock can be shared between
00144  * multiple ACE_Atomic_Op_Ex objects. If you do not require this
00145  * ability consider using the ACE_Atomic_Op class instead, which
00146  * may be able to take advantage of platform-specific
00147  * optimisations to provide atomic operations without requiring a
00148  * lock.
00149  */
00150 template <class ACE_LOCK, typename TYPE>
00151 class ACE_Atomic_Op_Ex
00152 {
00153 public:
00154 
00155   typedef typename ACE_Type_Traits<TYPE>::parameter_type arg_type;
00156 
00157   // = Initialization methods.
00158 
00159   /// Initialize @c value_ to 0.
00160   ACE_Atomic_Op_Ex (ACE_LOCK & mtx);
00161 
00162   /// Initialize @c value_ to c.
00163   ACE_Atomic_Op_Ex (ACE_LOCK & mtx, arg_type c);
00164 
00165   // = Accessors.
00166 
00167   /// Atomically pre-increment @c value_.
00168   TYPE operator++ (void);
00169 
00170   /// Atomically post-increment @c value_.
00171   TYPE operator++ (int);
00172 
00173   /// Atomically increment @c value_ by rhs.
00174   TYPE operator+= (arg_type rhs);
00175 
00176   /// Atomically pre-decrement @c value_.
00177   TYPE operator-- (void);
00178 
00179   /// Atomically post-decrement @c value_.
00180   TYPE operator-- (int);
00181 
00182   /// Atomically decrement @c value_ by rhs.
00183   TYPE operator-= (arg_type rhs);
00184 
00185   /// Atomically compare @c value_ with rhs.
00186   bool operator== (arg_type rhs) const;
00187 
00188   /// Atomically compare @c value_ with rhs.
00189   bool operator!= (arg_type rhs) const;
00190 
00191   /// Atomically check if @c value_ greater than or equal to rhs.
00192   bool operator>= (arg_type rhs) const;
00193 
00194   /// Atomically check if @c value_ greater than rhs.
00195   bool operator> (arg_type rhs) const;
00196 
00197   /// Atomically check if @c value_ less than or equal to rhs.
00198   bool operator<= (arg_type rhs) const;
00199 
00200   /// Atomically check if @c value_ less than rhs.
00201   bool operator< (arg_type rhs) const;
00202 
00203   /// Atomically assign rhs to @c value_.
00204   ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &operator= (arg_type rhs);
00205 
00206   /// Atomically assign <rhs> to @c value_.
00207   ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> &operator= (
00208     ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> const & rhs);
00209 
00210   /// Explicitly return @c value_.
00211   TYPE value (void) const;
00212 
00213   /// Dump the state of an object.
00214   void dump (void) const;
00215 
00216   // ACE_ALLOC_HOOK_DECLARE;
00217   // Declare the dynamic allocation hooks.
00218 
00219   /// Manage copying...
00220   ACE_Atomic_Op_Ex (ACE_Atomic_Op_Ex<ACE_LOCK, TYPE> const &);
00221 
00222   /**
00223    * Returns a reference to the underlying <ACE_LOCK>.  This makes it
00224    * possible to acquire the lock explicitly, which can be useful in
00225    * some cases if you instantiate the <ACE_Atomic_Op_Ex> with an
00226    * ACE_Recursive_Mutex or ACE_Process_Mutex.  @note the right
00227    * name would be lock_, but HP/C++ will choke on that!
00228    */
00229   ACE_LOCK & mutex (void);
00230 
00231   /**
00232    * Explicitly return @c value_ (by reference).  This gives the user
00233    * full, unrestricted access to the underlying value.  This method
00234    * will usually be used in conjunction with explicit access to the
00235    * lock.  Use with care ;-)
00236    */
00237   TYPE & value_i (void);
00238 
00239 private:
00240   /// Type of synchronization mechanism.
00241   ACE_LOCK & mutex_;
00242 
00243   /// Current object decorated by the atomic op.
00244   TYPE value_;
00245 };
00246 
00247 /**
00248  * @class ACE_Atomic_Op
00249  *
00250  * @brief Transparently parameterizes synchronization into basic
00251  * arithmetic operations.
00252  *
00253  * This class is described in an article in the July/August 1994
00254  * issue of the C++ Report magazine.  It implements a
00255  * templatized version of the Decorator pattern from the GoF book.
00256  *
00257  * Certain platforms may provide a template specialization for
00258  * ACE_Atomic_Op <ACE_Thread_Mutex, long> that provides optimized
00259  * atomic integer operations without actually requiring a mutex.
00260  */
00261 template <class ACE_LOCK, typename TYPE>
00262 class ACE_Atomic_Op
00263 {
00264 public:
00265 
00266   typedef typename ACE_Type_Traits<TYPE>::parameter_type arg_type;
00267 
00268   /// Initialize @c value_ to 0.
00269   ACE_Atomic_Op (void);
00270 
00271   /// Initialize @c value_ to c.
00272   ACE_Atomic_Op (arg_type c);
00273 
00274   /// Manage copying...
00275   ACE_Atomic_Op (ACE_Atomic_Op<ACE_LOCK, TYPE> const & c);
00276 
00277   /// Atomically assign rhs to @c value_.
00278   ACE_Atomic_Op<ACE_LOCK, TYPE> & operator= (arg_type rhs);
00279 
00280   /// Atomically assign <rhs> to @c value_.
00281   ACE_Atomic_Op<ACE_LOCK, TYPE> & operator= (
00282     ACE_Atomic_Op<ACE_LOCK, TYPE> const & rhs);
00283 
00284   /// Atomically pre-increment @c value_.
00285   TYPE operator++ (void);
00286 
00287   /// Atomically post-increment @c value_.
00288   TYPE operator++ (int);
00289 
00290   /// Atomically increment @c value_ by rhs.
00291   TYPE operator+= (arg_type rhs);
00292 
00293   /// Atomically pre-decrement @c value_.
00294   TYPE operator-- (void);
00295 
00296   /// Atomically post-decrement @c value_.
00297   TYPE operator-- (int);
00298 
00299   /// Atomically decrement @c value_ by rhs.
00300   TYPE operator-= (arg_type rhs);
00301 
00302   /// Atomically compare @c value_ with rhs.
00303   bool operator== (arg_type rhs) const;
00304 
00305   /// Atomically compare @c value_ with rhs.
00306   bool operator!= (arg_type rhs) const;
00307 
00308   /// Atomically check if @c value_ greater than or equal to rhs.
00309   bool operator>= (arg_type rhs) const;
00310 
00311   /// Atomically check if @c value_ greater than rhs.
00312   bool operator> (arg_type rhs) const;
00313 
00314   /// Atomically check if @c value_ less than or equal to rhs.
00315   bool operator<= (arg_type rhs) const;
00316 
00317   /// Atomically check if @c value_ less than rhs.
00318   bool operator< (arg_type rhs) const;
00319 
00320   /// Explicitly return @c value_.
00321   TYPE value (void) const;
00322 
00323   /// Dump the state of an object.
00324   void dump (void) const;
00325 
00326   /**
00327    * Returns a reference to the underlying <ACE_LOCK>.  This makes it
00328    * possible to acquire the lock explicitly, which can be useful in
00329    * some cases if you instantiate the ACE_Atomic_Op with an
00330    * ACE_Recursive_Mutex or ACE_Process_Mutex.
00331    *
00332    * @deprecated This member function is deprecated and so may go away in
00333    * the future. If you need access to the underlying mutex, consider
00334    * using the ACE_Atomic_Op_Ex template instead.
00335    */
00336   ACE_LOCK & mutex (void);
00337 
00338   /**
00339    * Explicitly return @c value_ (by reference).  This gives the user
00340    * full, unrestricted access to the underlying value.  This method
00341    * will usually be used in conjunction with explicit access to the
00342    * lock.  Use with care ;-)
00343    */
00344   TYPE & value_i (void);
00345 
00346 private:
00347   /// Type of synchronization mechanism.
00348   ACE_LOCK own_mutex_;
00349 
00350   /// Underlying atomic op implementation.
00351   ACE_Atomic_Op_Ex <ACE_LOCK, TYPE> impl_;
00352 };
00353 
00354 ACE_END_VERSIONED_NAMESPACE_DECL
00355 
00356 #if defined (__ACE_INLINE__)
00357 #include "ace/Atomic_Op_T.inl"
00358 #endif /* __ACE_INLINE__ */
00359 
00360 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
00361 #include "ace/Atomic_Op_T.cpp"
00362 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
00363 
00364 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
00365 #pragma implementation ("Atomic_Op_T.cpp")
00366 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
00367 
00368 #include /**/ "ace/post.h"
00369 #endif /*ACE_ATOMIC_OP_T_H*/

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7