1 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED 2 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_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) 2008 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/sp_interlocked.hpp> 19 #include <boost/smart_ptr/detail/yield_k.hpp> 20 21 #if defined(BOOST_SP_REPORT_IMPLEMENTATION) 22 23 #include <boost/config/pragma_message.hpp> 24 BOOST_PRAGMA_MESSAGE("Using Win32 spinlock") 25 26 #endif 27 28 // BOOST_COMPILER_FENCE 29 30 #if defined(__INTEL_COMPILER) 31 32 #define BOOST_COMPILER_FENCE __memory_barrier(); 33 34 #elif defined( _MSC_VER ) && _MSC_VER >= 1310 35 36 extern "C" void _ReadWriteBarrier(); 37 #pragma intrinsic( _ReadWriteBarrier ) 38 39 #define BOOST_COMPILER_FENCE _ReadWriteBarrier(); 40 41 #elif defined(__GNUC__) 42 43 #define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" ); 44 45 #else 46 47 #define BOOST_COMPILER_FENCE 48 49 #endif 50 51 // 52 53 namespace boost 54 { 55 56 namespace detail 57 { 58 59 class spinlock 60 { 61 public: 62 63 long v_; 64 65 public: 66 try_lock()67 bool try_lock() 68 { 69 long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 ); 70 71 BOOST_COMPILER_FENCE 72 73 return r == 0; 74 } 75 lock()76 void lock() 77 { 78 for( unsigned k = 0; !try_lock(); ++k ) 79 { 80 boost::detail::yield( k ); 81 } 82 } 83 unlock()84 void unlock() 85 { 86 BOOST_COMPILER_FENCE 87 *const_cast< long volatile* >( &v_ ) = 0; 88 } 89 90 public: 91 92 class scoped_lock 93 { 94 private: 95 96 spinlock & sp_; 97 98 scoped_lock( scoped_lock const & ); 99 scoped_lock & operator=( scoped_lock const & ); 100 101 public: 102 scoped_lock(spinlock & sp)103 explicit scoped_lock( spinlock & sp ): sp_( sp ) 104 { 105 sp.lock(); 106 } 107 ~scoped_lock()108 ~scoped_lock() 109 { 110 sp_.unlock(); 111 } 112 }; 113 }; 114 115 } // namespace detail 116 } // namespace boost 117 118 #define BOOST_DETAIL_SPINLOCK_INIT {0} 119 120 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED 121