1 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED 2 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED 3 4 // MS compatible compilers support #pragma once 5 6 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 7 # pragma once 8 #endif 9 10 // Copyright 2008, 2020 Peter Dimov 11 // Distributed under the Boost Software License, Version 1.0. 12 // https://www.boost.org/LICENSE_1_0.txt 13 14 #include <boost/smart_ptr/detail/yield_k.hpp> 15 16 #if defined(BOOST_SP_REPORT_IMPLEMENTATION) 17 18 #include <boost/config/pragma_message.hpp> 19 BOOST_PRAGMA_MESSAGE("Using __atomic spinlock") 20 21 #endif 22 23 namespace boost 24 { 25 26 namespace detail 27 { 28 29 class spinlock 30 { 31 public: 32 33 unsigned char v_; 34 35 public: 36 try_lock()37 bool try_lock() 38 { 39 return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0; 40 } 41 lock()42 void lock() 43 { 44 for( unsigned k = 0; !try_lock(); ++k ) 45 { 46 boost::detail::yield( k ); 47 } 48 } 49 unlock()50 void unlock() 51 { 52 __atomic_clear( &v_, __ATOMIC_RELEASE ); 53 } 54 55 public: 56 57 class scoped_lock 58 { 59 private: 60 61 spinlock & sp_; 62 63 scoped_lock( scoped_lock const & ); 64 scoped_lock & operator=( scoped_lock const & ); 65 66 public: 67 scoped_lock(spinlock & sp)68 explicit scoped_lock( spinlock & sp ): sp_( sp ) 69 { 70 sp.lock(); 71 } 72 ~scoped_lock()73 ~scoped_lock() 74 { 75 sp_.unlock(); 76 } 77 }; 78 }; 79 80 } // namespace detail 81 } // namespace boost 82 83 #define BOOST_DETAIL_SPINLOCK_INIT {0} 84 85 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED 86