# OgreAtomicWrappers.h

Go to the documentation of this file.

    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 Sat Apr 11 13:46:39 2009