spinlock_gcc_arm.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
  3. //
  4. // Copyright (c) 2008, 2011 Peter Dimov
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #include <boost/smart_ptr/detail/yield_k.hpp>
  11. #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__)
  12. # define BOOST_SP_ARM_BARRIER "dmb"
  13. # define BOOST_SP_ARM_HAS_LDREX
  14. #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__)
  15. # define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
  16. # define BOOST_SP_ARM_HAS_LDREX
  17. #else
  18. # define BOOST_SP_ARM_BARRIER ""
  19. #endif
  20. namespace boost
  21. {
  22. namespace detail
  23. {
  24. class spinlock
  25. {
  26. public:
  27. int v_;
  28. public:
  29. bool try_lock()
  30. {
  31. int r;
  32. #ifdef BOOST_SP_ARM_HAS_LDREX
  33. __asm__ __volatile__(
  34. "ldrex %0, [%2]; \n"
  35. "cmp %0, %1; \n"
  36. "strexne %0, %1, [%2]; \n"
  37. BOOST_SP_ARM_BARRIER :
  38. "=&r"( r ): // outputs
  39. "r"( 1 ), "r"( &v_ ): // inputs
  40. "memory", "cc" );
  41. #else
  42. __asm__ __volatile__(
  43. "swp %0, %1, [%2];\n"
  44. BOOST_SP_ARM_BARRIER :
  45. "=&r"( r ): // outputs
  46. "r"( 1 ), "r"( &v_ ): // inputs
  47. "memory", "cc" );
  48. #endif
  49. return r == 0;
  50. }
  51. void lock()
  52. {
  53. for( unsigned k = 0; !try_lock(); ++k )
  54. {
  55. boost::detail::yield( k );
  56. }
  57. }
  58. void unlock()
  59. {
  60. __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
  61. *const_cast< int volatile* >( &v_ ) = 0;
  62. __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
  63. }
  64. public:
  65. class scoped_lock
  66. {
  67. private:
  68. spinlock & sp_;
  69. scoped_lock( scoped_lock const & );
  70. scoped_lock & operator=( scoped_lock const & );
  71. public:
  72. explicit scoped_lock( spinlock & sp ): sp_( sp )
  73. {
  74. sp.lock();
  75. }
  76. ~scoped_lock()
  77. {
  78. sp_.unlock();
  79. }
  80. };
  81. };
  82. } // namespace detail
  83. } // namespace boost
  84. #define BOOST_DETAIL_SPINLOCK_INIT {0}
  85. #undef BOOST_SP_ARM_BARRIER
  86. #undef BOOST_SP_ARM_HAS_LDREX
  87. #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED