1#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
2#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_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) 2014 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/yield_k.hpp>
19#include <atomic>
20
21namespace boost
22{
23
24namespace detail
25{
26
27class spinlock
28{
29public:
30
31 std::atomic_flag v_;
32
33public:
34
35 bool try_lock()
36 {
37 return !v_.test_and_set( std::memory_order_acquire );
38 }
39
40 void lock()
41 {
42 for( unsigned k = 0; !try_lock(); ++k )
43 {
44 boost::detail::yield( k );
45 }
46 }
47
48 void unlock()
49 {
50 v_ .clear( std::memory_order_release );
51 }
52
53public:
54
55 class scoped_lock
56 {
57 private:
58
59 spinlock & sp_;
60
61 scoped_lock( scoped_lock const & );
62 scoped_lock & operator=( scoped_lock const & );
63
64 public:
65
66 explicit scoped_lock( spinlock & sp ): sp_( sp )
67 {
68 sp.lock();
69 }
70
71 ~scoped_lock()
72 {
73 sp_.unlock();
74 }
75 };
76};
77
78} // namespace detail
79} // namespace boost
80
81#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT }
82
83#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
84