1 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_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 // Copyright 2008, 2020 Peter Dimov
11 // Distributed under the Boost Software License, Version 1.0.
12 // https://www.boost.org/LICENSE_1_0.txt
13 
14 #include <boost/smart_ptr/detail/yield_k.hpp>
15 
16 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
17 
18 #include <boost/config/pragma_message.hpp>
19 BOOST_PRAGMA_MESSAGE("Using __atomic spinlock")
20 
21 #endif
22 
23 namespace boost
24 {
25 
26 namespace detail
27 {
28 
29 class spinlock
30 {
31 public:
32 
33     unsigned char v_;
34 
35 public:
36 
try_lock()37     bool try_lock()
38     {
39         return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0;
40     }
41 
lock()42     void lock()
43     {
44         for( unsigned k = 0; !try_lock(); ++k )
45         {
46             boost::detail::yield( k );
47         }
48     }
49 
unlock()50     void unlock()
51     {
52         __atomic_clear( &v_, __ATOMIC_RELEASE );
53     }
54 
55 public:
56 
57     class scoped_lock
58     {
59     private:
60 
61         spinlock & sp_;
62 
63         scoped_lock( scoped_lock const & );
64         scoped_lock & operator=( scoped_lock const & );
65 
66     public:
67 
scoped_lock(spinlock & sp)68         explicit scoped_lock( spinlock & sp ): sp_( sp )
69         {
70             sp.lock();
71         }
72 
~scoped_lock()73         ~scoped_lock()
74         {
75             sp_.unlock();
76         }
77     };
78 };
79 
80 } // namespace detail
81 } // namespace boost
82 
83 #define BOOST_DETAIL_SPINLOCK_INIT {0}
84 
85 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
86