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