diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/context/example | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/context/example')
30 files changed, 1492 insertions, 0 deletions
diff --git a/src/boost/libs/context/example/callcc/Jamfile.v2 b/src/boost/libs/context/example/callcc/Jamfile.v2 new file mode 100644 index 00000000..f6bf5044 --- /dev/null +++ b/src/boost/libs/context/example/callcc/Jamfile.v2 @@ -0,0 +1,79 @@ +# Boost.Context Library Examples Jamfile + +# Copyright Oliver Kowalke 2014. +# 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) + +# For more information, see http://www.boost.org/ + +import common ; +import feature ; +import indirect ; +import modules ; +import os ; +import toolset ; +import architecture ; + +project boost/context/example/callcc + : requirements + <library>/boost/context//boost_context + <toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack + <toolset>gcc,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS + <toolset>clang,<segmented-stacks>on:<cxxflags>-fsplit-stack + <toolset>clang,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS + <link>static + <threading>multi + ; + +exe stack + : stack.cpp + ; + +exe jump_void + : jump_void.cpp + ; + +exe jump + : jump.cpp + ; + +exe jump_mov + : jump_mov.cpp + ; + +exe ontop_void + : ontop_void.cpp + ; + +exe throw + : throw.cpp + ; + +exe fibonacci + : fibonacci.cpp + ; + +exe parser + : parser.cpp + ; + +exe ontop + : ontop.cpp + ; + +exe endless_loop + : endless_loop.cpp + ; + +exe segmented + : segmented.cpp + ; + +#exe backtrace +# : backtrace.cpp +# ; + +#exe echosse +# : echosse.cpp +# ; diff --git a/src/boost/libs/context/example/callcc/backtrace.cpp b/src/boost/libs/context/example/callcc/backtrace.cpp new file mode 100644 index 00000000..43acc573 --- /dev/null +++ b/src/boost/libs/context/example/callcc/backtrace.cpp @@ -0,0 +1,57 @@ + +// Copyright Oliver Kowalke 2016. +// 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) + +#define UNW_LOCAL_ONLY + +#include <cstdlib> +#include <iostream> + +#include <libunwind.h> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +void backtrace() { + unw_cursor_t cursor; + unw_context_t context; + unw_getcontext( & context); + unw_init_local( & cursor, & context); + while ( 0 < unw_step( & cursor) ) { + unw_word_t offset, pc; + unw_get_reg( & cursor, UNW_REG_IP, & pc); + if ( 0 == pc) { + break; + } + std::cout << "0x" << pc << ":"; + + char sym[256]; + if ( 0 == unw_get_proc_name( & cursor, sym, sizeof( sym), & offset) ) { + std::cout << " (" << sym << "+0x" << offset << ")" << std::endl; + } else { + std::cout << " -- error: unable to obtain symbol name for this frame" << std::endl; + } + } +} + +void bar() { + backtrace(); +} + +void foo() { + bar(); +} + +ctx::continuation f1( ctx::continuation && c) { + foo(); + return std::move( c); +} + +int main() { + ctx::callcc( f1); + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/circle.cpp b/src/boost/libs/context/example/callcc/circle.cpp new file mode 100644 index 00000000..4dd40361 --- /dev/null +++ b/src/boost/libs/context/example/callcc/circle.cpp @@ -0,0 +1,44 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <list> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +int main() { + ctx::fiber f1, f2, f3; + f3 = ctx::fiber{[&](ctx::fiber && f)->ctx::fiber{ + f2 = std::move( f); + for (;;) { + std::cout << "f3\n"; + f2 = f1.resume(); + } + return {}; + }}; + f2 = ctx::fiber{[&](ctx::fiber && f)->ctx::fiber{ + f1 = std::move( f); + for (;;) { + std::cout << "f2\n"; + f1 = f3.resume(); + } + return {}; + }}; + f1 = ctx::fiber{[&](ctx::fiber && /*main*/)->ctx::fiber{ + for (;;) { + std::cout << "f1\n"; + f3 = f2.resume(); + } + return {}; + }}; + f1.resume(); + + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/echosse.cpp b/src/boost/libs/context/example/callcc/echosse.cpp new file mode 100644 index 00000000..4b76ffc5 --- /dev/null +++ b/src/boost/libs/context/example/callcc/echosse.cpp @@ -0,0 +1,46 @@ + +// 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) + +#include <cstddef> +#include <cstdlib> +#include <cstring> +#include <iostream> +#include <emmintrin.h> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +void echoSSE( int i) { + __m128i xmm; + xmm = _mm_set_epi32( i, i + 1, i + 2, i + 3); + uint32_t v32[4]; + memcpy( & v32, & xmm, 16); + std::cout << v32[0]; + std::cout << v32[1]; + std::cout << v32[2]; + std::cout << v32[3]; +} + + +int main( int argc, char * argv[]) { + int i = 0; + ctx::continuation c = ctx::callcc( + [&i](ctx::continuation && c) { + for (;;) { + std::cout << i; + echoSSE( i); + std::cout << " "; + c = c.resume(); + } + return std::move( c); + }); + for (; i < 10; ++i) { + c = c.resume(); + } + std::cout << "\nmain: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/endless_loop.cpp b/src/boost/libs/context/example/callcc/endless_loop.cpp new file mode 100644 index 00000000..318bb88d --- /dev/null +++ b/src/boost/libs/context/example/callcc/endless_loop.cpp @@ -0,0 +1,28 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +ctx::continuation foo( ctx::continuation && c) { + do { + std::cout << "foo\n"; + } while ( ( c = c.resume() ) ); + return std::move( c); +} + +int main() { + ctx::continuation c = ctx::callcc( foo); + do { + std::cout << "bar\n"; + } while ( ( c = c.resume() ) ); + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/fibonacci.cpp b/src/boost/libs/context/example/callcc/fibonacci.cpp new file mode 100644 index 00000000..170b9f27 --- /dev/null +++ b/src/boost/libs/context/example/callcc/fibonacci.cpp @@ -0,0 +1,36 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <memory> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +int main() { + int a; + ctx::continuation c=ctx::callcc( + [&a](ctx::continuation && c){ + a=0; + int b=1; + for(;;){ + c=c.resume(); + int next=a+b; + a=b; + b=next; + } + return std::move( c); + }); + for ( int j = 0; j < 10; ++j) { + std::cout << a << " "; + c=c.resume(); + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/jump.cpp b/src/boost/libs/context/example/callcc/jump.cpp new file mode 100644 index 00000000..ab5d6b73 --- /dev/null +++ b/src/boost/libs/context/example/callcc/jump.cpp @@ -0,0 +1,35 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +int main() { + ctx::continuation c; + int data = 1; + c = ctx::callcc( + [&data](ctx::continuation && c){ + std::cout << "entered first time: " << data << std::endl; + data += 2; + c = c.resume(); + std::cout << "entered second time: " << data << std::endl; + return std::move( c); + }); + std::cout << "returned first time: " << data << std::endl; + data += 2; + c = c.resume(); + if ( c) { + std::cout << "returned second time: " << data << std::endl; + } else { + std::cout << "returned second time: execution context terminated" << std::endl; + } + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/jump_mov.cpp b/src/boost/libs/context/example/callcc/jump_mov.cpp new file mode 100644 index 00000000..1f522eff --- /dev/null +++ b/src/boost/libs/context/example/callcc/jump_mov.cpp @@ -0,0 +1,59 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +class moveable { +public: + int value; + + moveable() : + value( -1) { + } + + moveable( int v) : + value( v) { + } + + moveable( moveable && other) { + std::swap( value, other.value); + } + + moveable & operator=( moveable && other) { + if ( this == & other) return * this; + value = other.value; + other.value = -1; + return * this; + } + + moveable( moveable const& other) = delete; + moveable & operator=( moveable const& other) = delete; +}; + +int main() { + ctx::continuation c; + moveable data{ 1 }; + c = ctx::callcc( std::allocator_arg, ctx::fixedsize_stack{}, + [&data](ctx::continuation && c){ + std::cout << "entered first time: " << data.value << std::endl; + data = std::move( moveable{ 3 }); + c = c.resume(); + std::cout << "entered second time: " << data.value << std::endl; + data = std::move( moveable{}); + return std::move( c); + }); + std::cout << "returned first time: " << data.value << std::endl; + data.value = 5; + c = c.resume(); + std::cout << "returned second time: " << data.value << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/jump_void.cpp b/src/boost/libs/context/example/callcc/jump_void.cpp new file mode 100644 index 00000000..7cb5d41e --- /dev/null +++ b/src/boost/libs/context/example/callcc/jump_void.cpp @@ -0,0 +1,28 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +ctx::continuation f1( ctx::continuation && c) { + std::cout << "f1: entered first time" << std::endl; + c = c.resume(); + std::cout << "f1: entered second time" << std::endl; + return std::move( c); +} + +int main() { + ctx::continuation c = ctx::callcc( f1); + std::cout << "f1: returned first time" << std::endl; + c = c.resume(); + std::cout << "f1: returned second time" << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/ontop.cpp b/src/boost/libs/context/example/callcc/ontop.cpp new file mode 100644 index 00000000..d59fde8a --- /dev/null +++ b/src/boost/libs/context/example/callcc/ontop.cpp @@ -0,0 +1,40 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <tuple> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +int main() { + int data = 0; + ctx::continuation c = ctx::callcc( [&data](ctx::continuation && c) { + std::cout << "f1: entered first time: " << data << std::endl; + data += 1; + c = c.resume(); + std::cout << "f1: entered second time: " << data << std::endl; + data += 1; + c = c.resume(); + std::cout << "f1: entered third time: " << data << std::endl; + return std::move( c); + }); + std::cout << "f1: returned first time: " << data << std::endl; + data += 1; + c = c.resume(); + std::cout << "f1: returned second time: " << data << std::endl; + data += 1; + c = c.resume_with( [&data](ctx::continuation && c){ + std::cout << "f2: entered: " << data << std::endl; + data = -1; + return std::move( c); + }); + std::cout << "f1: returned third time" << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/ontop_void.cpp b/src/boost/libs/context/example/callcc/ontop_void.cpp new file mode 100644 index 00000000..fdc9827b --- /dev/null +++ b/src/boost/libs/context/example/callcc/ontop_void.cpp @@ -0,0 +1,40 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <tuple> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +ctx::continuation f1( ctx::continuation && c) { + std::cout << "f1: entered first time" << std::endl; + c = c.resume(); + std::cout << "f1: entered second time" << std::endl; + c = c.resume(); + std::cout << "f1: entered third time" << std::endl; + return std::move( c); +} + +ctx::continuation f2( ctx::continuation && c) { + std::cout << "f2: entered" << std::endl; + return std::move( c); +} + +int main() { + ctx::continuation c = ctx::callcc( f1); + std::cout << "f1: returned first time" << std::endl; + c = c.resume(); + std::cout << "f1: returned second time" << std::endl; + c = c.resume_with( f2); + std::cout << "f1: returned third time" << std::endl; + + std::cout << "main: done" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/parser.cpp b/src/boost/libs/context/example/callcc/parser.cpp new file mode 100644 index 00000000..b1744f02 --- /dev/null +++ b/src/boost/libs/context/example/callcc/parser.cpp @@ -0,0 +1,128 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdio> +#include <cstdlib> +#include <exception> +#include <functional> +#include <iostream> +#include <memory> +#include <sstream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +/* + * grammar: + * P ---> E '\0' + * E ---> T {('+'|'-') T} + * T ---> S {('*'|'/') S} + * S ---> digit | '(' E ')' + */ +class Parser{ + char next; + std::istream& is; + std::function<void(char)> cb; + + char pull(){ + return std::char_traits<char>::to_char_type(is.get()); + } + + void scan(){ + do{ + next=pull(); + } + while(isspace(next)); + } + +public: + Parser(std::istream& is_,std::function<void(char)> cb_) : + next(), is(is_), cb(cb_) + {} + + void run() { + scan(); + E(); + } + +private: + void E(){ + T(); + while (next=='+'||next=='-'){ + cb(next); + scan(); + T(); + } + } + + void T(){ + S(); + while (next=='*'||next=='/'){ + cb(next); + scan(); + S(); + } + } + + void S(){ + if (isdigit(next)){ + cb(next); + scan(); + } + else if(next=='('){ + cb(next); + scan(); + E(); + if (next==')'){ + cb(next); + scan(); + }else{ + throw std::runtime_error("parsing failed"); + } + } + else{ + throw std::runtime_error("parsing failed"); + } + } +}; + +int main() { + try { + std::istringstream is("1+1"); + // execute parser in new execution context + ctx::continuation source; + // user-code pulls parsed data from parser + // invert control flow + char c; + bool done = false; + source=ctx::callcc( + [&is,&c,&done](ctx::continuation && sink){ + // create parser with callback function + Parser p( is, + [&sink,&c](char c_){ + // resume main execution context + c = c_; + sink=sink.resume(); + }); + // start recursive parsing + p.run(); + // signal termination + done = true; + // resume main execution context + return std::move(sink); + }); + while(!done){ + printf("Parsed: %c\n",c); + source=source.resume(); + } + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; + } catch (std::exception const& e) { + std::cerr << "exception: " << e.what() << std::endl; + } + return EXIT_FAILURE; +} diff --git a/src/boost/libs/context/example/callcc/segmented.cpp b/src/boost/libs/context/example/callcc/segmented.cpp new file mode 100644 index 00000000..c70de99c --- /dev/null +++ b/src/boost/libs/context/example/callcc/segmented.cpp @@ -0,0 +1,51 @@ + +// Copyright Oliver Kowalke 2014. +// 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 <cstdlib> +#include <iostream> +#include <memory> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +#ifdef BOOST_MSVC //MS VisualStudio +__declspec(noinline) void access( char *buf); +#else // GCC +void access( char *buf) __attribute__ ((noinline)); +#endif +void access( char *buf) { + buf[0] = '\0'; +} + +void bar( int i) { + char buf[4 * 1024]; + if ( i > 0) { + access( buf); + std::cout << i << ". iteration" << std::endl; + bar( i - 1); + } +} + +int main() { + int count = 100*1024; +#if defined(BOOST_USE_SEGMENTED_STACKS) + std::cout << "using segmented_stack stacks: allocates " << count << " * 4kB == " << 4 * count << "kB on stack, "; + std::cout << "initial stack size = " << ctx::segmented_stack::traits_type::default_size() / 1024 << "kB" << std::endl; + std::cout << "application should not fail" << std::endl; +#else + std::cout << "using standard stacks: allocates " << count << " * 4kB == " << 4 * count << "kB on stack, "; + std::cout << "initial stack size = " << ctx::fixedsize_stack::traits_type::default_size() / 1024 << "kB" << std::endl; + std::cout << "application might fail" << std::endl; +#endif + ctx::continuation c = ctx::callcc( + [count](ctx::continuation && c){ + bar( count); + return std::move( c); + }); + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/stack.cpp b/src/boost/libs/context/example/callcc/stack.cpp new file mode 100644 index 00000000..88793265 --- /dev/null +++ b/src/boost/libs/context/example/callcc/stack.cpp @@ -0,0 +1,25 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +int main() { + std::cout << "minimum stack size: " << ctx::stack_traits::minimum_size() << " byte\n"; + std::cout << "default stack size: " << ctx::stack_traits::default_size() << " byte\n"; + std::cout << "maximum stack size: "; + if ( ctx::stack_traits::is_unbounded() ) { + std::cout << "unlimited\n"; + } else { + std::cout << ctx::stack_traits::maximum_size() << " byte\n"; + } + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/callcc/throw.cpp b/src/boost/libs/context/example/callcc/throw.cpp new file mode 100644 index 00000000..723a956b --- /dev/null +++ b/src/boost/libs/context/example/callcc/throw.cpp @@ -0,0 +1,47 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <exception> +#include <iostream> +#include <stdexcept> +#include <string> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +struct my_exception : public std::runtime_error { + ctx::continuation c; + my_exception( ctx::continuation && c_, std::string const& what) : + std::runtime_error{ what }, + c{ std::move( c_) } { + } +}; + +int main() { + ctx::continuation c = ctx::callcc([](ctx::continuation && c) { + for (;;) { + try { + std::cout << "entered" << std::endl; + c = c.resume(); + } catch ( my_exception & ex) { + std::cerr << "my_exception: " << ex.what() << std::endl; + return std::move( ex.c); + } + } + return std::move( c); + }); + c = c.resume_with( + [](ctx::continuation && c){ + throw my_exception(std::move( c), "abc"); + return std::move( c); + }); + + std::cout << "main: done" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/Jamfile.v2 b/src/boost/libs/context/example/fiber/Jamfile.v2 new file mode 100644 index 00000000..e827eff6 --- /dev/null +++ b/src/boost/libs/context/example/fiber/Jamfile.v2 @@ -0,0 +1,83 @@ +# Boost.Context Library Examples Jamfile + +# Copyright Oliver Kowalke 2014. +# 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) + +# For more information, see http://www.boost.org/ + +import common ; +import feature ; +import indirect ; +import modules ; +import os ; +import toolset ; +import architecture ; + +project boost/context/example/fiber + : requirements + <library>/boost/context//boost_context + <toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack + <toolset>gcc,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS + <toolset>clang,<segmented-stacks>on:<cxxflags>-fsplit-stack + <toolset>clang,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS + <link>static + <threading>multi + ; + +exe stack + : stack.cpp + ; + +exe jump_void + : jump_void.cpp + ; + +exe jump + : jump.cpp + ; + +exe jump_mov + : jump_mov.cpp + ; + +exe ontop_void + : ontop_void.cpp + ; + +exe throw + : throw.cpp + ; + +exe fibonacci + : fibonacci.cpp + ; + +exe parser + : parser.cpp + ; + +exe ontop + : ontop.cpp + ; + +exe endless_loop + : endless_loop.cpp + ; + +exe segmented + : segmented.cpp + ; + +exe circle + : circle.cpp + ; + +#exe backtrace +# : backtrace.cpp +# ; + +#exe echosse +# : echosse.cpp +# ; diff --git a/src/boost/libs/context/example/fiber/backtrace.cpp b/src/boost/libs/context/example/fiber/backtrace.cpp new file mode 100644 index 00000000..42c739bb --- /dev/null +++ b/src/boost/libs/context/example/fiber/backtrace.cpp @@ -0,0 +1,57 @@ + +// Copyright Oliver Kowalke 2016. +// 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) + +#define UNW_LOCAL_ONLY + +#include <cstdlib> +#include <iostream> + +#include <libunwind.h> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +void backtrace() { + unw_cursor_t cursor; + unw_context_t context; + unw_getcontext( & context); + unw_init_local( & cursor, & context); + while ( 0 < unw_step( & cursor) ) { + unw_word_t offset, pc; + unw_get_reg( & cursor, UNW_REG_IP, & pc); + if ( 0 == pc) { + break; + } + std::cout << "0x" << pc << ":"; + + char sym[256]; + if ( 0 == unw_get_proc_name( & cursor, sym, sizeof( sym), & offset) ) { + std::cout << " (" << sym << "+0x" << offset << ")" << std::endl; + } else { + std::cout << " -- error: unable to obtain symbol name for this frame" << std::endl; + } + } +} + +void bar() { + backtrace(); +} + +void foo() { + bar(); +} + +ctx::fiber f1( ctx::fiber && c) { + foo(); + return std::move( c); +} + +int main() { + ctx::fiber{ f1 }.resume(); + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/circle.cpp b/src/boost/libs/context/example/fiber/circle.cpp new file mode 100644 index 00000000..ed1cba63 --- /dev/null +++ b/src/boost/libs/context/example/fiber/circle.cpp @@ -0,0 +1,44 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <list> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +int main() { + ctx::fiber f1, f2, f3; + f3 = ctx::fiber{[&](ctx::fiber && f)->ctx::fiber{ + f2 = std::move( f); + for (;;) { + std::cout << "f3\n"; + f2 = std::move( f1).resume(); + } + return {}; + }}; + f2 = ctx::fiber{[&](ctx::fiber && f)->ctx::fiber{ + f1 = std::move( f); + for (;;) { + std::cout << "f2\n"; + f1 = std::move( f3).resume(); + } + return {}; + }}; + f1 = ctx::fiber{[&](ctx::fiber && /*main*/)->ctx::fiber{ + for (;;) { + std::cout << "f1\n"; + f3 = std::move( f2).resume(); + } + return {}; + }}; + std::move( f1).resume(); + + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/echosse.cpp b/src/boost/libs/context/example/fiber/echosse.cpp new file mode 100644 index 00000000..e4f6deba --- /dev/null +++ b/src/boost/libs/context/example/fiber/echosse.cpp @@ -0,0 +1,46 @@ + +// 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) + +#include <cstddef> +#include <cstdlib> +#include <cstring> +#include <iostream> +#include <emmintrin.h> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +void echoSSE( int i) { + __m128i xmm; + xmm = _mm_set_epi32( i, i + 1, i + 2, i + 3); + uint32_t v32[4]; + memcpy( & v32, & xmm, 16); + std::cout << v32[0]; + std::cout << v32[1]; + std::cout << v32[2]; + std::cout << v32[3]; +} + + +int main( int argc, char * argv[]) { + int i = 0; + ctx::fiber f{ + [&i](ctx::fiber && f) { + for (;;) { + std::cout << i; + echoSSE( i); + std::cout << " "; + f = std::move( f).resume(); + } + return std::move( f); + }}; + for (; i < 11; ++i) { + f = std::move( f).resume(); + } + std::cout << "\nmain: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/endless_loop.cpp b/src/boost/libs/context/example/fiber/endless_loop.cpp new file mode 100644 index 00000000..0ce434dd --- /dev/null +++ b/src/boost/libs/context/example/fiber/endless_loop.cpp @@ -0,0 +1,30 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +ctx::fiber bar( ctx::fiber && f) { + do { + std::cout << "bar\n"; + f = std::move( f).resume(); + } while ( f); + return std::move( f); +} + +int main() { + ctx::fiber f{ bar }; + do { + std::cout << "foo\n"; + f = std::move( f).resume(); + } while ( f); + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/fibonacci.cpp b/src/boost/libs/context/example/fiber/fibonacci.cpp new file mode 100644 index 00000000..a664c6f4 --- /dev/null +++ b/src/boost/libs/context/example/fiber/fibonacci.cpp @@ -0,0 +1,36 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <memory> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +int main() { + int a; + ctx::fiber f{ + [&a](ctx::fiber && f){ + a=0; + int b=1; + for(;;){ + f = std::move( f).resume(); + int next=a+b; + a=b; + b=next; + } + return std::move( f); + }}; + for ( int j = 0; j < 10; ++j) { + f = std::move( f).resume(); + std::cout << a << " "; + } + std::cout << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/jump.cpp b/src/boost/libs/context/example/fiber/jump.cpp new file mode 100644 index 00000000..59b592c1 --- /dev/null +++ b/src/boost/libs/context/example/fiber/jump.cpp @@ -0,0 +1,35 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +int main() { + int data = 1; + ctx::fiber f{ + [&data](ctx::fiber && f){ + std::cout << "entered first time: " << data << std::endl; + data += 2; + f = std::move( f).resume(); + std::cout << "entered second time: " << data << std::endl; + return std::move( f); + }}; + f = std::move( f).resume(); + std::cout << "returned first time: " << data << std::endl; + data += 2; + f = std::move( f).resume(); + if ( f) { + std::cout << "returned second time: " << data << std::endl; + } else { + std::cout << "returned second time: execution context terminated" << std::endl; + } + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/jump_mov.cpp b/src/boost/libs/context/example/fiber/jump_mov.cpp new file mode 100644 index 00000000..fc9bc4fe --- /dev/null +++ b/src/boost/libs/context/example/fiber/jump_mov.cpp @@ -0,0 +1,59 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +class moveable { +public: + int value; + + moveable() : + value( -1) { + } + + moveable( int v) : + value( v) { + } + + moveable( moveable && other) { + std::swap( value, other.value); + } + + moveable & operator=( moveable && other) { + if ( this == & other) return * this; + value = other.value; + other.value = -1; + return * this; + } + + moveable( moveable const& other) = delete; + moveable & operator=( moveable const& other) = delete; +}; + +int main() { + moveable data{ 1 }; + ctx::fiber f{ std::allocator_arg, ctx::fixedsize_stack{}, + [&data](ctx::fiber && f){ + std::cout << "entered first time: " << data.value << std::endl; + data = std::move( moveable{ 3 }); + f = std::move( f).resume(); + std::cout << "entered second time: " << data.value << std::endl; + data = std::move( moveable{}); + return std::move( f); + }}; + f = std::move( f).resume(); + std::cout << "returned first time: " << data.value << std::endl; + data.value = 5; + f = std::move( f).resume(); + std::cout << "returned second time: " << data.value << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/jump_void.cpp b/src/boost/libs/context/example/fiber/jump_void.cpp new file mode 100644 index 00000000..b4e9f39e --- /dev/null +++ b/src/boost/libs/context/example/fiber/jump_void.cpp @@ -0,0 +1,29 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +ctx::fiber f1( ctx::fiber && f) { + std::cout << "f1: entered first time" << std::endl; + f = std::move( f).resume(); + std::cout << "f1: entered second time" << std::endl; + return std::move( f); +} + +int main() { + ctx::fiber f{ f1 }; + f = std::move( f).resume(); + std::cout << "f1: returned first time" << std::endl; + f = std::move( f).resume(); + std::cout << "f1: returned second time" << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/ontop.cpp b/src/boost/libs/context/example/fiber/ontop.cpp new file mode 100644 index 00000000..9e4a1f40 --- /dev/null +++ b/src/boost/libs/context/example/fiber/ontop.cpp @@ -0,0 +1,41 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <tuple> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +int main() { + int data = 0; + ctx::fiber f{ [&data](ctx::fiber && f) { + std::cout << "f1: entered first time: " << data << std::endl; + data += 1; + f = std::move( f).resume(); + std::cout << "f1: entered second time: " << data << std::endl; + data += 1; + f = std::move( f).resume(); + std::cout << "f1: entered third time: " << data << std::endl; + return std::move( f); + }}; + f = std::move( f).resume(); + std::cout << "f1: returned first time: " << data << std::endl; + data += 1; + f = std::move( f).resume(); + std::cout << "f1: returned second time: " << data << std::endl; + data += 1; + f = std::move( f).resume_with([&data](ctx::fiber && f){ + std::cout << "f2: entered: " << data << std::endl; + data = -1; + return std::move( f); + }); + std::cout << "f1: returned third time" << std::endl; + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/ontop_void.cpp b/src/boost/libs/context/example/fiber/ontop_void.cpp new file mode 100644 index 00000000..b43cd2d7 --- /dev/null +++ b/src/boost/libs/context/example/fiber/ontop_void.cpp @@ -0,0 +1,41 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> +#include <tuple> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +ctx::fiber f1( ctx::fiber && f) { + std::cout << "f1: entered first time" << std::endl; + f = std::move( f).resume(); + std::cout << "f1: entered second time" << std::endl; + f = std::move( f).resume(); + std::cout << "f1: entered third time" << std::endl; + return std::move( f); +} + +ctx::fiber f2( ctx::fiber && f) { + std::cout << "f2: entered" << std::endl; + return std::move( f); +} + +int main() { + ctx::fiber f{ f1 }; + f = std::move( f).resume(); + std::cout << "f1: returned first time" << std::endl; + f = std::move( f).resume(); + std::cout << "f1: returned second time" << std::endl; + f = std::move( f).resume_with( f2); + std::cout << "f1: returned third time" << std::endl; + + std::cout << "main: done" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/parser.cpp b/src/boost/libs/context/example/fiber/parser.cpp new file mode 100644 index 00000000..fb1121b5 --- /dev/null +++ b/src/boost/libs/context/example/fiber/parser.cpp @@ -0,0 +1,127 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdio> +#include <cstdlib> +#include <exception> +#include <functional> +#include <iostream> +#include <memory> +#include <sstream> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +/* + * grammar: + * P ---> E '\0' + * E ---> T {('+'|'-') T} + * T ---> S {('*'|'/') S} + * S ---> digit | '(' E ')' + */ +class Parser{ + char next; + std::istream& is; + std::function<void(char)> cb; + + char pull(){ + return std::char_traits<char>::to_char_type(is.get()); + } + + void scan(){ + do{ + next=pull(); + } + while(isspace(next)); + } + +public: + Parser(std::istream& is_,std::function<void(char)> cb_) : + next(), is(is_), cb(cb_) + {} + + void run() { + scan(); + E(); + } + +private: + void E(){ + T(); + while (next=='+'||next=='-'){ + cb(next); + scan(); + T(); + } + } + + void T(){ + S(); + while (next=='*'||next=='/'){ + cb(next); + scan(); + S(); + } + } + + void S(){ + if (isdigit(next)){ + cb(next); + scan(); + } + else if(next=='('){ + cb(next); + scan(); + E(); + if (next==')'){ + cb(next); + scan(); + }else{ + throw std::runtime_error("parsing failed"); + } + } + else{ + throw std::runtime_error("parsing failed"); + } + } +}; + +int main() { + try { + std::istringstream is("1+1"); + // user-code pulls parsed data from parser + // invert control flow + char c; + bool done = false; + // execute parser in new execution context + ctx::fiber source{[&is,&c,&done](ctx::fiber && sink){ + // create parser with callback function + Parser p( is, + [&sink,&c](char c_){ + // resume main execution context + c = c_; + sink = std::move( sink).resume(); + }); + // start recursive parsing + p.run(); + // signal termination + done = true; + // resume main execution context + return std::move(sink); + }}; + source = std::move( source).resume(); + while(!done){ + printf("Parsed: %c\n",c); + source = std::move( source).resume(); + } + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; + } catch (std::exception const& e) { + std::cerr << "exception: " << e.what() << std::endl; + } + return EXIT_FAILURE; +} diff --git a/src/boost/libs/context/example/fiber/segmented.cpp b/src/boost/libs/context/example/fiber/segmented.cpp new file mode 100644 index 00000000..3d1a5c34 --- /dev/null +++ b/src/boost/libs/context/example/fiber/segmented.cpp @@ -0,0 +1,51 @@ + +// Copyright Oliver Kowalke 2014. +// 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 <cstdlib> +#include <iostream> +#include <memory> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +#ifdef BOOST_MSVC //MS VisualStudio +__declspec(noinline) void access( char *buf); +#else // GCC +void access( char *buf) __attribute__ ((noinline)); +#endif +void access( char *buf) { + buf[0] = '\0'; +} + +void bar( int i) { + char buf[4 * 1024]; + if ( i > 0) { + access( buf); + std::cout << i << ". iteration" << std::endl; + bar( i - 1); + } +} + +int main() { + int count = 100*1024; +#if defined(BOOST_USE_SEGMENTED_STACKS) + std::cout << "using segmented_stack stacks: allocates " << count << " * 4kB == " << 4 * count << "kB on stack, "; + std::cout << "initial stack size = " << ctx::segmented_stack::traits_type::default_size() / 1024 << "kB" << std::endl; + std::cout << "application should not fail" << std::endl; +#else + std::cout << "using standard stacks: allocates " << count << " * 4kB == " << 4 * count << "kB on stack, "; + std::cout << "initial stack size = " << ctx::fixedsize_stack::traits_type::default_size() / 1024 << "kB" << std::endl; + std::cout << "application might fail" << std::endl; +#endif + ctx::fiber{ + [count](ctx::fiber && f){ + bar( count); + return std::move( f); + }}.resume(); + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/stack.cpp b/src/boost/libs/context/example/fiber/stack.cpp new file mode 100644 index 00000000..88793265 --- /dev/null +++ b/src/boost/libs/context/example/fiber/stack.cpp @@ -0,0 +1,25 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <iostream> + +#include <boost/context/continuation.hpp> + +namespace ctx = boost::context; + +int main() { + std::cout << "minimum stack size: " << ctx::stack_traits::minimum_size() << " byte\n"; + std::cout << "default stack size: " << ctx::stack_traits::default_size() << " byte\n"; + std::cout << "maximum stack size: "; + if ( ctx::stack_traits::is_unbounded() ) { + std::cout << "unlimited\n"; + } else { + std::cout << ctx::stack_traits::maximum_size() << " byte\n"; + } + std::cout << "main: done" << std::endl; + return EXIT_SUCCESS; +} diff --git a/src/boost/libs/context/example/fiber/throw.cpp b/src/boost/libs/context/example/fiber/throw.cpp new file mode 100644 index 00000000..e5f1d6f6 --- /dev/null +++ b/src/boost/libs/context/example/fiber/throw.cpp @@ -0,0 +1,45 @@ + +// Copyright Oliver Kowalke 2016. +// 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 <cstdlib> +#include <exception> +#include <iostream> +#include <stdexcept> +#include <string> + +#include <boost/context/fiber.hpp> + +namespace ctx = boost::context; + +struct my_exception : public std::runtime_error { + ctx::fiber f; + my_exception( ctx::fiber && f_, std::string const& what) : + std::runtime_error{ what }, + f{ std::move( f_) } { + } +}; + +int main() { + ctx::fiber f{[](ctx::fiber && f) ->ctx::fiber { + std::cout << "entered" << std::endl; + try { + f = std::move( f).resume(); + } catch ( my_exception & ex) { + std::cerr << "my_exception: " << ex.what() << std::endl; + return std::move( ex.f); + } + return {}; + }}; + f = std::move( f).resume(); + f = std::move( f).resume_with([](ctx::fiber && f) ->ctx::fiber { + throw my_exception(std::move( f), "abc"); + return {}; + }); + + std::cout << "main: done" << std::endl; + + return EXIT_SUCCESS; +} |