Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/oneapi/tbb/spin_mutex.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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_spin_mutex_H
0018 #define __TBB_spin_mutex_H
0019 
0020 #include "detail/_namespace_injection.h"
0021 #include "detail/_mutex_common.h"
0022 
0023 #include "profiling.h"
0024 
0025 #include "detail/_assert.h"
0026 #include "detail/_utils.h"
0027 #include "detail/_scoped_lock.h"
0028 
0029 #include <atomic>
0030 
0031 namespace tbb {
0032 namespace detail {
0033 namespace d1 {
0034 
0035 #if __TBB_TSX_INTRINSICS_PRESENT
0036 class rtm_mutex;
0037 #endif
0038 
0039 /** A spin_mutex is a low-level synchronization primitive.
0040     While locked, it causes the waiting threads to spin in a loop until the lock is released.
0041     It should be used only for locking short critical sections
0042     (typically less than 20 instructions) when fairness is not an issue.
0043     If zero-initialized, the mutex is considered unheld.
0044     @ingroup synchronization */
0045 class spin_mutex {
0046 public:
0047     //! Constructors
0048     spin_mutex() noexcept : m_flag(false) {
0049         create_itt_sync(this, "tbb::spin_mutex", "");
0050     };
0051 
0052     //! Destructor
0053     ~spin_mutex() = default;
0054 
0055     //! No Copy
0056     spin_mutex(const spin_mutex&) = delete;
0057     spin_mutex& operator=(const spin_mutex&) = delete;
0058 
0059     using scoped_lock = unique_scoped_lock<spin_mutex>;
0060 
0061     //! Mutex traits
0062     static constexpr bool is_rw_mutex = false;
0063     static constexpr bool is_recursive_mutex = false;
0064     static constexpr bool is_fair_mutex = false;
0065 
0066     //! Acquire lock
0067     /** Spin if the lock is taken */
0068     void lock() {
0069         atomic_backoff backoff;
0070         call_itt_notify(prepare, this);
0071         while (m_flag.exchange(true)) backoff.pause();
0072         call_itt_notify(acquired, this);
0073     }
0074 
0075     //! Try acquiring lock (non-blocking)
0076     /** Return true if lock acquired; false otherwise. */
0077     bool try_lock() {
0078         bool result = !m_flag.exchange(true);
0079         if (result) {
0080             call_itt_notify(acquired, this);
0081         }
0082         return result;
0083     }
0084 
0085     //! Release lock
0086     void unlock() {
0087         call_itt_notify(releasing, this);
0088         m_flag.store(false, std::memory_order_release);
0089     }
0090 
0091 protected:
0092     std::atomic<bool> m_flag;
0093 }; // class spin_mutex
0094 
0095 #if TBB_USE_PROFILING_TOOLS
0096 inline void set_name(spin_mutex& obj, const char* name) {
0097     itt_set_sync_name(&obj, name);
0098 }
0099 #if (_WIN32||_WIN64)
0100 inline void set_name(spin_mutex& obj, const wchar_t* name) {
0101     itt_set_sync_name(&obj, name);
0102 }
0103 #endif //WIN
0104 #else
0105 inline void set_name(spin_mutex&, const char*) {}
0106 #if (_WIN32||_WIN64)
0107 inline void set_name(spin_mutex&, const wchar_t*) {}
0108 #endif // WIN
0109 #endif
0110 } // namespace d1
0111 } // namespace detail
0112 
0113 inline namespace v1 {
0114 using detail::d1::spin_mutex;
0115 } // namespace v1
0116 namespace profiling {
0117     using detail::d1::set_name;
0118 }
0119 } // namespace tbb
0120 
0121 #include "detail/_rtm_mutex.h"
0122 
0123 namespace tbb {
0124 inline namespace v1 {
0125 #if __TBB_TSX_INTRINSICS_PRESENT
0126     using speculative_spin_mutex = detail::d1::rtm_mutex;
0127 #else
0128     using speculative_spin_mutex = detail::d1::spin_mutex;
0129 #endif
0130 }
0131 }
0132 
0133 #endif /* __TBB_spin_mutex_H */
0134