mutex.h

00001 /*
00002     Copyright 2005-2011 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 "machine/windows_api.h"
00026 #else
00027 #include <pthread.h>
00028 #endif /* _WIN32||_WIN64 */
00029 
00030 #include <new>
00031 #include "aligned_space.h"
00032 #include "tbb_stddef.h"
00033 #include "tbb_profiling.h"
00034 
00035 namespace tbb {
00036 
00038 
00040 class mutex {
00041 public:
00043     mutex() {
00044 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
00045     internal_construct();
00046 #else
00047   #if _WIN32||_WIN64
00048         InitializeCriticalSection(&impl);
00049   #else
00050         int error_code = pthread_mutex_init(&impl,NULL);
00051         if( error_code )
00052             tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
00053   #endif /* _WIN32||_WIN64*/
00054 #endif /* TBB_USE_ASSERT */
00055     };
00056 
00057     ~mutex() {
00058 #if TBB_USE_ASSERT
00059         internal_destroy();
00060 #else
00061   #if _WIN32||_WIN64
00062         DeleteCriticalSection(&impl);
00063   #else
00064         pthread_mutex_destroy(&impl); 
00065 
00066   #endif /* _WIN32||_WIN64 */
00067 #endif /* TBB_USE_ASSERT */
00068     };
00069 
00070     class scoped_lock;
00071     friend class scoped_lock;
00072 
00074 
00076     class scoped_lock : internal::no_copy {
00077     public:
00079         scoped_lock() : my_mutex(NULL) {};
00080 
00082         scoped_lock( mutex& mutex ) {
00083             acquire( mutex );
00084         }
00085 
00087         ~scoped_lock() {
00088             if( my_mutex ) 
00089                 release();
00090         }
00091 
00093         void acquire( mutex& mutex ) {
00094 #if TBB_USE_ASSERT
00095             internal_acquire(mutex);
00096 #else
00097             mutex.lock();
00098             my_mutex = &mutex;
00099 #endif /* TBB_USE_ASSERT */
00100         }
00101 
00103         bool try_acquire( mutex& mutex ) {
00104 #if TBB_USE_ASSERT
00105             return internal_try_acquire (mutex);
00106 #else
00107             bool result = mutex.try_lock();
00108             if( result )
00109                 my_mutex = &mutex;
00110             return result;
00111 #endif /* TBB_USE_ASSERT */
00112         }
00113 
00115         void release() {
00116 #if TBB_USE_ASSERT
00117             internal_release ();
00118 #else
00119             my_mutex->unlock();
00120             my_mutex = NULL;
00121 #endif /* TBB_USE_ASSERT */
00122         }
00123 
00124     private:
00126         mutex* my_mutex;
00127 
00129         void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
00130 
00132         bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
00133 
00135         void __TBB_EXPORTED_METHOD internal_release();
00136 
00137         friend class mutex;
00138     };
00139 
00140     // Mutex traits
00141     static const bool is_rw_mutex = false;
00142     static const bool is_recursive_mutex = false;
00143     static const bool is_fair_mutex = false;
00144 
00145     // ISO C++0x compatibility methods
00146 
00148     void lock() {
00149 #if TBB_USE_ASSERT
00150         aligned_space<scoped_lock,1> tmp;
00151         new(tmp.begin()) scoped_lock(*this);
00152 #else
00153   #if _WIN32||_WIN64
00154         EnterCriticalSection(&impl);
00155   #else
00156         pthread_mutex_lock(&impl);
00157   #endif /* _WIN32||_WIN64 */
00158 #endif /* TBB_USE_ASSERT */
00159     }
00160 
00162 
00163     bool try_lock() {
00164 #if TBB_USE_ASSERT
00165         aligned_space<scoped_lock,1> tmp;
00166         scoped_lock& s = *tmp.begin();
00167         s.my_mutex = NULL;
00168         return s.internal_try_acquire(*this);
00169 #else
00170   #if _WIN32||_WIN64
00171         return TryEnterCriticalSection(&impl)!=0;
00172   #else
00173         return pthread_mutex_trylock(&impl)==0;
00174   #endif /* _WIN32||_WIN64 */
00175 #endif /* TBB_USE_ASSERT */
00176     }
00177 
00179     void unlock() {
00180 #if TBB_USE_ASSERT
00181         aligned_space<scoped_lock,1> tmp;
00182         scoped_lock& s = *tmp.begin();
00183         s.my_mutex = this;
00184         s.internal_release();
00185 #else
00186   #if _WIN32||_WIN64
00187         LeaveCriticalSection(&impl);
00188   #else
00189         pthread_mutex_unlock(&impl);
00190   #endif /* _WIN32||_WIN64 */
00191 #endif /* TBB_USE_ASSERT */
00192     }
00193 
00195   #if _WIN32||_WIN64
00196     typedef LPCRITICAL_SECTION native_handle_type;
00197   #else
00198     typedef pthread_mutex_t* native_handle_type;
00199   #endif
00200     native_handle_type native_handle() { return (native_handle_type) &impl; }
00201 
00202     enum state_t {
00203         INITIALIZED=0x1234,
00204         DESTROYED=0x789A,
00205         HELD=0x56CD
00206     };
00207 private:
00208 #if _WIN32||_WIN64
00209     CRITICAL_SECTION impl;    
00210     enum state_t state;
00211 #else
00212     pthread_mutex_t impl;
00213 #endif /* _WIN32||_WIN64 */
00214 
00216     void __TBB_EXPORTED_METHOD internal_construct();
00217 
00219     void __TBB_EXPORTED_METHOD internal_destroy();
00220 
00221 #if _WIN32||_WIN64
00222 public:
00224     void set_state( state_t to ) { state = to; }
00225 #endif
00226 };
00227 
00228 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
00229 
00230 } // namespace tbb 
00231 
00232 #endif /* __TBB_mutex_H */

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