Shadowrun: Awakened 29 September 2011 - Build 871
spin_mutex.h
Go to the documentation of this file.
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.

GNU Lesser General Public License 3 Sourceforge.net