diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 3719f7f..984d2f6 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -62,33 +62,33 @@ feature.set-default abi : [ default_abi ] ; actions gas { - as -o "$(<)" "$(>)" + as -o "$(<)" "$(>)" } actions masm { - ml /c /Fo"$(<)" "$(>)" + ml /c /Fo"$(<)" "$(>)" } actions masm64 { - ml64 /c /Fo"$(<)" "$(>)" + ml64 /c /Fo"$(<)" "$(>)" } rule configure ( properties * ) { - local result ; + local result ; - if ( ! ( gcc in $(properties) - || intel in $(properties) - || msvc in $(properties) ) ) - { - result = no ; - ECHO "toolset not supported" ; - } + if ( ! ( gcc in $(properties) + || intel in $(properties) + || msvc in $(properties) ) ) + { + result = no ; + ECHO "toolset not supported" ; + } - return $(result) ; + return $(result) ; } # ARM @@ -97,7 +97,7 @@ alias asm_context_sources : aapcs arm elf - gcc + gcc ; alias asm_context_sources @@ -113,7 +113,7 @@ alias asm_context_sources : o32 mips1 elf - gcc + gcc ; alias asm_context_sources @@ -130,7 +130,7 @@ alias asm_context_sources 32 power elf - gcc + gcc ; alias asm_context_sources @@ -148,7 +148,7 @@ alias asm_context_sources 64 power elf - gcc + gcc ; alias asm_context_sources @@ -166,7 +166,7 @@ alias asm_context_sources 32 x86 elf - gcc + gcc ; alias asm_context_sources @@ -175,7 +175,7 @@ alias asm_context_sources 32 x86 elf - intel + intel ; alias asm_context_sources @@ -193,7 +193,7 @@ alias asm_context_sources x86 mach-o darwin - gcc + gcc ; alias asm_context_sources @@ -203,7 +203,7 @@ alias asm_context_sources x86 mach-o darwin - intel + intel ; alias asm_context_sources @@ -222,7 +222,7 @@ alias asm_context_sources x86 pe windows - intel + intel ; alias asm_context_sources @@ -232,7 +232,7 @@ alias asm_context_sources x86 pe windows - msvc + msvc ; alias asm_context_sources @@ -242,7 +242,7 @@ alias asm_context_sources x86 pe windows - gcc + gcc ; @@ -253,7 +253,7 @@ alias asm_context_sources 64 x86 elf - gcc + gcc ; alias asm_context_sources @@ -262,7 +262,7 @@ alias asm_context_sources 64 x86 elf - intel + intel ; alias asm_context_sources @@ -281,7 +281,7 @@ alias asm_context_sources x86 mach-o darwin - gcc + gcc ; alias asm_context_sources @@ -291,7 +291,7 @@ alias asm_context_sources x86 mach-o darwin - intel + intel ; alias asm_context_sources @@ -310,7 +310,7 @@ alias asm_context_sources x86 pe windows - intel + intel ; alias asm_context_sources @@ -320,7 +320,7 @@ alias asm_context_sources x86 pe windows - msvc + msvc ; alias asm_context_sources @@ -330,7 +330,7 @@ alias asm_context_sources x86 pe windows - gcc + gcc ; explicit asm_context_sources ; diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index dfc9d6e..df263bb 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -3,8 +3,6 @@ # 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) -path-constant boost-images : ../../../doc/src/images ; - xml context : context.qbk ; boostbook standalone @@ -12,8 +10,6 @@ boostbook standalone context : # HTML options first: - # Use graphics not text for navigation: - navig.graphics=1 # How far down we chunk nested sections, basically all of them: chunk.section.depth=3 # Don't put the first section on the same page as the TOC: @@ -26,8 +22,4 @@ boostbook standalone generate.section.toc.level=10 # Path for links to Boost: boost.root=../../../.. - # Path for libraries index: - boost.libraries=../../../../libs/libraries.htm - # Use the main Boost stylesheet: - html.stylesheet=../../../../doc/html/boostbook.css ; diff --git a/doc/acknowledgements.qbk b/doc/acknowledgements.qbk index 2225021..34f0230 100644 --- a/doc/acknowledgements.qbk +++ b/doc/acknowledgements.qbk @@ -7,9 +7,9 @@ [section:acknowledgements Acknowledgments] -I'd like to thank Adreas Fett, Artyom Beilis, Fernando Pelliccioni, +I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull, Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Phil Endecott, Robert Stewart, -Steven Watanabe, Vicente J. Botet Escriba. +Steven Watanabe, Vicente J. Botet Escriba, Wayne Piekarski. [endsect] diff --git a/doc/fcontext.qbk b/doc/fcontext.qbk index 2adb092..2c320f0 100644 --- a/doc/fcontext.qbk +++ b/doc/fcontext.qbk @@ -33,12 +33,10 @@ intptr_t as argument) must be initialized by function __make_fcontext__. void f( intptr); // creates and manages a protected stack (with guard page) - boost::ctx::protected_stack stack( boost::ctx::default_stacksize() ); - - // let fcontext_t fc use stack - fc.fc_stack.base = stack.address(); + ctx::stack_allocator alloc; + fc.fc_stack.base = alloc.allocate(ctx::minimum_stacksize()); fc.fc_stack.limit = - static_cast< char * >( fc.fc_stack.base) - stack.size(); + static_cast< char * >( fc.fc_stack.base) - ctx::minimum_stacksize(); // context fc uses f() as context function make_fcontext( & fc, f); diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 58485f5..e08943f 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -37,13 +37,13 @@ project boost/context/example ; exe jump - : jump.cpp - ; + : jump.cpp + ; exe exit - : exit.cpp - ; + : exit.cpp + ; exe transfer - : transfer.cpp - ; + : transfer.cpp + ; diff --git a/example/exit.cpp b/example/exit.cpp index 05fb93c..638d9f4 100644 --- a/example/exit.cpp +++ b/example/exit.cpp @@ -18,17 +18,17 @@ ctx::fcontext_t fc1, fc2; void f1( intptr_t) { - std::cout << "f1: entered" << std::endl; - std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; - ctx::jump_fcontext( & fc1, & fc2, 0); - std::cout << "f1: return" << std::endl; + std::cout << "f1: entered" << std::endl; + std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; + ctx::jump_fcontext( & fc1, & fc2, 0); + std::cout << "f1: return" << std::endl; } void f2( intptr_t) { - std::cout << "f2: entered" << std::endl; - std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl; - ctx::jump_fcontext( & fc2, & fc1, 0); + std::cout << "f2: entered" << std::endl; + std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl; + ctx::jump_fcontext( & fc2, & fc1, 0); BOOST_ASSERT( false && ! "f2: never returns"); } @@ -40,17 +40,17 @@ int main( int argc, char * argv[]) fc1.fc_stack.base = alloc.allocate(ctx::minimum_stacksize()); fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize(); - ctx::make_fcontext( & fc1, f1); + ctx::make_fcontext( & fc1, f1); fc2.fc_stack.base = alloc.allocate(ctx::minimum_stacksize()); fc2.fc_stack.limit = static_cast< char * >( fc2.fc_stack.base) - ctx::minimum_stacksize(); - ctx::make_fcontext( & fc2, f2); + ctx::make_fcontext( & fc2, f2); - std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl; - ctx::jump_fcontext( & fcm, & fc1, 0); + std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl; + ctx::jump_fcontext( & fcm, & fc1, 0); - std::cout << "main: done" << std::endl; + std::cout << "main: done" << std::endl; BOOST_ASSERT( false && ! "main: never returns"); return EXIT_SUCCESS; diff --git a/example/jump.cpp b/example/jump.cpp index 413d273..7520b2f 100644 --- a/example/jump.cpp +++ b/example/jump.cpp @@ -18,18 +18,18 @@ ctx::fcontext_t fcm, fc1, fc2; void f1( intptr_t) { - std::cout << "f1: entered" << std::endl; - std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; - ctx::jump_fcontext( & fc1, & fc2, 0); - std::cout << "f1: return" << std::endl; - ctx::jump_fcontext( & fc1, & fcm, 0); + std::cout << "f1: entered" << std::endl; + std::cout << "f1: call jump_fcontext( & fc1, & fc2, 0)" << std::endl; + ctx::jump_fcontext( & fc1, & fc2, 0); + std::cout << "f1: return" << std::endl; + ctx::jump_fcontext( & fc1, & fcm, 0); } void f2( intptr_t) { - std::cout << "f2: entered" << std::endl; - std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl; - ctx::jump_fcontext( & fc2, & fc1, 0); + std::cout << "f2: entered" << std::endl; + std::cout << "f2: call jump_fcontext( & fc2, & fc1, 0)" << std::endl; + ctx::jump_fcontext( & fc2, & fc1, 0); BOOST_ASSERT( false && ! "f2: never returns"); } @@ -40,17 +40,17 @@ int main( int argc, char * argv[]) fc1.fc_stack.base = alloc1.allocate(ctx::minimum_stacksize()); fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize(); - ctx::make_fcontext( & fc1, f1); + ctx::make_fcontext( & fc1, f1); fc2.fc_stack.base = alloc2.allocate(ctx::minimum_stacksize()); fc2.fc_stack.limit = static_cast< char * >( fc2.fc_stack.base) - ctx::minimum_stacksize(); - ctx::make_fcontext( & fc2, f2); + ctx::make_fcontext( & fc2, f2); - std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl; - ctx::jump_fcontext( & fcm, & fc1, 0); + std::cout << "main: call start_fcontext( & fcm, & fc1, 0)" << std::endl; + ctx::jump_fcontext( & fcm, & fc1, 0); - std::cout << "main: done" << std::endl; + std::cout << "main: done" << std::endl; return EXIT_SUCCESS; } diff --git a/example/transfer.cpp b/example/transfer.cpp index 1bfcbfc..6837faf 100644 --- a/example/transfer.cpp +++ b/example/transfer.cpp @@ -23,29 +23,29 @@ void f1( intptr_t param) { pair_t * p = ( pair_t *) param; - p = ( pair_t *) ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) ); + p = ( pair_t *) ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) ); - ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) ); + ctx::jump_fcontext( & fc1, & fcm, ( intptr_t) ( p->first + p->second) ); } int main( int argc, char * argv[]) { ctx::stack_allocator alloc; - + fc1.fc_stack.base = alloc.allocate(ctx::minimum_stacksize()); fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize(); ctx::make_fcontext( & fc1, f1); - + pair_t p( std::make_pair( 2, 7) ); int res = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & p); std::cout << p.first << " + " << p.second << " == " << res << std::endl; - + p = std::make_pair( 5, 6); res = ( int) ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) & p); std::cout << p.first << " + " << p.second << " == " << res << std::endl; - + std::cout << "main: done" << std::endl; - + return EXIT_SUCCESS; } diff --git a/include/boost/context/detail/fcontext_arm.hpp b/include/boost/context/detail/fcontext_arm.hpp index 1adceb7..b4ed2fa 100644 --- a/include/boost/context/detail/fcontext_arm.hpp +++ b/include/boost/context/detail/fcontext_arm.hpp @@ -45,7 +45,7 @@ struct fp_t struct fcontext_t { boost::uint32_t fc_greg[11]; - stack_t fc_stack; + stack_t fc_stack; fp_t fc_fp; fcontext_t() : diff --git a/include/boost/context/detail/fcontext_i386.hpp b/include/boost/context/detail/fcontext_i386.hpp index 77406e1..573a22c 100644 --- a/include/boost/context/detail/fcontext_i386.hpp +++ b/include/boost/context/detail/fcontext_i386.hpp @@ -37,7 +37,7 @@ struct stack_t struct fp_t { - boost::uint32_t fc_freg[2]; + boost::uint32_t fc_freg[2]; fp_t() : fc_freg() @@ -46,8 +46,8 @@ struct fp_t struct fcontext_t { - boost::uint32_t fc_greg[6]; - stack_t fc_stack; + boost::uint32_t fc_greg[6]; + stack_t fc_stack; fp_t fc_fp; fcontext_t() : diff --git a/include/boost/context/detail/fcontext_i386_win.hpp b/include/boost/context/detail/fcontext_i386_win.hpp index 7499817..e250ec5 100644 --- a/include/boost/context/detail/fcontext_i386_win.hpp +++ b/include/boost/context/detail/fcontext_i386_win.hpp @@ -16,8 +16,10 @@ #include +#if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4351) +#endif #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -52,7 +54,7 @@ struct fp_t struct fcontext_t { boost::uint32_t fc_greg[6]; - stack_t fc_stack; + stack_t fc_stack; void * fc_excpt_lst; void * fc_local_storage; fp_t fc_fp; @@ -74,6 +76,8 @@ struct fcontext_t # include BOOST_ABI_SUFFIX #endif +#if defined(BOOST_MSVC) #pragma warning(pop) +#endif #endif // BOOST_CTX_DETAIL_FCONTEXT_I386_H diff --git a/include/boost/context/detail/fcontext_mips.hpp b/include/boost/context/detail/fcontext_mips.hpp index 068c482..1645adf 100644 --- a/include/boost/context/detail/fcontext_mips.hpp +++ b/include/boost/context/detail/fcontext_mips.hpp @@ -47,7 +47,7 @@ struct fp_t struct fcontext_t { boost::uint64_t fc_greg[13]; - stack_t fc_stack; + stack_t fc_stack; fp_t fc_fp; fcontext_t() : diff --git a/include/boost/context/detail/fcontext_ppc.hpp b/include/boost/context/detail/fcontext_ppc.hpp index a0b6ab1..5e6c64c 100644 --- a/include/boost/context/detail/fcontext_ppc.hpp +++ b/include/boost/context/detail/fcontext_ppc.hpp @@ -49,7 +49,7 @@ struct fcontext_t # else boost::uint32_t fc_greg[23]; # endif - stack_t fc_stack; + stack_t fc_stack; fp_t fc_fp; fcontext_t() : diff --git a/include/boost/context/detail/fcontext_x86_64.hpp b/include/boost/context/detail/fcontext_x86_64.hpp index 6e95337..106ee74 100644 --- a/include/boost/context/detail/fcontext_x86_64.hpp +++ b/include/boost/context/detail/fcontext_x86_64.hpp @@ -45,7 +45,7 @@ struct fp_t struct fcontext_t { boost::uint64_t fc_greg[8]; - stack_t fc_stack; + stack_t fc_stack; fp_t fc_fp; fcontext_t() : diff --git a/include/boost/context/detail/fcontext_x86_64_win.hpp b/include/boost/context/detail/fcontext_x86_64_win.hpp index 32d065b..96f153b 100644 --- a/include/boost/context/detail/fcontext_x86_64_win.hpp +++ b/include/boost/context/detail/fcontext_x86_64_win.hpp @@ -17,8 +17,10 @@ #include +#if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4351) +#endif #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -44,7 +46,7 @@ struct stack_t struct fp_t { boost::uint32_t fc_freg[2]; - void * fc_xmm; + void * fc_xmm; char fc_buffer[175]; fp_t() : @@ -52,17 +54,17 @@ struct fp_t fc_xmm( 0), fc_buffer() { - fc_xmm = fc_buffer; - if ( 0 != ( ( ( uintptr_t) fc_xmm) & 15) ) - fc_xmm = ( char *) ( ( ( ( uintptr_t) fc_xmm) + 15) & ~0x0F); - } + fc_xmm = fc_buffer; + if ( 0 != ( ( ( uintptr_t) fc_xmm) & 15) ) + fc_xmm = ( char *) ( ( ( ( uintptr_t) fc_xmm) + 15) & ~0x0F); + } }; struct fcontext_t { boost::uint64_t fc_greg[10]; - stack_t fc_stack; - void * fc_local_storage; + stack_t fc_stack; + void * fc_local_storage; fp_t fc_fp; fcontext_t() : @@ -81,6 +83,8 @@ struct fcontext_t # include BOOST_ABI_SUFFIX #endif +#if defined(BOOST_MSVC) #pragma warning(pop) +#endif #endif // BOOST_CTX_DETAIL_FCONTEXT_X86_64_H diff --git a/index.html b/index.html new file mode 100644 index 0000000..0ade6cb --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + +Automatic redirection failed, please go to +doc/html/index.html +
+

