00001 #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED 00002 #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED 00003 00004 // 00005 // Copyright (c) 2008 Peter Dimov 00006 // 00007 // Distributed under the Boost Software License, Version 1.0. 00008 // See accompanying file LICENSE_1_0.txt or copy at 00009 // http://www.boost.org/LICENSE_1_0.txt) 00010 // 00011 00012 #include <boost/smart_ptr/detail/yield_k.hpp> 00013 00014 namespace boost 00015 { 00016 00017 namespace detail 00018 { 00019 00020 class spinlock 00021 { 00022 public: 00023 00024 int v_; 00025 00026 public: 00027 00028 bool try_lock() 00029 { 00030 int r; 00031 00032 __asm__ __volatile__( 00033 "swp %0, %1, [%2]": 00034 "=&r"( r ): // outputs 00035 "r"( 1 ), "r"( &v_ ): // inputs 00036 "memory", "cc" ); 00037 00038 return r == 0; 00039 } 00040 00041 void lock() 00042 { 00043 for( unsigned k = 0; !try_lock(); ++k ) 00044 { 00045 boost::detail::yield( k ); 00046 } 00047 } 00048 00049 void unlock() 00050 { 00051 __asm__ __volatile__( "" ::: "memory" ); 00052 *const_cast< int volatile* >( &v_ ) = 0; 00053 } 00054 00055 public: 00056 00057 class scoped_lock 00058 { 00059 private: 00060 00061 spinlock & sp_; 00062 00063 scoped_lock( scoped_lock const & ); 00064 scoped_lock & operator=( scoped_lock const & ); 00065 00066 public: 00067 00068 explicit scoped_lock( spinlock & sp ): sp_( sp ) 00069 { 00070 sp.lock(); 00071 } 00072 00073 ~scoped_lock() 00074 { 00075 sp_.unlock(); 00076 } 00077 }; 00078 }; 00079 00080 } // namespace detail 00081 } // namespace boost 00082 00083 #define BOOST_DETAIL_SPINLOCK_INIT {0} 00084 00085 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED