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