blob: 2fcd790f4796d1af08f1ef300e493f24da489b6b [file] [log] [blame]
Jeff Thompson3d613fd2013-10-15 15:39:04 -07001#ifndef NDNBOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
2#define NDNBOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
Jeff Thompsonf7d49942013-08-01 16:47:40 -07003
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
Jeff Thompson2277ce52013-08-01 17:34:11 -070026#include <ndnboost/config.hpp>
Jeff Thompsonf7d49942013-08-01 16:47:40 -070027
Jeff Thompson3d613fd2013-10-15 15:39:04 -070028// NDNBOOST_SMT_PAUSE
Jeff Thompsonf7d49942013-08-01 16:47:40 -070029
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -070035#define NDNBOOST_SMT_PAUSE _mm_pause();
Jeff Thompsonf7d49942013-08-01 16:47:40 -070036
37#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
38
Jeff Thompson3d613fd2013-10-15 15:39:04 -070039#define NDNBOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
Jeff Thompsonf7d49942013-08-01 16:47:40 -070040
41#endif
42
43//
44
45#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
46
Jeff Thompson3d613fd2013-10-15 15:39:04 -070047#if defined( NDNBOOST_USE_WINDOWS_H )
Jeff Thompsonf7d49942013-08-01 16:47:40 -070048# include <windows.h>
49#endif
50
51namespace ndnboost
52{
53
54namespace detail
55{
56
Jeff Thompson3d613fd2013-10-15 15:39:04 -070057#if !defined( NDNBOOST_USE_WINDOWS_H )
Jeff Thompsonf7d49942013-08-01 16:47:40 -070058 extern "C" void __stdcall Sleep( unsigned long ms );
59#endif
60
61inline void yield( unsigned k )
62{
63 if( k < 4 )
64 {
65 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -070066#if defined( NDNBOOST_SMT_PAUSE )
Jeff Thompsonf7d49942013-08-01 16:47:40 -070067 else if( k < 16 )
68 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -070069 NDNBOOST_SMT_PAUSE
Jeff Thompsonf7d49942013-08-01 16:47:40 -070070 }
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -070086#elif defined( NDNBOOST_HAS_PTHREADS )
Jeff Thompsonf7d49942013-08-01 16:47:40 -070087
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 }
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700102#if defined( NDNBOOST_SMT_PAUSE )
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700103 else if( k < 16 )
104 {
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700105 NDNBOOST_SMT_PAUSE
Jeff Thompsonf7d49942013-08-01 16:47:40 -0700106 }
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700149#endif // #ifndef NDNBOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED