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_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 
00032 #else /* if not _WIN32||_WIN64 */
00033 #include <pthread.h>
00034 namespace tbb { namespace internal {
00035 // Use this internal TBB function to throw an exception
00036 extern void handle_perror( int error_code, const char* what );
00037 } } //namespaces
00038 #endif /* _WIN32||_WIN64 */
00039 
00040 #include "tbb_stddef.h"
00041 #include "tbb_profiling.h"
00042 
00043 namespace tbb {
00044 
00046 
00048 class mutex {
00049 public:
00051     mutex() {
00052 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
00053     internal_construct();
00054 #else
00055   #if _WIN32||_WIN64
00056         InitializeCriticalSection(&impl);
00057   #else
00058         int error_code = pthread_mutex_init(&impl,NULL);
00059         if( error_code )
00060             tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
00061   #endif /* _WIN32||_WIN64*/
00062 #endif /* TBB_USE_ASSERT */
00063     };
00064 
00065     ~mutex() {
00066 #if TBB_USE_ASSERT
00067         internal_destroy();
00068 #else
00069   #if _WIN32||_WIN64
00070         DeleteCriticalSection(&impl);
00071   #else
00072         pthread_mutex_destroy(&impl); 
00073 
00074   #endif /* _WIN32||_WIN64 */
00075 #endif /* TBB_USE_ASSERT */
00076     };
00077 
00078     class scoped_lock;
00079     friend class scoped_lock;
00080 
00082 
00084     class scoped_lock : internal::no_copy {
00085     public:
00087         scoped_lock() : my_mutex(NULL) {};
00088 
00090 
00091         scoped_lock( mutex& mutex ) {
00092             acquire( mutex );
00093         }
00094 
00096         ~scoped_lock() {
00097             if( my_mutex ) 
00098                 release();
00099         }
00100 
00102         void acquire( mutex& mutex ) {
00103 #if TBB_USE_ASSERT
00104             internal_acquire(mutex);
00105 #else
00106             my_mutex = &mutex;
00107   #if _WIN32||_WIN64
00108             EnterCriticalSection(&mutex.impl);
00109   #else
00110             pthread_mutex_lock(&mutex.impl);
00111   #endif /* _WIN32||_WIN64 */
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;
00121   #if _WIN32||_WIN64
00122             result = TryEnterCriticalSection(&mutex.impl)!=0;
00123   #else
00124             result = pthread_mutex_trylock(&mutex.impl)==0;
00125   #endif /* _WIN32||_WIN64 */
00126             if( result )
00127                 my_mutex = &mutex;
00128             return result;
00129 #endif /* TBB_USE_ASSERT */
00130         }
00131 
00133         void release() {
00134 #if TBB_USE_ASSERT
00135             internal_release ();
00136 #else
00137   #if _WIN32||_WIN64
00138             LeaveCriticalSection(&my_mutex->impl);
00139   #else
00140             pthread_mutex_unlock(&my_mutex->impl);
00141   #endif /* _WIN32||_WIN64 */
00142             my_mutex = NULL;
00143 #endif /* TBB_USE_ASSERT */
00144         }
00145 
00146     private:
00148         mutex* my_mutex;
00149 
00151         void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
00152 
00154         bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
00155 
00157         void __TBB_EXPORTED_METHOD internal_release();
00158     };
00159 
00160     // Mutex traits
00161     static const bool is_rw_mutex = false;
00162     static const bool is_recursive_mutex = false;
00163     static const bool is_fair_mutex = false;
00164 
00165 private:
00166 #if _WIN32||_WIN64
00167     CRITICAL_SECTION impl;    
00168     enum state_t {
00169         INITIALIZED=0x1234,
00170         DESTROYED=0x789A,
00171         HELD=0x56CD
00172     } state;
00173 #else
00174     pthread_mutex_t impl;
00175 #endif /* _WIN32||_WIN64 */
00176 
00178     void __TBB_EXPORTED_METHOD internal_construct();
00179 
00181     void __TBB_EXPORTED_METHOD internal_destroy();
00182 };
00183 
00184 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
00185 
00186 } // namespace tbb 
00187 
00188 #endif /* __TBB_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.