Chris@16: #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED Chris@16: #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED Chris@16: Chris@16: // Chris@16: // Copyright (c) 2008, 2011 Peter Dimov Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #include Chris@16: Chris@16: #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__) Chris@16: Chris@16: # define BOOST_SP_ARM_BARRIER "dmb" Chris@16: # define BOOST_SP_ARM_HAS_LDREX Chris@16: Chris@16: #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__) Chris@16: Chris@16: # define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5" Chris@16: # define BOOST_SP_ARM_HAS_LDREX Chris@16: Chris@16: #else Chris@16: Chris@16: # define BOOST_SP_ARM_BARRIER "" Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: class spinlock Chris@16: { Chris@16: public: Chris@16: Chris@16: int v_; Chris@16: Chris@16: public: Chris@16: Chris@16: bool try_lock() Chris@16: { Chris@16: int r; Chris@16: Chris@16: #ifdef BOOST_SP_ARM_HAS_LDREX Chris@16: Chris@16: __asm__ __volatile__( Chris@16: "ldrex %0, [%2]; \n" Chris@16: "cmp %0, %1; \n" Chris@16: "strexne %0, %1, [%2]; \n" Chris@16: BOOST_SP_ARM_BARRIER : Chris@16: "=&r"( r ): // outputs Chris@16: "r"( 1 ), "r"( &v_ ): // inputs Chris@16: "memory", "cc" ); Chris@16: Chris@16: #else Chris@16: Chris@16: __asm__ __volatile__( Chris@16: "swp %0, %1, [%2];\n" Chris@16: BOOST_SP_ARM_BARRIER : Chris@16: "=&r"( r ): // outputs Chris@16: "r"( 1 ), "r"( &v_ ): // inputs Chris@16: "memory", "cc" ); Chris@16: Chris@16: #endif Chris@16: Chris@16: return r == 0; Chris@16: } Chris@16: Chris@16: void lock() Chris@16: { Chris@16: for( unsigned k = 0; !try_lock(); ++k ) Chris@16: { Chris@16: boost::detail::yield( k ); Chris@16: } Chris@16: } Chris@16: Chris@16: void unlock() Chris@16: { Chris@16: __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); Chris@16: *const_cast< int volatile* >( &v_ ) = 0; Chris@16: } Chris@16: Chris@16: public: Chris@16: Chris@16: class scoped_lock Chris@16: { Chris@16: private: Chris@16: Chris@16: spinlock & sp_; Chris@16: Chris@16: scoped_lock( scoped_lock const & ); Chris@16: scoped_lock & operator=( scoped_lock const & ); Chris@16: Chris@16: public: Chris@16: Chris@16: explicit scoped_lock( spinlock & sp ): sp_( sp ) Chris@16: { Chris@16: sp.lock(); Chris@16: } Chris@16: Chris@16: ~scoped_lock() Chris@16: { Chris@16: sp_.unlock(); Chris@16: } Chris@16: }; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace boost Chris@16: Chris@16: #define BOOST_DETAIL_SPINLOCK_INIT {0} Chris@16: Chris@16: #undef BOOST_SP_ARM_BARRIER Chris@16: #undef BOOST_SP_ARM_HAS_LDREX Chris@16: Chris@16: #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED