spinlock_sync.hpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. //
  8. // Copyright (c) 2008 Peter Dimov
  9. //
  10. // Distributed under the Boost Software License, Version 1.0.
  11. // See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. //
  14. #include <boost/smart_ptr/detail/yield_k.hpp>
  15. #if defined( __ia64__ ) && defined( __INTEL_COMPILER )
  16. # include <ia64intrin.h>
  17. #endif
  18. #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
  19. #include <boost/config/pragma_message.hpp>
  20. BOOST_PRAGMA_MESSAGE("Using __sync spinlock")
  21. #endif
  22. namespace boost
  23. {
  24. namespace detail
  25. {
  26. class spinlock
  27. {
  28. public:
  29. unsigned char v_;
  30. public:
  31. bool try_lock()
  32. {
  33. int r = __sync_lock_test_and_set( &v_, 1 );
  34. return r == 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. __sync_lock_release( &v_ );
  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_SYNC_HPP_INCLUDED