From 3df6609ac522b5eb7ab906198f59fe14c8bfc0da Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Sat, 27 Jul 2019 14:12:00 +0200 Subject: [PATCH] examples regarding to unwinding --- example/Jamfile.v2 | 20 ++++++++++ example/unwind_default.cpp | 63 ++++++++++++++++++++++++++++++ example/unwind_return1.cpp | 73 +++++++++++++++++++++++++++++++++++ example/unwind_return2.cpp | 71 ++++++++++++++++++++++++++++++++++ example/unwind_throw1.cpp | 75 ++++++++++++++++++++++++++++++++++++ example/unwind_throw2.cpp | 79 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 381 insertions(+) create mode 100644 example/unwind_default.cpp create mode 100644 example/unwind_return1.cpp create mode 100644 example/unwind_return2.cpp create mode 100644 example/unwind_throw1.cpp create mode 100644 example/unwind_throw2.cpp diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 7794597..5c4c44c 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -90,6 +90,26 @@ exe unwind_main : unwind_main.cpp ; +exe unwind_return1 + : unwind_return1.cpp + ; + +exe unwind_return2 + : unwind_return2.cpp + ; + +exe unwind_throw1 + : unwind_throw1.cpp + ; + +exe unwind_throw2 + : unwind_throw2.cpp + ; + +exe unwind_default + : unwind_default.cpp + ; + #exe backtrace # : backtrace.cpp # ; diff --git a/example/unwind_default.cpp b/example/unwind_default.cpp new file mode 100644 index 0000000..b47d256 --- /dev/null +++ b/example/unwind_default.cpp @@ -0,0 +1,63 @@ + +// Copyright Oliver Kowalke 2019. +// 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 +#include +#include + +#include + +namespace ctx = boost::context; + +class fibonacci_generator { +private: + ctx::fiber_context fcallee; + uint64_t a; + + void run_(ctx::fiber_context && fcaller) { + a=0; + int b=1; + for(;;){ + fcaller = std::move( fcaller).resume(); + int next=a+b; + a=b; + b=next; + } + } + +public: + fibonacci_generator() : + fcallee{ + [this](ctx::fiber_context && fcaller) -> ctx::fiber_context { + run_( std::move( fcaller) ); + return {}; + } } { + } + + ~fibonacci_generator() { + if ( fcallee) { + std::move( fcallee).resume_with( ctx::unwind_fiber); + } + } + + fibonacci_generator( fibonacci_generator const&) = delete; + fibonacci_generator & operator=( fibonacci_generator const&) = delete; + + uint64_t operator()() { + fcallee = std::move( fcallee).resume(); + return a; + } +}; + +int main() { + fibonacci_generator generator; + for ( int j = 0; j < 10; ++j) { + std::cout << generator() << " "; + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/example/unwind_return1.cpp b/example/unwind_return1.cpp new file mode 100644 index 0000000..b91b5bf --- /dev/null +++ b/example/unwind_return1.cpp @@ -0,0 +1,73 @@ + +// Copyright Oliver Kowalke 2019. +// 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 +#include +#include + +#include + +namespace ctx = boost::context; + +class fibonacci_generator { +private: + bool terminate{ false }; + ctx::fiber_context fcallee; + ctx::fiber_context fexit; + uint64_t a; + + void run_(ctx::fiber_context && fcaller) { + a=0; + int b=1; + for(;;){ + fcaller = std::move( fcaller).resume(); + if ( terminate) { + return; + } + int next=a+b; + a=b; + b=next; + } + } + +public: + fibonacci_generator() : + fcallee{ + [this](ctx::fiber_context && fcaller) -> ctx::fiber_context { + run_( std::move( fcaller) ); + return std::move( fexit); + } } { + } + + ~fibonacci_generator() { + if ( fcallee) { + std::move( fcallee).resume_with( + [this](ctx::fiber_context && f) -> ctx::fiber_context { + terminate = true; + fexit = std::move( f); + return {}; + }); + } + } + + fibonacci_generator( fibonacci_generator const&) = delete; + fibonacci_generator & operator=( fibonacci_generator const&) = delete; + + uint64_t operator()() { + fcallee = std::move( fcallee).resume(); + return a; + } +}; + +int main() { + fibonacci_generator generator; + for ( int j = 0; j < 10; ++j) { + std::cout << generator() << " "; + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/example/unwind_return2.cpp b/example/unwind_return2.cpp new file mode 100644 index 0000000..2f0765f --- /dev/null +++ b/example/unwind_return2.cpp @@ -0,0 +1,71 @@ + +// Copyright Oliver Kowalke 2019. +// 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 +#include +#include + +#include + +namespace ctx = boost::context; + +class fibonacci_generator { +private: + ctx::fiber_context fcallee; + ctx::fiber_context fexit; + uint64_t a; + + void run_(ctx::fiber_context && fcaller) { + a=0; + int b=1; + for(;;){ + fcaller = std::move( fcaller).resume(); + if ( ! fcaller) { + return; + } + int next=a+b; + a=b; + b=next; + } + } + +public: + fibonacci_generator() : + fcallee{ + [this](ctx::fiber_context && fcaller) -> ctx::fiber_context { + run_( std::move( fcaller) ); + return std::move( fexit); + } } { + } + + ~fibonacci_generator() { + if ( fcallee) { + std::move( fcallee).resume_with( + [this](ctx::fiber_context && f) -> ctx::fiber_context { + fexit = std::move( f); + return {}; + }); + } + } + + fibonacci_generator( fibonacci_generator const&) = delete; + fibonacci_generator & operator=( fibonacci_generator const&) = delete; + + uint64_t operator()() { + fcallee = std::move( fcallee).resume(); + return a; + } +}; + +int main() { + fibonacci_generator generator; + for ( int j = 0; j < 10; ++j) { + std::cout << generator() << " "; + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/example/unwind_throw1.cpp b/example/unwind_throw1.cpp new file mode 100644 index 0000000..110b911 --- /dev/null +++ b/example/unwind_throw1.cpp @@ -0,0 +1,75 @@ + +// Copyright Oliver Kowalke 2019. +// 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 +#include +#include + +#include + +namespace ctx = boost::context; + +class fibonacci_generator { +private: + struct my_unwind_exception { + }; + + ctx::fiber_context fcallee; + ctx::fiber_context fexit; + uint64_t a; + + void run_(ctx::fiber_context && fcaller) { + a=0; + int b=1; + for(;;){ + fcaller = std::move( fcaller).resume(); + int next=a+b; + a=b; + b=next; + } + } + +public: + fibonacci_generator() : + fcallee{ + [this](ctx::fiber_context && fcaller) -> ctx::fiber_context { + try { + run_( std::move( fcaller) ); + } catch ( my_unwind_exception const&) { + } + return std::move( fexit); + } } { + } + + ~fibonacci_generator() { + if ( fcallee) { + std::move( fcallee).resume_with( + [this](ctx::fiber_context && f) -> ctx::fiber_context { + fexit = std::move( f); + throw my_unwind_exception{}; + return {}; + }); + } + } + + fibonacci_generator( fibonacci_generator const&) = delete; + fibonacci_generator & operator=( fibonacci_generator const&) = delete; + + uint64_t operator()() { + fcallee = std::move( fcallee).resume(); + return a; + } +}; + +int main() { + fibonacci_generator generator; + for ( int j = 0; j < 10; ++j) { + std::cout << generator() << " "; + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/example/unwind_throw2.cpp b/example/unwind_throw2.cpp new file mode 100644 index 0000000..0af28d3 --- /dev/null +++ b/example/unwind_throw2.cpp @@ -0,0 +1,79 @@ + +// Copyright Oliver Kowalke 2019. +// 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 +#include +#include + +#include + +namespace ctx = boost::context; + +class fibonacci_generator { +private: + struct my_unwind_exception { + ctx::fiber_context fexit; + + my_unwind_exception( ctx::fiber_context && f) : + fexit{ std::move( f) } { + } + }; + + ctx::fiber_context fcallee; + uint64_t a; + + void run_(ctx::fiber_context && fcaller) { + a=0; + int b=1; + for(;;){ + fcaller = std::move( fcaller).resume(); + int next=a+b; + a=b; + b=next; + } + } + +public: + fibonacci_generator() : + fcallee{ + [this](ctx::fiber_context && fcaller) -> ctx::fiber_context { + try { + run_( std::move( fcaller) ); + } catch ( my_unwind_exception & ex) { + return std::move( ex.fexit); + } + return {}; + } } { + } + + ~fibonacci_generator() { + if ( fcallee) { + std::move( fcallee).resume_with( + [this](ctx::fiber_context && f) -> ctx::fiber_context { + throw my_unwind_exception{ std::move( f) }; + return {}; + }); + } + } + + fibonacci_generator( fibonacci_generator const&) = delete; + fibonacci_generator & operator=( fibonacci_generator const&) = delete; + + uint64_t operator()() { + fcallee = std::move( fcallee).resume(); + return a; + } +}; + +int main() { + fibonacci_generator generator; + for ( int j = 0; j < 10; ++j) { + std::cout << generator() << " "; + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +}