diff options
Diffstat (limited to 'src/boost/libs/context/example/callcc')
-rw-r--r-- | src/boost/libs/context/example/callcc/Jamfile.v2 | 79 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/backtrace.cpp | 57 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/circle.cpp | 44 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/echosse.cpp | 46 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/endless_loop.cpp | 28 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/fibonacci.cpp | 36 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/jump.cpp | 35 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/jump_mov.cpp | 59 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/jump_void.cpp | 28 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/ontop.cpp | 40 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/ontop_void.cpp | 40 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/parser.cpp | 128 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/segmented.cpp | 51 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/stack.cpp | 25 | ||||
-rw-r--r-- | src/boost/libs/context/example/callcc/throw.cpp | 47 |
15 files changed, 743 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 000000000..f6bf50443 --- /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 000000000..43acc5730 --- /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 000000000..4dd403614 --- /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 000000000..4b76ffc5d --- /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 000000000..318bb88db --- /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 000000000..170b9f274 --- /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 000000000..ab5d6b739 --- /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 000000000..1f522eff6 --- /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 000000000..7cb5d41e0 --- /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 000000000..d59fde8a4 --- /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 000000000..fdc9827b2 --- /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 000000000..b1744f02c --- /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 000000000..c70de99c3 --- /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 000000000..887932650 --- /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 000000000..723a956b6 --- /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; +} |