spinlock_w32.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_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/sp_interlocked.hpp>
  15. #include <boost/smart_ptr/detail/yield_k.hpp>
  16. #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
  17. #include <boost/config/pragma_message.hpp>
  18. BOOST_PRAGMA_MESSAGE("Using Win32 spinlock")
  19. #endif
  20. // BOOST_COMPILER_FENCE
  21. #if defined(__INTEL_COMPILER)
  22. #define BOOST_COMPILER_FENCE __memory_barrier();
  23. #elif defined( _MSC_VER ) && _MSC_VER >= 1310
  24. extern "C" void _ReadWriteBarrier();
  25. #pragma intrinsic( _ReadWriteBarrier )
  26. #define BOOST_COMPILER_FENCE _ReadWriteBarrier();
  27. #elif defined(__GNUC__)
  28. #define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
  29. #else
  30. #define BOOST_COMPILER_FENCE
  31. #endif
  32. //
  33. namespace boost
  34. {
  35. namespace detail
  36. {
  37. class spinlock
  38. {
  39. public:
  40. long v_;
  41. public:
  42. bool try_lock()
  43. {
  44. long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
  45. BOOST_COMPILER_FENCE
  46. return r == 0;
  47. }
  48. void lock()
  49. {
  50. for( unsigned k = 0; !try_lock(); ++k )
  51. {
  52. boost::detail::yield( k );
  53. }
  54. }
  55. void unlock()
  56. {
  57. BOOST_COMPILER_FENCE
  58. *const_cast< long volatile* >( &v_ ) = 0;
  59. }
  60. public:
  61. class scoped_lock
  62. {
  63. private:
  64. spinlock & sp_;
  65. scoped_lock( scoped_lock const & );
  66. scoped_lock & operator=( scoped_lock const & );
  67. public:
  68. explicit scoped_lock( spinlock & sp ): sp_( sp )
  69. {
  70. sp.lock();
  71. }
  72. ~scoped_lock()
  73. {
  74. sp_.unlock();
  75. }
  76. };
  77. };
  78. } // namespace detail
  79. } // namespace boost
  80. #define BOOST_DETAIL_SPINLOCK_INIT {0}
  81. #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED