Shadowrun: Awakened 29 September 2011 - Build 871
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_mutex_H
00030 #define __TBB_mutex_H
00031 
00032 #if _WIN32||_WIN64
00033     #include <windows.h>
00034     #if !defined(_WIN32_WINNT)
00035     // The following Windows API function is declared explicitly;
00036     // otherwise any user would have to specify /D_WIN32_WINNT=0x0400
00037     extern "C" BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION );
00038     #endif
00039 #else /* if not _WIN32||_WIN64 */
00040     #include <pthread.h>
00041 #endif /* _WIN32||_WIN64 */
00042 
00043 #include <new>
00044 #include "aligned_space.h"
00045 #include "tbb_stddef.h"
00046 #include "tbb_profiling.h"
00047 
00048 namespace tbb {
00049 
00051 
00053 class mutex {
00054 public:
00056     mutex() {
00057 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
00058     internal_construct();
00059 #else
00060   #if _WIN32||_WIN64
00061         InitializeCriticalSection(&impl);
00062   #else
00063         int error_code = pthread_mutex_init(&impl,NULL);
00064         if( error_code )
00065             tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
00066   #endif /* _WIN32||_WIN64*/
00067 #endif /* TBB_USE_ASSERT */
00068     };
00069 
00070     ~mutex() {
00071 #if TBB_USE_ASSERT
00072         internal_destroy();
00073 #else
00074   #if _WIN32||_WIN64
00075         DeleteCriticalSection(&impl);
00076   #else
00077         pthread_mutex_destroy(&impl); 
00078 
00079   #endif /* _WIN32||_WIN64 */
00080 #endif /* TBB_USE_ASSERT */
00081     };
00082 
00083     class scoped_lock;
00084     friend class scoped_lock;
00085 
00087 
00089     class scoped_lock : internal::no_copy {
00090     public:
00092         scoped_lock() : my_mutex(NULL) {};
00093 
00095         scoped_lock( mutex& mutex ) {
00096             acquire( mutex );
00097         }
00098 
00100         ~scoped_lock() {
00101             if( my_mutex ) 
00102                 release();
00103         }
00104 
00106         void acquire( mutex& mutex ) {
00107 #if TBB_USE_ASSERT
00108             internal_acquire(mutex);
00109 #else
00110             mutex.lock();
00111             my_mutex = &mutex;
00112 #endif /* TBB_USE_ASSERT */
00113         }
00114 
00116         bool try_acquire( mutex& mutex ) {
00117 #if TBB_USE_ASSERT
00118             return internal_try_acquire (mutex);
00119 #else
00120             bool result = mutex.try_lock();
00121             if( result )
00122                 my_mutex = &mutex;
00123             return result;
00124 #endif /* TBB_USE_ASSERT */
00125         }
00126 
00128         void release() {
00129 #if TBB_USE_ASSERT
00130             internal_release ();
00131 #else
00132             my_mutex->unlock();
00133             my_mutex = NULL;
00134 #endif /* TBB_USE_ASSERT */
00135         }
00136 
00137     private:
00139         mutex* my_mutex;
00140 
00142         void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
00143 
00145         bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
00146 
00148         void __TBB_EXPORTED_METHOD internal_release();
00149 
00150         friend class mutex;
00151     };
00152 
00153     // Mutex traits
00154     static const bool is_rw_mutex = false;
00155     static const bool is_recursive_mutex = false;
00156     static const bool is_fair_mutex = false;
00157 
00158     // ISO C++0x compatibility methods
00159 
00161     void lock() {
00162 #if TBB_USE_ASSERT
00163         aligned_space<scoped_lock,1> tmp;
00164         new(tmp.begin()) scoped_lock(*this);
00165 #else
00166   #if _WIN32||_WIN64
00167         EnterCriticalSection(&impl);
00168   #else
00169         pthread_mutex_lock(&impl);
00170   #endif /* _WIN32||_WIN64 */
00171 #endif /* TBB_USE_ASSERT */
00172     }
00173 
00175 
00176     bool try_lock() {
00177 #if TBB_USE_ASSERT
00178         aligned_space<scoped_lock,1> tmp;
00179         scoped_lock& s = *tmp.begin();
00180         s.my_mutex = NULL;
00181         return s.internal_try_acquire(*this);
00182 #else
00183   #if _WIN32||_WIN64
00184         return TryEnterCriticalSection(&impl)!=0;
00185   #else
00186         return pthread_mutex_trylock(&impl)==0;
00187   #endif /* _WIN32||_WIN64 */
00188 #endif /* TBB_USE_ASSERT */
00189     }
00190 
00192     void unlock() {
00193 #if TBB_USE_ASSERT
00194         aligned_space<scoped_lock,1> tmp;
00195         scoped_lock& s = *tmp.begin();
00196         s.my_mutex = this;
00197         s.internal_release();
00198 #else
00199   #if _WIN32||_WIN64
00200         LeaveCriticalSection(&impl);
00201   #else
00202         pthread_mutex_unlock(&impl);
00203   #endif /* _WIN32||_WIN64 */
00204 #endif /* TBB_USE_ASSERT */
00205     }
00206 
00208   #if _WIN32||_WIN64
00209     typedef LPCRITICAL_SECTION native_handle_type;
00210   #else
00211     typedef pthread_mutex_t* native_handle_type;
00212   #endif
00213     native_handle_type native_handle() { return (native_handle_type) &impl; }
00214 
00215     enum state_t {
00216         INITIALIZED=0x1234,
00217         DESTROYED=0x789A,
00218         HELD=0x56CD
00219     };
00220 private:
00221 #if _WIN32||_WIN64
00222     CRITICAL_SECTION impl;    
00223     enum state_t state;
00224 #else
00225     pthread_mutex_t impl;
00226 #endif /* _WIN32||_WIN64 */
00227 
00229     void __TBB_EXPORTED_METHOD internal_construct();
00230 
00232     void __TBB_EXPORTED_METHOD internal_destroy();
00233 
00234 #if _WIN32||_WIN64
00235 public:
00237     void set_state( state_t to ) { state = to; }
00238 #endif
00239 };
00240 
00241 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
00242 
00243 } // namespace tbb 
00244 
00245 #endif /* __TBB_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