yield_k.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. //
  8. // yield_k.hpp
  9. //
  10. // Copyright (c) 2008 Peter Dimov
  11. //
  12. // void yield( unsigned k );
  13. //
  14. // Typical use:
  15. //
  16. // for( unsigned k = 0; !try_lock(); ++k ) yield( k );
  17. //
  18. // Distributed under the Boost Software License, Version 1.0.
  19. // See accompanying file LICENSE_1_0.txt or copy at
  20. // http://www.boost.org/LICENSE_1_0.txt
  21. //
  22. #include <boost/config.hpp>
  23. // BOOST_SMT_PAUSE
  24. #if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
  25. extern "C" void _mm_pause();
  26. #pragma intrinsic( _mm_pause )
  27. #define BOOST_SMT_PAUSE _mm_pause();
  28. #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
  29. #define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
  30. #endif
  31. //
  32. #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
  33. #if defined( BOOST_USE_WINDOWS_H )
  34. # include <windows.h>
  35. #endif
  36. namespace boost
  37. {
  38. namespace detail
  39. {
  40. #if !defined( BOOST_USE_WINDOWS_H )
  41. extern "C" void __stdcall Sleep( unsigned ms );
  42. #endif
  43. inline void yield( unsigned k )
  44. {
  45. if( k < 4 )
  46. {
  47. }
  48. #if defined( BOOST_SMT_PAUSE )
  49. else if( k < 16 )
  50. {
  51. BOOST_SMT_PAUSE
  52. }
  53. #endif
  54. else if( k < 32 )
  55. {
  56. Sleep( 0 );
  57. }
  58. else
  59. {
  60. Sleep( 1 );
  61. }
  62. }
  63. } // namespace detail
  64. } // namespace boost
  65. #elif defined( BOOST_HAS_PTHREADS )
  66. #include <sched.h>
  67. #include <time.h>
  68. namespace boost
  69. {
  70. namespace detail
  71. {
  72. inline void yield( unsigned k )
  73. {
  74. if( k < 4 )
  75. {
  76. }
  77. #if defined( BOOST_SMT_PAUSE )
  78. else if( k < 16 )
  79. {
  80. BOOST_SMT_PAUSE
  81. }
  82. #endif
  83. else if( k < 32 || k & 1 )
  84. {
  85. sched_yield();
  86. }
  87. else
  88. {
  89. // g++ -Wextra warns on {} or {0}
  90. struct timespec rqtp = { 0, 0 };
  91. // POSIX says that timespec has tv_sec and tv_nsec
  92. // But it doesn't guarantee order or placement
  93. rqtp.tv_sec = 0;
  94. rqtp.tv_nsec = 1000;
  95. nanosleep( &rqtp, 0 );
  96. }
  97. }
  98. } // namespace detail
  99. } // namespace boost
  100. #else
  101. namespace boost
  102. {
  103. namespace detail
  104. {
  105. inline void yield( unsigned )
  106. {
  107. }
  108. } // namespace detail
  109. } // namespace boost
  110. #endif
  111. #endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED