Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-30 08:46:18

0001 /*
0002     Copyright (c) 2005-2021 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 #ifndef __TBB__rtm_mutex_impl_H
0018 #define __TBB__rtm_mutex_impl_H
0019 
0020 #include "_assert.h"
0021 #include "_utils.h"
0022 #include "../spin_mutex.h"
0023 
0024 #include "../profiling.h"
0025 
0026 namespace tbb {
0027 namespace detail {
0028 namespace r1 {
0029 struct rtm_mutex_impl;
0030 }
0031 namespace d1 {
0032 
0033 #if _MSC_VER && !defined(__INTEL_COMPILER)
0034     // Suppress warning: structure was padded due to alignment specifier
0035     #pragma warning (push)
0036     #pragma warning (disable: 4324)
0037 #endif
0038 
0039 /** A rtm_mutex is an speculation-enabled spin mutex.
0040     It should be used for locking short critical sections where the lock is
0041     contended but the data it protects are not.  If zero-initialized, the
0042     mutex is considered unheld.
0043     @ingroup synchronization */
0044 class alignas(max_nfs_size) rtm_mutex : private spin_mutex {
0045 private:
0046     enum class rtm_state {
0047         rtm_none,
0048         rtm_transacting,
0049         rtm_real
0050     };
0051 public:
0052     //! Constructors
0053     rtm_mutex() noexcept {
0054         create_itt_sync(this, "tbb::speculative_spin_mutex", "");
0055     }
0056 
0057     //! Destructor
0058     ~rtm_mutex() = default;
0059 
0060     //! Represents acquisition of a mutex.
0061     class scoped_lock {
0062     public:
0063         friend class rtm_mutex;
0064         //! Construct lock that has not acquired a mutex.
0065         /** Equivalent to zero-initialization of *this. */
0066         constexpr scoped_lock() : m_mutex(nullptr), m_transaction_state(rtm_state::rtm_none) {}
0067 
0068         //! Acquire lock on given mutex.
0069         scoped_lock(rtm_mutex& m) : m_mutex(nullptr), m_transaction_state(rtm_state::rtm_none) {
0070             acquire(m);
0071         }
0072 
0073         //! Release lock (if lock is held).
0074         ~scoped_lock() {
0075             if(m_transaction_state != rtm_state::rtm_none) {
0076                 release();
0077             }
0078         }
0079 
0080         //! No Copy
0081         scoped_lock(const scoped_lock&) = delete;
0082         scoped_lock& operator=(const scoped_lock&) = delete;
0083 
0084         //! Acquire lock on given mutex.
0085         void acquire(rtm_mutex& m);
0086 
0087         //! Try acquire lock on given mutex.
0088         bool try_acquire(rtm_mutex& m);
0089 
0090         //! Release lock
0091         void release();
0092 
0093     private:
0094         rtm_mutex* m_mutex;
0095         rtm_state m_transaction_state;
0096         friend r1::rtm_mutex_impl;
0097     };
0098 
0099     //! Mutex traits
0100     static constexpr bool is_rw_mutex = false;
0101     static constexpr bool is_recursive_mutex = false;
0102     static constexpr bool is_fair_mutex = false;
0103 private:
0104     friend r1::rtm_mutex_impl;
0105 }; // end of rtm_mutex
0106 } // namespace d1
0107 
0108 namespace r1 {
0109     //! Internal acquire lock.
0110     // only_speculate == true if we're doing a try_lock, else false.
0111     TBB_EXPORT void __TBB_EXPORTED_FUNC acquire(d1::rtm_mutex&, d1::rtm_mutex::scoped_lock&, bool only_speculate = false);
0112     //! Internal try_acquire lock.
0113     TBB_EXPORT bool __TBB_EXPORTED_FUNC try_acquire(d1::rtm_mutex&, d1::rtm_mutex::scoped_lock&);
0114     //! Internal release lock.
0115     TBB_EXPORT void __TBB_EXPORTED_FUNC release(d1::rtm_mutex::scoped_lock&);
0116 } // namespace r1
0117 
0118 namespace d1 {
0119 //! Acquire lock on given mutex.
0120 inline void rtm_mutex::scoped_lock::acquire(rtm_mutex& m) {
0121     __TBB_ASSERT(!m_mutex, "lock is already acquired");
0122     r1::acquire(m, *this);
0123 }
0124 
0125 //! Try acquire lock on given mutex.
0126 inline bool rtm_mutex::scoped_lock::try_acquire(rtm_mutex& m) {
0127     __TBB_ASSERT(!m_mutex, "lock is already acquired");
0128     return r1::try_acquire(m, *this);
0129 }
0130 
0131 //! Release lock
0132 inline void rtm_mutex::scoped_lock::release() {
0133     __TBB_ASSERT(m_mutex, "lock is not acquired");
0134     __TBB_ASSERT(m_transaction_state != rtm_state::rtm_none, "lock is not acquired");
0135     return r1::release(*this);
0136 }
0137 
0138 #if _MSC_VER && !defined(__INTEL_COMPILER)
0139     #pragma warning (pop) // 4324 warning
0140 #endif
0141 
0142 #if TBB_USE_PROFILING_TOOLS
0143 inline void set_name(rtm_mutex& obj, const char* name) {
0144     itt_set_sync_name(&obj, name);
0145 }
0146 #if (_WIN32||_WIN64)
0147 inline void set_name(rtm_mutex& obj, const wchar_t* name) {
0148     itt_set_sync_name(&obj, name);
0149 }
0150 #endif // WIN
0151 #else
0152 inline void set_name(rtm_mutex&, const char*) {}
0153 #if (_WIN32||_WIN64)
0154 inline void set_name(rtm_mutex&, const wchar_t*) {}
0155 #endif // WIN
0156 #endif
0157 
0158 } // namespace d1
0159 } // namespace detail
0160 } // namespace tbb
0161 
0162 #endif /* __TBB__rtm_mutex_impl_H */