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