early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -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
<target-os>linux,<toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack
<target-os>linux,<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
# ;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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::cout << "main: done" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -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
<target-os>linux,<toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack
<target-os>linux,<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
# ;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}