yield_k.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. #define BOOST_SMT_PAUSE _mm_pause();
  27. #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
  28. #define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
  29. #endif
  30. //
  31. #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
  32. #if defined( BOOST_USE_WINDOWS_H )
  33. # include <windows.h>
  34. #endif
  35. namespace boost
  36. {
  37. namespace detail
  38. {
  39. #if !defined( BOOST_USE_WINDOWS_H )
  40. extern "C" void __stdcall Sleep( unsigned long ms );
  41. #endif
  42. inline void yield( unsigned k )
  43. {
  44. if( k < 4 )
  45. {
  46. }
  47. #if defined( BOOST_SMT_PAUSE )
  48. else if( k < 16 )
  49. {
  50. BOOST_SMT_PAUSE
  51. }
  52. #endif
  53. else if( k < 32 )
  54. {
  55. Sleep( 0 );
  56. }
  57. else
  58. {
  59. Sleep( 1 );
  60. }
  61. }
  62. } // namespace detail
  63. } // namespace boost
  64. #elif defined( BOOST_HAS_PTHREADS )
  65. #include <sched.h>
  66. #include <time.h>
  67. namespace boost
  68. {
  69. namespace detail
  70. {
  71. inline void yield( unsigned k )
  72. {
  73. if( k < 4 )
  74. {
  75. }
  76. #if defined( BOOST_SMT_PAUSE )
  77. else if( k < 16 )
  78. {
  79. BOOST_SMT_PAUSE
  80. }
  81. #endif
  82. else if( k < 32 || k & 1 )
  83. {
  84. sched_yield();
  85. }
  86. else
  87. {
  88. // g++ -Wextra warns on {} or {0}
  89. struct timespec rqtp = { 0, 0 };
  90. // POSIX says that timespec has tv_sec and tv_nsec
  91. // But it doesn't guarantee order or placement
  92. rqtp.tv_sec = 0;
  93. rqtp.tv_nsec = 1000;
  94. nanosleep( &rqtp, 0 );
  95. }
  96. }
  97. } // namespace detail
  98. } // namespace boost
  99. #else
  100. namespace boost
  101. {
  102. namespace detail
  103. {
  104. inline void yield( unsigned )
  105. {
  106. }
  107. } // namespace detail
  108. } // namespace boost
  109. #endif
  110. #endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED