mutex.h Source File

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# mutex.h

    00001 /*
    00002     Copyright 2005-2012 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         InitializeCriticalSectionEx(&impl, 4000, 0);
    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-2012 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.