diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-04-08 03:09:47 +0000 |
---|---|---|
committer | <> | 2015-05-05 14:37:32 +0000 |
commit | f2541bb90af059680aa7036f315f052175999355 (patch) | |
tree | a5b214744b256f07e1dc2bd7273035a7808c659f /libs/context/example | |
parent | ed232fdd34968697a68783b3195b1da4226915b5 (diff) | |
download | boost-tarball-master.tar.gz |
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_58_0.tar.bz2.HEADboost_1_58_0master
Diffstat (limited to 'libs/context/example')
-rw-r--r-- | libs/context/example/Jamfile.v2 | 1 | ||||
-rw-r--r-- | libs/context/example/execution_context/Jamfile.v2 | 47 | ||||
-rw-r--r-- | libs/context/example/execution_context/fibonacci.cpp | 36 | ||||
-rw-r--r-- | libs/context/example/execution_context/jump.cpp | 44 | ||||
-rw-r--r-- | libs/context/example/execution_context/parameter.cpp | 55 | ||||
-rw-r--r-- | libs/context/example/execution_context/parser.cpp | 125 | ||||
-rw-r--r-- | libs/context/example/execution_context/segmented.cpp | 68 |
7 files changed, 376 insertions, 0 deletions
diff --git a/libs/context/example/Jamfile.v2 b/libs/context/example/Jamfile.v2 index e4d7e5466..a3bd12b7c 100644 --- a/libs/context/example/Jamfile.v2 +++ b/libs/context/example/Jamfile.v2 @@ -19,6 +19,7 @@ project boost/context/example : requirements <library>/boost/context//boost_context <link>static + <threading>multi ; rule configure ( properties * ) diff --git a/libs/context/example/execution_context/Jamfile.v2 b/libs/context/example/execution_context/Jamfile.v2 new file mode 100644 index 000000000..1b9a61068 --- /dev/null +++ b/libs/context/example/execution_context/Jamfile.v2 @@ -0,0 +1,47 @@ +# 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/execution_context + : 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 jump + : jump.cpp + ; + +exe segmented + : segmented.cpp + ; + +exe parser + : parser.cpp + ; + +exe fibonacci + : fibonacci.cpp + ; + +exe parameter + : parameter.cpp + ; diff --git a/libs/context/example/execution_context/fibonacci.cpp b/libs/context/example/execution_context/fibonacci.cpp new file mode 100644 index 000000000..7424fef89 --- /dev/null +++ b/libs/context/example/execution_context/fibonacci.cpp @@ -0,0 +1,36 @@ + +// 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 <boost/context/all.hpp> + +#define yield(x) p=x; mctx.resume(); + +int main() { + int n=35; + int p=0; + boost::context::execution_context mctx( boost::context::execution_context::current() ); + boost::context::execution_context ctx( + boost::context::fixedsize_stack(), + [n,&p,mctx]()mutable{ + int a=0; + int b=1; + while(n-->0){ + yield(a); + auto next=a+b; + a=b; + b=next; + } + }); + for(int i=0;i<10;++i){ + ctx.resume(); + std::cout<<p<<std::endl; + } + + std::cout << "main: done" << std::endl; +} diff --git a/libs/context/example/execution_context/jump.cpp b/libs/context/example/execution_context/jump.cpp new file mode 100644 index 000000000..1a48ca4ff --- /dev/null +++ b/libs/context/example/execution_context/jump.cpp @@ -0,0 +1,44 @@ + +// 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 <boost/context/all.hpp> + +boost::context::execution_context * ctx1 = nullptr; +boost::context::execution_context * ctx2 = nullptr; +boost::context::execution_context * ctx = nullptr; + +void f1( int i) { + std::cout << "f1: entered" << std::endl; + std::cout << "i == " << i << std::endl; + ctx2->resume(); + std::cout << "f1: re-entered" << std::endl; + ctx2->resume(); +} + +void f2() { + std::cout << "f2: entered" << std::endl; + ctx1->resume(); + std::cout << "f2: re-entered" << std::endl; + ctx->resume(); +} + +int main() { + boost::context::execution_context ctx1_( boost::context::fixedsize_stack(), f1, 3); + ctx1 = & ctx1_; + boost::context::execution_context ctx2_( boost::context::protected_fixedsize_stack(), f2); + ctx2 = & ctx2_; + boost::context::execution_context ctx_( boost::context::execution_context::current() ); + ctx = & ctx_; + + ctx1->resume(); + + std::cout << "main: done" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/libs/context/example/execution_context/parameter.cpp b/libs/context/example/execution_context/parameter.cpp new file mode 100644 index 000000000..c33de7382 --- /dev/null +++ b/libs/context/example/execution_context/parameter.cpp @@ -0,0 +1,55 @@ + +// 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 <exception> +#include <iostream> +#include <string> + +#include <boost/context/all.hpp> +#include <boost/lexical_cast.hpp> + +class X{ +private: + int * inp_; + std::string outp_; + std::exception_ptr excptr_; + boost::context::execution_context caller_; + boost::context::execution_context callee_; + +public: + X(): + inp_( nullptr), + outp_(), + excptr_(), + caller_(boost::context::execution_context::current()), + callee_(boost::context::fixedsize_stack(), + [=](){ + try { + int i = * inp_; + outp_ = boost::lexical_cast<std::string>(i); + caller_.resume(); + } catch (...) { + excptr_=std::current_exception(); + } + }) + {} + + std::string operator()(int i){ + inp_ = & i; + callee_.resume(); + if(excptr_){ + std::rethrow_exception(excptr_); + } + return outp_; + } +}; + +int main() { + X x; + std::cout<<x(7)<<std::endl; + std::cout << "done" << std::endl; +} diff --git a/libs/context/example/execution_context/parser.cpp b/libs/context/example/execution_context/parser.cpp new file mode 100644 index 000000000..da16fee96 --- /dev/null +++ b/libs/context/example/execution_context/parser.cpp @@ -0,0 +1,125 @@ + +// 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 <functional> +#include <iostream> +#include <sstream> + +#include <boost/context/all.hpp> + +/* + * 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 (std::isdigit(next)){ + cb(next); + scan(); + } + else if(next=='('){ + cb(next); + scan(); + E(); + if (next==')'){ + cb(next); + scan(); + }else{ + exit(2); + } + } + else{ + exit(3); + } + } +}; + +int main() { + std::istringstream is("1+1"); + bool done=false; + char c; + + // create handle to main execution context + boost::context::execution_context main_ctx( + boost::context::execution_context::current() ); + + // executes parser in new execution context + boost::context::execution_context parser_ctx( + boost::context::fixedsize_stack(), + [&main_ctx,&is,&c,&done](){ + // create parser with callback function + Parser p( is, + [&main_ctx,&c](char ch){ + c=ch; + // resume main execution context + main_ctx.resume(); + }); + // start recursive parsing + p.run(); + done=true; + main_ctx.resume(); + }); + + // user-code pulls parsed data from parser + // invert control flow + parser_ctx.resume(); + do { + printf("Parsed: %c\n",c); + parser_ctx.resume(); + } while( ! done); + + std::cout << "main: done" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/libs/context/example/execution_context/segmented.cpp b/libs/context/example/execution_context/segmented.cpp new file mode 100644 index 000000000..6f5e457d1 --- /dev/null +++ b/libs/context/example/execution_context/segmented.cpp @@ -0,0 +1,68 @@ + +// 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 <boost/config.hpp> + +#include <boost/context/all.hpp> + +#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 = 384; + +#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 = " << boost::context::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 = " << boost::context::fixedsize_stack::traits_type::default_size() / 1024 << "kB" << std::endl; + std::cout << "application might fail" << std::endl; +#endif + + boost::context::execution_context main_ctx( + boost::context::execution_context::current() ); + + boost::context::execution_context bar_ctx( +#if defined(BOOST_USE_SEGMENTED_STACKS) + boost::context::segmented_stack(), +#else + boost::context::fixedsize_stack(), +#endif + [& main_ctx, count](){ + bar( count); + main_ctx.resume(); + }); + + bar_ctx.resume(); + + std::cout << "main: done" << std::endl; + + return 0; +} |