Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:59

0001 /*
0002     Copyright (c) 2005-2020 Intel Corporation
0003 
0004     Licensed under the Apache License, Version 2.0 (the "License");
0005     you may not use this file except in compliance with the License.
0006     You may obtain a copy of the License at
0007 
0008         http://www.apache.org/licenses/LICENSE-2.0
0009 
0010     Unless required by applicable law or agreed to in writing, software
0011     distributed under the License is distributed on an "AS IS" BASIS,
0012     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013     See the License for the specific language governing permissions and
0014     limitations under the License.
0015 */
0016 
0017 #include "internal/_deprecated_header_message_guard.h"
0018 
0019 #if !defined(__TBB_show_deprecation_message_recursive_mutex_H) && defined(__TBB_show_deprecated_header_message)
0020 #define  __TBB_show_deprecation_message_recursive_mutex_H
0021 #pragma message("TBB Warning: tbb/recursive_mutex.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.")
0022 #endif
0023 
0024 #if defined(__TBB_show_deprecated_header_message)
0025 #undef __TBB_show_deprecated_header_message
0026 #endif
0027 
0028 #ifndef __TBB_recursive_mutex_H
0029 #define __TBB_recursive_mutex_H
0030 
0031 #define __TBB_recursive_mutex_H_include_area
0032 #include "internal/_warning_suppress_enable_notice.h"
0033 
0034 #if _WIN32||_WIN64
0035 #include "machine/windows_api.h"
0036 #else
0037 #include <pthread.h>
0038 #endif /* _WIN32||_WIN64 */
0039 
0040 #include <new>
0041 #include "aligned_space.h"
0042 #include "tbb_stddef.h"
0043 #include "tbb_profiling.h"
0044 
0045 namespace tbb {
0046 //! Mutex that allows recursive mutex acquisition.
0047 /** Mutex that allows recursive mutex acquisition.
0048     @ingroup synchronization */
0049 class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::recursive_mutex is deprecated, use std::recursive_mutex")
0050 recursive_mutex : internal::mutex_copy_deprecated_and_disabled {
0051 public:
0052     //! Construct unacquired recursive_mutex.
0053     recursive_mutex() {
0054 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
0055         internal_construct();
0056 #else
0057   #if _WIN32||_WIN64
0058         InitializeCriticalSectionEx(&impl, 4000, 0);
0059   #else
0060         pthread_mutexattr_t mtx_attr;
0061         int error_code = pthread_mutexattr_init( &mtx_attr );
0062         if( error_code )
0063             tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed");
0064 
0065         pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE );
0066         error_code = pthread_mutex_init( &impl, &mtx_attr );
0067         if( error_code )
0068             tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed");
0069 
0070         pthread_mutexattr_destroy( &mtx_attr );
0071   #endif /* _WIN32||_WIN64*/
0072 #endif /* TBB_USE_ASSERT */
0073     };
0074 
0075     ~recursive_mutex() {
0076 #if TBB_USE_ASSERT
0077         internal_destroy();
0078 #else
0079   #if _WIN32||_WIN64
0080         DeleteCriticalSection(&impl);
0081   #else
0082         pthread_mutex_destroy(&impl);
0083 
0084   #endif /* _WIN32||_WIN64 */
0085 #endif /* TBB_USE_ASSERT */
0086     };
0087 
0088     class scoped_lock;
0089     friend class scoped_lock;
0090 
0091     //! The scoped locking pattern
0092     /** It helps to avoid the common problem of forgetting to release lock.
0093         It also nicely provides the "node" for queuing locks. */
0094     class scoped_lock: internal::no_copy {
0095     public:
0096         //! Construct lock that has not acquired a recursive_mutex.
0097         scoped_lock() : my_mutex(NULL) {};
0098 
0099         //! Acquire lock on given mutex.
0100         scoped_lock( recursive_mutex& mutex ) {
0101 #if TBB_USE_ASSERT
0102             my_mutex = &mutex;
0103 #endif /* TBB_USE_ASSERT */
0104             acquire( mutex );
0105         }
0106 
0107         //! Release lock (if lock is held).
0108         ~scoped_lock() {
0109             if( my_mutex )
0110                 release();
0111         }
0112 
0113         //! Acquire lock on given mutex.
0114         void acquire( recursive_mutex& mutex ) {
0115 #if TBB_USE_ASSERT
0116             internal_acquire( mutex );
0117 #else
0118             my_mutex = &mutex;
0119             mutex.lock();
0120 #endif /* TBB_USE_ASSERT */
0121         }
0122 
0123         //! Try acquire lock on given recursive_mutex.
0124         bool try_acquire( recursive_mutex& mutex ) {
0125 #if TBB_USE_ASSERT
0126             return internal_try_acquire( mutex );
0127 #else
0128             bool result = mutex.try_lock();
0129             if( result )
0130                 my_mutex = &mutex;
0131             return result;
0132 #endif /* TBB_USE_ASSERT */
0133         }
0134 
0135         //! Release lock
0136         void release() {
0137 #if TBB_USE_ASSERT
0138             internal_release();
0139 #else
0140             my_mutex->unlock();
0141             my_mutex = NULL;
0142 #endif /* TBB_USE_ASSERT */
0143         }
0144 
0145     private:
0146         //! The pointer to the current recursive_mutex to work
0147         recursive_mutex* my_mutex;
0148 
0149         //! All checks from acquire using mutex.state were moved here
0150         void __TBB_EXPORTED_METHOD internal_acquire( recursive_mutex& m );
0151 
0152         //! All checks from try_acquire using mutex.state were moved here
0153         bool __TBB_EXPORTED_METHOD internal_try_acquire( recursive_mutex& m );
0154 
0155         //! All checks from release using mutex.state were moved here
0156         void __TBB_EXPORTED_METHOD internal_release();
0157 
0158         friend class recursive_mutex;
0159     };
0160 
0161     // Mutex traits
0162     static const bool is_rw_mutex = false;
0163     static const bool is_recursive_mutex = true;
0164     static const bool is_fair_mutex = false;
0165 
0166     // C++0x compatibility interface
0167 
0168     //! Acquire lock
0169     void lock() {
0170 #if TBB_USE_ASSERT
0171         aligned_space<scoped_lock> tmp;
0172         new(tmp.begin()) scoped_lock(*this);
0173 #else
0174   #if _WIN32||_WIN64
0175         EnterCriticalSection(&impl);
0176   #else
0177         int error_code = pthread_mutex_lock(&impl);
0178         if( error_code )
0179             tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_lock failed");
0180   #endif /* _WIN32||_WIN64 */
0181 #endif /* TBB_USE_ASSERT */
0182     }
0183 
0184     //! Try acquiring lock (non-blocking)
0185     /** Return true if lock acquired; false otherwise. */
0186     bool try_lock() {
0187 #if TBB_USE_ASSERT
0188         aligned_space<scoped_lock> tmp;
0189         return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
0190 #else
0191   #if _WIN32||_WIN64
0192         return TryEnterCriticalSection(&impl)!=0;
0193   #else
0194         return pthread_mutex_trylock(&impl)==0;
0195   #endif /* _WIN32||_WIN64 */
0196 #endif /* TBB_USE_ASSERT */
0197     }
0198 
0199     //! Release lock
0200     void unlock() {
0201 #if TBB_USE_ASSERT
0202         aligned_space<scoped_lock> tmp;
0203         scoped_lock& s = *tmp.begin();
0204         s.my_mutex = this;
0205         s.internal_release();
0206 #else
0207   #if _WIN32||_WIN64
0208         LeaveCriticalSection(&impl);
0209   #else
0210         pthread_mutex_unlock(&impl);
0211   #endif /* _WIN32||_WIN64 */
0212 #endif /* TBB_USE_ASSERT */
0213     }
0214 
0215     //! Return native_handle
0216   #if _WIN32||_WIN64
0217     typedef LPCRITICAL_SECTION native_handle_type;
0218   #else
0219     typedef pthread_mutex_t* native_handle_type;
0220   #endif
0221     native_handle_type native_handle() { return (native_handle_type) &impl; }
0222 
0223 private:
0224 #if _WIN32||_WIN64
0225     CRITICAL_SECTION impl;
0226     enum state_t {
0227         INITIALIZED=0x1234,
0228         DESTROYED=0x789A,
0229     } state;
0230 #else
0231     pthread_mutex_t impl;
0232 #endif /* _WIN32||_WIN64 */
0233 
0234     //! All checks from mutex constructor using mutex.state were moved here
0235     void __TBB_EXPORTED_METHOD internal_construct();
0236 
0237     //! All checks from mutex destructor using mutex.state were moved here
0238     void __TBB_EXPORTED_METHOD internal_destroy();
0239 };
0240 
0241 __TBB_DEFINE_PROFILING_SET_NAME(recursive_mutex)
0242 
0243 } // namespace tbb
0244 
0245 #include "internal/_warning_suppress_disable_notice.h"
0246 #undef __TBB_recursive_mutex_H_include_area
0247 
0248 #endif /* __TBB_recursive_mutex_H */