00001
00029
00030
00031
00032
00033
00034 #if COMPILE_THREADS
00035 #ifndef BASE_THREAD_ATOMIC_HH
00036 #define BASE_THREAD_ATOMIC_HH 1
00037
00038 #include "base_thread_common.hh"
00039
00040 namespace base {
00041
00045 class Atomic
00046 {
00047 ;
00048 public:
00049
00050 Atomic( void ) { }
00051 ~Atomic() { }
00052
00053 typedef volatile int Bool;
00054 typedef volatile int Int;
00055 typedef volatile long Long;
00056
00057 #define ATOMIC_TYPE Int
00058 #include "base_thread_atomic2.hh"
00059 #undef ATOMIC_TYPE
00060
00061 #define ATOMIC_TYPE Long
00062 #include "base_thread_atomic2.hh"
00063 #undef ATOMIC_TYPE
00064
00068 #if ! COMPILE_GCC_TLS
00069 inline CLASS_METHOD
00070 void
00071 Set( volatile pthread_t* out, volatile pthread_t val )
00072 {
00073 *out = val;
00074 }
00075 #endif
00076
00077 };
00078
00086 class Busy
00087 {
00088 public:
00089 Busy( Atomic::Int* busy )
00090 : mBusy(busy)
00091 {
00092 mBusy2 = Atomic::Add( mBusy, +1 );
00093 }
00094
00095 ~Busy()
00096 {
00097 Atomic::Add( mBusy, -1 );
00098 }
00099
00100 bool IfBusy( void ) const
00101 {
00102 ASSERT( mBusy2 >= 0 );
00103 return mBusy2 > 1;
00104 }
00105
00106 private:
00107 Atomic::Int* const mBusy;
00108 Atomic::Int mBusy2;
00109 };
00110
00111 #define BUSY_BEGIN PERSISTENT Atomic::Int sBusy = 0; \
00112 Busy busy( &sBusy ); \
00113 if ( busy.IfBusy() ) return;
00114
00115 #define BUSY_BEGIN_ASSERT PERSISTENT Atomic::Int sBusy = 0; \
00116 Busy busy ( &sBusy ); \
00117 ASSERT_OR_RETURN( not busy.IfBusy() );
00118
00119 #define BUSY_END
00120
00121
00122
00123 }
00124
00125 #endif // BASE_THREAD_ATOMIC_HH
00126 #endif // COMPILE_THREADS