© Copyright Beman Dawes, 2001

+

Distributed under the Boost Software +License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +www.boost.org/LICENSE_1_0.txt)

+ + diff --git a/performance/Jamfile.v2 b/performance/Jamfile.v2 index 6382df2..108c0e1 100644 --- a/performance/Jamfile.v2 +++ b/performance/Jamfile.v2 @@ -15,12 +15,10 @@ import toolset ; project boost/context/performance : requirements - /boost/program_options//boost_program_options - /boost/thread//boost_thread - /boost/system//boost_system /boost/context//boost_context static - multi + "-lrt" + single ; alias sources diff --git a/performance/bind_processor_aix.cpp b/performance/bind_processor_aix.cpp index 7306d9e..7ddc2eb 100644 --- a/performance/bind_processor_aix.cpp +++ b/performance/bind_processor_aix.cpp @@ -12,22 +12,14 @@ extern "C" #include } -#include -#include -#include +#include #include void bind_to_processor( unsigned int n) { - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - if ( ::bindprocessor( BINDTHREAD, ::thread_self(), static_cast< cpu_t >( n) ) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); + throw std::runtime_error("::bindprocessor() failed"); } #include diff --git a/performance/bind_processor_freebsd.cpp b/performance/bind_processor_freebsd.cpp index 5dd4f9f..7e28b70 100644 --- a/performance/bind_processor_freebsd.cpp +++ b/performance/bind_processor_freebsd.cpp @@ -12,26 +12,18 @@ extern "C" #include } -#include -#include -#include +#include #include void bind_to_processor( unsigned int n) { - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - cpuset_t cpuset; CPU_ZERO( & cpuset); CPU_SET( n, & cpuset); if ( ::cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof( cpuset), & cpuset) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); + throw std::runtime_error("::cpuset_setaffinity() failed"); } #include diff --git a/performance/bind_processor_hpux.cpp b/performance/bind_processor_hpux.cpp index e65e606..af33c11 100644 --- a/performance/bind_processor_hpux.cpp +++ b/performance/bind_processor_hpux.cpp @@ -11,17 +11,12 @@ extern "C" #include } -#include -#include -#include +#include #include void bind_to_processor( unsigned int n) { - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - ::pthread_spu_t spu; int errno_( ::pthread_processor_bind_np( @@ -30,10 +25,7 @@ void bind_to_processor( unsigned int n) static_cast< pthread_spu_t >( n), PTHREAD_SELFTID_NP) ); if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category() ) ); + throw std::runtime_error("::pthread_processor_bind_np() failed"); } #include diff --git a/performance/bind_processor_linux.cpp b/performance/bind_processor_linux.cpp index 3f06421..3fb9588 100644 --- a/performance/bind_processor_linux.cpp +++ b/performance/bind_processor_linux.cpp @@ -12,28 +12,19 @@ extern "C" #include } -#include -#include -#include +#include #include void bind_to_processor( unsigned int n) { - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < CPU_SETSIZE); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - cpu_set_t cpuset; CPU_ZERO( & cpuset); CPU_SET( n, & cpuset); int errno_( ::pthread_setaffinity_np( ::pthread_self(), sizeof( cpuset), & cpuset) ); if ( errno_ != 0) - throw boost::system::system_error( - boost::system::error_code( - errno_, - boost::system::system_category() ) ); + throw std::runtime_error("::pthread_setaffinity_np() failed"); } #include diff --git a/performance/bind_processor_solaris.cpp b/performance/bind_processor_solaris.cpp index 8af8313..0830c1b 100644 --- a/performance/bind_processor_solaris.cpp +++ b/performance/bind_processor_solaris.cpp @@ -13,22 +13,14 @@ extern "C" #include } -#include -#include -#include +#include #include void bind_to_processor( unsigned int n) { - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - if ( ::processor_bind( P_LWPID, P_MYID, static_cast< processorid_t >( n), 0) == -1) - throw boost::system::system_error( - boost::system::error_code( - errno, - boost::system::system_category() ) ); + throw std::runtime_error("::processor_bind() failed"); } #include diff --git a/performance/bind_processor_windows.cpp b/performance/bind_processor_windows.cpp index 44f9a3e..6fefbc6 100644 --- a/performance/bind_processor_windows.cpp +++ b/performance/bind_processor_windows.cpp @@ -11,22 +11,14 @@ extern "C" #include } -#include -#include -#include +#include #include void bind_to_processor( unsigned int n) { - BOOST_ASSERT( n >= 0); - BOOST_ASSERT( n < boost::thread::hardware_concurrency() ); - if ( ::SetThreadAffinityMask( ::GetCurrentThread(), ( DWORD_PTR)1 << n) == 0) - throw boost::system::system_error( - boost::system::error_code( - ::GetLastError(), - boost::system::system_category() ) ); + throw std::runtime_error("::SetThreadAffinityMask() failed"); } #include diff --git a/performance/cycle.hpp b/performance/cycle.hpp index 2e12a47..c26c859 100644 --- a/performance/cycle.hpp +++ b/performance/cycle.hpp @@ -21,8 +21,6 @@ || defined(__I86__) || defined(__INTEL__) || defined(__IA32__) \ || defined(_M_IX86) || defined(_I86_) # include "cycle_i386.hpp" -#else -# error "this platform is not supported" #endif #endif // CYCLE_H diff --git a/performance/cycle_i386.hpp b/performance/cycle_i386.hpp index 6e0547a..3e67007 100644 --- a/performance/cycle_i386.hpp +++ b/performance/cycle_i386.hpp @@ -16,6 +16,8 @@ #include #include +#define BOOST_CONTEXT_CYCLE + typedef boost::uint64_t cycle_t; #if _MSC_VER @@ -49,14 +51,14 @@ cycle_t cycles() "cpuid\n" ::: "%eax", "%ebx", "%ecx", "%edx" ); - + return ( cycle_t)hi << 32 | lo; } #else # error "this compiler is not supported" #endif -struct measure +struct measure_cycles { cycle_t operator()() { @@ -66,14 +68,14 @@ struct measure }; inline -cycle_t overhead() +cycle_t overhead_cycles() { std::size_t iterations( 10); std::vector< cycle_t > overhead( iterations, 0); for ( std::size_t i( 0); i < iterations; ++i) std::generate( overhead.begin(), overhead.end(), - measure() ); + measure_cycles() ); BOOST_ASSERT( overhead.begin() != overhead.end() ); return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations; } diff --git a/performance/cycle_x86-64.hpp b/performance/cycle_x86-64.hpp index 9cbf7c2..a2212b8 100644 --- a/performance/cycle_x86-64.hpp +++ b/performance/cycle_x86-64.hpp @@ -16,6 +16,8 @@ #include #include +#define BOOST_CONTEXT_CYCLE + typedef boost::uint64_t cycle_t; #if _MSC_VER >= 1400 @@ -33,7 +35,7 @@ inline cycle_t cycles() { boost::uint32_t lo, hi; - + __asm__ __volatile__ ( "xorl %%eax, %%eax\n" "cpuid\n" @@ -45,14 +47,14 @@ cycle_t cycles() "cpuid\n" ::: "%rax", "%rbx", "%rcx", "%rdx" ); - + return ( cycle_t)hi << 32 | lo; } #else # error "this compiler is not supported" #endif -struct measure +struct measure_cycles { cycle_t operator()() { @@ -62,14 +64,14 @@ struct measure }; inline -cycle_t overhead() +cycle_t overhead_cycles() { std::size_t iterations( 10); std::vector< cycle_t > overhead( iterations, 0); for ( std::size_t i( 0); i < iterations; ++i) std::generate( overhead.begin(), overhead.end(), - measure() ); + measure_cycles() ); BOOST_ASSERT( overhead.begin() != overhead.end() ); return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations; } diff --git a/performance/performance.cpp b/performance/performance.cpp index 6a9d24f..f6461e1 100644 --- a/performance/performance.cpp +++ b/performance/performance.cpp @@ -26,10 +26,13 @@ #include "bind_processor.hpp" #include "cycle.hpp" -namespace ctx = boost::ctx; -namespace po = boost::program_options; +#if _POSIX_C_SOURCE >= 199309L +#include "zeit.hpp" +#endif -bool preserve_fpu = true; +namespace ctx = boost::ctx; + +bool preserve_fpu = false; #define CALL_FUNCTION(z,n,unused) \ fn(); @@ -62,7 +65,8 @@ static void f1( intptr_t) ctx::jump_fcontext( & fc, & fcm, 7, preserve_fpu); } -cycle_t test_function( cycle_t ov) +#ifdef BOOST_CONTEXT_CYCLE +cycle_t test_function_cycle( cycle_t ov) { boost::function< void() > fn( boost::bind( f3) ); // cache warum-up @@ -81,7 +85,7 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~) } #ifndef BOOST_WINDOWS -cycle_t test_ucontext( cycle_t ov) +cycle_t test_ucontext_cycle( cycle_t ov) { ctx::stack_allocator alloc; @@ -108,13 +112,13 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~) } #endif -cycle_t test_fcontext( cycle_t ov) +cycle_t test_fcontext_cycle( cycle_t ov) { ctx::stack_allocator alloc; fc.fc_stack.base = alloc.allocate(ctx::default_stacksize()); fc.fc_stack.limit = static_cast< char * >( fc.fc_stack.base) - ctx::default_stacksize(); - ctx::make_fcontext( & fc, f1); + ctx::make_fcontext( & fc, f1); ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu); @@ -132,43 +136,118 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~) return total; } +#endif + +#if _POSIX_C_SOURCE >= 199309L +zeit_t test_function_zeit( zeit_t ov) +{ + boost::function< void() > fn( boost::bind( f3) ); + // cache warum-up +BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~) + + zeit_t start( zeit() ); +BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~) + zeit_t total( zeit() - start); + + // we have two jumps and two measuremt-overheads + total -= ov; // overhead of measurement + total /= BOOST_PP_LIMIT_MAG; // per call + total /= 2; // 2x jump_to c1->c2 && c2->c1 + + return total; +} + +#ifndef BOOST_WINDOWS +zeit_t test_ucontext_zeit( zeit_t ov) +{ + ctx::stack_allocator alloc; + + ::getcontext( & uc); + uc.uc_stack.ss_sp = + static_cast< char * >( alloc.allocate(ctx::default_stacksize() ) ) + - ctx::default_stacksize(); + uc.uc_stack.ss_size = ctx::default_stacksize(); + ::makecontext( & uc, f2, 7); + + // cache warum-up +BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~) + + zeit_t start( zeit() ); +BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_UCONTEXT, ~) + zeit_t total( zeit() - start); + + // we have two jumps and two measuremt-overheads + total -= ov; // overhead of measurement + total /= BOOST_PP_LIMIT_MAG; // per call + total /= 2; // 2x jump_to c1->c2 && c2->c1 + + return total; +} +#endif + +zeit_t test_fcontext_zeit( zeit_t ov) +{ + ctx::stack_allocator alloc; + fc.fc_stack.base = alloc.allocate(ctx::default_stacksize()); + fc.fc_stack.limit = + static_cast< char * >( fc.fc_stack.base) - ctx::default_stacksize(); + ctx::make_fcontext( & fc, f1); + + ctx::jump_fcontext( & fcm, & fc, 7, preserve_fpu); + + // cache warum-up +BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~) + + zeit_t start( zeit() ); +BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~) + zeit_t total( zeit() - start); + + // we have two jumps and two measuremt-overheads + total -= ov; // overhead of measurement + total /= BOOST_PP_LIMIT_MAG; // per call + total /= 2; // 2x jump_to c1->c2 && c2->c1 + + return total; +} +#endif int main( int argc, char * argv[]) { try { - po::options_description desc("allowed options"); - desc.add_options() - ("help,h", "help message") - ("preserve-fpu,p", po::value< bool >( & preserve_fpu), "preserve floating point env"); - - po::variables_map vm; - po::store( - po::parse_command_line( - argc, - argv, - desc), - vm); - po::notify( vm); - - if ( vm.count("help") ) - { - std::cout << desc << std::endl; - return EXIT_SUCCESS; - } bind_to_processor( 0); - cycle_t ov( overhead() ); - std::cout << "overhead for rdtsc == " << ov << " cycles" << std::endl; +#ifdef BOOST_CONTEXT_CYCLE + { + cycle_t ov( overhead_cycles() ); + std::cout << "overhead for rdtsc == " << ov << " cycles" << std::endl; - unsigned int res = test_fcontext( ov); - std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl; + unsigned int res = test_fcontext_cycle( ov); + std::cout << "fcontext: average of " << res << " cycles per switch" << std::endl; #ifndef BOOST_WINDOWS - res = test_ucontext( ov); - std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl; + res = test_ucontext_cycle( ov); + std::cout << "ucontext: average of " << res << " cycles per switch" << std::endl; +#endif + res = test_function_cycle( ov); + std::cout << "boost::function: average of " << res << " cycles per switch" << std::endl; + } +#endif + +#if _POSIX_C_SOURCE >= 199309L + { + zeit_t ov( overhead_zeit() ); + std::cout << "\noverhead for clock_gettime() == " << ov << " ns" << std::endl; + + unsigned int res = test_fcontext_zeit( ov); + std::cout << "fcontext: average of " << res << " ns per switch" << std::endl; +#ifndef BOOST_WINDOWS + res = test_ucontext_zeit( ov); + std::cout << "ucontext: average of " << res << " ns per switch" << std::endl; +#endif + res = test_function_zeit( ov); + std::cout << "boost::function: average of " << res << " ns per switch" << std::endl; + } #endif - res = test_function( ov); - std::cout << "boost::function: average of " << res << " cycles per switch" << std::endl; return EXIT_SUCCESS; } diff --git a/performance/zeit.hpp b/performance/zeit.hpp new file mode 100644 index 0000000..2c082bf --- /dev/null +++ b/performance/zeit.hpp @@ -0,0 +1,53 @@ + +// Copyright Oliver Kowalke 2009. +// 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) + +#ifndef ZEIT_H +#define ZEIT_H + +#include + +#include +#include +#include +#include + +#include +#include +#include + +typedef boost::uint64_t zeit_t; + +inline +zeit_t zeit() +{ + timespec t; + ::clock_gettime( CLOCK_PROCESS_CPUTIME_ID, & t); + return t.tv_sec * 1000000000 + t.tv_nsec; +} + +struct measure_zeit +{ + zeit_t operator()() + { + zeit_t start( zeit() ); + return zeit() - start; + } +}; + +inline +zeit_t overhead_zeit() +{ + std::size_t iterations( 10); + std::vector< zeit_t > overhead( iterations, 0); + for ( std::size_t i( 0); i < iterations; ++i) + std::generate( + overhead.begin(), overhead.end(), + measure_zeit() ); + BOOST_ASSERT( overhead.begin() != overhead.end() ); + return std::accumulate( overhead.begin(), overhead.end(), 0) / iterations; +} + +#endif // ZEIT_H diff --git a/src/asm/fcontext_arm_aapcs_elf_gas.S b/src/asm/fcontext_arm_aapcs_elf_gas.S index 0f1f8fb..7724441 100644 --- a/src/asm/fcontext_arm_aapcs_elf_gas.S +++ b/src/asm/fcontext_arm_aapcs_elf_gas.S @@ -52,20 +52,23 @@ jump_fcontext: stmia a1, {v1-v8,sp-lr} @ save V1-V8,SP-LR str lr, [a1,#40] @ save LR as PC + #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) cmp a4, #0 @ test if fpu env should be preserved - be 1f + beq 1f - ldr a4, [a1,#52] - stmia a4, {s16-s31} @ save S16-S31 + mov a4, a1 + add a4, #52 + fstmiax a4, {d8-d15} @ save S16-S31 - ldr a4, [a2,#52] - ldmia a4, {s16-s31} @ restore S16-S31 + mov a4, a2 + add a4, #52 + fldmiax a4, {d8-d15} @ restore S16-S31 1: #endif - mov a1, a3 @ use third arg as return value after jump - @ and as first arg in context function + mov a1, a3 @ use third arg as return value after jump + @ and as first arg in context function ldmia a2, {v1-v8,sp-pc} @ restore v1-V8,SP-PC .size jump_fcontext,.-jump_fcontext @@ -78,11 +81,11 @@ make_fcontext: str a2, [a1,#40] @ save address of the context function ldr a2, [a1,#44] @ load the stack base - push {a1,lr} @ save pointer to fcontext_t - mov a1, a2 @ stack pointer as arg for align_stack - bl align_stack@PLT @ align stack - mov a2, a1 @ begin of aligned stack - pop {a1,lr} @ restore pointer to fcontext_t + push {a1,lr} @ save pointer to fcontext_t + mov a1, a2 @ stack pointer as arg for align_stack + bl align_stack@PLT @ align stack + mov a2, a1 @ begin of aligned stack + pop {a1,lr} @ restore pointer to fcontext_t str a2, [a1,#32] @ save the aligned stack base diff --git a/src/asm/fcontext_x86_64_ms_pe_masm.asm b/src/asm/fcontext_x86_64_ms_pe_masm.asm index f3a882c..f1f8ca1 100644 --- a/src/asm/fcontext_x86_64_ms_pe_masm.asm +++ b/src/asm/fcontext_x86_64_ms_pe_masm.asm @@ -112,7 +112,7 @@ jump_fcontext PROC EXPORT FRAME:seh_fcontext stmxcsr [rcx+068h] ; save MMX control and status word fnstcw [rcx+06ch] ; save x87 control word - mov r10, [rcx+070h] ; address of aligned XMM storage + mov r10, [rcx+070h] ; address of aligned XMM storage movaps [r10], xmm6 movaps [r10+010h], xmm7 movaps [r10+020h], xmm8 @@ -126,7 +126,7 @@ jump_fcontext PROC EXPORT FRAME:seh_fcontext ldmxcsr [rdx+068h] ; restore MMX control and status word fldcw [rdx+06ch] ; restore x87 control word - mov r10, [rdx+070h] ; address of aligned XMM storage + mov r10, [rdx+070h] ; address of aligned XMM storage movaps xmm6, [r10] movaps xmm7, [r10+010h] movaps xmm8, [r10+020h] diff --git a/src/fcontext.cpp b/src/fcontext.cpp index e1658ca..596cbd8 100644 --- a/src/fcontext.cpp +++ b/src/fcontext.cpp @@ -21,10 +21,10 @@ namespace detail { extern "C" BOOST_CONTEXT_DECL void * BOOST_CONTEXT_CALLDECL align_stack( void * vp) { - void * base = vp; + void * base = vp; if ( 0 != ( ( ( uintptr_t) base) & 15) ) base = ( char * ) ( ( ( ( uintptr_t) base) - 15) & ~0x0F); - return base; + return base; } } diff --git a/src/seh.cpp b/src/seh.cpp index 5c9c9d4..9363805 100644 --- a/src/seh.cpp +++ b/src/seh.cpp @@ -21,7 +21,7 @@ extern "C" { # define SNPRINTF snprintf #endif -static char * exception_description( +static const char * exception_description( _EXCEPTION_RECORD const* record, char * description, size_t len) { const DWORD code = record->ExceptionCode; @@ -33,7 +33,7 @@ static char * exception_description( { const char * accessType = ( info[0]) ? "writing" : "reading"; const ULONG_PTR address = info[1]; - SNPRINTF( description, len, "Access violation %s 0x%08lX", accessType, address); + SNPRINTF( description, len, "Access violation %s %p", accessType, reinterpret_cast< void * >( address) ); return description; } case EXCEPTION_DATATYPE_MISALIGNMENT: return "Datatype misalignment"; diff --git a/src/stack_allocator_posix.cpp b/src/stack_allocator_posix.cpp index 314c789..a373e56 100644 --- a/src/stack_allocator_posix.cpp +++ b/src/stack_allocator_posix.cpp @@ -45,7 +45,7 @@ stack_allocator::allocate( std::size_t size) const % maximum_stacksize() ) ); const std::size_t pages( page_count( size) + 1); // add +1 for guard page - std::size_t size_ = pages * pagesize(); + std::size_t size_ = pages * pagesize(); const int fd( ::open("/dev/zero", O_RDONLY) ); BOOST_ASSERT( -1 != fd); @@ -69,8 +69,8 @@ stack_allocator::deallocate( void * vp, std::size_t size) const { if ( vp) { - const std::size_t pages( page_count( size) + 1); // add +1 for guard page - std::size_t size_ = pages * pagesize(); + const std::size_t pages( page_count( size) + 1); // add +1 for guard page + std::size_t size_ = pages * pagesize(); BOOST_ASSERT( 0 < size && 0 < size_); void * limit = static_cast< char * >( vp) - size_; ::munmap( limit, size_); diff --git a/src/stack_allocator_windows.cpp b/src/stack_allocator_windows.cpp index 6759e9b..518239f 100644 --- a/src/stack_allocator_windows.cpp +++ b/src/stack_allocator_windows.cpp @@ -16,6 +16,7 @@ extern "C" { #include #include +#include #include #include diff --git a/test/test_context.cpp b/test/test_context.cpp index ffe5528..42f09ea 100644 --- a/test/test_context.cpp +++ b/test/test_context.cpp @@ -26,25 +26,25 @@ double value3 = 0.; void f1( intptr_t) { ++value1; - ctx::jump_fcontext( & fc1, & fcm, 0); + ctx::jump_fcontext( & fc1, & fcm, 0); } void f3( intptr_t) { ++value1; - ctx::jump_fcontext( & fc1, & fcm, 0); + ctx::jump_fcontext( & fc1, & fcm, 0); ++value1; - ctx::jump_fcontext( & fc1, & fcm, 0); + ctx::jump_fcontext( & fc1, & fcm, 0); } void f4( intptr_t) { - ctx::jump_fcontext( & fc1, & fcm, 7); + ctx::jump_fcontext( & fc1, & fcm, 7); } void f5( intptr_t arg) { - ctx::jump_fcontext( & fc1, & fcm, arg); + ctx::jump_fcontext( & fc1, & fcm, arg); } void f6( intptr_t arg) @@ -63,7 +63,7 @@ void f7( intptr_t arg) { throw std::runtime_error( ( char *) arg); } catch ( std::runtime_error const& e) { value2 = e.what(); } - ctx::jump_fcontext( & fc1, & fcm, arg); + ctx::jump_fcontext( & fc1, & fcm, arg); } void f8( intptr_t arg) @@ -71,7 +71,7 @@ void f8( intptr_t arg) double d = * ( double *) arg; d += 3.45; value3 = d; - ctx::jump_fcontext( & fc1, & fcm, 0); + ctx::jump_fcontext( & fc1, & fcm, 0); } void test_start() @@ -153,7 +153,7 @@ void test_exception() fc1.fc_stack.base = alloc.allocate( ctx::minimum_stacksize() ); fc1.fc_stack.limit = static_cast< char * >( fc1.fc_stack.base) - ctx::minimum_stacksize(); - char * what = "hello world"; + const char * what = "hello world"; ctx::make_fcontext( & fc1, f7); ctx::jump_fcontext( & fcm, & fc1, ( intptr_t) what);