Back to home page

EIC code displayed by LXR

 
 

    


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

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_mutex_H) && defined(__TBB_show_deprecated_header_message)
0020 #define  __TBB_show_deprecation_message_mutex_H
0021 #pragma message("TBB Warning: tbb/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_mutex_H
0029 #define __TBB_mutex_H
0030 
0031 #define __TBB_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 
0047 //! Wrapper around the platform's native lock.
0048 /** @ingroup synchronization */
0049 class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::critical_section is deprecated, use std::mutex") mutex : internal::mutex_copy_deprecated_and_disabled {
0050 public:
0051     //! Construct unacquired mutex.
0052     mutex() {
0053 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
0054     internal_construct();
0055 #else
0056   #if _WIN32||_WIN64
0057         InitializeCriticalSectionEx(&impl, 4000, 0);
0058   #else
0059         int error_code = pthread_mutex_init(&impl,NULL);
0060         if( error_code )
0061             tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
0062   #endif /* _WIN32||_WIN64*/
0063 #endif /* TBB_USE_ASSERT */
0064     };
0065 
0066     ~mutex() {
0067 #if TBB_USE_ASSERT
0068         internal_destroy();
0069 #else
0070   #if _WIN32||_WIN64
0071         DeleteCriticalSection(&impl);
0072   #else
0073         pthread_mutex_destroy(&impl);
0074 
0075   #endif /* _WIN32||_WIN64 */
0076 #endif /* TBB_USE_ASSERT */
0077     };
0078 
0079     class scoped_lock;
0080     friend class scoped_lock;
0081 
0082     //! The scoped locking pattern
0083     /** It helps to avoid the common problem of forgetting to release lock.
0084         It also nicely provides the "node" for queuing locks. */
0085     class scoped_lock : internal::no_copy {
0086     public:
0087         //! Construct lock that has not acquired a mutex.
0088         scoped_lock() : my_mutex(NULL) {};
0089 
0090         //! Acquire lock on given mutex.
0091         scoped_lock( mutex& mutex ) {
0092             acquire( mutex );
0093         }
0094 
0095         //! Release lock (if lock is held).
0096         ~scoped_lock() {
0097             if( my_mutex )
0098                 release();
0099         }
0100 
0101         //! Acquire lock on given mutex.
0102         void acquire( mutex& mutex ) {
0103 #if TBB_USE_ASSERT
0104             internal_acquire(mutex);
0105 #else
0106             mutex.lock();
0107             my_mutex = &mutex;
0108 #endif /* TBB_USE_ASSERT */
0109         }
0110 
0111         //! Try acquire lock on given mutex.
0112         bool try_acquire( mutex& mutex ) {
0113 #if TBB_USE_ASSERT
0114             return internal_try_acquire (mutex);
0115 #else
0116             bool result = mutex.try_lock();
0117             if( result )
0118                 my_mutex = &mutex;
0119             return result;
0120 #endif /* TBB_USE_ASSERT */
0121         }
0122 
0123         //! Release lock
0124         void release() {
0125 #if TBB_USE_ASSERT
0126             internal_release ();
0127 #else
0128             my_mutex->unlock();
0129             my_mutex = NULL;
0130 #endif /* TBB_USE_ASSERT */
0131         }
0132 
0133     private:
0134         //! The pointer to the current mutex to work
0135         mutex* my_mutex;
0136 
0137         //! All checks from acquire using mutex.state were moved here
0138         void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
0139 
0140         //! All checks from try_acquire using mutex.state were moved here
0141         bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
0142 
0143         //! All checks from release using mutex.state were moved here
0144         void __TBB_EXPORTED_METHOD internal_release();
0145 
0146         friend class mutex;
0147     };
0148 
0149     // Mutex traits
0150     static const bool is_rw_mutex = false;
0151     static const bool is_recursive_mutex = false;
0152     static const bool is_fair_mutex = false;
0153 
0154     // ISO C++0x compatibility methods
0155 
0156     //! Acquire lock
0157     void lock() {
0158 #if TBB_USE_ASSERT
0159         aligned_space<scoped_lock> tmp;
0160         new(tmp.begin()) scoped_lock(*this);
0161 #else
0162   #if _WIN32||_WIN64
0163         EnterCriticalSection(&impl);
0164   #else
0165         int error_code = pthread_mutex_lock(&impl);
0166         if( error_code )
0167             tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_lock failed");
0168   #endif /* _WIN32||_WIN64 */
0169 #endif /* TBB_USE_ASSERT */
0170     }
0171 
0172     //! Try acquiring lock (non-blocking)
0173     /** Return true if lock acquired; false otherwise. */
0174     bool try_lock() {
0175 #if TBB_USE_ASSERT
0176         aligned_space<scoped_lock> tmp;
0177         scoped_lock& s = *tmp.begin();
0178         s.my_mutex = NULL;
0179         return s.internal_try_acquire(*this);
0180 #else
0181   #if _WIN32||_WIN64
0182         return TryEnterCriticalSection(&impl)!=0;
0183   #else
0184         return pthread_mutex_trylock(&impl)==0;
0185   #endif /* _WIN32||_WIN64 */
0186 #endif /* TBB_USE_ASSERT */
0187     }
0188 
0189     //! Release lock
0190     void unlock() {
0191 #if TBB_USE_ASSERT
0192         aligned_space<scoped_lock> tmp;
0193         scoped_lock& s = *tmp.begin();
0194         s.my_mutex = this;
0195         s.internal_release();
0196 #else
0197   #if _WIN32||_WIN64
0198         LeaveCriticalSection(&impl);
0199   #else
0200         pthread_mutex_unlock(&impl);
0201   #endif /* _WIN32||_WIN64 */
0202 #endif /* TBB_USE_ASSERT */
0203     }
0204 
0205     //! Return native_handle
0206   #if _WIN32||_WIN64
0207     typedef LPCRITICAL_SECTION native_handle_type;
0208   #else
0209     typedef pthread_mutex_t* native_handle_type;
0210   #endif
0211     native_handle_type native_handle() { return (native_handle_type) &impl; }
0212 
0213     enum state_t {
0214         INITIALIZED=0x1234,
0215         DESTROYED=0x789A,
0216         HELD=0x56CD
0217     };
0218 private:
0219 #if _WIN32||_WIN64
0220     CRITICAL_SECTION impl;
0221     enum state_t state;
0222 #else
0223     pthread_mutex_t impl;
0224 #endif /* _WIN32||_WIN64 */
0225 
0226     //! All checks from mutex constructor using mutex.state were moved here
0227     void __TBB_EXPORTED_METHOD internal_construct();
0228 
0229     //! All checks from mutex destructor using mutex.state were moved here
0230     void __TBB_EXPORTED_METHOD internal_destroy();
0231 
0232 #if _WIN32||_WIN64
0233 public:
0234     //!  Set the internal state
0235     void set_state( state_t to ) { state = to; }
0236 #endif
0237 };
0238 
0239 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
0240 
0241 } // namespace tbb
0242 
0243 #include "internal/_warning_suppress_disable_notice.h"
0244 #undef __TBB_mutex_H_include_area
0245 
0246 #endif /* __TBB_mutex_H */