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 
try_lock()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 
lock()73     void lock()
74     {
75         for( unsigned k = 0; !try_lock(); ++k )
76         {
77             boost::detail::yield( k );
78         }
79     }
80 
unlock()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 
scoped_lock(spinlock & sp)101         explicit scoped_lock( spinlock & sp ): sp_( sp )
102         {
103             sp.lock();
104         }
105 
~scoped_lock()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
122