![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright 2005-2010 Intel Corporation. All Rights Reserved. 00003 00004 This file is part of Threading Building Blocks. 00005 00006 Threading Building Blocks is free software; you can redistribute it 00007 and/or modify it under the terms of the GNU General Public License 00008 version 2 as published by the Free Software Foundation. 00009 00010 Threading Building Blocks is distributed in the hope that it will be 00011 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00012 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Threading Building Blocks; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 As a special exception, you may use this file as part of a free software 00020 library without restriction. Specifically, if other files instantiate 00021 templates or use macros or inline functions from this file, or you compile 00022 this file and link it with other files to produce an executable, this 00023 file does not by itself cause the resulting executable to be covered by 00024 the GNU General Public License. This exception does not however 00025 invalidate any other reasons why the executable file might be covered by 00026 the GNU General Public License. 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 unsigned char 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 uintptr_t my_unlock_value; 00068 00070 void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m ); 00071 00073 bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m ); 00074 00076 void __TBB_EXPORTED_METHOD internal_release(); 00077 00078 friend class spin_mutex; 00079 00080 public: 00082 scoped_lock() : my_mutex(NULL), my_unlock_value(0) {} 00083 00085 scoped_lock( spin_mutex& m ) { 00086 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT 00087 my_mutex=NULL; 00088 internal_acquire(m); 00089 #else 00090 my_unlock_value = __TBB_LockByte(m.flag); 00091 my_mutex=&m; 00092 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ 00093 } 00094 00096 void acquire( spin_mutex& m ) { 00097 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT 00098 internal_acquire(m); 00099 #else 00100 my_unlock_value = __TBB_LockByte(m.flag); 00101 my_mutex = &m; 00102 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ 00103 } 00104 00106 00107 bool try_acquire( spin_mutex& m ) { 00108 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT 00109 return internal_try_acquire(m); 00110 #else 00111 bool result = __TBB_TryLockByte(m.flag); 00112 if( result ) { 00113 my_unlock_value = 0; 00114 my_mutex = &m; 00115 } 00116 return result; 00117 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ 00118 } 00119 00121 void release() { 00122 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT 00123 internal_release(); 00124 #else 00125 __TBB_store_with_release(my_mutex->flag, static_cast<unsigned char>(my_unlock_value)); 00126 my_mutex = NULL; 00127 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ 00128 } 00129 00131 ~scoped_lock() { 00132 if( my_mutex ) { 00133 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT 00134 internal_release(); 00135 #else 00136 __TBB_store_with_release(my_mutex->flag, static_cast<unsigned char>(my_unlock_value)); 00137 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ 00138 } 00139 } 00140 }; 00141 00142 void __TBB_EXPORTED_METHOD internal_construct(); 00143 00144 // Mutex traits 00145 static const bool is_rw_mutex = false; 00146 static const bool is_recursive_mutex = false; 00147 static const bool is_fair_mutex = false; 00148 00149 // ISO C++0x compatibility methods 00150 00152 void lock() { 00153 #if TBB_USE_THREADING_TOOLS 00154 aligned_space<scoped_lock,1> tmp; 00155 new(tmp.begin()) scoped_lock(*this); 00156 #else 00157 __TBB_LockByte(flag); 00158 #endif /* TBB_USE_THREADING_TOOLS*/ 00159 } 00160 00162 00163 bool try_lock() { 00164 #if TBB_USE_THREADING_TOOLS 00165 aligned_space<scoped_lock,1> tmp; 00166 return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); 00167 #else 00168 return __TBB_TryLockByte(flag); 00169 #endif /* TBB_USE_THREADING_TOOLS*/ 00170 } 00171 00173 void unlock() { 00174 #if TBB_USE_THREADING_TOOLS 00175 aligned_space<scoped_lock,1> tmp; 00176 scoped_lock& s = *tmp.begin(); 00177 s.my_mutex = this; 00178 s.my_unlock_value = 0; 00179 s.internal_release(); 00180 #else 00181 __TBB_store_with_release(flag, 0); 00182 #endif /* TBB_USE_THREADING_TOOLS */ 00183 } 00184 00185 friend class scoped_lock; 00186 }; 00187 00188 __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex) 00189 00190 } // namespace tbb 00191 00192 #endif /* __TBB_spin_mutex_H */
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.