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 unsigned char 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 internal::uintptr my_unlock_value;
00060
00062 void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m );
00063
00065 bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m );
00066
00068 void __TBB_EXPORTED_METHOD internal_release();
00069
00070 friend class spin_mutex;
00071
00072 public:
00074 scoped_lock() : my_mutex(NULL), my_unlock_value(0) {}
00075
00077 scoped_lock( spin_mutex& m ) {
00078 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00079 my_mutex=NULL;
00080 internal_acquire(m);
00081 #else
00082 my_unlock_value = __TBB_LockByte(m.flag);
00083 my_mutex=&m;
00084 #endif
00085 }
00086
00088 void acquire( spin_mutex& m ) {
00089 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00090 internal_acquire(m);
00091 #else
00092 my_unlock_value = __TBB_LockByte(m.flag);
00093 my_mutex = &m;
00094 #endif
00095 }
00096
00098
00099 bool try_acquire( spin_mutex& m ) {
00100 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00101 return internal_try_acquire(m);
00102 #else
00103 bool result = __TBB_TryLockByte(m.flag);
00104 if( result ) {
00105 my_unlock_value = 0;
00106 my_mutex = &m;
00107 }
00108 return result;
00109 #endif
00110 }
00111
00113 void release() {
00114 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00115 internal_release();
00116 #else
00117 __TBB_store_with_release(my_mutex->flag, static_cast<unsigned char>(my_unlock_value));
00118 my_mutex = NULL;
00119 #endif
00120 }
00121
00123 ~scoped_lock() {
00124 if( my_mutex ) {
00125 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00126 internal_release();
00127 #else
00128 __TBB_store_with_release(my_mutex->flag, static_cast<unsigned char>(my_unlock_value));
00129 #endif
00130 }
00131 }
00132 };
00133
00134 void __TBB_EXPORTED_METHOD internal_construct();
00135
00136
00137 static const bool is_rw_mutex = false;
00138 static const bool is_recursive_mutex = false;
00139 static const bool is_fair_mutex = false;
00140
00141
00142
00144 void lock() {
00145 #if TBB_USE_THREADING_TOOLS
00146 aligned_space<scoped_lock,1> tmp;
00147 new(tmp.begin()) scoped_lock(*this);
00148 #else
00149 __TBB_LockByte(flag);
00150 #endif
00151 }
00152
00154
00155 bool try_lock() {
00156 #if TBB_USE_THREADING_TOOLS
00157 aligned_space<scoped_lock,1> tmp;
00158 return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
00159 #else
00160 return __TBB_TryLockByte(flag);
00161 #endif
00162 }
00163
00165 void unlock() {
00166 #if TBB_USE_THREADING_TOOLS
00167 aligned_space<scoped_lock,1> tmp;
00168 scoped_lock& s = *tmp.begin();
00169 s.my_mutex = this;
00170 s.my_unlock_value = 0;
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