spinlock_w32.hpp 1.9 KB

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