From bb076d67e66ac3c317a87b11be56ee8b658d094b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 27 Mar 2008 22:20:11 +0000 Subject: [PATCH] detail::yield(k) added. [SVN r43888] --- include/boost/detail/yield_k.hpp | 132 +++++++++++++++++++++++++++++++ test/Jamfile.v2 | 1 + test/yield_k_test.cpp | 23 ++++++ 3 files changed, 156 insertions(+) create mode 100644 include/boost/detail/yield_k.hpp create mode 100644 test/yield_k_test.cpp diff --git a/include/boost/detail/yield_k.hpp b/include/boost/detail/yield_k.hpp new file mode 100644 index 0000000..08dfc8f --- /dev/null +++ b/include/boost/detail/yield_k.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED +#define BOOST_DETAIL_YIELD_K_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/yield_k.hpp +// +// Copyright (c) 2008 Peter Dimov +// +// void yield( unsigned k ); +// +// Typical use: +// +// for( unsigned k = 0; !try_lock(); ++k ) yield( k ); +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) + +#if defined( BOOST_USE_WINDOWS_H ) +# include +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1310 + extern "C" void _mm_pause(); +#endif + +namespace boost +{ + +namespace detail +{ + +#if !defined( BOOST_USE_WINDOWS_H ) + extern "C" void __stdcall Sleep( unsigned ms ); +#endif + +void yield( unsigned k ) +{ + if( k < 4 ) + { + } +#if defined(_MSC_VER) && _MSC_VER >= 1310 + else if( k < 16 ) + { + _mm_pause(); + } +#endif + else if( k < 32 ) + { + Sleep( 0 ); + } + else + { + Sleep( 1 ); + } +} + +} // namespace detail + +} // namespace boost + +#elif defined( BOOST_HAS_PTHREADS ) + +#include +#include + +namespace boost +{ + +namespace detail +{ + +void yield( unsigned k ) +{ + if( k < 4 ) + { + } +#if defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) + else if( k < 16 ) + { + __asm__ __volatile__( "rep; nop" ::: "memory" ); + } +#endif + else if( k < 32 || k & 1 ) + { + sched_yield(); + } + else + { + struct timespec rqtp = { 0 }; + + rqtp.tv_sec = 0; + rqtp.tv_nsec = 1000; + + nanosleep( &rqtp, 0 ); + } +} + +} // namespace detail + +} // namespace boost + +#else + +namespace boost +{ + +namespace detail +{ + +inline void yield( unsigned ) +{ +} + +} // namespace detail + +} // namespace boost + +#endif + +#endif // #ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 837c83c..13109da 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -37,5 +37,6 @@ import testing ; [ compile-fail scoped_array_eq_fail.cpp ] [ run esft_regtest.cpp ] [ run esft_constructor_test.cpp ] + [ run yield_k_test.cpp ] ; } diff --git a/test/yield_k_test.cpp b/test/yield_k_test.cpp new file mode 100644 index 0000000..1e6ab13 --- /dev/null +++ b/test/yield_k_test.cpp @@ -0,0 +1,23 @@ +// +// yield_k_test.cpp +// +// Copyright 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +// Sanity check only + +int main() +{ + for( unsigned k = 0; k < 256; ++k ) + { + boost::detail::yield( k ); + } + + return 0; +}