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