1 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED 2 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_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 // 11 // Copyright (c) 2014 Peter Dimov 12 // 13 // Distributed under the Boost Software License, Version 1.0. 14 // See accompanying file LICENSE_1_0.txt or copy at 15 // http://www.boost.org/LICENSE_1_0.txt) 16 // 17 18 #include <boost/smart_ptr/detail/yield_k.hpp> 19 #include <boost/config.hpp> 20 #include <atomic> 21 22 #if defined(BOOST_SP_REPORT_IMPLEMENTATION) 23 24 #include <boost/config/pragma_message.hpp> 25 BOOST_PRAGMA_MESSAGE("Using std::atomic spinlock") 26 27 #endif 28 29 namespace boost 30 { 31 32 namespace detail 33 { 34 35 class spinlock 36 { 37 public: 38 39 std::atomic_flag v_; 40 41 public: 42 try_lock()43 bool try_lock() BOOST_NOEXCEPT 44 { 45 return !v_.test_and_set( std::memory_order_acquire ); 46 } 47 lock()48 void lock() BOOST_NOEXCEPT 49 { 50 for( unsigned k = 0; !try_lock(); ++k ) 51 { 52 boost::detail::yield( k ); 53 } 54 } 55 unlock()56 void unlock() BOOST_NOEXCEPT 57 { 58 v_ .clear( std::memory_order_release ); 59 } 60 61 public: 62 63 class scoped_lock 64 { 65 private: 66 67 spinlock & sp_; 68 69 scoped_lock( scoped_lock const & ); 70 scoped_lock & operator=( scoped_lock const & ); 71 72 public: 73 scoped_lock(spinlock & sp)74 explicit scoped_lock( spinlock & sp ) BOOST_NOEXCEPT: sp_( sp ) 75 { 76 sp.lock(); 77 } 78 ~scoped_lock()79 ~scoped_lock() /*BOOST_NOEXCEPT*/ 80 { 81 sp_.unlock(); 82 } 83 }; 84 }; 85 86 } // namespace detail 87 } // namespace boost 88 89 #define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT } 90 91 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED 92