![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLONK_ATOMIC_H 00040 #define PLONK_ATOMIC_H 00041 00043 class AtomicOps //: public PlonkBase // need to reorganise headers etc 00044 { 00045 public: 00046 inline static void memoryBarrier() throw() 00047 { 00048 pl_AtomicMemoryBarrier(); 00049 } 00050 }; 00051 00052 template<class Type> 00053 class AtomicBase : public AtomicOps 00054 { 00055 }; 00056 00057 template<class Type> 00058 class AtomicBase<Type*> : public AtomicOps 00059 { 00060 public: 00061 static inline Long incrementSize() { return sizeof (Type); } 00062 }; 00063 00064 template<> 00065 class AtomicBase<void*> : public AtomicOps 00066 { 00067 public: 00068 static inline Long incrementSize() { return 1; } 00069 }; 00070 00071 00075 template<class Type> 00076 class AtomicValue : public AtomicBase<Type> 00077 { 00078 public: 00079 }; 00080 00086 template<class Type> 00087 class AtomicExtended : public AtomicBase<Type> 00088 { 00089 }; 00090 00091 00092 #define PLONK_ATOMIC_DEFINE(ATOMIC_CLASS,TYPECODE,FUNCCODE,NUMCODE,ALIGN) \ 00093 template<>\ 00094 class ATOMIC_CLASS<Plank##TYPECODE> : public AtomicBase<Plank##TYPECODE>\ 00095 {\ 00096 public:\ 00097 typedef PlankAtomic##FUNCCODE AtomType;\ 00098 typedef PlankAtomic##FUNCCODE##Ref AtomTypeRef;\ 00099 \ 00100 inline ATOMIC_CLASS() throw() {\ 00101 pl_Atomic##FUNCCODE##_Init (getAtomicRef());\ 00102 }\ 00103 \ 00104 inline ATOMIC_CLASS (const Plank##TYPECODE initialValue) throw() {\ 00105 pl_Atomic##FUNCCODE##_Init (getAtomicRef());\ 00106 pl_Atomic##FUNCCODE##_SetUnchecked (getAtomicRef(), initialValue);\ 00107 }\ 00108 \ 00109 inline ATOMIC_CLASS (ATOMIC_CLASS const& copy) throw() {\ 00110 pl_Atomic##FUNCCODE##_Init (getAtomicRef());\ 00111 pl_Atomic##FUNCCODE##_SetUnchecked (getAtomicRef(), pl_Atomic##FUNCCODE##_Get (copy.getAtomicRef()));\ 00112 }\ 00113 \ 00114 inline ~ATOMIC_CLASS() {\ 00115 pl_Atomic##FUNCCODE##_DeInit (getAtomicRef());\ 00116 }\ 00117 \ 00118 inline ATOMIC_CLASS& operator= (ATOMIC_CLASS const& other) throw() {\ 00119 if (this != &other) pl_Atomic##FUNCCODE##_Set (getAtomicRef(), pl_Atomic##FUNCCODE##_Get (other.getAtomicRef()));\ 00120 return *this;\ 00121 }\ 00122 inline ATOMIC_CLASS& operator= (const Plank##TYPECODE other) throw() {\ 00123 pl_Atomic##FUNCCODE##_Set (getAtomicRef(), other);\ 00124 return *this;\ 00125 }\ 00126 \ 00127 template<class OtherType>\ 00128 inline ATOMIC_CLASS& operator= (const OtherType other) throw() {\ 00129 pl_Atomic##FUNCCODE##_Set (getAtomicRef(), static_cast<const Plank##TYPECODE> (other));\ 00130 return *this;\ 00131 }\ 00132 \ 00133 inline bool compareAndSwap (const Plank##NUMCODE oldValue, const Plank##NUMCODE newValue) throw() {\ 00134 return pl_Atomic##FUNCCODE##_CompareAndSwap (getAtomicRef(), oldValue, newValue);\ 00135 }\ 00136 \ 00137 inline bool compareAndSwap (const Plank##NUMCODE newValue) throw() {\ 00138 return pl_Atomic##FUNCCODE##_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), newValue);\ 00139 }\ 00140 \ 00141 inline Plank##NUMCODE swap (const Plank##NUMCODE newValue) throw() {\ 00142 return pl_Atomic##FUNCCODE##_Swap (getAtomicRef(), newValue);\ 00143 }\ 00144 inline void swapWith (ATOMIC_CLASS& other) throw() {\ 00145 return pl_Atomic##FUNCCODE##_SwapOther (getAtomicRef(), other.getAtomicRef());\ 00146 }\ 00147 \ 00148 inline void setValue (const Plank##TYPECODE other) throw() { pl_Atomic##FUNCCODE##_Set (getAtomicRef(), other); }\ 00149 inline Plank##TYPECODE getValue() const throw() { return pl_Atomic##FUNCCODE##_Get (getAtomicRef()); }\ 00150 inline Plank##TYPECODE getValueUnchecked() const throw() { return pl_Atomic##FUNCCODE##_GetUnchecked (getAtomicRef()); }\ 00151 \ 00152 template<class OtherType> operator OtherType () const throw() { return static_cast<OtherType> (pl_Atomic##FUNCCODE##_Get (getAtomicRef())); }\ 00153 inline operator Plank##TYPECODE () const throw() { return pl_Atomic##FUNCCODE##_Get (getAtomicRef()); }\ 00154 inline const Plank##NUMCODE getExtra() const throw() { return pl_Atomic##FUNCCODE##_GetExtra (getAtomicRef()); }\ 00155 inline const Plank##NUMCODE getExtraUnchecked() const throw() { return pl_Atomic##FUNCCODE##_GetExtraUnchecked (getAtomicRef()); }\ 00156 inline const Plank##TYPECODE operator+= (const Plank##NUMCODE operand) throw() { return pl_Atomic##FUNCCODE##_Add (getAtomicRef(), operand); }\ 00157 inline const Plank##TYPECODE operator-= (const Plank##NUMCODE operand) throw() { return pl_Atomic##FUNCCODE##_Add (getAtomicRef(), -operand); }\ 00158 inline const Plank##TYPECODE operator++() throw() { return pl_Atomic##FUNCCODE##_Increment (getAtomicRef()); }\ 00159 inline const Plank##TYPECODE operator--() throw() { return pl_Atomic##FUNCCODE##_Decrement (getAtomicRef()); }\ 00160 inline const Plank##TYPECODE operator++ (int) throw() { const Plank##TYPECODE oldValue = pl_Atomic##FUNCCODE##_Get (getAtomicRef()); ++(*this); return oldValue; }\ 00161 inline const Plank##TYPECODE operator-- (int) throw() { const Plank##TYPECODE oldValue = pl_Atomic##FUNCCODE##_Get (getAtomicRef()); --(*this); return oldValue; }\ 00162 \ 00163 template<class OtherType> bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == Plank##TYPECODE (other); }\ 00164 template<class OtherType> bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != Plank##TYPECODE (other); }\ 00165 template<class OtherType> bool operator< (OtherType const& other) const throw() { return this->getValueUnchecked() < Plank##TYPECODE (other); }\ 00166 template<class OtherType> bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= Plank##TYPECODE (other); }\ 00167 template<class OtherType> bool operator> (OtherType const& other) const throw() { return this->getValueUnchecked() > Plank##TYPECODE (other); }\ 00168 template<class OtherType> bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= Plank##TYPECODE (other); }\ 00169 \ 00170 inline const void setIfLarger (const Plank##TYPECODE newValue) throw()\ 00171 {\ 00172 Plank##TYPECODE oldValue;\ 00173 bool success;\ 00174 do {\ 00175 oldValue = getValueUnchecked();\ 00176 success = compareAndSwap (oldValue, newValue > oldValue ? newValue : oldValue);\ 00177 } while (!success);\ 00178 }\ 00179 \ 00180 inline const void setIfSmaller (const Plank##TYPECODE newValue) throw()\ 00181 {\ 00182 Plank##TYPECODE oldValue;\ 00183 bool success;\ 00184 do {\ 00185 oldValue = getValueUnchecked();\ 00186 success = compareAndSwap (oldValue, newValue < oldValue ? newValue : oldValue);\ 00187 } while (!success);\ 00188 }\ 00189 \ 00190 inline AtomTypeRef getAtomicRef() { return static_cast<AtomTypeRef> (&atomic); }\ 00191 inline const AtomTypeRef getAtomicRef() const { return const_cast<AtomTypeRef> (&atomic); }\ 00192 private:\ 00193 \ 00194 PLONK_ALIGN(ALIGN)\ 00195 AtomType atomic;\ 00196 }; 00197 00198 #define PLONK_ATOMIC_DEFINE_SIMPLE(TYPECODE,ALIGN) PLONK_ATOMIC_DEFINE(AtomicValue,TYPECODE,TYPECODE,TYPECODE,ALIGN) 00199 00200 PLONK_ATOMIC_DEFINE_SIMPLE(I,4); 00201 PLONK_ATOMIC_DEFINE(AtomicValue,UI,I,I,4); 00202 PLONK_ATOMIC_DEFINE_SIMPLE(L,PLONK_WORDSIZE); 00203 PLONK_ATOMIC_DEFINE(AtomicValue,UL,L,L,PLONK_WORDSIZE); 00204 00205 #if !(PLANK_WIN && PLANK_64BIT) || DOXYGEN 00206 PLONK_ATOMIC_DEFINE_SIMPLE(LL,8); 00207 PLONK_ATOMIC_DEFINE(AtomicValue,ULL,LL,LL,8); 00208 #endif 00209 00210 PLONK_ATOMIC_DEFINE_SIMPLE(F,4); 00211 PLONK_ATOMIC_DEFINE_SIMPLE(D,8); 00212 00213 template<class Type> 00214 class AtomicValue<Type*> : public AtomicBase<Type*> 00215 { 00216 public: 00217 inline AtomicValue() throw() 00218 { 00219 pl_AtomicP_Init (getAtomicRef()); 00220 } 00221 00222 inline AtomicValue (Type& initialValue) throw() 00223 { 00224 pl_AtomicP_Init (getAtomicRef()); 00225 pl_AtomicP_SetUnchecked (getAtomicRef(), &initialValue); 00226 } 00227 00228 template<class OtherType> 00229 inline AtomicValue (OtherType* initialPtr) throw() 00230 { 00231 pl_AtomicP_Init (getAtomicRef()); 00232 pl_AtomicP_SetUnchecked (getAtomicRef(), static_cast<Type*> (initialPtr)); 00233 } 00234 00235 inline AtomicValue (Type* initialPtr) throw() 00236 { 00237 pl_AtomicP_Init (getAtomicRef()); 00238 pl_AtomicP_SetUnchecked (getAtomicRef(), initialPtr); 00239 } 00240 00241 inline AtomicValue (AtomicValue const& copy) throw() 00242 { 00243 pl_AtomicP_Init (getAtomicRef()); 00244 pl_AtomicP_SetUnchecked (getAtomicRef(), pl_AtomicP_Get (copy.getAtomicRef())); 00245 } 00246 00247 inline ~AtomicValue() 00248 { 00249 pl_AtomicP_DeInit (getAtomicRef()); 00250 } 00251 00252 inline AtomicValue& operator= (AtomicValue const& other) throw() 00253 { 00254 if (this != &other) 00255 pl_AtomicP_Set (getAtomicRef(), pl_AtomicP_Get (other.getAtomicRef())); 00256 00257 return *this; 00258 } 00259 00260 template<class OtherType> 00261 inline AtomicValue& operator= (OtherType* other) throw() 00262 { 00263 pl_AtomicP_Set (getAtomicRef(), static_cast<Type*> (other)); 00264 return *this; 00265 } 00266 00267 inline AtomicValue& operator= (Type& other) throw() 00268 { 00269 pl_AtomicP_Set (getAtomicRef(), static_cast<Type*> (&other)); 00270 return *this; 00271 } 00272 00273 inline bool compareAndSwap (const Type* oldValue, const Type* newValue) throw() 00274 { 00275 return pl_AtomicP_CompareAndSwap (getAtomicRef(), oldValue, newValue); 00276 } 00277 00278 inline bool compareAndSwap (const Type* newValue) throw() 00279 { 00280 return pl_AtomicP_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), newValue); 00281 } 00282 00283 inline Type* swap (const Type* newValue) throw() 00284 { 00285 return pl_AtomicP_Swap (getAtomicRef(), newValue); 00286 } 00287 00288 inline void swapWith (AtomicValue& other) throw() 00289 { 00290 return pl_AtomicP_SwapOther (getAtomicRef(), other.getAtomicRef()); 00291 } 00292 00293 inline void setValue (Type* other) throw() { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); } 00294 inline void setPtr (Type* other) throw() { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); } 00295 00296 inline Type* getValue() const throw() { return static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); } 00297 inline Type* getPtr() const throw() { return static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); } 00298 inline Type* operator->() const throw() { return static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); } 00299 00300 inline Type* getValueUnchecked() const throw() { return static_cast<Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); } 00301 inline Type* getPtrUnchecked() const throw() { return static_cast<Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); } 00302 inline Long getExtra() const throw() { return pl_AtomicP_GetExtra (getAtomicRef()); } 00303 inline Long getExtraUnchecked() const throw() { return pl_AtomicP_GetExtraUnchecked (getAtomicRef()); } 00304 00305 inline operator const Type* () const throw() { return static_cast<const Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); } 00306 inline operator Type* () const throw() { return static_cast<Type*> (pl_AtomicP_GetUnchecked (getAtomicRef())); } 00307 00308 inline void deletePtr() throw() { delete this->getPtrUnchecked(); } 00309 inline void deleteAndZeroPtr() throw() { delete this->swap (0); } 00310 00311 template<class OtherType> inline bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Type*> (other); } 00312 template<class OtherType> inline bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Type*> (other); } 00313 template<class OtherType> inline bool operator< (OtherType const& other) const throw() { return this->getValueUnchecked() < static_cast<Type*> (other); } 00314 template<class OtherType> inline bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Type*> (other); } 00315 template<class OtherType> inline bool operator> (OtherType const& other) const throw() { return this->getValueUnchecked() > static_cast<Type*> (other); } 00316 template<class OtherType> inline bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Type*> (other); } 00317 00318 inline bool operator== (Type* const other) const throw() { return this->getPtrUnchecked() == other; } 00319 inline bool operator!= (Type* const other) const throw() { return this->getPtrUnchecked() != other; } 00320 inline bool operator< (Type* const other) const throw() { return this->getPtrUnchecked() < other; } 00321 inline bool operator<= (Type* const other) const throw() { return this->getPtrUnchecked() <= other; } 00322 inline bool operator> (Type* const other) const throw() { return this->getPtrUnchecked() > other; } 00323 inline bool operator>= (Type* const other) const throw() { return this->getPtrUnchecked() >= other; } 00324 00325 inline Type* const operator+= (const Long operand) throw() 00326 { 00327 return pl_AtomicP_Add (getAtomicRef(), operand * AtomicValue::incrementSize()); 00328 } 00329 00330 inline Type* const operator-= (const Long operand) throw() 00331 { 00332 return pl_AtomicP_Add (getAtomicRef(), -operand * AtomicValue::incrementSize()); 00333 } 00334 00335 inline Type* const operator++() throw() 00336 { 00337 return pl_AtomicP_Add (getAtomicRef(), AtomicValue::incrementSize()); 00338 } 00339 00340 inline Type* const operator--() throw() 00341 { 00342 return pl_AtomicP_Subtract (getAtomicRef(), AtomicValue::incrementSize()); 00343 } 00344 00345 inline Type* const operator++ (int) throw() 00346 { 00347 Type* const oldPtr = static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); 00348 ++(*this); 00349 return oldPtr; 00350 } 00351 00352 inline Type* const operator-- (int) throw() 00353 { 00354 Type* const oldPtr = static_cast<Type*> (pl_AtomicP_Get (getAtomicRef())); 00355 --(*this); 00356 return oldPtr; 00357 } 00358 00359 inline PlankAtomicPRef getAtomicRef() { return static_cast<PlankAtomicPRef> (&u.atomic); } 00360 inline const PlankAtomicPRef getAtomicRef() const { return const_cast<PlankAtomicPRef> (&u.atomic); } 00361 00362 private: 00363 union Union 00364 { 00365 PlankAtomicP atomic; 00366 Type* ptr; 00367 }; 00368 00369 PLONK_ALIGN(PLONK_WORDSIZE) Union u; 00370 }; 00371 00372 template<> 00373 class AtomicValue<void*> : public AtomicBase<void*> 00374 { 00375 public: 00376 inline AtomicValue() throw() 00377 { 00378 pl_AtomicP_Init (getAtomicRef()); 00379 } 00380 00381 template<class OtherType> 00382 inline AtomicValue (OtherType* initialPtr) throw() 00383 { 00384 pl_AtomicP_Init (getAtomicRef()); 00385 pl_AtomicP_SetUnchecked (getAtomicRef(), static_cast<void*> (initialPtr)); 00386 } 00387 00388 inline AtomicValue (void* initialPtr) throw() 00389 { 00390 pl_AtomicP_Init (getAtomicRef()); 00391 pl_AtomicP_SetUnchecked (getAtomicRef(), initialPtr); 00392 } 00393 00394 inline AtomicValue (AtomicValue const& copy) throw() 00395 { 00396 pl_AtomicP_Init (getAtomicRef()); 00397 pl_AtomicP_SetUnchecked (getAtomicRef(), pl_AtomicP_Get (copy.getAtomicRef())); 00398 } 00399 00400 inline ~AtomicValue() 00401 { 00402 pl_AtomicP_DeInit (getAtomicRef()); 00403 } 00404 00405 inline AtomicValue& operator= (AtomicValue const& other) throw() 00406 { 00407 if (this != &other) 00408 pl_AtomicP_Set (getAtomicRef(), pl_AtomicP_Get (other.getAtomicRef())); 00409 00410 return *this; 00411 } 00412 00413 template<class OtherType> 00414 inline AtomicValue& operator= (OtherType* other) throw() 00415 { 00416 pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); 00417 return *this; 00418 } 00419 00420 inline bool compareAndSwap (void* oldValue, void* newValue) throw() 00421 { 00422 return pl_AtomicP_CompareAndSwap (getAtomicRef(), oldValue, newValue); 00423 } 00424 00425 inline bool compareAndSwap (void* newValue) throw() 00426 { 00427 return pl_AtomicP_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), newValue); 00428 } 00429 00430 inline void* swap (void* newValue) throw() 00431 { 00432 return pl_AtomicP_Swap (getAtomicRef(), newValue); 00433 } 00434 00435 inline void swapWith (AtomicValue& other) throw() 00436 { 00437 return pl_AtomicP_SwapOther (getAtomicRef(), other.getAtomicRef()); 00438 } 00439 00440 inline void setValue (void* other) throw() { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); } 00441 inline void setPtr (void* other) throw() { pl_AtomicP_Set (getAtomicRef(), static_cast<void*> (other)); } 00442 00443 inline void* getValue() const throw() { return pl_AtomicP_Get (getAtomicRef()); } 00444 inline void* getPtr() const throw() { return pl_AtomicP_Get (getAtomicRef()); } 00445 inline void* operator->() const throw() { return pl_AtomicP_Get (getAtomicRef()); } 00446 00447 inline void* getValueUnchecked() const throw() { return pl_AtomicP_GetUnchecked (getAtomicRef()); } 00448 inline void* getPtrUnchecked() const throw() { return pl_AtomicP_GetUnchecked (getAtomicRef()); } 00449 inline UnsignedLong getExtra() const throw() { return pl_AtomicP_GetExtra (getAtomicRef()); } 00450 inline UnsignedLong getExtraUnchecked() const throw() { return pl_AtomicP_GetExtraUnchecked (getAtomicRef()); } 00451 00452 inline operator const void* () const throw() { return static_cast<const void*> (pl_AtomicP_GetUnchecked (getAtomicRef())); } 00453 inline operator void* () const throw() { return pl_AtomicP_GetUnchecked (getAtomicRef()); } 00454 00455 template<class OtherType> inline bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == reinterpret_cast<void*> (other); } 00456 template<class OtherType> inline bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != reinterpret_cast<void*> (other); } 00457 template<class OtherType> inline bool operator< (OtherType const& other) const throw() { return this->getValueUnchecked() < reinterpret_cast<void*> (other); } 00458 template<class OtherType> inline bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= reinterpret_cast<void*> (other); } 00459 template<class OtherType> inline bool operator> (OtherType const& other) const throw() { return this->getValueUnchecked() > reinterpret_cast<void*> (other); } 00460 template<class OtherType> inline bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= reinterpret_cast<void*> (other); } 00461 00462 inline bool operator== (void* const other) const throw() { return this->getPtrUnchecked() == other; } 00463 inline bool operator!= (void* const other) const throw() { return this->getPtrUnchecked() != other; } 00464 inline bool operator< (void* const other) const throw() { return this->getPtrUnchecked() < other; } 00465 inline bool operator<= (void* const other) const throw() { return this->getPtrUnchecked() <= other; } 00466 inline bool operator> (void* const other) const throw() { return this->getPtrUnchecked() > other; } 00467 inline bool operator>= (void* const other) const throw() { return this->getPtrUnchecked() >= other; } 00468 00469 inline void* const operator+= (const Long operand) throw() 00470 { 00471 return pl_AtomicP_Add (getAtomicRef(), operand * AtomicValue::incrementSize()); 00472 } 00473 00474 inline void* const operator-= (const Long operand) throw() 00475 { 00476 return pl_AtomicP_Add (getAtomicRef(), -operand * AtomicValue::incrementSize()); 00477 } 00478 00479 inline void* const operator++() throw() 00480 { 00481 return pl_AtomicP_Add (getAtomicRef(), AtomicValue::incrementSize()); 00482 } 00483 00484 inline void* const operator--() throw() 00485 { 00486 return pl_AtomicP_Subtract (getAtomicRef(), AtomicValue::incrementSize()); 00487 } 00488 00489 inline void* const operator++ (int) throw() 00490 { 00491 void* const oldPtr = pl_AtomicP_Get (getAtomicRef()); 00492 ++(*this); 00493 return oldPtr; 00494 } 00495 00496 inline void* const operator-- (int) throw() 00497 { 00498 void* const oldPtr = pl_AtomicP_Get (getAtomicRef()); 00499 --(*this); 00500 return oldPtr; 00501 } 00502 00503 inline PlankAtomicPRef getAtomicRef() { return static_cast<PlankAtomicPRef> (&atomic); } 00504 inline const PlankAtomicPRef getAtomicRef() const { return const_cast<PlankAtomicPRef> (&atomic); } 00505 00506 private: 00507 PLONK_ALIGN(PLONK_WORDSIZE) 00508 PlankAtomicP atomic; 00509 }; 00510 00511 00512 template<class Type> 00513 class AtomicExtended<Type*> : public AtomicBase<Type*> 00514 { 00515 public: 00516 00517 template<class OtherType> 00518 static inline bool ptrUsesValidBits (OtherType* ptr) throw() 00519 { 00520 union Utility 00521 { 00522 OtherType* ptr; 00523 UnsignedLong bits; 00524 }; 00525 00526 Utility u; 00527 u.ptr = ptr; 00528 return (u.bits & PLANK_ATOMIC_PMASK) == u.bits; 00529 } 00530 00531 inline AtomicExtended() throw() 00532 { 00533 pl_AtomicPX_Init (getAtomicRef()); 00534 } 00535 00536 inline AtomicExtended (Type& initialValue) throw() 00537 { 00538 plonk_assert (ptrUsesValidBits (&initialValue)); 00539 pl_AtomicPX_Init (getAtomicRef()); 00540 pl_AtomicPX_SetAllUnchecked (getAtomicRef(), static_cast<void*> (&initialValue), 0); 00541 } 00542 00543 template<class OtherType> 00544 inline AtomicExtended (OtherType* const initialPtr) throw() 00545 { 00546 plonk_assert (ptrUsesValidBits (initialPtr)); 00547 pl_AtomicPX_Init (getAtomicRef()); 00548 pl_AtomicPX_SetAllUnchecked (getAtomicRef(), static_cast<Type*> (initialPtr), 0); 00549 } 00550 00551 inline AtomicExtended (Type* initialPtr) throw() 00552 { 00553 plonk_assert (ptrUsesValidBits (initialPtr)); 00554 pl_AtomicPX_Init (getAtomicRef()); 00555 pl_AtomicPX_SetAllUnchecked (getAtomicRef(), initialPtr, 0); 00556 } 00557 00558 inline AtomicExtended (Type* initialPtr, const UnsignedLong extra) throw() 00559 { 00560 plonk_assert (ptrUsesValidBits (initialPtr)); 00561 pl_AtomicPX_Init (getAtomicRef()); 00562 pl_AtomicPX_SetAllUnchecked (getAtomicRef(), initialPtr, extra); 00563 } 00564 00565 inline AtomicExtended (AtomicExtended const& copy) throw() 00566 { 00567 pl_AtomicPX_Init (getAtomicRef()); 00568 pl_AtomicPX_SetAllUnchecked (getAtomicRef(), pl_AtomicPX_Get (copy.getAtomicRef()), 0); 00569 } 00570 00571 inline ~AtomicExtended() 00572 { 00573 pl_AtomicPX_DeInit (getAtomicRef()); 00574 } 00575 00576 inline AtomicExtended& operator= (AtomicExtended const& other) throw() 00577 { 00578 if (this != &other) 00579 pl_AtomicPX_Set (getAtomicRef(), pl_AtomicPX_Get (other.getAtomicRef())); 00580 00581 return *this; 00582 } 00583 00584 // inline AtomicExtended& operator= (void* other) throw() 00585 // { 00586 // plonk_assert (other == 0); 00587 // pl_AtomicPX_Set (getAtomicRef(), static_cast<Type*> (other)); 00588 // return *this; 00589 // } 00590 // 00591 00592 template<class OtherType> 00593 inline AtomicExtended& operator= (OtherType* const other) throw() 00594 { 00595 plonk_assert (ptrUsesValidBits (other)); 00596 pl_AtomicPX_Set (getAtomicRef(), static_cast<Type*> (other)); 00597 return *this; 00598 } 00599 00600 // inline AtomicExtended& operator= (Type& other) throw() 00601 // { 00602 // pl_AtomicPX_Set (getAtomicRef(), static_cast<void*> (&other)); 00603 // return *this; 00604 // } 00605 00606 inline AtomicExtended& operator= (Type* other) throw() 00607 { 00608 plonk_assert (ptrUsesValidBits (other)); 00609 pl_AtomicPX_Set (getAtomicRef(), const_cast<Type*> (other)); 00610 return *this; 00611 } 00612 00613 inline void setAll (Type* const other, const UnsignedLong extra) throw() 00614 { 00615 plonk_assert (ptrUsesValidBits (other)); 00616 pl_AtomicPX_SetAll (getAtomicRef(), other, extra); 00617 } 00618 00619 inline bool compareAndSwap (Type* const oldValue, const UnsignedLong oldExtra, Type* const newValue, const UnsignedLong newExtra) throw() 00620 { 00621 plonk_assert (ptrUsesValidBits (newValue)); 00622 return pl_AtomicPX_CompareAndSwap (getAtomicRef(), oldValue, oldExtra, newValue, newExtra); 00623 } 00624 00625 inline bool compareAndSwap (Type* const newValue, const UnsignedLong newExtra) throw() 00626 { 00627 plonk_assert (ptrUsesValidBits (newValue)); 00628 return pl_AtomicPX_CompareAndSwap (getAtomicRef(), this->getValueUnchecked(), this->getExtraUnchecked(), newValue, newExtra); 00629 } 00630 00631 inline Type* swap (Type* const newValue) throw() 00632 { 00633 plonk_assert (ptrUsesValidBits (newValue)); 00634 return pl_AtomicPX_Swap (getAtomicRef(), newValue); 00635 } 00636 00637 inline Type* swapAll (Type* const newValue, const UnsignedLong newExtra) throw() 00638 { 00639 plonk_assert (ptrUsesValidBits (newValue)); 00640 return pl_AtomicPX_SwapAll (getAtomicRef(), newValue, newExtra, 0); 00641 } 00642 00643 inline Type* swapAll (Type* const newValue, const UnsignedLong newExtra, UnsignedLong& oldExtra) throw() 00644 { 00645 plonk_assert (ptrUsesValidBits (newValue)); 00646 return pl_AtomicPX_SwapAll (getAtomicRef(), newValue, newExtra, &oldExtra); 00647 } 00648 00649 inline void swapWith (AtomicExtended& other) throw() 00650 { 00651 return pl_AtomicPX_SwapOther (getAtomicRef(), other.getAtomicRef()); 00652 } 00653 00654 inline void setValue (Type* const other) throw() { plonk_assert (ptrUsesValidBits (other)); pl_AtomicPX_Set (getAtomicRef(), static_cast<void*> (other)); } 00655 inline void setPtr (Type* const other) throw() { plonk_assert (ptrUsesValidBits (other)); pl_AtomicPX_Set (getAtomicRef(), static_cast<void*> (other)); } 00656 00657 inline Type* getValue() const throw() { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); } 00658 inline Type* getPtr() const throw() { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); } 00659 inline Type* operator->() const throw() { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); } 00660 00661 inline Type* getValueUnchecked() const throw() { return static_cast<Type*> (pl_AtomicPX_GetUnchecked (getAtomicRef())); } 00662 inline Type* getPtrUnchecked() const throw() { return static_cast<Type*> (pl_AtomicPX_GetUnchecked (getAtomicRef())); } 00663 00664 inline operator const Type* () const throw() { return static_cast<const Type*> (pl_AtomicPX_GetUnchecked (getAtomicRef())); } 00665 inline operator Type* () throw() { return static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); } 00666 00667 inline UnsignedLong getExtra() const throw() { return pl_AtomicPX_GetExtra (getAtomicRef()); } 00668 inline UnsignedLong getExtraUnchecked() const throw() { return pl_AtomicPX_GetExtraUnchecked (getAtomicRef()); } 00669 00670 inline void deletePtr() throw() { delete this->getPtrUnchecked(); } 00671 inline void deleteAndZeroPtr() throw() { delete this->getPtrUnchecked(); this->setPtr (0); } 00672 00673 template<class OtherType> inline bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Type*> (other); } 00674 template<class OtherType> inline bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Type*> (other); } 00675 template<class OtherType> inline bool operator< (OtherType const& other) const throw() { return this->getValueUnchecked() < static_cast<Type*> (other); } 00676 template<class OtherType> inline bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Type*> (other); } 00677 template<class OtherType> inline bool operator> (OtherType const& other) const throw() { return this->getValueUnchecked() > static_cast<Type*> (other); } 00678 template<class OtherType> inline bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Type*> (other); } 00679 00680 inline bool operator== (Type* const other) const throw() { return this->getPtrUnchecked() == other; } 00681 inline bool operator!= (Type* const other) const throw() { return this->getPtrUnchecked() != other; } 00682 inline bool operator< (Type* const other) const throw() { return this->getPtrUnchecked() < other; } 00683 inline bool operator<= (Type* const other) const throw() { return this->getPtrUnchecked() <= other; } 00684 inline bool operator> (Type* const other) const throw() { return this->getPtrUnchecked() > other; } 00685 inline bool operator>= (Type* const other) const throw() { return this->getPtrUnchecked() >= other; } 00686 00687 // inline Type* const operator+= (const Long operand) throw() 00688 // { 00689 // return pl_AtomicPX_Add (getAtomicRef(), operand * AtomicExtended::incrementSize()); 00690 // } 00691 // 00692 // inline Type* const operator-= (const Long operand) throw() 00693 // { 00694 // return pl_AtomicPX_Add (getAtomicRef(), -operand * AtomicExtended::incrementSize()); 00695 // } 00696 // 00697 // inline Type* const operator++() throw() 00698 // { 00699 // return pl_AtomicPX_Add (getAtomicRef(), AtomicExtended::incrementSize()); 00700 // } 00701 // 00702 // inline Type* const operator--() throw() 00703 // { 00704 // return pl_AtomicPX_Subtract (getAtomicRef(), AtomicExtended::incrementSize()); 00705 // } 00706 // 00707 // inline Type* const operator++ (int) throw() 00708 // { 00709 // Type* const oldPtr = static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); 00710 // ++(*this); 00711 // return oldPtr; 00712 // } 00713 // 00714 // inline Type* const operator-- (int) throw() 00715 // { 00716 // Type* const oldPtr = static_cast<Type*> (pl_AtomicPX_Get (getAtomicRef())); 00717 // --(*this); 00718 // return oldPtr; 00719 // } 00720 00721 inline PlankAtomicPXRef getAtomicRef() { return static_cast<PlankAtomicPXRef> (&atomic); } 00722 inline const PlankAtomicPXRef getAtomicRef() const { return const_cast<PlankAtomicPXRef> (&atomic); } 00723 00724 private: 00725 PLONK_ALIGN(PLONK_WIDESIZE) PlankAtomicPX atomic; 00726 }; 00727 00728 template<> 00729 class AtomicExtended<Int> : public AtomicBase<LongLong> 00730 { 00731 public: 00732 inline AtomicExtended() throw() 00733 { 00734 } 00735 00736 inline AtomicExtended (const Int initialValue) throw() 00737 : atom (fromParts (initialValue, 0)) 00738 { 00739 } 00740 00741 inline AtomicExtended (AtomicExtended const& copy) throw() 00742 { 00743 setValue (copy.getValue()); 00744 } 00745 00746 inline ~AtomicExtended() 00747 { 00748 plonk_staticassert (sizeof (Separate) == sizeof (LongLong)); 00749 plonk_staticassert (sizeof (Element) == sizeof (LongLong)); 00750 } 00751 00752 inline AtomicExtended& operator= (AtomicExtended const& other) throw() 00753 { 00754 if (this != &other) 00755 setValue (other.getValue()); 00756 00757 return *this; 00758 } 00759 00760 inline AtomicExtended& operator= (const Int other) throw() 00761 { 00762 setValue (other); 00763 return *this; 00764 } 00765 00766 inline void setAll (const Int other, const Int extra) throw() 00767 { 00768 atom.setValue (fromParts (other, extra)); 00769 } 00770 00771 inline bool compareAndSwap (const Int oldValue, const Int oldExtra, const Int newValue, const Int newExtra) throw() 00772 { 00773 return atom.compareAndSwap (fromParts (oldValue, oldExtra), fromParts (newValue, newExtra)); 00774 } 00775 00776 inline bool compareAndSwap (const Int newValue, const Int newExtra) throw() 00777 { 00778 return atom.compareAndSwap (atom.getValueUnchecked(), fromParts (newValue, newExtra)); 00779 } 00780 00781 inline Int swap (const Int newValue) throw() 00782 { 00783 bool success; 00784 Element oldAll, newAll; 00785 00786 do 00787 { 00788 oldAll.whole = atom.getValueUnchecked(); 00789 newAll.separate.value = newValue; 00790 newAll.separate.extra = oldAll.separate.extra + 1; 00791 success = atom.compareAndSwap (oldAll.whole, newAll.whole); 00792 } while (!success); 00793 00794 return oldAll.separate.value; 00795 } 00796 00797 Int swapAll (const Int newValue, const Int newExtra) throw() 00798 { 00799 return swapAll (newValue, newExtra, 0); 00800 } 00801 00802 Int swapAll (const Int newValue, const Int newExtra, Int* oldExtraPtr) throw() 00803 { 00804 bool success; 00805 Element oldAll; 00806 00807 do 00808 { 00809 oldAll.whole = atom.getValueUnchecked(); 00810 success = atom.compareAndSwap (oldAll.whole, fromParts (newValue, newExtra)); 00811 } while (!success); 00812 00813 if (oldExtraPtr != 0) 00814 *oldExtraPtr = oldAll.separate.extra; 00815 00816 return oldAll.separate.value; 00817 } 00818 00819 inline void setValue (const Int other) throw() 00820 { 00821 swap (other); 00822 } 00823 00824 inline Int getValue() const throw() 00825 { 00826 Element element; 00827 element.whole = atom.getValue(); 00828 return element.separate.value; 00829 } 00830 00831 inline Int getExtra() const throw() 00832 { 00833 Element element; 00834 element.whole = atom.getValue(); 00835 return element.separate.extra; 00836 } 00837 00838 inline Int getValueUnchecked() const throw() 00839 { 00840 Element element; 00841 element.whole = atom.getValueUnchecked(); 00842 return element.separate.value; 00843 } 00844 00845 inline Int getExtraUnchecked() const throw() 00846 { 00847 Element element; 00848 element.whole = atom.getValueUnchecked(); 00849 return element.separate.extra; 00850 } 00851 00852 template<class OtherType> bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Int> (other); } 00853 template<class OtherType> bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Int> (other); } 00854 template<class OtherType> bool operator< (OtherType const& other) const throw() { return this->getValueUnchecked() < static_cast<Int> (other); } 00855 template<class OtherType> bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Int> (other); } 00856 template<class OtherType> bool operator> (OtherType const& other) const throw() { return this->getValueUnchecked() > static_cast<Int> (other); } 00857 template<class OtherType> bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Int> (other); } 00858 00859 bool operator== (const Int other) const throw() { return this->getValueUnchecked() == other; } 00860 bool operator!= (const Int other) const throw() { return this->getValueUnchecked() != other; } 00861 bool operator< (const Int other) const throw() { return this->getValueUnchecked() < other; } 00862 bool operator<= (const Int other) const throw() { return this->getValueUnchecked() <= other; } 00863 bool operator> (const Int other) const throw() { return this->getValueUnchecked() > other; } 00864 bool operator>= (const Int other) const throw() { return this->getValueUnchecked() >= other; } 00865 00866 inline Int operator+= (const Int operand) throw() 00867 { 00868 bool success; 00869 Element oldAll, newAll; 00870 00871 do 00872 { 00873 oldAll.whole = atom.getValueUnchecked(); 00874 newAll.separate.value = oldAll.separate.value + operand; 00875 newAll.separate.extra = oldAll.separate.extra + 1; 00876 success = atom.compareAndSwap (oldAll.whole, newAll.whole); 00877 } while (!success); 00878 00879 return newAll.separate.value; 00880 } 00881 00882 inline Int operator-= (const Int operand) throw() 00883 { 00884 return operator+= (-operand); 00885 } 00886 00887 inline Int operator++() throw() 00888 { 00889 return operator+= (1); 00890 } 00891 00892 inline Int operator--() throw() 00893 { 00894 return operator+= (-1); 00895 } 00896 00897 inline Int operator++ (int) throw() 00898 { 00899 const Int oldValue = getValueUnchecked(); 00900 ++(*this); 00901 return oldValue; 00902 } 00903 00904 inline Int operator-- (int) throw() 00905 { 00906 const Int oldValue = getValueUnchecked(); 00907 --(*this); 00908 return oldValue; 00909 } 00910 00911 private: 00912 AtomicValue<LongLong> atom; 00913 00914 struct Separate 00915 { 00916 Int value; 00917 Int extra; 00918 }; 00919 00920 union Element 00921 { 00922 Separate separate; 00923 LongLong whole; 00924 }; 00925 00926 static inline LongLong fromParts (const Int value, const Int extra) throw() 00927 { 00928 Element element; 00929 element.separate.value = value; 00930 element.separate.extra = extra; 00931 return element.whole; 00932 } 00933 00934 static inline Separate fromWhole (LongLong const& whole) throw() 00935 { 00936 Element element; 00937 element.whole = whole; 00938 return element.separate; 00939 } 00940 00941 }; 00942 00943 template<> 00944 class AtomicExtended<Short> : public AtomicBase<Int> 00945 { 00946 public: 00947 inline AtomicExtended() throw() 00948 { 00949 } 00950 00951 inline AtomicExtended (const Short initialValue) throw() 00952 : atom (fromParts (initialValue, 0)) 00953 { 00954 } 00955 00956 inline AtomicExtended (AtomicExtended const& copy) throw() 00957 { 00958 setValue (copy.getValue()); 00959 } 00960 00961 inline ~AtomicExtended() 00962 { 00963 plonk_staticassert (sizeof (Separate) == sizeof (Int)); 00964 plonk_staticassert (sizeof (Element) == sizeof (Int)); 00965 } 00966 00967 inline AtomicExtended& operator= (AtomicExtended const& other) throw() 00968 { 00969 if (this != &other) 00970 setValue (other.getValue()); 00971 00972 return *this; 00973 } 00974 00975 inline AtomicExtended& operator= (const Short other) throw() 00976 { 00977 setValue (other); 00978 return *this; 00979 } 00980 00981 inline void setAll (const Short other, const Short extra) throw() 00982 { 00983 atom.setValue (fromParts (other, extra)); 00984 } 00985 00986 inline bool compareAndSwap (const Short oldValue, const Short oldExtra, const Short newValue, const Short newExtra) throw() 00987 { 00988 return atom.compareAndSwap (fromParts (oldValue, oldExtra), fromParts (newValue, newExtra)); 00989 } 00990 00991 inline bool compareAndSwap (const Short newValue, const Short newExtra) throw() 00992 { 00993 return atom.compareAndSwap (atom.getValueUnchecked(), fromParts (newValue, newExtra)); 00994 } 00995 00996 inline Short swap (const Short newValue) throw() 00997 { 00998 bool success; 00999 Element oldAll, newAll; 01000 01001 do 01002 { 01003 oldAll.whole = atom.getValueUnchecked(); 01004 newAll.separate.value = newValue; 01005 newAll.separate.extra = oldAll.separate.extra + 1; 01006 success = atom.compareAndSwap (oldAll.whole, newAll.whole); 01007 } while (!success); 01008 01009 return oldAll.separate.value; 01010 } 01011 01012 Short swapAll (const Short newValue, const Short newExtra) throw() 01013 { 01014 return swapAll (newValue, newExtra, 0); 01015 } 01016 01017 Short swapAll (const Short newValue, const Short newExtra, Short* oldExtraPtr) throw() 01018 { 01019 bool success; 01020 Element oldAll; 01021 01022 do 01023 { 01024 oldAll.whole = atom.getValueUnchecked(); 01025 success = atom.compareAndSwap (oldAll.whole, fromParts (newValue, newExtra)); 01026 } while (!success); 01027 01028 if (oldExtraPtr != 0) 01029 *oldExtraPtr = oldAll.separate.extra; 01030 01031 return oldAll.separate.value; 01032 } 01033 01034 inline void setValue (const Short other) throw() 01035 { 01036 swap (other); 01037 } 01038 01039 inline Short getValue() const throw() 01040 { 01041 Element element; 01042 element.whole = atom.getValue(); 01043 return element.separate.value; 01044 } 01045 01046 inline Short getExtra() const throw() 01047 { 01048 Element element; 01049 element.whole = atom.getValue(); 01050 return element.separate.extra; 01051 } 01052 01053 inline Short getValueUnchecked() const throw() 01054 { 01055 Element element; 01056 element.whole = atom.getValueUnchecked(); 01057 return element.separate.value; 01058 } 01059 01060 inline Short getExtraUnchecked() const throw() 01061 { 01062 Element element; 01063 element.whole = atom.getValueUnchecked(); 01064 return element.separate.extra; 01065 } 01066 01067 template<class OtherType> bool operator== (OtherType const& other) const throw() { return this->getValueUnchecked() == static_cast<Short> (other); } 01068 template<class OtherType> bool operator!= (OtherType const& other) const throw() { return this->getValueUnchecked() != static_cast<Short> (other); } 01069 template<class OtherType> bool operator< (OtherType const& other) const throw() { return this->getValueUnchecked() < static_cast<Short> (other); } 01070 template<class OtherType> bool operator<= (OtherType const& other) const throw() { return this->getValueUnchecked() <= static_cast<Short> (other); } 01071 template<class OtherType> bool operator> (OtherType const& other) const throw() { return this->getValueUnchecked() > static_cast<Short> (other); } 01072 template<class OtherType> bool operator>= (OtherType const& other) const throw() { return this->getValueUnchecked() >= static_cast<Short> (other); } 01073 01074 bool operator== (const Short other) const throw() { return this->getValueUnchecked() == other; } 01075 bool operator!= (const Short other) const throw() { return this->getValueUnchecked() != other; } 01076 bool operator< (const Short other) const throw() { return this->getValueUnchecked() < other; } 01077 bool operator<= (const Short other) const throw() { return this->getValueUnchecked() <= other; } 01078 bool operator> (const Short other) const throw() { return this->getValueUnchecked() > other; } 01079 bool operator>= (const Short other) const throw() { return this->getValueUnchecked() >= other; } 01080 01081 inline Short operator+= (const Short operand) throw() 01082 { 01083 bool success; 01084 Element oldAll, newAll; 01085 01086 do 01087 { 01088 oldAll.whole = atom.getValueUnchecked(); 01089 newAll.separate.value = oldAll.separate.value + operand; 01090 newAll.separate.extra = oldAll.separate.extra + 1; 01091 success = atom.compareAndSwap (oldAll.whole, newAll.whole); 01092 } while (!success); 01093 01094 return newAll.separate.value; 01095 } 01096 01097 inline Short operator-= (const Short operand) throw() 01098 { 01099 return operator+= (-operand); 01100 } 01101 01102 inline Short operator++() throw() 01103 { 01104 return operator+= (1); 01105 } 01106 01107 inline Short operator--() throw() 01108 { 01109 return operator+= (-1); 01110 } 01111 01112 inline Short operator++ (int) throw() 01113 { 01114 const Short oldValue = getValueUnchecked(); 01115 ++(*this); 01116 return oldValue; 01117 } 01118 01119 inline Short operator-- (int) throw() 01120 { 01121 const Short oldValue = getValueUnchecked(); 01122 --(*this); 01123 return oldValue; 01124 } 01125 01126 private: 01127 AtomicValue<Int> atom; 01128 01129 struct Separate 01130 { 01131 Short value; 01132 Short extra; 01133 }; 01134 01135 union Element 01136 { 01137 Separate separate; 01138 Int whole; 01139 }; 01140 01141 static inline Int fromParts (const Short value, const Short extra) throw() 01142 { 01143 Element element; 01144 element.separate.value = value; 01145 element.separate.extra = extra; 01146 return element.whole; 01147 } 01148 01149 static inline Separate fromWhole (const Short whole) throw() 01150 { 01151 Element element; 01152 element.whole = whole; 01153 return element.separate; 01154 } 01155 01156 }; 01157 01158 01159 #endif // PLONK_ATOMIC_H