Merge c:/dyninst/pc_bluegene/dyninst into dyn_pc_integration
[dyninst.git] / external / boost / detail / spinlock_w32.hpp
1 #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
2 #define BOOST_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/detail/interlocked.hpp>
19 #include <boost/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
60     bool try_lock()
61     {
62         long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
63
64         BOOST_COMPILER_FENCE
65
66         return r == 0;
67     }
68
69     void lock()
70     {
71         for( unsigned k = 0; !try_lock(); ++k )
72         {
73             boost::detail::yield( k );
74         }
75     }
76
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
96         explicit scoped_lock( spinlock & sp ): sp_( sp )
97         {
98             sp.lock();
99         }
100
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_DETAIL_SPINLOCK_W32_HPP_INCLUDED