00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __TBB_spin_mutex_H
00030 #define __TBB_spin_mutex_H
00031
00032 #include <cstddef>
00033 #include <new>
00034 #include "aligned_space.h"
00035 #include "tbb_stddef.h"
00036 #include "tbb_machine.h"
00037 #include "tbb_profiling.h"
00038
00039 namespace tbb {
00040
00042
00047 class spin_mutex {
00049 __TBB_atomic_flag flag;
00050
00051 public:
00053
00054 spin_mutex() : flag(0) {
00055 #if TBB_USE_THREADING_TOOLS
00056 internal_construct();
00057 #endif
00058 }
00059
00061 class scoped_lock : internal::no_copy {
00062 private:
00064 spin_mutex* my_mutex;
00065
00067
00070 __TBB_Flag my_unlock_value;
00071
00073 void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m );
00074
00076 bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m );
00077
00079 void __TBB_EXPORTED_METHOD internal_release();
00080
00081 friend class spin_mutex;
00082
00083 public:
00085 scoped_lock() : my_mutex(NULL), my_unlock_value(0) {}
00086
00088 scoped_lock( spin_mutex& m ) : my_unlock_value(0) {
00089 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00090 my_mutex=NULL;
00091 internal_acquire(m);
00092 #else
00093 __TBB_LockByte(m.flag);
00094 my_mutex=&m;
00095 #endif
00096 }
00097
00099 void acquire( spin_mutex& m ) {
00100 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00101 internal_acquire(m);
00102 #else
00103 __TBB_LockByte(m.flag);
00104 my_mutex = &m;
00105 #endif
00106 }
00107
00109
00110 bool try_acquire( spin_mutex& m ) {
00111 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00112 return internal_try_acquire(m);
00113 #else
00114 bool result = __TBB_TryLockByte(m.flag);
00115 if( result )
00116 my_mutex = &m;
00117 return result;
00118 #endif
00119 }
00120
00122 void release() {
00123 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00124 internal_release();
00125 #else
00126 __TBB_UnlockByte(my_mutex->flag, 0);
00127 my_mutex = NULL;
00128 #endif
00129 }
00130
00132 ~scoped_lock() {
00133 if( my_mutex ) {
00134 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00135 internal_release();
00136 #else
00137 __TBB_UnlockByte(my_mutex->flag, 0);
00138 #endif
00139 }
00140 }
00141 };
00142
00143 void __TBB_EXPORTED_METHOD internal_construct();
00144
00145
00146 static const bool is_rw_mutex = false;
00147 static const bool is_recursive_mutex = false;
00148 static const bool is_fair_mutex = false;
00149
00150
00151
00153 void lock() {
00154 #if TBB_USE_THREADING_TOOLS
00155 aligned_space<scoped_lock,1> tmp;
00156 new(tmp.begin()) scoped_lock(*this);
00157 #else
00158 __TBB_LockByte(flag);
00159 #endif
00160 }
00161
00163
00164 bool try_lock() {
00165 #if TBB_USE_THREADING_TOOLS
00166 aligned_space<scoped_lock,1> tmp;
00167 return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
00168 #else
00169 return __TBB_TryLockByte(flag);
00170 #endif
00171 }
00172
00174 void unlock() {
00175 #if TBB_USE_THREADING_TOOLS
00176 aligned_space<scoped_lock,1> tmp;
00177 scoped_lock& s = *tmp.begin();
00178 s.my_mutex = this;
00179 s.internal_release();
00180 #else
00181 __TBB_store_with_release(flag, 0);
00182 #endif
00183 }
00184
00185 friend class scoped_lock;
00186 };
00187
00188 __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex)
00189
00190 }
00191
00192 #endif