2 // Copyright Oliver Kowalke 2009.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
12 #include <boost/context/detail/fcontext.hpp>
13 #include <boost/cstdint.hpp>
14 #include <boost/program_options.hpp>
16 #include "../clock.hpp"
17 #include "../cycle.hpp"
19 template< std::size_t Max
, std::size_t Default
, std::size_t Min
>
20 class simple_stack_allocator
23 static std::size_t maximum_stacksize()
26 static std::size_t default_stacksize()
29 static std::size_t minimum_stacksize()
32 void * allocate( std::size_t size
) const
34 BOOST_ASSERT( minimum_stacksize() <= size
);
35 BOOST_ASSERT( maximum_stacksize() >= size
);
37 void * limit
= std::malloc( size
);
38 if ( ! limit
) throw std::bad_alloc();
40 return static_cast< char * >( limit
) + size
;
43 void deallocate( void * vp
, std::size_t size
) const
46 BOOST_ASSERT( minimum_stacksize() <= size
);
47 BOOST_ASSERT( maximum_stacksize() >= size
);
49 void * limit
= static_cast< char * >( vp
) - size
;
54 typedef simple_stack_allocator
<
55 8 * 1024 * 1024, 64 * 1024, 8 * 1024
58 boost::uint64_t jobs
= 1000000;
60 static void foo( boost::context::detail::transfer_t t_
) {
61 boost::context::detail::transfer_t t
= t_
;
63 t
= boost::context::detail::jump_fcontext( t
.fctx
, 0);
67 duration_type
measure_time_fc() {
68 stack_allocator stack_alloc
;
69 boost::context::detail::fcontext_t ctx
= boost::context::detail::make_fcontext(
70 stack_alloc
.allocate( stack_allocator::default_stacksize() ),
71 stack_allocator::default_stacksize(),
75 boost::context::detail::transfer_t t
= boost::context::detail::jump_fcontext( ctx
, 0);
77 time_point_type
start( clock_type::now() );
78 for ( std::size_t i
= 0; i
< jobs
; ++i
) {
79 t
= boost::context::detail::jump_fcontext( t
.fctx
, 0);
81 duration_type total
= clock_type::now() - start
;
82 total
-= overhead_clock(); // overhead of measurement
83 total
/= jobs
; // loops
84 total
/= 2; // 2x jump_fcontext
89 #ifdef BOOST_CONTEXT_CYCLE
90 cycle_type
measure_cycles_fc() {
91 stack_allocator stack_alloc
;
92 boost::context::detail::fcontext_t ctx
= boost::context::detail::make_fcontext(
93 stack_alloc
.allocate( stack_allocator::default_stacksize() ),
94 stack_allocator::default_stacksize(),
98 boost::context::detail::transfer_t t
= boost::context::detail::jump_fcontext( ctx
, 0);
100 cycle_type
start( cycles() );
101 for ( std::size_t i
= 0; i
< jobs
; ++i
) {
102 t
= boost::context::detail::jump_fcontext( t
.fctx
, 0);
104 cycle_type total
= cycles() - start
;
105 total
-= overhead_cycle(); // overhead of measurement
106 total
/= jobs
; // loops
107 total
/= 2; // 2x jump_fcontext
113 int main( int argc
, char * argv
[])
117 boost::program_options::options_description
desc("allowed options");
119 ("help", "help message")
120 ("jobs,j", boost::program_options::value
< boost::uint64_t >( & jobs
), "jobs to run");
122 boost::program_options::variables_map vm
;
123 boost::program_options::store(
124 boost::program_options::parse_command_line(
129 boost::program_options::notify( vm
);
131 if ( vm
.count("help") ) {
132 std::cout
<< desc
<< std::endl
;
136 boost::uint64_t res
= measure_time_fc().count();
137 std::cout
<< "fcontext_t: average of " << res
<< " nano seconds" << std::endl
;
138 #ifdef BOOST_CONTEXT_CYCLE
139 res
= measure_cycles_fc();
140 std::cout
<< "fcontext_t: average of " << res
<< " cpu cycles" << std::endl
;
145 catch ( std::exception
const& e
)
146 { std::cerr
<< "exception: " << e
.what() << std::endl
; }
148 { std::cerr
<< "unhandled exception" << std::endl
; }