]> git.lyx.org Git - features.git/blob - 3rdparty/boost/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
Update to boost 1.72
[features.git] / 3rdparty / boost / boost / smart_ptr / detail / spinlock_gcc_arm.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
3
4 //
5 //  Copyright (c) 2008, 2011 Peter Dimov
6 //
7 //  Distributed under the Boost Software License, Version 1.0.
8 //  See accompanying file LICENSE_1_0.txt or copy at
9 //  http://www.boost.org/LICENSE_1_0.txt)
10 //
11
12 #include <boost/smart_ptr/detail/yield_k.hpp>
13
14 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
15
16 # define BOOST_SP_ARM_BARRIER "dmb"
17 # define BOOST_SP_ARM_HAS_LDREX
18
19 #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
20
21 # define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
22 # define BOOST_SP_ARM_HAS_LDREX
23
24 #else
25
26 # define BOOST_SP_ARM_BARRIER ""
27
28 #endif
29
30 namespace boost
31 {
32
33 namespace detail
34 {
35
36 class spinlock
37 {
38 public:
39
40     int v_;
41
42 public:
43
44     bool try_lock()
45     {
46         int r;
47
48 #ifdef BOOST_SP_ARM_HAS_LDREX
49
50         __asm__ __volatile__(
51             "ldrex %0, [%2]; \n"
52             "cmp %0, %1; \n"
53             "strexne %0, %1, [%2]; \n"
54             BOOST_SP_ARM_BARRIER :
55             "=&r"( r ): // outputs
56             "r"( 1 ), "r"( &v_ ): // inputs
57             "memory", "cc" );
58
59 #else
60
61         __asm__ __volatile__(
62             "swp %0, %1, [%2];\n"
63             BOOST_SP_ARM_BARRIER :
64             "=&r"( r ): // outputs
65             "r"( 1 ), "r"( &v_ ): // inputs
66             "memory", "cc" );
67
68 #endif
69
70         return r == 0;
71     }
72
73     void lock()
74     {
75         for( unsigned k = 0; !try_lock(); ++k )
76         {
77             boost::detail::yield( k );
78         }
79     }
80
81     void unlock()
82     {
83         __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
84         *const_cast< int volatile* >( &v_ ) = 0;
85         __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
86     }
87
88 public:
89
90     class scoped_lock
91     {
92     private:
93
94         spinlock & sp_;
95
96         scoped_lock( scoped_lock const & );
97         scoped_lock & operator=( scoped_lock const & );
98
99     public:
100
101         explicit scoped_lock( spinlock & sp ): sp_( sp )
102         {
103             sp.lock();
104         }
105
106         ~scoped_lock()
107         {
108             sp_.unlock();
109         }
110     };
111 };
112
113 } // namespace detail
114 } // namespace boost
115
116 #define BOOST_DETAIL_SPINLOCK_INIT {0}
117
118 #undef BOOST_SP_ARM_BARRIER
119 #undef BOOST_SP_ARM_HAS_LDREX
120
121 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED