Back to home page

EIC code displayed by LXR

 
 

    


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 //  Copyright (c) 2008, 2011 Peter Dimov
0006 //
0007 //  Distributed under the Boost Software License, Version 1.0.
0008 //  See accompanying file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
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 ): // outputs
0063             "r"( 1 ), "r"( &v_ ): // inputs
0064             "memory", "cc" );
0065 
0066 #else
0067 
0068         __asm__ __volatile__(
0069             "swp %0, %1, [%2];\n"
0070             BOOST_SP_ARM_BARRIER :
0071             "=&r"( r ): // outputs
0072             "r"( 1 ), "r"( &v_ ): // inputs
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 } // namespace detail
0121 } // namespace boost
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 // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED