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