#include #include #include namespace { template< std::size_t Max, std::size_t Default, std::size_t Min > class simple_stack_allocator { public: static std::size_t maximum_stacksize() { return Max; } static std::size_t default_stacksize() { return Default; } static std::size_t minimum_stacksize() { return Min; } void * allocate( std::size_t size) const { BOOST_ASSERT( minimum_stacksize() <= size); BOOST_ASSERT( maximum_stacksize() >= size); void * limit = std::calloc( size, sizeof( char) ); if ( ! limit) throw std::bad_alloc(); return static_cast< char * >( limit) + size; } void deallocate( void * vp, std::size_t size) const { BOOST_ASSERT( vp); BOOST_ASSERT( minimum_stacksize() <= size); BOOST_ASSERT( maximum_stacksize() >= size); void * limit = static_cast< char * >( vp) - size; std::free( limit); } }; } namespace sample { namespace ctx = yboost::context; typedef simple_stack_allocator< 8 * 1024 * 1024, // 8MB 64 * 1024, // 64kB 8 * 1024 // 8kB > stack_allocator; ctx::fcontext_t fcm; ctx::fcontext_t* fc = 0; void do_throw() { throw std::exception(); } void routine(intptr_t) { try { ctx::jump_fcontext(fc, &fcm, 0); do_throw(); } catch(std::exception) { std::cout << "exception caught" << std::endl; } ctx::jump_fcontext(fc, &fcm, 0); } void try_jump() { try { ctx::jump_fcontext(&fcm, fc, 0); } catch (...) { } } void test() { stack_allocator alloc; void* base = alloc.allocate(stack_allocator::default_stacksize()); fc = ctx::make_fcontext(base, stack_allocator::default_stacksize(), routine); try_jump(); ctx::jump_fcontext(&fcm, fc, 0); } } int main(int argc, const char * argv[]) { sample::test(); }