mutex.h

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

Copyright © 2005-2010 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.