spinlock_gcc_atomic.hpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. // Copyright 2008, 2020 Peter Dimov
  8. // Distributed under the Boost Software License, Version 1.0.
  9. // https://www.boost.org/LICENSE_1_0.txt
  10. #include <boost/smart_ptr/detail/yield_k.hpp>
  11. #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
  12. #include <boost/config/pragma_message.hpp>
  13. BOOST_PRAGMA_MESSAGE("Using __atomic spinlock")
  14. #endif
  15. namespace boost
  16. {
  17. namespace detail
  18. {
  19. class spinlock
  20. {
  21. public:
  22. // `bool` alignment is required for Apple PPC32
  23. // https://github.com/boostorg/smart_ptr/issues/105
  24. // https://github.com/PurpleI2P/i2pd/issues/1726
  25. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107590
  26. union
  27. {
  28. unsigned char v_;
  29. bool align_;
  30. };
  31. public:
  32. bool try_lock()
  33. {
  34. return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0;
  35. }
  36. void lock()
  37. {
  38. for( unsigned k = 0; !try_lock(); ++k )
  39. {
  40. boost::detail::yield( k );
  41. }
  42. }
  43. void unlock()
  44. {
  45. __atomic_clear( &v_, __ATOMIC_RELEASE );
  46. }
  47. public:
  48. class scoped_lock
  49. {
  50. private:
  51. spinlock & sp_;
  52. scoped_lock( scoped_lock const & );
  53. scoped_lock & operator=( scoped_lock const & );
  54. public:
  55. explicit scoped_lock( spinlock & sp ): sp_( sp )
  56. {
  57. sp.lock();
  58. }
  59. ~scoped_lock()
  60. {
  61. sp_.unlock();
  62. }
  63. };
  64. };
  65. } // namespace detail
  66. } // namespace boost
  67. #define BOOST_DETAIL_SPINLOCK_INIT {{0}}
  68. #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED