spin_mutex.h

00001 /*
00002     Copyright 2005-2009 Intel Corporation.  All Rights Reserved.
00003 
00004     The source code contained or described herein and all documents related
00005     to the source code ("Material") are owned by Intel Corporation or its
00006     suppliers or licensors.  Title to the Material remains with Intel
00007     Corporation or its suppliers and licensors.  The Material is protected
00008     by worldwide copyright laws and treaty provisions.  No part of the
00009     Material may be used, copied, reproduced, modified, published, uploaded,
00010     posted, transmitted, distributed, or disclosed in any way without
00011     Intel's prior express written permission.
00012 
00013     No license under any patent, copyright, trade secret or other
00014     intellectual property right is granted to or conferred upon you by
00015     disclosure or delivery of the Materials, either expressly, by
00016     implication, inducement, estoppel or otherwise.  Any license under such
00017     intellectual property rights must be express and approved by Intel in
00018     writing.
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 /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
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 /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
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 /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
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 /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
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 /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
00130             }
00131         }
00132     };
00133 
00134     void __TBB_EXPORTED_METHOD internal_construct();
00135 
00136     // Mutex traits
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     // ISO C++0x compatibility methods
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 /* TBB_USE_THREADING_TOOLS*/
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 /* TBB_USE_THREADING_TOOLS*/
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 /* TBB_USE_THREADING_TOOLS */
00175     }
00176 
00177     friend class scoped_lock;
00178 };
00179 
00180 __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex)
00181 
00182 } // namespace tbb
00183 
00184 #endif /* __TBB_spin_mutex_H */

Copyright © 2005-2009 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.