]> git.donarmstrong.com Git - rsem.git/blob - boost/smart_ptr/detail/spinlock_gcc_arm.hpp
016796a91d09a2b88e526195d0a26a241351d7fd
[rsem.git] / 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     }
86
87 public:
88
89     class scoped_lock
90     {
91     private:
92
93         spinlock & sp_;
94
95         scoped_lock( scoped_lock const & );
96         scoped_lock & operator=( scoped_lock const & );
97
98     public:
99
100         explicit scoped_lock( spinlock & sp ): sp_( sp )
101         {
102             sp.lock();
103         }
104
105         ~scoped_lock()
106         {
107             sp_.unlock();
108         }
109     };
110 };
111
112 } // namespace detail
113 } // namespace boost
114
115 #define BOOST_DETAIL_SPINLOCK_INIT {0}
116
117 #undef BOOST_SP_ARM_BARRIER
118 #undef BOOST_SP_ARM_HAS_LDREX
119
120 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED