Back to home page

EIC code displayed by LXR

 
 

    


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

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 #ifndef __TBB__x86_eliding_mutex_impl_H
0018 #define __TBB__x86_eliding_mutex_impl_H
0019 
0020 #ifndef __TBB_spin_mutex_H
0021 #error Do not #include this internal file directly; use public TBB headers instead.
0022 #endif
0023 
0024 #if ( __TBB_x86_32 || __TBB_x86_64 )
0025 
0026 namespace tbb {
0027 namespace interface7 {
0028 namespace internal {
0029 
0030 template<typename Mutex, bool is_rw>
0031 class padded_mutex;
0032 
0033 //! An eliding lock that occupies a single byte.
0034 /** A x86_eliding_mutex is an HLE-enabled spin mutex. It is recommended to
0035     put the mutex on a cache line that is not shared by the data it protects.
0036     It should be used for locking short critical sections where the lock is
0037     contended but the data it protects are not.  If zero-initialized, the
0038     mutex is considered unheld.
0039     @ingroup synchronization */
0040 class x86_eliding_mutex : tbb::internal::mutex_copy_deprecated_and_disabled {
0041     //! 0 if lock is released, 1 if lock is acquired.
0042     __TBB_atomic_flag flag;
0043 
0044     friend class padded_mutex<x86_eliding_mutex, false>;
0045 
0046 public:
0047     //! Construct unacquired lock.
0048     /** Equivalent to zero-initialization of *this. */
0049     x86_eliding_mutex() : flag(0) {}
0050 
0051 // bug in gcc 3.x.x causes syntax error in spite of the friend declaration above.
0052 // Make the scoped_lock public in that case.
0053 #if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000
0054 #else
0055     // by default we will not provide the scoped_lock interface.  The user
0056     // should use the padded version of the mutex.  scoped_lock is used in
0057     // padded_mutex template.
0058 private:
0059 #endif
0060     // scoped_lock in padded_mutex<> is the interface to use.
0061     //! Represents acquisition of a mutex.
0062     class scoped_lock : tbb::internal::no_copy {
0063     private:
0064         //! Points to currently held mutex, or NULL if no lock is held.
0065         x86_eliding_mutex* my_mutex;
0066 
0067     public:
0068         //! Construct without acquiring a mutex.
0069         scoped_lock() : my_mutex(NULL) {}
0070 
0071         //! Construct and acquire lock on a mutex.
0072         scoped_lock( x86_eliding_mutex& m ) : my_mutex(NULL) { acquire(m); }
0073 
0074         //! Acquire lock.
0075         void acquire( x86_eliding_mutex& m ) {
0076             __TBB_ASSERT( !my_mutex, "already holding a lock" );
0077 
0078             my_mutex=&m;
0079             my_mutex->lock();
0080         }
0081 
0082         //! Try acquiring lock (non-blocking)
0083         /** Return true if lock acquired; false otherwise. */
0084         bool try_acquire( x86_eliding_mutex& m ) {
0085             __TBB_ASSERT( !my_mutex, "already holding a lock" );
0086 
0087             bool result = m.try_lock();
0088             if( result ) {
0089                 my_mutex = &m;
0090             }
0091             return result;
0092         }
0093 
0094         //! Release lock
0095         void release() {
0096             __TBB_ASSERT( my_mutex, "release on scoped_lock that is not holding a lock" );
0097 
0098             my_mutex->unlock();
0099             my_mutex = NULL;
0100         }
0101 
0102         //! Destroy lock.  If holding a lock, releases the lock first.
0103         ~scoped_lock() {
0104             if( my_mutex ) {
0105                 release();
0106             }
0107         }
0108     };
0109 #if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000
0110 #else
0111 public:
0112 #endif  /* __TBB_USE_X86_ELIDING_MUTEX */
0113 
0114     // Mutex traits
0115     static const bool is_rw_mutex = false;
0116     static const bool is_recursive_mutex = false;
0117     static const bool is_fair_mutex = false;
0118 
0119     // ISO C++0x compatibility methods
0120 
0121     //! Acquire lock
0122     void lock() {
0123         __TBB_LockByteElided(flag);
0124     }
0125 
0126     //! Try acquiring lock (non-blocking)
0127     /** Return true if lock acquired; false otherwise. */
0128     bool try_lock() {
0129         return __TBB_TryLockByteElided(flag);
0130     }
0131 
0132     //! Release lock
0133     void unlock() {
0134         __TBB_UnlockByteElided( flag );
0135     }
0136 }; // end of x86_eliding_mutex
0137 
0138 } // namespace internal
0139 } // namespace interface7
0140 } // namespace tbb
0141 
0142 #endif /* ( __TBB_x86_32 || __TBB_x86_64 ) */
0143 
0144 #endif /* __TBB__x86_eliding_mutex_impl_H */