00001 // Filename: atomicAdjustPosixImpl.I 00002 // Created by: drose (10Feb06) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: AtomicAdjustPosixImpl::inc 00018 // Access: Public, Static 00019 // Description: Atomically increments the indicated variable. 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE void AtomicAdjustPosixImpl:: 00022 inc(TVOLATILE AtomicAdjustPosixImpl::Integer &var) { 00023 pthread_mutex_lock(&_mutex); 00024 ++var; 00025 pthread_mutex_unlock(&_mutex); 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: AtomicAdjustPosixImpl::dec 00030 // Access: Public, Static 00031 // Description: Atomically decrements the indicated variable and 00032 // returns true if the new value is nonzero, false if it 00033 // is zero. 00034 //////////////////////////////////////////////////////////////////// 00035 INLINE bool AtomicAdjustPosixImpl:: 00036 dec(TVOLATILE AtomicAdjustPosixImpl::Integer &var) { 00037 pthread_mutex_lock(&_mutex); 00038 Integer result = --var; 00039 pthread_mutex_unlock(&_mutex); 00040 return (result != 0); 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: AtomicAdjustPosixImpl::add 00045 // Access: Public, Static 00046 // Description: Atomically computes var += delta. It is legal for 00047 // delta to be negative. 00048 //////////////////////////////////////////////////////////////////// 00049 INLINE void AtomicAdjustPosixImpl:: 00050 add(TVOLATILE AtomicAdjustPosixImpl::Integer &var, 00051 AtomicAdjustPosixImpl::Integer delta) { 00052 pthread_mutex_lock(&_mutex); 00053 var += delta; 00054 pthread_mutex_unlock(&_mutex); 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: AtomicAdjustPosixImpl::set 00059 // Access: Public, Static 00060 // Description: Atomically changes the indicated variable and 00061 // returns the original value. 00062 //////////////////////////////////////////////////////////////////// 00063 INLINE AtomicAdjustPosixImpl::Integer AtomicAdjustPosixImpl:: 00064 set(TVOLATILE AtomicAdjustPosixImpl::Integer &var, 00065 AtomicAdjustPosixImpl::Integer new_value) { 00066 pthread_mutex_lock(&_mutex); 00067 Integer orig_value = var; 00068 var = new_value; 00069 pthread_mutex_unlock(&_mutex); 00070 return orig_value; 00071 } 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: AtomicAdjustPosixImpl::get 00075 // Access: Public, Static 00076 // Description: Atomically retrieves the snapshot value of the 00077 // indicated variable. This is the only guaranteed safe 00078 // way to retrieve the value that other threads might be 00079 // asynchronously setting, incrementing, or decrementing 00080 // (via other AtomicAjust methods). 00081 //////////////////////////////////////////////////////////////////// 00082 INLINE AtomicAdjustPosixImpl::Integer AtomicAdjustPosixImpl:: 00083 get(const TVOLATILE AtomicAdjustPosixImpl::Integer &var) { 00084 pthread_mutex_lock(&_mutex); 00085 Integer orig_value = var; 00086 pthread_mutex_unlock(&_mutex); 00087 return orig_value; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: AtomicAdjustPosixImpl::set_ptr 00092 // Access: Public, Static 00093 // Description: Atomically changes the indicated variable and 00094 // returns the original value. 00095 //////////////////////////////////////////////////////////////////// 00096 INLINE AtomicAdjustPosixImpl::Pointer AtomicAdjustPosixImpl:: 00097 set_ptr(TVOLATILE AtomicAdjustPosixImpl::Pointer &var, 00098 AtomicAdjustPosixImpl::Pointer new_value) { 00099 pthread_mutex_lock(&_mutex); 00100 Pointer orig_value = var; 00101 var = new_value; 00102 pthread_mutex_unlock(&_mutex); 00103 return orig_value; 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: AtomicAdjustPosixImpl::get_ptr 00108 // Access: Public, Static 00109 // Description: Atomically retrieves the snapshot value of the 00110 // indicated variable. This is the only guaranteed safe 00111 // way to retrieve the value that other threads might be 00112 // asynchronously setting, incrementing, or decrementing 00113 // (via other AtomicAjust methods). 00114 //////////////////////////////////////////////////////////////////// 00115 INLINE AtomicAdjustPosixImpl::Pointer AtomicAdjustPosixImpl:: 00116 get_ptr(const TVOLATILE AtomicAdjustPosixImpl::Pointer &var) { 00117 pthread_mutex_lock(&_mutex); 00118 Pointer orig_value = var; 00119 pthread_mutex_unlock(&_mutex); 00120 return orig_value; 00121 } 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: AtomicAdjustPosixImpl::compare_and_exchange 00125 // Access: Public, Static 00126 // Description: Atomic compare and exchange. 00127 // 00128 // If mem is equal to old_value, store new_value in mem. 00129 // In either case, return the original value of mem. 00130 // The caller can test for success by comparing 00131 // return_value == old_value. 00132 // 00133 // The atomic function expressed in pseudo-code: 00134 // 00135 // orig_value = mem; 00136 // if (mem == old_value) { 00137 // mem = new_value; 00138 // } 00139 // return orig_value; 00140 // 00141 //////////////////////////////////////////////////////////////////// 00142 INLINE AtomicAdjustPosixImpl::Integer AtomicAdjustPosixImpl:: 00143 compare_and_exchange(TVOLATILE AtomicAdjustPosixImpl::Integer &mem, 00144 AtomicAdjustPosixImpl::Integer old_value, 00145 AtomicAdjustPosixImpl::Integer new_value) { 00146 pthread_mutex_lock(&_mutex); 00147 Integer orig_value = mem; 00148 if (mem == old_value) { 00149 mem = new_value; 00150 } 00151 pthread_mutex_unlock(&_mutex); 00152 return orig_value; 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: AtomicAdjustPosixImpl::compare_and_exchange_ptr 00157 // Access: Public, Static 00158 // Description: Atomic compare and exchange. 00159 // 00160 // As above, but works on pointers instead of integers. 00161 //////////////////////////////////////////////////////////////////// 00162 INLINE AtomicAdjustPosixImpl::Pointer AtomicAdjustPosixImpl:: 00163 compare_and_exchange_ptr(TVOLATILE AtomicAdjustPosixImpl::Pointer &mem, 00164 AtomicAdjustPosixImpl::Pointer old_value, 00165 AtomicAdjustPosixImpl::Pointer new_value) { 00166 pthread_mutex_lock(&_mutex); 00167 Pointer orig_value = mem; 00168 if (mem == old_value) { 00169 mem = new_value; 00170 } 00171 pthread_mutex_unlock(&_mutex); 00172 return orig_value; 00173 }