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 namespace boost 23 { 24 25 namespace detail 26 { 27 28 class spinlock 29 { 30 public: 31 32 std::atomic_flag v_; 33 34 public: 35 try_lock()36 bool try_lock() BOOST_NOEXCEPT 37 { 38 return !v_.test_and_set( std::memory_order_acquire ); 39 } 40 lock()41 void lock() BOOST_NOEXCEPT 42 { 43 for( unsigned k = 0; !try_lock(); ++k ) 44 { 45 boost::detail::yield( k ); 46 } 47 } 48 unlock()49 void unlock() BOOST_NOEXCEPT 50 { 51 v_ .clear( std::memory_order_release ); 52 } 53 54 public: 55 56 class scoped_lock 57 { 58 private: 59 60 spinlock & sp_; 61 62 scoped_lock( scoped_lock const & ); 63 scoped_lock & operator=( scoped_lock const & ); 64 65 public: 66 scoped_lock(spinlock & sp)67 explicit scoped_lock( spinlock & sp ) BOOST_NOEXCEPT: sp_( sp ) 68 { 69 sp.lock(); 70 } 71 ~scoped_lock()72 ~scoped_lock() /*BOOST_NOEXCEPT*/ 73 { 74 sp_.unlock(); 75 } 76 }; 77 }; 78 79 } // namespace detail 80 } // namespace boost 81 82 #define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT } 83 84 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED 85