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