OSGAtomic.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2003 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 #ifndef _OSGATOMIC_H_
00040 #define _OSGATOMIC_H_
00041 
00042 #include "OSGBaseTypes.h"
00043
00044 #if !defined(WIN32)
00045 #include <boost/version.hpp>
00046
00047 #if BOOST_VERSION < 103900
00048 #include <boost/detail/sp_counted_base.hpp>
00049 #else
00050 #include <boost/smart_ptr/detail/sp_counted_base.hpp>
00051 #endif
00052 
00053 #else
00054 #pragma intrinsic( _InterlockedExchangeAdd )
00055 #pragma intrinsic( _InterlockedIncrement )
00056 #pragma intrinsic( _InterlockedDecrement )
00057 #pragma intrinsic( _InterlockedAnd )
00058 #pragma intrinsic( _InterlockedOr )
00059 #endif
00060 
00061 OSG_BEGIN_NAMESPACE
00062
00063 #if !defined(WIN32)
00064 
00065 inline
00066 RefCountStore osgAtomicExchangeAndAdd(RefCountStore *pValue,
00067                                       RefCountStore  rcDelta)
00068 {
00069 #if 0
00070     RefCountStore ret = *pValue;
00071
00072     *pValue += rcDelta;
00073
00074     return ret;
00075 #endif
00076 
00077     return boost::detail::atomic_exchange_and_add(pValue, rcDelta);
00078 }
00079
00080 inline
00081 void osgAtomicIncrement(RefCountStore *pValue)
00082 {
00083 #if 0
00084     ++(*pValue);
00085 #endif
00086 
00087     boost::detail::atomic_increment(pValue);
00088 }
00089
00090 inline
00091 void osgAtomicDecrement(RefCountStore *pValue)
00092 {
00093 #if 0
00094     --(*pValue);
00095 #endif
00096 
00097     __asm__
00098     (
00099         "lock\n\t"
00100         "decl %0":
00101         "=m"( *pValue ): // output (%0)
00102         "m"( *pValue ): // input (%1)
00103         "cc" // clobbers
00104     );
00105 }
00106
00107 inline
00108 void osgSpinLock(UInt32 *pLock, UInt32 uiMask)
00109 {
00110 #if __GNUC__ >= 4 && __GNUC_MINOR__ >=2
00111     for(UInt32 tmpVal = __sync_fetch_and_or(pLock, uiMask);
00112         (tmpVal & uiMask) != 0x0000;
00113         tmpVal = __sync_fetch_and_or(pLock, uiMask)) ;
00114 #endif
00115 }
00116
00117 inline
00118 void osgSpinLockRelease(UInt32 *pLock, UInt32 uiInvMask)
00119 {
00120 #if __GNUC__ >= 4 && __GNUC_MINOR__ >=2
00121     __sync_fetch_and_and(pLock, uiInvMask);
00122 #endif
00123 }
00124
00125 #else // !defined(WIN32)
00126 
00127 inline
00128 RefCountStore osgAtomicExchangeAndAdd(RefCountStore *pValue,
00129                                       RefCountStore  rcDelta)
00130 {
00131 #if 0
00132     RefCountStore ret = *pValue;
00133
00134     *pValue += rcDelta;
00135
00136     return ret;
00137 #endif
00138 
00139     return _InterlockedExchangeAdd(pValue, rcDelta);
00140 }
00141
00142 inline
00143 void osgAtomicIncrement(RefCountStore *pValue)
00144 {
00145 #if 0
00146     ++(*pValue);
00147 #endif
00148 
00149     _InterlockedIncrement(pValue);
00150 }
00151
00152 inline
00153 void osgAtomicDecrement(RefCountStore *pValue)
00154 {
00155 #if 0
00156     ++(*pValue);
00157 #endif
00158 
00159     _InterlockedDecrement(pValue);
00160 }
00161
00162 inline
00163 void osgSpinLock(UInt32 *pLock, UInt32 uiMask)
00164 {
00165     for(UInt32 tmpVal = _InterlockedOr((long *) pLock, uiMask);
00166         (tmpVal & uiMask) != 0x0000;
00167         tmpVal = _InterlockedOr((long *) pLock, uiMask));
00168 }
00169
00170 inline
00171 void osgSpinLockRelease(UInt32 *pLock, UInt32 uiInvMask)
00172 {
00173     _InterlockedAnd((long *) pLock, uiInvMask);
00174 }
00175
00176 #endif
00177 
00178 OSG_END_NAMESPACE
00179
00180 #endif // _OSGATOMIC_H_