00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2006 Torus Knot Software Ltd 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 00024 You may alternatively use this source under the terms of a specific version of 00025 the OGRE Unrestricted License provided you have obtained such a license from 00026 Torus Knot Software Ltd. 00027 ----------------------------------------------------------------------------- 00028 */ 00029 #ifndef _AtomicWrapper_H__ 00030 #define _AtomicWrapper_H__ 00031 00032 #include <signal.h> 00033 #include "OgrePrerequisites.h" 00034 #include "OgreException.h" 00035 00036 namespace Ogre { 00037 00038 template <class T> class AtomicObject { 00039 00040 public: 00041 00042 AtomicObject (const T &initial) 00043 : mField(initial) 00044 { } 00045 00046 AtomicObject (const AtomicObject<T> &cousin) 00047 : mField(cousin.get()) 00048 { } 00049 00050 AtomicObject () 00051 { } 00052 00053 void operator= (const AtomicObject<T> &cousin) 00054 { 00055 set(cousin.get()); 00056 } 00057 00058 T get (void) const 00059 { 00060 OGRE_LOCK_AUTO_MUTEX 00061 return mField; 00062 } 00063 00064 void set (const T &v) 00065 { 00066 OGRE_LOCK_AUTO_MUTEX 00067 mField = v; 00068 } 00069 00070 bool cas (const T &old, const T &nu) 00071 { 00072 OGRE_LOCK_AUTO_MUTEX 00073 if (mField != old) return false; 00074 mField = nu; 00075 return true; 00076 } 00077 00078 T operator++ (void) 00079 { 00080 OGRE_LOCK_AUTO_MUTEX 00081 return ++mField; 00082 } 00083 00084 T operator++ (int) 00085 { 00086 OGRE_LOCK_AUTO_MUTEX 00087 return mField++; 00088 } 00089 00090 T operator-- (int) 00091 { 00092 OGRE_LOCK_AUTO_MUTEX 00093 return mField--; 00094 } 00095 00096 protected: 00097 00098 OGRE_AUTO_MUTEX 00099 00100 volatile T mField; 00101 00102 }; 00103 00104 } 00105 00106 #if OGRE_COMPILER == OGRE_COMPILER_GNUC && OGRE_COMP_VER >= 412 && OGRE_THREAD_SUPPORT 00107 00108 namespace Ogre { 00109 00110 template<class T> class AtomicScalar 00111 { 00112 00113 public: 00114 00115 AtomicScalar (const T &initial) 00116 : mField(initial) 00117 { } 00118 00119 AtomicScalar (const AtomicScalar<T> &cousin) 00120 : mField(cousin.mField) 00121 { } 00122 00123 AtomicScalar () 00124 { } 00125 00126 void operator= (const AtomicScalar<T> &cousin) 00127 { 00128 mField = cousin.mField; 00129 } 00130 00131 T get (void) const 00132 { 00133 return mField; 00134 } 00135 00136 void set (const T &v) 00137 { 00138 mField = v; 00139 } 00140 00141 bool cas (const T &old, const T &nu) 00142 { 00143 return __sync_bool_compare_and_swap (&mField, old, nu); 00144 } 00145 00146 T operator++ (void) 00147 { 00148 __sync_add_and_fetch (&mField, 1); 00149 } 00150 00151 T operator-- (void) 00152 { 00153 __sync_add_and_fetch (&mField, -1); 00154 } 00155 00156 T operator++ (int) 00157 { 00158 __sync_fetch_and_add (&mField, 1); 00159 } 00160 00161 T operator-- (int) 00162 { 00163 __sync_fetch_and_add (&mField, -1); 00164 } 00165 00166 00167 volatile T mField; 00168 00169 }; 00170 00171 } 00172 00173 #elif OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_COMP_VER >= 1400 && OGRE_THREAD_SUPPORT 00174 00175 #define WIN32_LEAN_AND_MEAN 00176 #define NOMINMAX // required to stop windows.h messing up std::min 00177 #include <windows.h> 00178 #include <intrin.h> 00179 00180 namespace Ogre { 00181 00182 template<class T> class AtomicScalar 00183 { 00184 00185 public: 00186 00187 AtomicScalar (const T &initial) 00188 : mField(initial) 00189 { } 00190 00191 AtomicScalar (const AtomicScalar<T> &cousin) 00192 : mField(cousin.mField) 00193 { } 00194 00195 AtomicScalar () 00196 { } 00197 00198 void operator= (const AtomicScalar<T> &cousin) 00199 { 00200 mField = cousin.mField; 00201 } 00202 00203 T get (void) const 00204 { 00205 return mField; 00206 } 00207 00208 void set (const T &v) 00209 { 00210 mField = v; 00211 } 00212 00213 bool cas (const T &old, const T &nu) 00214 { 00215 if (sizeof(T)==2) { 00216 return _InterlockedCompareExchange16((SHORT*)&mField, static_cast<SHORT>(nu), static_cast<SHORT>(old)) == static_cast<SHORT>(old); 00217 } 00218 else if (sizeof(T)==4) 00219 { 00220 return _InterlockedCompareExchange((LONG*)&mField, static_cast<LONG>(nu), static_cast<LONG>(old)) == static_cast<LONG>(old); 00221 } 00222 else if (sizeof(T)==8) { 00223 return _InterlockedCompareExchange64((LONGLONG*)&mField, static_cast<LONGLONG>(nu), static_cast<LONGLONG>(old)) == static_cast<LONGLONG>(old); 00224 } 00225 else { 00226 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,"Only 16, 32, and 64 bit scalars supported in win32.","AtomicScalar::cas"); 00227 } 00228 } 00229 00230 T operator++ (void) 00231 { 00232 if (sizeof(T)==2) { 00233 return InterlockedIncrement16((SHORT*)&mField); 00234 } else if (sizeof(T)==4) { 00235 return InterlockedIncrement((LONG*)&mField); 00236 } else if (sizeof(T)==8) { 00237 return InterlockedIncrement64((LONGLONG*)&mField); 00238 } else { 00239 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,"Only 16, 32, and 64 bit scalars supported in win32.","AtomicScalar::operator++(prefix)"); 00240 } 00241 } 00242 00243 T operator-- (void) 00244 { 00245 if (sizeof(T)==2) { 00246 return InterlockedDecrement16((SHORT*)&mField); 00247 } else if (sizeof(T)==4) { 00248 return InterlockedDecrement((LONG*)&mField); 00249 } else if (sizeof(T)==8) { 00250 return InterlockedDecrement64((LONGLONG*)&mField); 00251 } else { 00252 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,"Only 16, 32, and 64 bit scalars supported in win32.","AtomicScalar::operator--(prefix)"); 00253 } 00254 } 00255 00256 T operator++ (int) 00257 { 00258 if (sizeof(T)==2) { 00259 return InterlockedIncrement16((SHORT*)&mField)-1; 00260 } else if (sizeof(T)==4) { 00261 return InterlockedIncrement((LONG*)&mField)-1; 00262 } else if (sizeof(T)==8) { 00263 return InterlockedIncrement64((LONGLONG*)&mField)-1; 00264 } else { 00265 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,"Only 16, 32, and 64 bit scalars supported in win32.","AtomicScalar::operator++(postfix)"); 00266 } 00267 } 00268 00269 T operator-- (int) 00270 { 00271 if (sizeof(T)==2) { 00272 return InterlockedDecrement16((SHORT*)&mField)+1; 00273 } else if (sizeof(T)==4) { 00274 return InterlockedDecrement((LONG*)&mField)+1; 00275 } else if (sizeof(T)==8) { 00276 return InterlockedDecrement64((LONGLONG*)&mField)+1; 00277 } else { 00278 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,"Only 16, 32, and 64 bit scalars supported in win32.","AtomicScalar::operator--(postfix)"); 00279 } 00280 } 00281 00282 volatile T mField; 00283 00284 }; 00285 00286 } 00287 00288 #else 00289 00290 namespace Ogre { 00291 00292 template <class T> class AtomicScalar { 00293 00294 public: 00295 00296 AtomicScalar (const T &initial) 00297 : mField(initial) 00298 { } 00299 00300 AtomicScalar (const AtomicScalar<T> &cousin) 00301 : mField(cousin.mField) 00302 { } 00303 00304 AtomicScalar () 00305 { } 00306 00307 void operator= (const AtomicScalar<T> &cousin) 00308 { 00309 OGRE_LOCK_AUTO_MUTEX 00310 mField = cousin.mField; 00311 } 00312 00313 T get (void) const 00314 { 00315 // no lock required here 00316 // since get will not interfere with set or cas 00317 // we may get a stale value, but this is ok 00318 return mField; 00319 } 00320 00321 void set (const T &v) 00322 { 00323 OGRE_LOCK_AUTO_MUTEX 00324 mField = v; 00325 } 00326 00327 bool cas (const T &old, const T &nu) 00328 { 00329 OGRE_LOCK_AUTO_MUTEX 00330 if (mField != old) return false; 00331 mField = nu; 00332 return true; 00333 } 00334 00335 T operator++ (void) 00336 { 00337 OGRE_LOCK_AUTO_MUTEX 00338 return ++mField; 00339 } 00340 00341 T operator-- (void) 00342 { 00343 OGRE_LOCK_AUTO_MUTEX 00344 return --mField; 00345 } 00346 00347 T operator++ (int) 00348 { 00349 OGRE_LOCK_AUTO_MUTEX 00350 return mField++; 00351 } 00352 00353 T operator-- (int) 00354 { 00355 OGRE_LOCK_AUTO_MUTEX 00356 return mField--; 00357 } 00358 00359 protected: 00360 00361 OGRE_AUTO_MUTEX 00362 00363 volatile T mField; 00364 00365 }; 00366 00367 } 00368 00369 #endif 00370 00371 00372 #endif 00373
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:22 2009