Chris@16
|
1 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
Chris@16
|
2 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
Chris@16
|
3
|
Chris@16
|
4 // MS compatible compilers support #pragma once
|
Chris@16
|
5
|
Chris@16
|
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
Chris@16
|
7 # pragma once
|
Chris@16
|
8 #endif
|
Chris@16
|
9
|
Chris@16
|
10 //
|
Chris@16
|
11 // Copyright (c) 2008 Peter Dimov
|
Chris@16
|
12 //
|
Chris@16
|
13 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
14 // See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
15 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
16 //
|
Chris@16
|
17
|
Chris@101
|
18 #include <boost/smart_ptr/detail/sp_interlocked.hpp>
|
Chris@16
|
19 #include <boost/smart_ptr/detail/yield_k.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 // BOOST_COMPILER_FENCE
|
Chris@16
|
22
|
Chris@16
|
23 #if defined(__INTEL_COMPILER)
|
Chris@16
|
24
|
Chris@16
|
25 #define BOOST_COMPILER_FENCE __memory_barrier();
|
Chris@16
|
26
|
Chris@16
|
27 #elif defined( _MSC_VER ) && _MSC_VER >= 1310
|
Chris@16
|
28
|
Chris@16
|
29 extern "C" void _ReadWriteBarrier();
|
Chris@16
|
30 #pragma intrinsic( _ReadWriteBarrier )
|
Chris@16
|
31
|
Chris@16
|
32 #define BOOST_COMPILER_FENCE _ReadWriteBarrier();
|
Chris@16
|
33
|
Chris@16
|
34 #elif defined(__GNUC__)
|
Chris@16
|
35
|
Chris@16
|
36 #define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
|
Chris@16
|
37
|
Chris@16
|
38 #else
|
Chris@16
|
39
|
Chris@16
|
40 #define BOOST_COMPILER_FENCE
|
Chris@16
|
41
|
Chris@16
|
42 #endif
|
Chris@16
|
43
|
Chris@16
|
44 //
|
Chris@16
|
45
|
Chris@16
|
46 namespace boost
|
Chris@16
|
47 {
|
Chris@16
|
48
|
Chris@16
|
49 namespace detail
|
Chris@16
|
50 {
|
Chris@16
|
51
|
Chris@16
|
52 class spinlock
|
Chris@16
|
53 {
|
Chris@16
|
54 public:
|
Chris@16
|
55
|
Chris@16
|
56 long v_;
|
Chris@16
|
57
|
Chris@16
|
58 public:
|
Chris@16
|
59
|
Chris@16
|
60 bool try_lock()
|
Chris@16
|
61 {
|
Chris@101
|
62 long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
|
Chris@16
|
63
|
Chris@16
|
64 BOOST_COMPILER_FENCE
|
Chris@16
|
65
|
Chris@16
|
66 return r == 0;
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 void lock()
|
Chris@16
|
70 {
|
Chris@16
|
71 for( unsigned k = 0; !try_lock(); ++k )
|
Chris@16
|
72 {
|
Chris@16
|
73 boost::detail::yield( k );
|
Chris@16
|
74 }
|
Chris@16
|
75 }
|
Chris@16
|
76
|
Chris@16
|
77 void unlock()
|
Chris@16
|
78 {
|
Chris@16
|
79 BOOST_COMPILER_FENCE
|
Chris@16
|
80 *const_cast< long volatile* >( &v_ ) = 0;
|
Chris@16
|
81 }
|
Chris@16
|
82
|
Chris@16
|
83 public:
|
Chris@16
|
84
|
Chris@16
|
85 class scoped_lock
|
Chris@16
|
86 {
|
Chris@16
|
87 private:
|
Chris@16
|
88
|
Chris@16
|
89 spinlock & sp_;
|
Chris@16
|
90
|
Chris@16
|
91 scoped_lock( scoped_lock const & );
|
Chris@16
|
92 scoped_lock & operator=( scoped_lock const & );
|
Chris@16
|
93
|
Chris@16
|
94 public:
|
Chris@16
|
95
|
Chris@16
|
96 explicit scoped_lock( spinlock & sp ): sp_( sp )
|
Chris@16
|
97 {
|
Chris@16
|
98 sp.lock();
|
Chris@16
|
99 }
|
Chris@16
|
100
|
Chris@16
|
101 ~scoped_lock()
|
Chris@16
|
102 {
|
Chris@16
|
103 sp_.unlock();
|
Chris@16
|
104 }
|
Chris@16
|
105 };
|
Chris@16
|
106 };
|
Chris@16
|
107
|
Chris@16
|
108 } // namespace detail
|
Chris@16
|
109 } // namespace boost
|
Chris@16
|
110
|
Chris@16
|
111 #define BOOST_DETAIL_SPINLOCK_INIT {0}
|
Chris@16
|
112
|
Chris@16
|
113 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|