File indexing completed on 2025-01-18 09:51:43
0001 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <boost/smart_ptr/detail/yield_k.hpp>
0013
0014 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0015
0016 #include <boost/config/pragma_message.hpp>
0017 BOOST_PRAGMA_MESSAGE("Using g++/ARM spinlock")
0018
0019 #endif
0020
0021 #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__)
0022
0023 # define BOOST_SP_ARM_BARRIER "dmb"
0024 # define BOOST_SP_ARM_HAS_LDREX
0025
0026 #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__)
0027
0028 # define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
0029 # define BOOST_SP_ARM_HAS_LDREX
0030
0031 #else
0032
0033 # define BOOST_SP_ARM_BARRIER ""
0034
0035 #endif
0036
0037 namespace boost
0038 {
0039
0040 namespace detail
0041 {
0042
0043 class spinlock
0044 {
0045 public:
0046
0047 int v_;
0048
0049 public:
0050
0051 bool try_lock()
0052 {
0053 int r;
0054
0055 #ifdef BOOST_SP_ARM_HAS_LDREX
0056
0057 __asm__ __volatile__(
0058 "ldrex %0, [%2]; \n"
0059 "cmp %0, %1; \n"
0060 "strexne %0, %1, [%2]; \n"
0061 BOOST_SP_ARM_BARRIER :
0062 "=&r"( r ):
0063 "r"( 1 ), "r"( &v_ ):
0064 "memory", "cc" );
0065
0066 #else
0067
0068 __asm__ __volatile__(
0069 "swp %0, %1, [%2];\n"
0070 BOOST_SP_ARM_BARRIER :
0071 "=&r"( r ):
0072 "r"( 1 ), "r"( &v_ ):
0073 "memory", "cc" );
0074
0075 #endif
0076
0077 return r == 0;
0078 }
0079
0080 void lock()
0081 {
0082 for( unsigned k = 0; !try_lock(); ++k )
0083 {
0084 boost::detail::yield( k );
0085 }
0086 }
0087
0088 void unlock()
0089 {
0090 __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
0091 *const_cast< int volatile* >( &v_ ) = 0;
0092 __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
0093 }
0094
0095 public:
0096
0097 class scoped_lock
0098 {
0099 private:
0100
0101 spinlock & sp_;
0102
0103 scoped_lock( scoped_lock const & );
0104 scoped_lock & operator=( scoped_lock const & );
0105
0106 public:
0107
0108 explicit scoped_lock( spinlock & sp ): sp_( sp )
0109 {
0110 sp.lock();
0111 }
0112
0113 ~scoped_lock()
0114 {
0115 sp_.unlock();
0116 }
0117 };
0118 };
0119
0120 }
0121 }
0122
0123 #define BOOST_DETAIL_SPINLOCK_INIT {0}
0124
0125 #undef BOOST_SP_ARM_BARRIER
0126 #undef BOOST_SP_ARM_HAS_LDREX
0127
0128 #endif