From a46d86c566f6d2a8df5128f8ca070491614888dd Mon Sep 17 00:00:00 2001 From: Mateusz Jakub Fila Date: Wed, 19 Aug 2026 09:05:52 +0200 Subject: [PATCH 1/2] remove documentation artifacts --- .gitignore | 1 + doc/context.xml | 3913 ----------------- doc/html/context/acknowledgements.html | 49 - doc/html/context/architectures.html | 396 -- .../context/architectures/crosscompiling.html | 48 - doc/html/context/cc.html | 538 --- doc/html/context/cc/class__continuation_.html | 507 --- ...__fcontext_t__ucontext_t_and_winfiber.html | 108 - doc/html/context/ecv1.html | 879 ---- doc/html/context/ecv2.html | 808 ---- doc/html/context/ff.html | 522 --- doc/html/context/ff/class__fiber_.html | 506 --- ...__fcontext_t__ucontext_t_and_winfiber.html | 109 - doc/html/context/fib.html | 512 --- doc/html/context/fib/class__fiber_.html | 467 -- ...__fcontext_t__ucontext_t_and_winfiber.html | 108 - doc/html/context/overview.html | 96 - doc/html/context/performance.html | 94 - doc/html/context/rationale.html | 86 - doc/html/context/rationale/other_apis_.html | 117 - .../rationale/x86_and_floating_point_env.html | 124 - doc/html/context/reference.html | 104 - doc/html/context/requirements.html | 112 - doc/html/context/stack.html | 177 - doc/html/context/stack/fixedsize.html | 109 - doc/html/context/stack/pooled_fixedsize.html | 137 - .../context/stack/protected_fixedsize.html | 132 - doc/html/context/stack/sanitizers.html | 49 - doc/html/context/stack/segmented.html | 151 - doc/html/context/stack/stack_context.html | 84 - doc/html/context/stack/stack_traits.html | 157 - doc/html/context/stack/valgrind.html | 51 - doc/html/context/struct__preallocated_.html | 66 - doc/html/context_HTML.manifest | 27 - doc/html/index.html | 87 - 35 files changed, 1 insertion(+), 11430 deletions(-) delete mode 100644 doc/context.xml delete mode 100644 doc/html/context/acknowledgements.html delete mode 100644 doc/html/context/architectures.html delete mode 100644 doc/html/context/architectures/crosscompiling.html delete mode 100644 doc/html/context/cc.html delete mode 100644 doc/html/context/cc/class__continuation_.html delete mode 100644 doc/html/context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html delete mode 100644 doc/html/context/ecv1.html delete mode 100644 doc/html/context/ecv2.html delete mode 100644 doc/html/context/ff.html delete mode 100644 doc/html/context/ff/class__fiber_.html delete mode 100644 doc/html/context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html delete mode 100644 doc/html/context/fib.html delete mode 100644 doc/html/context/fib/class__fiber_.html delete mode 100644 doc/html/context/fib/implementations__fcontext_t__ucontext_t_and_winfiber.html delete mode 100644 doc/html/context/overview.html delete mode 100644 doc/html/context/performance.html delete mode 100644 doc/html/context/rationale.html delete mode 100644 doc/html/context/rationale/other_apis_.html delete mode 100644 doc/html/context/rationale/x86_and_floating_point_env.html delete mode 100644 doc/html/context/reference.html delete mode 100644 doc/html/context/requirements.html delete mode 100644 doc/html/context/stack.html delete mode 100644 doc/html/context/stack/fixedsize.html delete mode 100644 doc/html/context/stack/pooled_fixedsize.html delete mode 100644 doc/html/context/stack/protected_fixedsize.html delete mode 100644 doc/html/context/stack/sanitizers.html delete mode 100644 doc/html/context/stack/segmented.html delete mode 100644 doc/html/context/stack/stack_context.html delete mode 100644 doc/html/context/stack/stack_traits.html delete mode 100644 doc/html/context/stack/valgrind.html delete mode 100644 doc/html/context/struct__preallocated_.html delete mode 100644 doc/html/context_HTML.manifest delete mode 100644 doc/html/index.html diff --git a/.gitignore b/.gitignore index b72f9be2..12cd3d29 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *~ *.swp +doc/html diff --git a/doc/context.xml b/doc/context.xml deleted file mode 100644 index fb4931d1..00000000 --- a/doc/context.xml +++ /dev/null @@ -1,3913 +0,0 @@ - - - - - - - Oliver Kowalke - - - - 2014 Oliver Kowalke - - - - 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) - - - - C++ Library for switching different user ctx - - - - Context -
- <link linkend="context.overview">Overview</link> - - Boost.Context is a foundational library that - provides a sort of cooperative multitasking on a single thread. By providing - an abstraction of the current execution state in the current thread, including - the stack (with local variables) and stack pointer, all registers and CPU flags, - and the instruction pointer, a execution context represents a specific point - in the application's execution path. This is useful for building higher-level - abstractions, like coroutines, cooperative threads - (userland threads) or an equivalent to C# - keyword yield in C++. - - - callcc()/continuation - provides the means to suspend the current execution path and to transfer execution - control, thereby permitting another context to run on the current thread. This - state full transfer mechanism enables a context to suspend execution from within - nested functions and, later, to resume from where it was suspended. While the - execution path represented by a continuation - only runs on a single thread, it can be migrated to another thread at any given - time. - - - A context switch - between threads requires system calls (involving the OS kernel), which can - cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring control - vias callcc()/continuation - requires only few CPU cycles because it does not involve system calls as it - is done within a single thread. - - - All functions and classes are contained in the namespace boost::context. - - - - This library requires C++11! - - - - - Windows using fcontext_t: turn off global program optimization (/GL) and - change /EHsc (compiler assumes that functions declared as extern "C" - never throw a C++ exception) to /EHs (tells compiler assumes that functions - declared as extern "C" may throw an exception). - - -
-
- <link linkend="context.requirements">Requirements</link> - - If Boost.Context uses fcontext_t (the default) - as its implementation, it must be built for the particular compiler(s) and - CPU architecture(s) being targeted. Using fcontext_t, - Boost.Context includes assembly code and, - therefore, requires GNU as and GNU preprocessor for supported POSIX systems, - MASM for Windows/x86 systems and ARMasm for Windows/arm systems. - - - - MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit. - - - - - Please note that address-model=64 must be - given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit - code will be generated. - - - - - For cross-compiling the lib you must specify certain additional properties - at bjam command line: target-os, abi, binary-format, - architecture and address-model. - - - - - Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must - be specified at bjam command line. - - - - - Windows using fcontext_t: turn off global program optimization (/GL) and - change /EHsc (compiler assumes that functions declared as extern "C" - never throw a C++ exception) to /EHs (tells compiler assumes that functions - declared as extern "C" may throw an exception). - - - - Because this library uses C++11 extensively, it requires a compatible compiler. - Known minimum working versions are as follows: Microsoft Visual Studio 2015 - (msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other - compilers may work, if they support the following language features: auto declarations, - constexpr, defaulted functions, final, hdr thread, hdr tuple, lambdas, noexcept, - nullptr, rvalue references, template aliases. thread local, variadic templates. - -
-
- <anchor id="ff"/><link linkend="context.ff">Context switching with fibers</link> - - - fiber is the reference implementation of C++ proposal - P0876R0: - fibers without scheduler. - - - - A fiber represents the state of the control flow of a - program at a given point in time. Fibers can be suspended and resumed later - in order to change the control flow of a program. - - - Modern micro-processors are registers machines; the content of processor registers - represent a fiber of the executed program at a given point in time. Operating - systems simulate parallel execution of programs on a single processor by switching - between programs (context switch) by preserving and restoring the fiber, e.g. - the content of all registers. - - - fiber - - - fiber captures the current fiber - (the rest of the computation; code after fiber) - and triggers a context switch. The context switch is achieved by preserving - certain registers (including instruction and stack pointer), defined by the - calling convention of the ABI, of the current fiber and restoring those registers - of the resumed fiber. The control flow of the resumed fiber continues. The - current fiber is suspended and passed as argument to the resumed fiber. - - - fiber expects a context-function - with signature 'fiber(fiber && f)'. - The parameter f represents - the current fiber from which this fiber was resumed (e.g. that has called - fiber). - - - On return the context-function of the current fiber has - to specify an fiber to which - the execution control is transferred after termination of the current fiber. - - - If an instance with valid state goes out of scope and the context-function - has not yet returned, the stack is traversed in order to access the control - structure (address stored at the first stack frame) and fiber's stack is deallocated - via the StackAllocator. - - - - Segmented stacks are - supported by fiber using - ucontext_t. - - - - fiber represents a fiber; - it contains the content of preserved registers and manages the associated stack - (allocation/deallocation). fiber - is a one-shot fiber - it can be used only once, after calling continuation::resume() - or continuation::resume_with() it is invalidated. - - - fiber is only move-constructible - and move-assignable. - - - As a first-class object fiber - can be applied to and returned from a function, assigned to a variable or stored - in a container. - - - A fiber is continued by calling resume()/resume_with(). - - - Usage - -namespace ctx=boost::context; -int a; -ctx::fiber source{[&a](ctx::fiber&& sink){ - a=0; - int b=1; - for(;;){ - sink=std::move(sink).resume(); - int next=a+b; - a=b; - b=next; - } - return std::move(sink); -}}; -for (int j=0;j<10;++j) { - source=std::move(source).resume(); - std::cout << a << " "; -} - -output: - 0 1 1 2 3 5 8 13 21 34 - - - This simple example demonstrates the basic usage of fiber - as a generator. The fiber sink - represents the main-fiber (function main()). sink - is captured (current-fiber) by invoking fiber - and passed as parameter to the lambda. - - - Because the state is invalidated (one-shot fiber) by each call of continuation::resume(), - the new state of the fiber, - returned by continuation::resume(), needs to be assigned - to sink after each call. In - order to express the invalidation of the resumed fiber, the member functions - resume() - and resume_with() - are rvalue-ref qualified. Both functions bind only to rvalues. Thus an lvalue - fiber must be casted to an rvalue via std::move(). - - - The lambda that calculates the Fibonacci numbers is executed inside the fiber - represented by source. Calculated - Fibonacci numbers are transferred between the two fibers via variable a (lambda capture reference). - - - The locale variables b and - next remain their values during - each context switch. This is possible due source - has its own stack and the stack is exchanged by each context switch. - - - Parameter - passing - - - Data can be transferred between two fibers via global pointers, calling wrappers - (like std::bind) or lambda captures. - -namespace ctx=boost::context; -int i=1; -ctx::fiber f1{[&i](ctx::fiber&& f2){ - std::printf("inside f1,i==%d\n",i); - i+=1; - return std::move(f2).resume(); -}}; -f1=std::move(f1).resume(); -std::printf("i==%d\n",i); - -output: - inside c1,i==1 - i==2 - - - f1.resume() - enters the lambda in fiber represented by f1 - with lambda capture reference i=1. The expression - f2.resume() - resumes the fiber f2. On return - of f1.resume(), - the variable i has the value - of i+1. - - - Exception - handling - - - If the function executed inside a context-function emits - an exception, the application is terminated by calling std::terminate(). std::exception_ptr - can be used to transfer exceptions between different fibers. - - - - Do not jump from inside a catch block and then re-throw the exception in - another fiber. - - - - - Executing - function on top of a fiber - - - Sometimes it is useful to execute a new function on top of a resumed fiber. - For this purpose continuation::resume_with() has to be - used. The function passed as argument must accept a rvalue reference to fiber and return void. - -namespace ctx=boost::context; -int data=0; -ctx::fiber f1{[&data](ctx::fiber&& f2) { - std::cout << "f1: entered first time: " << data << std::endl; - data+=1; - f2=std::move(f2).resume(); - std::cout << "f1: entered second time: " << data << std::endl; - data+=1; - f2=std::move(f2).resume(); - std::cout << "f1: entered third time: " << data << std::endl; - return std::move(f2); -}}; -f1=std::move(f1).resume(); -std::cout << "f1: returned first time: " << data << std::endl; -data+=1; -f1=std::move(f1).resume(); -std::cout << "f1: returned second time: " << data << std::endl; -data+=1; -f1=f1.resume_with([&data](ctx::fiber&& f2){ - std::cout << "f2: entered: " << data << std::endl; - data=-1; - return std::move(f2); -}); -std::cout << "f1: returned third time" << std::endl; - -output: - f1: entered first time: 0 - f1: returned first time: 1 - f1: entered second time: 2 - f1: returned second time: 3 - f2: entered: 4 - f1: entered third time: -1 - f1: returned third time - - - The expression f1.resume_with(...) - executes a lambda on top of fiber f1, - e.g. an additional stack frame is allocated on top of the stack. This lambda - assigns -1 - to data and returns to the - second invocation of f1.resume(). - - - Another option is to execute a function on top of the fiber that throws an - exception. - -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_) } { - } -}; - -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 {}; -}); - -output: - entered - my_exception: abc - - - In this exception my_exception - is throw from a function invoked on-top of fiber f - and catched inside the for-loop. - - - Stack - unwinding - - - On construction of fiber a stack - is allocated. If the context-function returns the stack - will be destructed. If the context-function has not yet - returned and the destructor of an valid fiber - instance (e.g. fiber::operator bool() returns true) is called, the stack will be destructed - too. - - - - Code executed by context-function must not prevent the - propagation ofs the detail::forced_unwind exception. - Absorbing that exception will cause stack unwinding to fail. Thus, any code - that catches all exceptions must re-throw any pending detail::forced_unwind - exception. - - - - - Allocating - control structures on top of stack - - - Allocating control structures on top of the stack requires to allocated the - stack_context and create the control structure with placement - new before fiber is created. - - - - The user is responsible for destructing the control structure at the top - of the stack. - - -namespace ctx=boost::context; -// stack-allocator used for (de-)allocating stack -fixedsize_stack salloc(4048); -// allocate stack space -stack_context sctx(salloc.allocate()); -// reserve space for control structure on top of the stack -void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure); -std::size_t size=sctx.size-sizeof(my_control_structure); -// placement new creates control structure on reserved space -my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc); -... -// destructing the control structure -cs->~my_control_structure(); -... -struct my_control_structure { - // captured fiber - ctx::fiber f; - - template< typename StackAllocator > - my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) : - // create captured fiber - f{std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func} { - } - ... -}; - - - Inverting - the control flow - -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"); - } - } -}; - -std::istringstream is("1+1"); -// user-code pulls parsed data from parser -// invert control flow -char c; -bool done=false; -// execute parser in new fiber -ctx::fiber source{[&is,&c,&done](ctx::fiber&& sink){ - // create parser with callback function - Parser p(is, - [&sink,&c](char c_){ - // resume main fiber - c=c_; - sink=std::move(sink).resume(); - }); - // start recursive parsing - p.run(); - // signal termination - done=true; - // resume main fiber - return std::move(sink); -}}; -source=std::move(source).resume(); -while(!done){ - printf("Parsed: %c\n",c); - source=std::Move(source).resume(); -} - -output: - Parsed: 1 - Parsed: + - Parsed: 1 - - - In this example a recursive descent parser uses a callback to emit a newly - passed symbol. Using fiber the - control flow can be inverted, e.g. the user-code pulls parsed symbols from - the parser - instead to get pushed from the parser (via callback). - - - The data (character) is transferred between the two fibers. - -
- <anchor id="implementation"/><link linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber">Implementations: - fcontext_t, ucontext_t and WinFiber</link> - - fcontext_t - - - The implementation uses fcontext_t per default. fcontext_t - is based on assembler and not available for all platforms. It provides a - much better performance than ucontext_t (the context - switch takes two magnitudes of order less CPU cycles; see section performance) - and WinFiber. - - - - Because the TIB (thread information block on Windows) is not fully described - in the MSDN, it might be possible that not all required TIB-parts are swapped. - Using WinFiber implementation might be an alternative. - - - - ucontext_t - - - As an alternative, ucontext_t - can be used by compiling with BOOST_USE_UCONTEXT - and b2 property context-impl=ucontext. - ucontext_t might be available on a broader range of - POSIX-platforms but has some disadvantages - (for instance deprecated since POSIX.1-2003, not C99 conform). - - - - fiber supports Segmented - stacks only with ucontext_t as its - implementation. - - - - WinFiber - - - With BOOST_USE_WINFIB and - b2 property context-impl=winfib - Win32-Fibers are used as implementation for fiber. - - - - The first call of fiber - converts the thread into a Windows fiber by invoking ConvertThreadToFiber(). If desired, ConvertFiberToThread() has to be called by the user explicitly - in order to release resources allocated by ConvertThreadToFiber() (e.g. after using boost.context). - - -
-
- <link linkend="context.ff.class__fiber_">Class <code><phrase role="identifier">fiber</phrase></code></link> -#include <boost/context/fiber.hpp> - -class fiber { -public: - fiber() noexcept; - - template<typename Fn> - fiber(Fn && fn); - - template<typename StackAlloc, typename Fn> - fiber(std::allocator_arg_t, StackAlloc && salloc, Fn && fn); - - ~fiber(); - - fiber(fiber && other) noexcept; - - fiber & operator=(fiber && other) noexcept; - - fiber(fiber const& other) noexcept = delete; - fiber & operator=(fiber const& other) noexcept = delete; - - fiber resume() &&; - - template<typename Fn> - fiber resume_with(Fn && fn) &&; - - explicit operator bool() const noexcept; - - bool operator!() const noexcept; - - bool operator==(fiber const& other) const noexcept; - - bool operator!=(fiber const& other) const noexcept; - - bool operator<(fiber const& other) const noexcept; - - bool operator>(fiber const& other) const noexcept; - - bool operator<=(fiber const& other) const noexcept; - - bool operator>=(fiber const& other) const noexcept; - - template<typename charT,class traitsT> - friend std::basic_ostream<charT,traitsT> & - operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other) { - - void swap(fiber & other) noexcept; -}; - - - - - Constructor - - -fiber() noexcept; - - - - - Effects: - - - Creates a invalid fiber. - - - - - Throws: - - - Nothing. - - - - - - - - Constructor - - -template<typename Fn> -fiber(Fn && fn); - -template<typename StackAlloc, typename Fn> -fiber(std::allocator_arg_t, StackAlloc && salloc, Fn && fn); - - - - - Effects: - - - Creates a new fiber and prepares the context to execute fn. fixedsize_stack - is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()). - The constructor with argument type preallocated, - is used to create a user defined data (for - instance additional control structures) on top of the stack. - - - - - - - - Destructor - - -~fiber(); - - - - - Effects: - - - Destructs the associated stack if *this is a valid fiber, e.g. fiber::operator - bool() returns true. - - - - - Throws: - - - Nothing. - - - - - - - - Move - constructor - - -fiber(fiber && other) noexcept; - - - - - Effects: - - - Moves underlying capture fiber to *this. - - - - - Throws: - - - Nothing. - - - - - - - - Move assignment - operator - - -fiber & operator=(fiber && other) noexcept; - - - - - Effects: - - - Moves the state of other - to *this - using move semantics. - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator()() - - -fiber resume() &&; - -template<typename Fn> -fiber resume_with(Fn && fn) &&; - - - - - Effects: - - - Captures current fiber and resumes *this. The function resume_with, - is used to execute function fn - in the execution context of *this (e.g. the stack frame of fn is allocated on stack of *this). - - - - - Returns: - - - The fiber representing the fiber that has been suspended. - - - - - Note: - - - Because *this - gets invalidated, resume() and resume_with() are rvalue-ref qualified and bind - only to rvalues. - - - - - Note: - - - Function fn needs to - return fiber. - - - - - Note: - - - The returned fiber indicates if the suspended fiber has terminated - (return from context-function) via bool - operator(). - - - - - - - - Member function - operator bool() - - -explicit operator bool() const noexcept; - - - - - Returns: - - - true if *this - points to a captured fiber. - - - - - Throws: - - - Nothing. - - - - - - - - Member function operator!() - - -bool operator!() const noexcept; - - - - - Returns: - - - true if *this - does not point to a captured fiber. - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator==() - - -bool operator==(fiber const& other) const noexcept; - - - - - Returns: - - - true if *this - and other represent - the same fiber, false - otherwise. - - - - - Throws: - - - Nothing. - - - - - - - - Member - function operator!=() - - -bool operator!=(fiber const& other) const noexcept; - - - - - Returns: - - - ! (other == * this) - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator<() - - -bool operator<(fiber const& other) const noexcept; - - - - - Returns: - - - true if *this != other - is true and the implementation-defined total order of fiber values places *this - before other, false - otherwise. - - - - - Throws: - - - Nothing. - - - - - - - - Member - function operator>() - - -bool operator>(fiber const& other) const noexcept; - - - - - Returns: - - - other < - * this - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator<=() - - -bool operator<=(fiber const& other) const noexcept; - - - - - Returns: - - - ! (other < - * this) - - - - - Throws: - - - Nothing. - - - - - - - - Member - function operator>=() - - -bool operator>=(fiber const& other) const noexcept; - - - - - Returns: - - - ! (* - this < - other) - - - - - Throws: - - - Nothing. - - - - - - - - Non-member function operator<<() - - -template<typename charT,class traitsT> -std::basic_ostream<charT,traitsT> & -operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other); - - - - - Effects: - - - Writes the representation of other - to stream os. - - - - - Returns: - - - os - - - - -
-
-
- <anchor id="cc"/><link linkend="context.cc">Context switching with call/cc</link> - - - call/cc is the reference implementation of C++ proposal - P0534R3: - call/cc (call-with-current-continuation): A low-level API for stackful context - switching. - - - - call/cc (call with current continuation) is a universal - control operator (well-known from the programming language Scheme) that captures - the current continuation as a first-class object and pass it as an argument - to another continuation. - - - A continuation (abstract concept of functional programming languages) represents - the state of the control flow of a program at a given point in time. Continuations - can be suspended and resumed later in order to change the control flow of a - program. - - - Modern micro-processors are registers machines; the content of processor registers - represent a continuation of the executed program at a given point in time. - Operating systems simulate parallel execution of programs on a single processor - by switching between programs (context switch) by preserving and restoring - the continuation, e.g. the content of all registers. - - - callcc() - - - callcc() is the C++ equivalent - to Scheme's call/cc operator. It captures the current - continuation (the rest of the computation; code after callcc()) - and triggers a context switch. The context switch is achieved by preserving - certain registers (including instruction and stack pointer), defined by the - calling convention of the ABI, of the current continuation and restoring those - registers of the resumed continuation. The control flow of the resumed continuation - continues. The current continuation is suspended and passed as argument to - the resumed continuation. - - - callcc() expects a context-function - with signature 'continuation(continuation && - c)'. The parameter c - represents the current continuation from which this continuation was resumed - (e.g. that has called callcc()). - - - On return the context-function of the current continuation - has to specify an continuation - to which the execution control is transferred after termination of the current - continuation. - - - If an instance with valid state goes out of scope and the context-function - has not yet returned, the stack is traversed in order to access the control - structure (address stored at the first stack frame) and continuation's stack - is deallocated via the StackAllocator. - - - - Segmented stacks are - supported by callcc() using - ucontext_t. - - - - continuation - - - continuation represents a continuation; - it contains the content of preserved registers and manages the associated stack - (allocation/deallocation). continuation - is a one-shot continuation - it can be used only once, after calling continuation::resume() - or continuation::resume_with() it is invalidated. - - - continuation is only move-constructible - and move-assignable. - - - As a first-class object continuation - can be applied to and returned from a function, assigned to a variable or stored - in a container. - - - A continuation is continued by calling resume()/resume_with(). - - - Usage - -namespace ctx=boost::context; -int a; -ctx::continuation source=ctx::callcc( - [&a](ctx::continuation && sink){ - a=0; - int b=1; - for(;;){ - sink=sink.resume(); - int next=a+b; - a=b; - b=next; - } - return std::move(sink); - }); -for (int j=0;j<10;++j) { - std::cout << a << " "; - source=source.resume(); -} - -output: - 0 1 1 2 3 5 8 13 21 34 - - - This simple example demonstrates the basic usage of call/cc - as a generator. The continuation sink - represents the main-continuation (function main()). - sink is captured (current-continuation) - by invoking callcc() and passed - as parameter to the lambda. - - - Because the state is invalidated (one-shot continuation) by each call of continuation::resume(), - the new state of the continuation, - returned by continuation::resume(), needs to be assigned - to sink after each call. - - - The lambda that calculates the Fibonacci numbers is executed inside the continuation - represented by source. Calculated - Fibonacci numbers are transferred between the two continuations via variable - a (lambda capture reference). - - - The locale variables b and - next remain their values during - each context switch. This is possible due source - has its own stack and the stack is exchanged by each context switch. - - - Parameter - passing - - - Data can be transferred between two continuations via global pointers, calling - wrappers (like std::bind) or lambda captures. - -namespace ctx=boost::context; -int i=1; -ctx::continuation c1=callcc([&i](ctx::continuation && c2){ - std::printf("inside c1,i==%d\n",i); - i+=1; - return c2.resume(); - }); -std::printf("i==%d\n",i); - -output: - inside c1,i==1 - i==2 - - - callcc(<lambda>) - enters the lambda in continuation represented by c1 - with lambda capture reference i=1. The expression - c2.resume() - resumes the continuation c2. - On return of callcc(<lambda>), - the variable i has the value - of i+1. - - - Exception - handling - - - If the function executed inside a context-function emits - an exception, the application is terminated by calling std::terminate(). std::exception_ptr - can be used to transfer exceptions between different continuations. - - - - Do not jump from inside a catch block and then re-throw the exception in - another continuation. - - - - - Executing - function on top of a continuation - - - Sometimes it is useful to execute a new function on top of a resumed continuation. - For this purpose continuation::resume_with() has to be - used. The function passed as argument must accept a rvalue reference to continuation and return void. - -namespace ctx=boost::context; -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; - -output: - f1: entered first time: 0 - f1: returned first time: 1 - f1: entered second time: 2 - f1: returned second time: 3 - f2: entered: 4 - f1: entered third time: -1 - f1: returned third time - - - The expression c.resume_with(...) - executes a lambda on top of continuation c, - e.g. an additional stack frame is allocated on top of the stack. This lambda - assigns -1 - to data and returns to the - second invocation of c.resume(). - - - Another option is to execute a function on top of the continuation that throws - an exception. - -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_) } { - } -}; - -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); - }); - -output: - entered - my_exception: abc - - - In this exception my_exception - is throw from a function invoked on-top of continuation c - and catched inside the for-loop. - - - Stack - unwinding - - - On construction of continuation - a stack is allocated. If the context-function returns - the stack will be destructed. If the context-function - has not yet returned and the destructor of an valid continuation - instance (e.g. continuation::operator bool() returns - true) is called, the stack will - be destructed too. - - - - Code executed by context-function must not prevent the - propagation ofs the detail::forced_unwind exception. - Absorbing that exception will cause stack unwinding to fail. Thus, any code - that catches all exceptions must re-throw any pending detail::forced_unwind - exception. - - - - - Allocating - control structures on top of stack - - - Allocating control structures on top of the stack requires to allocated the - stack_context and create the control structure with placement - new before continuation is created. - - - - The user is responsible for destructing the control structure at the top - of the stack. - - -namespace ctx=boost::context; -// stack-allocator used for (de-)allocating stack -fixedsize_stack salloc(4048); -// allocate stack space -stack_context sctx(salloc.allocate()); -// reserve space for control structure on top of the stack -void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure); -std::size_t size=sctx.size-sizeof(my_control_structure); -// placement new creates control structure on reserved space -my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc); -... -// destructing the control structure -cs->~my_control_structure(); -... -struct my_control_structure { - // captured continuation - ctx::continuation c; - - template< typename StackAllocator > - my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) : - // create captured continuation - c{} { - c=ctx::callcc(std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func); - } - ... -}; - - - Inverting - the control flow - -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"); - } - } -}; - -std::istringstream is("1+1"); -// execute parser in new continuation -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 continuation - c=c_; - sink=sink.resume(); - }); - // start recursive parsing - p.run(); - // signal termination - done=true; - // resume main continuation - return std::move(sink); - }); -while(!done){ - printf("Parsed: %c\n",c); - source=source.resume(); -} - -output: - Parsed: 1 - Parsed: + - Parsed: 1 - - - In this example a recursive descent parser uses a callback to emit a newly - passed symbol. Using call/cc the control flow can be inverted, - e.g. the user-code pulls parsed symbols from the parser - instead to get pushed - from the parser (via callback). - - - The data (character) is transferred between the two continuations. - -
- <anchor id="implementation0"/><link linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber">Implementations: - fcontext_t, ucontext_t and WinFiber</link> - - fcontext_t - - - The implementation uses fcontext_t per default. fcontext_t - is based on assembler and not available for all platforms. It provides a - much better performance than ucontext_t (the context - switch takes two magnitudes of order less CPU cycles; see section performance) - and WinFiber. - - - - Because the TIB (thread information block on Windows) is not fully described - in the MSDN, it might be possible that not all required TIB-parts are swapped. - Using WinFiber implementation might be an alternative. - - - - ucontext_t - - - As an alternative, ucontext_t - can be used by compiling with BOOST_USE_UCONTEXT - and b2 property context-impl=ucontext. - ucontext_t might be available on a broader range of - POSIX-platforms but has some disadvantages - (for instance deprecated since POSIX.1-2003, not C99 conform). - - - - callcc() supports Segmented stacks only with - ucontext_t as its implementation. - - - - WinFiber - - - With BOOST_USE_WINFIB and - b2 property context-impl=winfib - Win32-Fibers are used as implementation for callcc(). - - - - The first call of callcc() - converts the thread into a Windows fiber by invoking ConvertThreadToFiber(). If desired, ConvertFiberToThread() has to be called by the user explicitly - in order to release resources allocated by ConvertThreadToFiber() (e.g. after using boost.context). - - -
-
- <link linkend="context.cc.class__continuation_">Class <code><phrase - role="identifier">continuation</phrase></code></link> -#include <boost/context/continuation.hpp> - -class continuation { -public: - continuation() noexcept = default; - - ~continuation(); - - continuation(continuation && other) noexcept; - - continuation & operator=(continuation && other) noexcept; - - continuation(continuation const& other) noexcept = delete; - continuation & operator=(continuation const& other) noexcept = delete; - - continuation resume(); - - template<typename Fn> - continuation resume_with(Fn && fn); - - explicit operator bool() const noexcept; - - bool operator!() const noexcept; - - bool operator==(continuation const& other) const noexcept; - - bool operator!=(continuation const& other) const noexcept; - - bool operator<(continuation const& other) const noexcept; - - bool operator>(continuation const& other) const noexcept; - - bool operator<=(continuation const& other) const noexcept; - - bool operator>=(continuation const& other) const noexcept; - - template<typename charT,class traitsT> - friend std::basic_ostream<charT,traitsT> & - operator<<(std::basic_ostream<charT,traitsT> & os,continuation const& other) { - - void swap(continuation & other) noexcept; -}; - - - - - Constructor - - -continuation() noexcept; - - - - - Effects: - - - Creates a invalid continuation. - - - - - Throws: - - - Nothing. - - - - - - - - Destructor - - -~continuation(); - - - - - Effects: - - - Destructs the associated stack if *this is a valid continuation, e.g. - continuation::operator bool() returns true. - - - - - Throws: - - - Nothing. - - - - - - - - Move - constructor - - -continuation(continuation && other) noexcept; - - - - - Effects: - - - Moves underlying capture continuation to *this. - - - - - Throws: - - - Nothing. - - - - - - - - Move assignment - operator - - -continuation & operator=(continuation && other) noexcept; - - - - - Effects: - - - Moves the state of other - to *this - using move semantics. - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator()() - - -continuation resume(); - -template<typename Fn> -continuation resume_with(Fn && fn); - - - - - Effects: - - - Captures current continuation and resumes *this. The function resume_with, - is used to execute function fn - in the execution context of *this (e.g. the stack frame of fn is allocated on stack of *this). - - - - - Returns: - - - The continuation representing the continuation that has been suspended. - - - - - Note: - - - Function fn needs to - return continuation. - - - - - Note: - - - The returned continuation indicates if the suspended continuation has - terminated (return from context-function) via bool - operator(). - - - - - - - - Member function - operator bool() - - -explicit operator bool() const noexcept; - - - - - Returns: - - - true if *this - points to a captured continuation. - - - - - Throws: - - - Nothing. - - - - - - - - Member function operator!() - - -bool operator!() const noexcept; - - - - - Returns: - - - true if *this - does not point to a captured continuation. - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator==() - - -bool operator==(continuation const& other) const noexcept; - - - - - Returns: - - - true if *this - and other represent - the same continuation, false - otherwise. - - - - - Throws: - - - Nothing. - - - - - - - - Member - function operator!=() - - -bool operator!=(continuation const& other) const noexcept; - - - - - Returns: - - - ! (other == * this) - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator<() - - -bool operator<(continuation const& other) const noexcept; - - - - - Returns: - - - true if *this != other - is true and the implementation-defined total order of continuation values places *this - before other, false - otherwise. - - - - - Throws: - - - Nothing. - - - - - - - - Member - function operator>() - - -bool operator>(continuation const& other) const noexcept; - - - - - Returns: - - - other < - * this - - - - - Throws: - - - Nothing. - - - - - - - - Member function - operator<=() - - -bool operator<=(continuation const& other) const noexcept; - - - - - Returns: - - - ! (other < - * this) - - - - - Throws: - - - Nothing. - - - - - - - - Member - function operator>=() - - -bool operator>=(continuation const& other) const noexcept; - - - - - Returns: - - - ! (* - this < - other) - - - - - Throws: - - - Nothing. - - - - - - - - Non-member function operator<<() - - -template<typename charT,class traitsT> -std::basic_ostream<charT,traitsT> & -operator<<(std::basic_ostream<charT,traitsT> & os,continuation const& other); - - - - - Effects: - - - Writes the representation of other - to stream os. - - - - - Returns: - - - os - - - - - - Call - with current continuation - -#include <boost/context/continuation.hpp> - -template<typename Fn> -continuation callcc(Fn && fn); - -template<typename StackAlloc,typename Fn> -continuation callcc(std::allocator_arg_t,StackAlloc salloc,Fn && fn); - -template<typename StackAlloc,typename Fn> -continuation callcc(std::allocator_arg_t,preallocated palloc,StackAlloc salloc,Fn && fn); - - - - - Effects: - - - Captures current continuation and creates a new continuation prepared - to execute fn. fixedsize_stack is used as default - stack allocator (stack size == fixedsize_stack::traits::default_size()). - The function with argument type preallocated, - is used to create a user defined data (for - instance additional control structures) on top of the stack. - - - - - Returns: - - - The continuation representing the contexcontinuation that has been - suspended. - - - - - Note: - - - The returned continuation indicates if the suspended continuation has - terminated (return from context-function) via bool - operator(). - - - - -
-
-
- <anchor id="stack"/><link linkend="context.stack">Stack allocation</link> - - The memory used by the stack is allocated/deallocated via a StackAllocator - which is required to model a stack-allocator concept. - - - stack-allocator - concept - - - A StackAllocator must satisfy the stack-allocator - concept requirements shown in the following table, in which a is an object of a StackAllocator - type, sctx is a stack_context, and size - is a std::size_t: - - - - - - - - expression - - - - - return type - - - - - notes - - - - - - - - - a(size) - - - - - - - creates a stack allocator - - - - - - - a.allocate() - - - - - stack_context - - - - - creates a stack - - - - - - - a.deallocate( - sctx) - - - - - void - - - - - deallocates the stack created by a.allocate() - - - - - - - - - The implementation of allocate() might include logic to protect against - exceeding the context's available stack size rather than leaving it as undefined - behaviour. - - - - - Calling deallocate() - with a stack_context not - set by allocate() - results in undefined behaviour. - - - - - Depending on the architecture allocate() stores an address from the top of the stack - (growing downwards) or the bottom of the stack (growing upwards). - - -
- <link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link> - - Boost.Context provides the class protected_fixedsize_stack - which models the stack-allocator concept. It appends - a guard page at the end of each stack to protect against exceeding the stack. - If the guard page is accessed (read or write operation) a segmentation fault/access - violation is generated by the operating system. - - - - Using protected_fixedsize_stack is expensive. That - is, launching a new coroutine with a new stack is expensive; the allocated - stack is just as efficient to use as any other stack. - - - - - The appended guard page - is not mapped to physical memory, only - virtual addresses are used. - - -#include <boost/context/protected_fixedsize.hpp> - -template< typename traitsT > -struct basic_protected_fixedsize { - typedef traitT traits_type; - - basic_protected_fixesize(std::size_t size = traits_type::default_size()); - - stack_context allocate(); - - void deallocate( stack_context &); -} - -typedef basic_protected_fixedsize< stack_traits > protected_fixedsize - - - stack_context allocate() - - - - - Preconditions: - - - traits_type::minimum:size() - <= size - and ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= size). - - - - - Effects: - - - Allocates memory of at least size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. - - - - - - void deallocate( stack_context - & sctx) - - - - - Preconditions: - - - sctx.sp is valid, traits_type::minimum:size() <= sctx.size and ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). - - - - - Effects: - - - Deallocates the stack space. - - - - -
-
- <link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link> - - Boost.Context provides the class pooled_fixedsize_stack - which models the stack-allocator concept. In contrast - to protected_fixedsize_stack it does not append a guard - page at the end of each stack. The memory is managed internally by boost::pool<>. - -#include <boost/context/pooled_fixedsize_stack.hpp> - -template< typename traitsT > -struct basic_pooled_fixedsize_stack { - typedef traitT traits_type; - - basic_pooled_fixedsize_stack(std::size_t stack_size = traits_type::default_size(), std::size_t next_size = 32, std::size_t max_size = 0); - - stack_context allocate(); - - void deallocate( stack_context &); -} - -typedef basic_pooled_fixedsize_stack< stack_traits > pooled_fixedsize_stack; - - - basic_pooled_fixedsize_stack(std::size_t - stack_size, - std::size_t next_size, std::size_t max_size) - - - - - Preconditions: - - - ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= stack_size) - and 0 < - nest_size. - - - - - Effects: - - - Allocates memory of at least stack_size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. Argument next_size - determines the number of stacks to request from the system the first - time that *this - needs to allocate system memory. The third argument max_size - controls how many memory might be allocated for stacks - a value of - zero means no upper limit. - - - - - - stack_context allocate() - - - - - Preconditions: - - - ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= stack_size). - - - - - Effects: - - - Allocates memory of at least stack_size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. - - - - - - void deallocate( stack_context - & sctx) - - - - - Preconditions: - - - sctx.sp is valid, ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). - - - - - Effects: - - - Deallocates the stack space. - - - - -
-
- <link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link> - - Boost.Context provides the class fixedsize_stack - which models the stack-allocator concept. In contrast - to protected_fixedsize_stack it does not append a guard - page at the end of each stack. The memory is simply managed by std::malloc() and std::free(). - -#include <boost/context/fixedsize_stack.hpp> - -template< typename traitsT > -struct basic_fixedsize_stack { - typedef traitT traits_type; - - basic_fixesize_stack(std::size_t size = traits_type::default_size()); - - stack_context allocate(); - - void deallocate( stack_context &); -} - -typedef basic_fixedsize_stack< stack_traits > fixedsize_stack; - - - stack_context allocate() - - - - - Preconditions: - - - traits_type::minimum:size() - <= size - and ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= size). - - - - - Effects: - - - Allocates memory of at least size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. - - - - - - void deallocate( stack_context - & sctx) - - - - - Preconditions: - - - sctx.sp is valid, traits_type::minimum:size() <= sctx.size and ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). - - - - - Effects: - - - Deallocates the stack space. - - - - -
-
- <anchor id="segmented"/><link linkend="context.stack.segmented">Class - <emphasis>segmented_stack</emphasis></link> - - Boost.Context supports usage of a segmented_stack, e. g. the - size of the stack grows on demand. The coroutine is created with a minimal - stack size and will be increased as required. Class segmented_stack - models the stack-allocator concept. In contrast to - protected_fixedsize_stack and fixedsize_stack - it creates a stack which grows on demand. - - - - Segmented stacks are currently only supported by gcc - from version 4.7 clang - from version 3.4 onwards. In order to - use a segmented_stack Boost.Context - must be built with property segmented-stacks, - e.g. toolset=gcc segmented-stacks=on and - applying BOOST_USE_SEGMENTED_STACKS - at b2/bjam command line. - - - - - Segmented stacks can only be used with callcc() - (using ucontext_t) - - - - . - -#include <boost/context/segmented_stack.hpp> - -template< typename traitsT > -struct basic_segmented_stack { - typedef traitT traits_type; - - basic_segmented_stack(std::size_t size = traits_type::default_size()); - - stack_context allocate(); - - void deallocate( stack_context &); -} - -typedef basic_segmented_stack< stack_traits > segmented_stack; - - - stack_context allocate() - - - - - Preconditions: - - - traits_type::minimum:size() - <= size - and ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= size). - - - - - Effects: - - - Allocates memory of at least size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. - - - - - - void deallocate( stack_context - & sctx) - - - - - Preconditions: - - - sctx.sp is valid, traits_type::minimum:size() <= sctx.size and ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). - - - - - Effects: - - - Deallocates the stack space. - - - - - - - If the library is compiled for segmented stacks, segmented_stack - is the only available stack allocator. - - -
-
- <link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link> - - stack_traits models a stack-traits - providing a way to access certain properties defined by the environment. Stack - allocators use stack-traits to allocate stacks. - -#include <boost/context/stack_traits.hpp> - -struct stack_traits { - static bool is_unbounded() noexcept; - - static std::size_t page_size() noexcept; - - static std::size_t default_size() noexcept; - - static std::size_t minimum_size() noexcept; - - static std::size_t maximum_size() noexcept; -} - - - static bool is_unbounded() - - - - - Returns: - - - Returns true if the environment - defines no limit for the size of a stack. - - - - - Throws: - - - Nothing. - - - - - - static std::size_t page_size() - - - - - Returns: - - - Returns the page size in bytes. - - - - - Throws: - - - Nothing. - - - - - - static std::size_t default_size() - - - - - Returns: - - - Returns a default stack size, which may be platform specific. If the - stack is unbounded then the present implementation returns the maximum - of 64 kB - and minimum_size(). - - - - - Throws: - - - Nothing. - - - - - - static std::size_t minimum_size() - - - - - Returns: - - - Returns the minimum size in bytes of stack defined by the environment - (Win32 4kB/Win64 8kB, defined by rlimit on POSIX). - - - - - Throws: - - - Nothing. - - - - - - static std::size_t maximum_size() - - - - - Preconditions: - - - is_unbounded() - returns false. - - - - - Returns: - - - Returns the maximum size in bytes of stack defined by the environment. - - - - - Throws: - - - Nothing. - - - - -
-
- <link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link> - - Boost.Context provides the class stack_context - which will contain the stack pointer and the size of the stack. In case of - a segmented_stack, - stack_context contains some extra control structures. - -struct stack_context { - void * sp; - std::size_t size; - - // might contain additional control structures - // for segmented stacks -} - - - void * sp - - - - - Value: - - - Pointer to the beginning of the stack. - - - - - - std::size_t - size - - - - - Value: - - - Actual size of the stack. - - - - -
-
- <link linkend="context.stack.valgrind">Support for valgrind</link> - - Running programs that switch stacks under valgrind causes problems. Property - (b2 command-line) valgrind=on let - valgrind treat the memory regions as stack space which suppresses the errors. - Users must define BOOST_USE_VALGRIND - before including any Boost.Context headers when linking against Boost binaries - compiled with valgrind=on. - -
-
- <link linkend="context.stack.sanitizers">Support for sanitizers</link> - - Sanitizers (GCC/Clang) are confused by the stack switches. The library is - required to be compiled with property (b2 command-line) context-impl=ucontext and compilers sanitizer options. - Users must define BOOST_USE_ASAN - before including any Boost.Context headers when linking against Boost binaries. - -
-
-
- <link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link> -struct preallocated { - void * sp; - std::size_t size; - stack_context sctx; - - preallocated( void * sp, std:size_t size, stack_allocator sctx) noexcept; -}; - - - Constructor - -preallocated( void * sp, std:size_t size, stack_allocator sctx) noexcept; - - - - - Effects: - - - Creates an object of preallocated. - - - - -
-
- <anchor id="performance"/><link linkend="context.performance">Performance</link> - - Performance measurements were taken using std::chrono::highresolution_clock, - with overhead corrections. The code was compiled with gcc-6.3.1, using build - options: variant = release, optimization = speed. Tests were executed on dual - Intel XEON E5 2620v4 2.2GHz, 16C/32T, 64GB RAM, running Linux (x86_64). - - - Performance of context switch - - - - - - callcc()/continuation (fcontext_t) - - - - - callcc()/continuation (ucontext_t) - - - - - callcc()/continuation (Windows-Fiber) - - - - - - - - - 9 ns / 19 CPU cycles - - - - - 547 ns / 1130 CPU cycles - - - - - 49 ns / 98 CPU cycles - - - - - -
-
-
- <link linkend="context.architectures">Architectures</link> - - Boost.Context, using fcontext_t, - supports following architectures: - - - Supported architectures (<ABI|binary format>) - - - - - - Architecture - - - - - LINUX (UNIX) - - - - - Windows - - - - - MacOS X - - - - - iOS - - - - - - - - - arm (aarch32) - - - - - AAPCS|ELF - - - - - AAPCS|PE - - - - - - - - - - - AAPCS|MACH-O - - - - - - - arm (aarch64) - - - - - AAPCS|ELF - - - - - - - - - - - - - - - - - AAPCS|MACH-O - - - - - - - i386 - - - - - SYSV|ELF - - - - - MS|PE - - - - - SYSV|MACH-O - - - - - - - - - - - - - loongarch64 - - - - - SYSV|ELF - - - - - - - - - - - - - - - - - - - - - - - - - mips - - - - - O32,N64|ELF - - - - - - - - - - - - - - - - - - - - - - - - - ppc32 - - - - - SYSV|ELF,XCOFF - - - - - - - - - - - SYSV|MACH-O - - - - - - - - - - - - - ppc64 - - - - - SYSV|ELF,XCOFF - - - - - - - - - - - SYSV|MACH-O - - - - - - - - - - - - - riscv64 - - - - - SYSV|ELF - - - - - - - - - - - SYSV - - - - - - - - - - - - - s390x - - - - - SYSV|ELF - - - - - - - - - - - - - - - - - - - - - - - - - sparc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - x86_64 - - - - - SYSV,X32|ELF - - - - - MS|PE - - - - - SYSV|MACH-O - - - - - - - - - - - -
- - - If the architecture is not supported but the platform provides ucontext_t, - Boost.Context should be compiled with BOOST_USE_UCONTEXT and b2 property context-impl=ucontext. - - -
- <link linkend="context.architectures.crosscompiling">Cross compiling</link> - - Cross compiling the library requires to specify the build properties <architecture>, - <address-model>, <binary-format> and <abi> at b2 command - line. - -
-
-
- <link linkend="context.rationale">Rationale</link> - - No - inline-assembler - - - Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support - inline assembler. - - MSDN article - 'Inline Assembler' - - . Inlined assembler generates code bloating which is not welcome - on embedded systems. - - - fcontext_t - - - Boost.Context provides the low level API fcontext_t - which is implemented in assembler to provide context swapping operations. fcontext_t - is the part to port to new platforms. - - - - Context switches do not preserve the signal mask on UNIX systems. - - - - fcontext_t is an opaque pointer. - -
- <link linkend="context.rationale.other_apis_">Other APIs </link> - - setjmp()/longjmp() - - - C99 defines setjmp()/longjmp() - to provide non-local jumps but it does not require that longjmp() - preserves the current stack frame. Therefore, jumping into a function which - was exited via a call to longjmp() is undefined - - ISO/IEC 9899:1999, 2005, 7.13.2.1:2 - - . - - - - ucontext_t - - - Since POSIX.1-2004 ucontext_t - is deprecated and was removed in POSIX.1-2008! The function signature of - makecontext() - is: - -void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...); - - - The third argument of makecontext() specifies the number of integer arguments - that follow which will require function pointer cast if func - will accept those arguments which is undefined in C99 - - ISO/IEC 9899:1999, 2005, J.2 - - . - - - The arguments in the var-arg list are required to be integers, passing pointers - in var-arg list is not guaranteed to work, especially it will fail for architectures - where pointers are larger than integers. - - - ucontext_t preserves signal - mask between context switches which involves system calls consuming a lot - of CPU cycles (ucontext_t is slower; a context switch takes two - magnitutes of order more CPU cycles more than fcontext_t). - - - Windows - fibers - - - A drawback of Windows Fiber API is that CreateFiber() does not accept a pointer to user allocated - stack space preventing the reuse of stacks for other context instances. Because - the Windows Fiber API requires to call ConvertThreadToFiber() if SwitchFiber() is called for a thread which has not been - converted to a fiber. For the same reason ConvertFiberToThread() must be called after return from SwitchFiber() - if the thread was forced to be converted to a fiber before (which is inefficient). - -if ( ! is_a_fiber() ) -{ - ConvertThreadToFiber( 0); - SwitchToFiber( ctx); - ConvertFiberToThread(); -} - - - If the condition _WIN32_WINNT >= _WIN32_WINNT_VISTA - is met function IsThreadAFiber() is provided in order to detect if the current - thread was already converted. Unfortunately Windows XP + SP 2/3 defines - _WIN32_WINNT >= - _WIN32_WINNT_VISTA without providing - IsThreadAFiber(). - -
-
- <link linkend="context.rationale.x86_and_floating_point_env">x86 and - floating-point env</link> - - i386 - - - "The FpCsr and the MxCsr register must be saved and restored before - any call or return by any procedure that needs to modify them ..." - - - 'Calling Conventions', Agner Fog - - . - - - x86_64 - - - Windows - - - MxCsr - "A callee that modifies any of the non-volatile fields within - MxCsr must restore them before returning to its caller. Furthermore, a caller - that has modified any of these fields must restore them to their standard - values before invoking a callee ..." - - MSDN - article 'MxCsr' - - . - - - FpCsr - "A callee that modifies any of the fields within FpCsr must - restore them before returning to its caller. Furthermore, a caller that has - modified any of these fields must restore them to their standard values before - invoking a callee ..." - - MSDN - article 'FpCsr' - - . - - - "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved - across context switches. There is no explicit calling convention for these - registers." - - MSDN - article 'Legacy Floating-Point Support' - - . - - - "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7". - - - 'Calling Conventions', Agner Fog - - . - - - "XMM6-XMM15 must be preserved" - - MSDN - article 'Register Usage' - - - - - SysV - - - "The control bits of the MxCsr register are callee-saved (preserved - across calls), while the status bits are caller-saved (not preserved). The - x87 status word register is caller-saved, whereas the x87 control word (FpCsr) - is callee-saved." - - SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, - 3.2.1 - - . - -
-
-
- <link linkend="context.reference">Reference</link> - - ARM - - - - - AAPCS ABI: Procedure Call Standard for the ARM Architecture - - - - - AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement - - - - - MIPS - - - - - O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement - - - - - PowerPC32 - - - - - SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement - - - - - PowerPC64 - - - - - SYSV ABI: PowerPC User Instruction Set Architecture, Book I - - - - - X86-32 - - - - - SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture - Processor Supplement - - - - - MS PE: Calling - Conventions - - - - - X86-64 - - - - - SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor - Supplement - - - - - MS PE: x64 - Software Conventions - - - -
-
- <link linkend="context.acknowledgements">Acknowledgments</link> - - I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins, - Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull, - Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin - Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente - J. Botet Escriba, Wayne Piekarski. - -
-
diff --git a/doc/html/context/acknowledgements.html b/doc/html/context/acknowledgements.html deleted file mode 100644 index ac785ab9..00000000 --- a/doc/html/context/acknowledgements.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Acknowledgments - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHome -
-
- -

- I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins, - Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull, - Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin - Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente - J. Botet Escriba, Wayne Piekarski. -

-
- - - -
-
-
-PrevUpHome -
- - diff --git a/doc/html/context/architectures.html b/doc/html/context/architectures.html deleted file mode 100644 index f461e24e..00000000 --- a/doc/html/context/architectures.html +++ /dev/null @@ -1,396 +0,0 @@ - - - -Architectures - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -

- Boost.Context, using fcontext_t, - supports following architectures: -

-
-

Table 1.2. Supported architectures (<ABI|binary format>)

-
------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- Architecture -

-
-

- LINUX (UNIX) -

-
-

- Windows -

-
-

- MacOS X -

-
-

- iOS -

-
-

- arm (aarch32) -

-
-

- AAPCS|ELF -

-
-

- AAPCS|PE -

-
-

- - -

-
-

- AAPCS|MACH-O -

-
-

- arm (aarch64) -

-
-

- AAPCS|ELF -

-
-

- - -

-
-

- - -

-
-

- AAPCS|MACH-O -

-
-

- i386 -

-
-

- SYSV|ELF -

-
-

- MS|PE -

-
-

- SYSV|MACH-O -

-
-

- - -

-
-

- loongarch64 -

-
-

- SYSV|ELF -

-
-

- - -

-
-

- - -

-
-

- - -

-
-

- mips -

-
-

- O32,N64|ELF -

-
-

- - -

-
-

- - -

-
-

- - -

-
-

- ppc32 -

-
-

- SYSV|ELF,XCOFF -

-
-

- - -

-
-

- SYSV|MACH-O -

-
-

- - -

-
-

- ppc64 -

-
-

- SYSV|ELF,XCOFF -

-
-

- - -

-
-

- SYSV|MACH-O -

-
-

- - -

-
-

- riscv64 -

-
-

- SYSV|ELF -

-
-

- - -

-
-

- SYSV -

-
-

- - -

-
-

- s390x -

-
-

- SYSV|ELF -

-
-

- - -

-
-

- - -

-
-

- - -

-
-

- sparc -

-
-

- - -

-
-

- - -

-
-

- - -

-
-

- - -

-
-

- x86_64 -

-
-

- SYSV,X32|ELF -

-
-

- MS|PE -

-
-

- SYSV|MACH-O -

-
-

- - -

-
-
-
- - - - - -
[Note]Note

- If the architecture is not supported but the platform provides ucontext_t, - Boost.Context should be compiled with BOOST_USE_UCONTEXT and b2 property context-impl=ucontext. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/architectures/crosscompiling.html b/doc/html/context/architectures/crosscompiling.html deleted file mode 100644 index 9e219f00..00000000 --- a/doc/html/context/architectures/crosscompiling.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -Cross compiling - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Cross compiling the library requires to specify the build properties <architecture>, - <address-model>, <binary-format> and <abi> at b2 command - line. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/cc.html b/doc/html/context/cc.html deleted file mode 100644 index 91edca8a..00000000 --- a/doc/html/context/cc.html +++ /dev/null @@ -1,538 +0,0 @@ - - - -Context switching with call/cc - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- - - - - -
[Note]Note

- call/cc is the reference implementation of C++ proposal - P0534R3: - call/cc (call-with-current-continuation): A low-level API for stackful context - switching. -

-

- call/cc (call with current continuation) is a universal - control operator (well-known from the programming language Scheme) that captures - the current continuation as a first-class object and pass it as an argument - to another continuation. -

-

- A continuation (abstract concept of functional programming languages) represents - the state of the control flow of a program at a given point in time. Continuations - can be suspended and resumed later in order to change the control flow of a - program. -

-

- Modern micro-processors are registers machines; the content of processor registers - represent a continuation of the executed program at a given point in time. - Operating systems simulate parallel execution of programs on a single processor - by switching between programs (context switch) by preserving and restoring - the continuation, e.g. the content of all registers. -

-

- - callcc() -

-

- callcc() is the C++ equivalent - to Scheme's call/cc operator. It captures the current - continuation (the rest of the computation; code after callcc()) - and triggers a context switch. The context switch is achieved by preserving - certain registers (including instruction and stack pointer), defined by the - calling convention of the ABI, of the current continuation and restoring those - registers of the resumed continuation. The control flow of the resumed continuation - continues. The current continuation is suspended and passed as argument to - the resumed continuation. -

-

- callcc() expects a context-function - with signature 'continuation(continuation && - c)'. The parameter c - represents the current continuation from which this continuation was resumed - (e.g. that has called callcc()). -

-

- On return the context-function of the current continuation - has to specify an continuation - to which the execution control is transferred after termination of the current - continuation. -

-

- If an instance with valid state goes out of scope and the context-function - has not yet returned, the stack is traversed in order to access the control - structure (address stored at the first stack frame) and continuation's stack - is deallocated via the StackAllocator. -

-
- - - - - -
[Note]Note

- Segmented stacks are - supported by callcc() using - ucontext_t. -

-

- - continuation -

-

- continuation represents a continuation; - it contains the content of preserved registers and manages the associated stack - (allocation/deallocation). continuation - is a one-shot continuation - it can be used only once, after calling continuation::resume() - or continuation::resume_with() it is invalidated. -

-

- continuation is only move-constructible - and move-assignable. -

-

- As a first-class object continuation - can be applied to and returned from a function, assigned to a variable or stored - in a container. -

-

- A continuation is continued by calling resume()/resume_with(). -

-

- - Usage -

-
namespace ctx=boost::context;
-int a;
-ctx::continuation source=ctx::callcc(
-    [&a](ctx::continuation && sink){
-        a=0;
-        int b=1;
-        for(;;){
-            sink=sink.resume();
-            int next=a+b;
-            a=b;
-            b=next;
-        }
-        return std::move(sink);
-    });
-for (int j=0;j<10;++j) {
-    std::cout << a << " ";
-    source=source.resume();
-}
-
-output:
-    0 1 1 2 3 5 8 13 21 34
-
-

- This simple example demonstrates the basic usage of call/cc - as a generator. The continuation sink - represents the main-continuation (function main()). - sink is captured (current-continuation) - by invoking callcc() and passed - as parameter to the lambda. -

-

- Because the state is invalidated (one-shot continuation) by each call of continuation::resume(), - the new state of the continuation, - returned by continuation::resume(), needs to be assigned - to sink after each call. -

-

- The lambda that calculates the Fibonacci numbers is executed inside the continuation - represented by source. Calculated - Fibonacci numbers are transferred between the two continuations via variable - a (lambda capture reference). -

-

- The locale variables b and - next remain their values during - each context switch. This is possible due source - has its own stack and the stack is exchanged by each context switch. -

-

- - Parameter - passing -

-

- Data can be transferred between two continuations via global pointers, calling - wrappers (like std::bind) or lambda captures. -

-
namespace ctx=boost::context;
-int i=1;
-ctx::continuation c1=callcc([&i](ctx::continuation && c2){
-            std::printf("inside c1,i==%d\n",i);
-            i+=1;
-            return c2.resume();
-        });
-std::printf("i==%d\n",i);
-
-output:
-    inside c1,i==1
-    i==2
-
-

- callcc(<lambda>) - enters the lambda in continuation represented by c1 - with lambda capture reference i=1. The expression - c2.resume() - resumes the continuation c2. - On return of callcc(<lambda>), - the variable i has the value - of i+1. -

-

- - Exception - handling -

-

- If the function executed inside a context-function emits - an exception, the application is terminated by calling std::terminate(). std::exception_ptr - can be used to transfer exceptions between different continuations. -

-
- - - - - -
[Important]Important

- Do not jump from inside a catch block and then re-throw the exception in - another continuation. -

-

- - Executing - function on top of a continuation -

-

- Sometimes it is useful to execute a new function on top of a resumed continuation. - For this purpose continuation::resume_with() has to be - used. The function passed as argument must accept a rvalue reference to continuation and return void. -

-
namespace ctx=boost::context;
-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;
-
-output:
-    f1: entered first time: 0
-    f1: returned first time: 1
-    f1: entered second time: 2
-    f1: returned second time: 3
-    f2: entered: 4
-    f1: entered third time: -1
-    f1: returned third time
-
-

- The expression c.resume_with(...) - executes a lambda on top of continuation c, - e.g. an additional stack frame is allocated on top of the stack. This lambda - assigns -1 - to data and returns to the - second invocation of c.resume(). -

-

- Another option is to execute a function on top of the continuation that throws - an exception. -

-
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_) } {
-    }
-};
-
-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);
-       });
-
-output:
-    entered
-    my_exception: abc
-
-

- In this exception my_exception - is throw from a function invoked on-top of continuation c - and catched inside the for-loop. -

-

- - Stack - unwinding -

-

- On construction of continuation - a stack is allocated. If the context-function returns - the stack will be destructed. If the context-function - has not yet returned and the destructor of an valid continuation - instance (e.g. continuation::operator bool() returns - true) is called, the stack will - be destructed too. -

-
- - - - - -
[Important]Important

- Code executed by context-function must not prevent the - propagation ofs the detail::forced_unwind exception. - Absorbing that exception will cause stack unwinding to fail. Thus, any code - that catches all exceptions must re-throw any pending detail::forced_unwind - exception. -

-

- - Allocating - control structures on top of stack -

-

- Allocating control structures on top of the stack requires to allocated the - stack_context and create the control structure with placement - new before continuation is created. -

-
- - - - - -
[Note]Note

- The user is responsible for destructing the control structure at the top - of the stack. -

-
namespace ctx=boost::context;
-// stack-allocator used for (de-)allocating stack
-fixedsize_stack salloc(4048);
-// allocate stack space
-stack_context sctx(salloc.allocate());
-// reserve space for control structure on top of the stack
-void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure);
-std::size_t size=sctx.size-sizeof(my_control_structure);
-// placement new creates control structure on reserved space
-my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc);
-...
-// destructing the control structure
-cs->~my_control_structure();
-...
-struct my_control_structure  {
-    // captured continuation
-    ctx::continuation   c;
-
-    template< typename StackAllocator >
-    my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) :
-        // create captured continuation
-        c{} {
-        c=ctx::callcc(std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func);
-    }
-    ...
-};
-
-

- - Inverting - the control flow -

-
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");
-      }
-   }
-};
-
-std::istringstream is("1+1");
-// execute parser in new continuation
-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 continuation
-                    c=c_;
-                    sink=sink.resume();
-                 });
-            // start recursive parsing
-            p.run();
-            // signal termination
-            done=true;
-            // resume main continuation
-            return std::move(sink);
-        });
-while(!done){
-    printf("Parsed: %c\n",c);
-    source=source.resume();
-}
-
-output:
-    Parsed: 1
-    Parsed: +
-    Parsed: 1
-
-

- In this example a recursive descent parser uses a callback to emit a newly - passed symbol. Using call/cc the control flow can be inverted, - e.g. the user-code pulls parsed symbols from the parser - instead to get pushed - from the parser (via callback). -

-

- The data (character) is transferred between the two continuations. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/cc/class__continuation_.html b/doc/html/context/cc/class__continuation_.html deleted file mode 100644 index b1dad120..00000000 --- a/doc/html/context/cc/class__continuation_.html +++ /dev/null @@ -1,507 +0,0 @@ - - - -Class continuation - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
#include <boost/context/continuation.hpp>
-
-class continuation {
-public:
-    continuation() noexcept = default;
-
-    ~continuation();
-
-    continuation(continuation && other) noexcept;
-
-    continuation & operator=(continuation && other) noexcept;
-
-    continuation(continuation const& other) noexcept = delete;
-    continuation & operator=(continuation const& other) noexcept = delete;
-
-    continuation resume();
-
-    template<typename Fn>
-    continuation resume_with(Fn && fn);
-
-    explicit operator bool() const noexcept;
-
-    bool operator!() const noexcept;
-
-    bool operator==(continuation const& other) const noexcept;
-
-    bool operator!=(continuation const& other) const noexcept;
-
-    bool operator<(continuation const& other) const noexcept;
-
-    bool operator>(continuation const& other) const noexcept;
-
-    bool operator<=(continuation const& other) const noexcept;
-
-    bool operator>=(continuation const& other) const noexcept;
-
-    template<typename charT,class traitsT>
-    friend std::basic_ostream<charT,traitsT> &
-    operator<<(std::basic_ostream<charT,traitsT> & os,continuation const& other) {
-
-    void swap(continuation & other) noexcept;
-};
-
-

-

-
- - - Constructor -
-

-

-
continuation() noexcept;
-
-
-

-
-
Effects:
-

- Creates a invalid continuation. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Destructor -
-

-

-
~continuation();
-
-
-

-
-
Effects:
-

- Destructs the associated stack if *this is a valid continuation, e.g. - continuation::operator bool() returns true. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - constructor -
-

-

-
continuation(continuation && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves underlying capture continuation to *this. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move assignment - operator -
-

-

-
continuation & operator=(continuation && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves the state of other - to *this - using move semantics. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator()() -
-

-

-
continuation resume();
-
-template<typename Fn>
-continuation resume_with(Fn && fn);
-
-
-

-
-
Effects:
-

- Captures current continuation and resumes *this. The function resume_with, - is used to execute function fn - in the execution context of *this (e.g. the stack frame of fn is allocated on stack of *this). -

-
Returns:
-

- The continuation representing the continuation that has been suspended. -

-
Note:
-

- Function fn needs to - return continuation. -

-
Note:
-

- The returned continuation indicates if the suspended continuation has - terminated (return from context-function) via bool - operator(). -

-
-
-

-

-
- - - Member function - operator bool() -
-

-

-
explicit operator bool() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - points to a captured continuation. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function operator!() -
-

-

-
bool operator!() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - does not point to a captured continuation. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator==() -
-

-

-
bool operator==(continuation const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - and other represent - the same continuation, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator!=() -
-

-

-
bool operator!=(continuation const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other == * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<() -
-

-

-
bool operator<(continuation const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this != other - is true and the implementation-defined total order of continuation values places *this - before other, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>() -
-

-

-
bool operator>(continuation const& other) const noexcept;
-
-
-

-
-
Returns:
-

- other < - * this -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<=() -
-

-

-
bool operator<=(continuation const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other < - * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>=() -
-

-

-
bool operator>=(continuation const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (* - this < - other) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Non-member function operator<<() -
-

-

-
template<typename charT,class traitsT>
-std::basic_ostream<charT,traitsT> &
-operator<<(std::basic_ostream<charT,traitsT> & os,continuation const& other);
-
-
-

-
-
Effects:
-

- Writes the representation of other - to stream os. -

-
Returns:
-

- os -

-
-
-
- - Call - with current continuation -
-
#include <boost/context/continuation.hpp>
-
-template<typename Fn>
-continuation callcc(Fn && fn);
-
-template<typename StackAlloc,typename Fn>
-continuation callcc(std::allocator_arg_t,StackAlloc salloc,Fn && fn);
-
-template<typename StackAlloc,typename Fn>
-continuation callcc(std::allocator_arg_t,preallocated palloc,StackAlloc salloc,Fn && fn);
-
-
-

-
-
Effects:
-

- Captures current continuation and creates a new continuation prepared - to execute fn. fixedsize_stack is used as default - stack allocator (stack size == fixedsize_stack::traits::default_size()). - The function with argument type preallocated, - is used to create a user defined data (for - instance additional control structures) on top of the stack. -

-
Returns:
-

- The continuation representing the contexcontinuation that has been - suspended. -

-
Note:
-

- The returned continuation indicates if the suspended continuation has - terminated (return from context-function) via bool - operator(). -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html b/doc/html/context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html deleted file mode 100644 index b1c52806..00000000 --- a/doc/html/context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -Implementations: fcontext_t, ucontext_t and WinFiber - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - fcontext_t -
-

- The implementation uses fcontext_t per default. fcontext_t - is based on assembler and not available for all platforms. It provides a - much better performance than ucontext_t (the context - switch takes two magnitudes of order less CPU cycles; see section performance) - and WinFiber. -

-
- - - - - -
[Note]Note

- Because the TIB (thread information block on Windows) is not fully described - in the MSDN, it might be possible that not all required TIB-parts are swapped. - Using WinFiber implementation might be an alternative. -

-
- - ucontext_t -
-

- As an alternative, ucontext_t - can be used by compiling with BOOST_USE_UCONTEXT - and b2 property context-impl=ucontext. - ucontext_t might be available on a broader range of - POSIX-platforms but has some disadvantages - (for instance deprecated since POSIX.1-2003, not C99 conform). -

-
- - - - - -
[Note]Note

- callcc() supports Segmented stacks only with - ucontext_t as its implementation. -

-
- - WinFiber -
-

- With BOOST_USE_WINFIB and - b2 property context-impl=winfib - Win32-Fibers are used as implementation for callcc(). -

-
- - - - - -
[Note]Note

- The first call of callcc() - converts the thread into a Windows fiber by invoking ConvertThreadToFiber(). If desired, ConvertFiberToThread() has to be called by the user explicitly - in order to release resources allocated by ConvertThreadToFiber() (e.g. after using boost.context). -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/ecv1.html b/doc/html/context/ecv1.html deleted file mode 100644 index 8b31eba5..00000000 --- a/doc/html/context/ecv1.html +++ /dev/null @@ -1,879 +0,0 @@ - - - -Class execution_context (version 1) - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - - - - -
[Warning]Warning

- execution_context (v1) is deprecated (does not prevent - UB). -

-
- - - - - -
[Note]Note

- execution_context (v1) is the reference implementation - of C++ proposal P099R0: - A low-level API for stackful context switching. -

-
- - - - - -
[Note]Note

- execution_context (v1) resides in sub-namespace v1. -

-
- - - - - -
[Note]Note

- Segmented stacks (segmented-stacks=on), e.g. on demand - growing stacks, can be used with execution_context (v1). -

-

- Class execution_context encapsulates context switching - and manages the associated context' stack (allocation/deallocation). -

-

- execution_context allocates the context stack (using its - StackAllocator argument) - and creates a control structure on top of it. This structure is responsible - for managing context' stack. Instances of execution_context, - associated with a specific context, share the ownership of the control structure. - If the last reference goes out of scope, the control structure is destroyed - and the stack gets deallocated via the StackAllocator. -

-

- execution_context is copy-constructible, move-constructible, - copy-assignable and move-assignable. -

-

- execution_context maintains a static (thread-local) pointer, - accessed by execution_context::current(), pointing to - the active context. On each context switch the pointer is updated. The usage - of this global pointer makes the context switch a little bit slower (due access - of thread local storage) but has some advantages. It allows to access the control - structure of the current active context from arbitrary code paths required - in order to support segmented stacks, which require to call certain maintenance - functions (like __splitstack_getcontext() etc.) before each context switch - (each context switch exchanges the stack). -

-

- execution_context expects a function/functor with signature - void(void* vp) (vp - is the data passed at the first invocation of ecv1::operator()()). -

-

- - usage - of execution_context -

-
int n=35;
-boost::context::v1::execution_context sink(boost::context::v1::execution_context::current());
-boost::context::v1::execution_context source(
-    [n,&sink](void*)mutable{
-        int a=0;
-        int b=1;
-        while(n-->0){
-            sink(&a);
-            auto next=a+b;
-            a=b;
-            b=next;
-        }
-    });
-for(int i=0;i<10;++i){
-    std::cout<<*(int*)source()<<" ";
-}
-
-output:
-    0 1 1 2 3 5 8 13 21 34
-
-

- This simple example demonstrates the basic usage of execution_context. - The context sink, returned - by execution_context::current(), represents the main-context - (function main() running) and is one of the captured parameters - in the lambda expression. The lambda that calculates the Fibonacci numbers - is executed inside the context represented by source. - Calculated Fibonacci numbers are transferred between the two context' via expression - sink(&a) (and returned by source()). -

-

- The locale variables a, b and next - remain their values during each context switch (yield(a)). - This is possible because ctx - owns a stack (exchanged by context switch). -

-

- - inverting - the control flow -

-
/*
- * grammar:
- *   P ---> E '\0'
- *   E ---> T {('+'|'-') T}
- *   T ---> S {('*'|'/') S}
- *   S ---> digit | '(' E ')'
- */
-class Parser{
-    // implementation omitted; see examples directory
-};
-
-std::istringstream is("1+1");
-bool done=false;
-std::exception_ptr except;
-
-// create handle to main execution context
-auto main_ctx(boost::context::v1::execution_context::current());
-// execute parser in new execution context
-boost::context::v1::execution_context source(
-        [&sink,&is,&done,&except](void*){
-        // create parser with callback function
-        Parser p(is,
-                 [&sink](char ch){
-                        // resume main execution context
-                        sink(&ch);
-                });
-            try {
-                // start recursive parsing
-                p.run();
-            } catch (...) {
-                // store other exceptions in exception-pointer
-                except = std::current_exception();
-            }
-            // set termination flag
-            done=true;
-            // resume main execution context
-            sink();
-        });
-
-// user-code pulls parsed data from parser
-// invert control flow
-void* vp = source();
-if (except) {
-    std::rethrow_exception(except);
-}
-while( ! done) {
-    printf("Parsed: %c\n",* static_cast<char*>(vp));
-    vp = source();
-    if (except) {
-        std::rethrow_exception(except);
-    }
-}
-
-output:
-    Parsed: 1
-    Parsed: +
-    Parsed: 1
-
-

- In this example a recursive descent parser uses a callback to emit a newly - passed symbol. Using execution_context the control flow - can be inverted, e.g. the user-code pulls parsed symbols from the parser - - instead to get pushed from the parser (via callback). -

-

- The data (character) is transferred between the two execution_context. -

-

- If the code executed by execution_context emits an exception, - the application is terminated. std::exception_ptr can - be used to transfer exceptions between different execution contexts. -

-

- - stack - unwinding -

-

- Sometimes it is necessary to unwind the stack of an unfinished context to destroy - local stack variables so they can release allocated resources (RAII pattern). - The user is responsible for this task. -

-

- - allocating - control structures on top of stack -

-

- Allocating control structures on top of the stack requires to allocated the - stack_context and create the control structure with placement - new before execution_context is created. -

-
- - - - - -
[Note]Note

- The user is responsible for destructing the control structure at the top - of the stack. -

-
// stack-allocator used for (de-)allocating stack
-fixedsize_stack salloc( 4048);
-// allocate stack space
-stack_context sctx( salloc.allocate() );
-// reserve space for control structure on top of the stack
-void * sp = static_cast< char * >( sctx.sp) - sizeof( my_control_structure);
-std::size_t size = sctx.size - sizeof( my_control_structure);
-// placement new creates control structure on reserved space
-my_control_structure * cs = new ( sp) my_control_structure( sp, size, sctx, salloc);
-...
-// destructing the control structure
-cs->~my_control_structure();
-...
-struct my_control_structure  {
-    // execution context
-    execution_context ectx;
-
-    template< typename StackAllocator >
-    my_control_structure( void * sp, std::size_t size, stack_context sctx, StackAllocator salloc) :
-        // create execution context
-        ectx( std::allocator_arg, preallocated( sp, size, sctx), salloc, entry_func) {
-    }
-    ...
-};
-
-

- - exception - handling -

-

- If the function executed inside a execution_context emits - an exception, the application is terminated by calling std::terminate(). - std::exception_ptr can be used to transfer exceptions - between different execution contexts. -

-
- - - - - -
[Important]Important

- Do not jump from inside a catch block and then re-throw the exception in - another execution context. -

-

- - parameter - passing -

-

- The void pointer argument passed to execution_context::operator(), - in one context, is passed as the last argument of the context-function - if the context is started for the first time. In all following invocations - of execution_context::operator() the void pointer passed - to execution_context::operator(), in one context, is returned - by execution_context::operator() in the other context. -

-
class X {
-private:
-    std::exception_ptr excptr_;
-    boost::context::v1::execution_context caller_;
-    boost::context::v1::execution_context callee_;
-
-public:
-    X() :
-        excptr_(),
-        caller_( boost::context::v1::execution_context::current() ),
-        callee_( [=] (void * vp) {
-                    try {
-                        int i = * static_cast< int * >( vp);
-                        std::string str = boost::lexical_cast<std::string>(i);
-                        caller_( & str);
-                    } catch (std::bad_cast const&) {
-                        excptr_=std::current_exception();
-                    }
-                 })
-    {}
-
-    std::string operator()( int i) {
-        void * ret = callee_( & i);
-        if(excptr_){
-            std::rethrow_exception(excptr_);
-        }
-        return * static_cast< std::string * >( ret);
-    }
-};
-
-X x;
-std::cout << x( 7) << std::endl;
-
-output:
-    7
-
-

- - Class - execution_context -

-
class execution_context {
-public:
-    static execution_context current() noexcept;
-
-    template< typename Fn, typename ... Args >
-    execution_context( Fn && fn, Args && ... args);
-
-    template< typename StackAlloc, typename Fn, typename ... Args >
-    execution_context( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Args && ... args);
-
-    template< typename StackAlloc, typename Fn, typename ... Args >
-    execution_context( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args);
-
-    execution_context( execution_context const& other) noexcept;
-    execution_context( execution_context && other) noexcept;
-
-    execution_context & operator=( execution_context const& other) noexcept;
-    execution_context & operator=( execution_context && other) noexcept;
-
-    explicit operator bool() const noexcept;
-    bool operator!() const noexcept;
-
-    void * operator()( void * vp = nullptr);
-
-    template< typename Fn >
-    void * operator()( exec_ontop_arg_t, Fn && fn, void * vp = nullptr);
-
-    bool operator==( execution_context const& other) const noexcept;
-
-    bool operator!=( execution_context const& other) const noexcept;
-
-    bool operator<( execution_context const& other) const noexcept;
-
-    bool operator>( execution_context const& other) const noexcept;
-
-    bool operator<=( execution_context const& other) const noexcept;
-
-    bool operator>=( execution_context const& other) const noexcept;
-
-    template< typename charT, class traitsT >
-    friend std::basic_ostream< charT, traitsT > &
-    operator<<( std::basic_ostream< charT, traitsT > & os, execution_context const& other);
-};
-
-

-

-
- - - Static member function current() -
-

-

-
static execution_context current() noexcept;
-
-
-

-
-
Returns:
-

- Returns an instance of excution_context pointing to the active execution - context. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Constructor -
-

-

-
template< typename Fn, typename ... Args >
-execution_context( Fn && fn, Args && ... args);
-
-template< typename StackAlloc, typename Fn, typename ... Args >
-execution_context( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Args && ... args);
-
-template< typename StackAlloc, typename Fn, typename ... Args >
-execution_context( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args);
-
-
-

-
-
Effects:
-

- Creates a new execution context and prepares the context to execute - fn. fixedsize_stack - is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()). - The constructor with argument type preallocated, - is used to create a user defined data (for - instance additional control structures) on top of the stack. -

-
-
-

-

-
- - - Copy - constructor -
-

-

-
execution_context( execution_context const& other) noexcept;
-
-
-

-
-
Effects:
-

- Copies other, e.g. underlying - control structure is shared with *this. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - constructor -
-

-

-
execution_context( execution_context && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves underlying control structure to *this. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Copy - assignment operator -
-

-

-
execution_context & operator=( execution_context const& other) noexcept;
-
-
-

-
-
Effects:
-

- Copies the state of other - to *this, - control structure is shared. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - assignment operator -
-

-

-
execution_context & operator=( execution_context && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves the control structure of other - to *this - using move semantics. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator bool() -
-

-

-
explicit operator bool() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this points to a control structure. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator!() -
-

-

-
bool operator!() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this does not point to a control structure. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator()() -
-

-

-
void * operator()( void * vp = nullptr) noexcept;
-
-
-

-
-
Effects:
-

- Stores internally the current context data (stack pointer, instruction - pointer, and CPU registers) of the current active context and restores - the context data from *this, which implies jumping to *this's - context. The void pointer argument, vp, - is passed to the current context to be returned by the most recent call - to execution_context::operator() in the same thread. fn - is executed with arguments args - on top of the stack of this. -

-
Note:
-

- The behaviour is undefined if operator()() is called while execution_context::current() - returns *this - (e.g. resuming an already running context). If the top-level context - function returns, std::exit() is called. -

-
Returns:
-

- The void pointer argument passed to the most recent call to execution_context::operator(), - if any. -

-
-
-

-

-
- - - Member - function operator(exec_ontop_arg_t)() -
-

-

-
template< typename Fn >
-void * operator()( exec_ontop_arg_t, Fn && fn, void * vp = nullptr);
-
-
-

-
-
Effects:
-

- Same as execution_context::operator(). Additionally, - function fn is executed - with arguments vp in - the context of *this - (e.g. the stack frame of fn - is allocated on stack of *this). -

-
Returns:
-

- The void pointer argument passed to the most recent call to execution_context::operator(), - if any. -

-
-
-

-

-
- - - Member - function operator==() -
-

-

-
bool operator==( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this and other - represent the same execution context, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator!=() -
-

-

-
bool operator!=( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other == * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<() -
-

-

-
bool operator<( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this != other is true and the implementation-defined - total order of execution_context - values places *this - before other, false otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>() -
-

-

-
bool operator>( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- other < - * this -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator<=() -
-

-

-
bool operator<=( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other < - * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>=() -
-

-

-
bool operator>=( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (* - this < - other) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Non-member function operator<<() -
-

-

-
template< typename charT, class traitsT >
-std::basic_ostream< charT, traitsT > &
-operator<<( std::basic_ostream< charT, traitsT > & os, execution_context const& other);
-
-
-

-
-
Effects:
-

- Writes the representation of other - to stream os. -

-
Returns:
-

- os -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/ecv2.html b/doc/html/context/ecv2.html deleted file mode 100644 index 7fc23869..00000000 --- a/doc/html/context/ecv2.html +++ /dev/null @@ -1,808 +0,0 @@ - - - -Class execution_context (version 2) - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - - - - -
[Note]Note

- execution_context (v2) is the reference implementation - of C++ proposal P099R1: - A low-level API for stackful context switching. -

-
- - - - - -
[Note]Note

- execution_context (v2) resides in the inlined sub-namespace - v2. -

-
- - - - - -
[Note]Note

- Segmented stacks (segmented-stacks=on), e.g. on demand - growing stacks, are not supported by execution_context - (v2). -

-

- Class execution_context encapsulates context switching - and manages the associated context' stack (allocation/deallocation). -

-

- execution_context allocates the context stack (using its - StackAllocator argument) - and creates a control structure on top of it. This structure is responsible - for managing context' stack. The address of the control structure is stored - in the first frame of context' stack (e.g. it can not directly accessed from - within execution_context). In contrast to execution_context - (v1) the ownership of the control structure is not shared (no member - variable to control structure in execution_context). - execution_context keeps internally a state that is moved - by a call of execution_context::operator() (*this will be - invalidated), e.g. after a calling execution_context::operator(), - *this - can not be used for an additional context switch. -

-

- execution_context is only move-constructible and move-assignable. -

-

- The moved state is assigned to a new instance of execution_context. - This object becomes the first argument of the context-function, if the context - was resumed the first time, or the first element in a tuple returned by execution_context::operator() - that has been called in the resumed context. In contrast to execution_context - (v1), the context switch is faster because no global pointer etc. is - involved. -

-
- - - - - -
[Important]Important

- Segmented stacks are not supported by execution_context - (v2). -

-

- On return the context-function of the current context has to specify an execution_context - to which the execution control is transferred after termination of the current - context. -

-

- If an instance with valid state goes out of scope and the context-function - has not yet returned, the stack is traversed in order to access the control - structure (address stored at the first stack frame) and context' stack is deallocated - via the StackAllocator. The stack walking makes the destruction - of execution_context slow and should be prevented if possible. -

-

- execution_context expects a context-function - with signature execution_context(execution_context - ctx, Args ... args). The - parameter ctx represents the - context from which this context was resumed (e.g. that has called execution_context::operator() - on *this) - and args are the data passed - to execution_context::operator(). The return value represents - the execution_context that has to be resumed, after termination of this context. -

-

- Benefits of execution_context (v2) - over execution_context (v1) - are: faster context switch, type-safety of passed/returned arguments. -

-

- - usage - of execution_context -

-
int n=35;
-ctx::execution_context<int> source(
-    [n](ctx::execution_context<int> && sink,int) mutable {
-        int a=0;
-        int b=1;
-        while(n-->0){
-            auto result=sink(a);
-            sink=std::move(std::get<0>(result));
-            auto next=a+b;
-            a=b;
-            b=next;
-        }
-        return std::move(sink);
-    });
-for(int i=0;i<10;++i){
-    auto result=source(i);
-    source=std::move(std::get<0>(result));
-    std::cout<<std::get<1>(result)<<" ";
-}
-
-output:
-    0 1 1 2 3 5 8 13 21 34
-
-

- This simple example demonstrates the basic usage of execution_context - as a generator. The context sink - represents the main-context (function main() - running). sink is generated - by the framework (first element of lambda's parameter list). Because the state - is invalidated (== changed) by each call of execution_context::operator(), - the new state of the execution_context, returned by execution_context::operator(), - needs to be assigned to sink - after each call. -

-

- The lambda that calculates the Fibonacci numbers is executed inside the context - represented by source. Calculated - Fibonacci numbers are transferred between the two context' via expression - sink(a) (and returned by source()). - Note that this example represents a generator thus the - value transferred into the lambda via source() is not - used. Using boost::optional<> as transferred type, - might also appropriate to express this fact. -

-

- The locale variables a, b and next - remain their values during each context switch (yield(a)). - This is possible due source - has its own stack and the stack is exchanged by each context switch. -

-

- - parameter - passing -

-

- With execution_context<void> no - data will be transferred, only the context switch is executed. -

-
boost::context::execution_context<void> ctx1([](boost::context::execution_context<void> && ctx2){
-            std::printf("inside ctx1\n");
-            return ctx2();
-        });
-ctx1();
-
-output:
-    inside ctx1
-
-

- ctx1() - resumes ctx1, e.g. the lambda - passed at the constructor of ctx1 - is entered. Argument ctx2 represents - the context that has been suspended with the invocation of ctx1(). When the lambda returns ctx2, - context ctx1 will be terminated - while the context represented by ctx2 - is resumed, hence the control of execution returns from ctx1(). -

-

- The arguments passed to execution_context::operator(), - in one context, is passed as the last arguments of the context-function - if the context is started for the first time. In all following invocations - of execution_context::operator() the arguments passed - to execution_context::operator(), in one context, is returned - by execution_context::operator() in the other context. -

-
boost::context::execution_context<int> ctx1([](boost::context::execution_context<int> && ctx2,int j){
-            std::printf("inside ctx1,j==%d\n",j);
-            std::tie(ctx2,j)=ctx2(j+1);
-            return std::move(ctx2);
-        });
-int i=1;
-std::tie(ctx1,i)=ctx1(i);
-std::printf("i==%d\n",i);
-
-output:
-    inside ctx1,j==1
-    i==2
-
-

- ctx1(i) enters - the lambda in context ctx1 - with argument j=1. The expression ctx2(j+1) resumes the - context represented by ctx2 - and transfers back an integer of j+1. On return - of ctx1(i), the variable - i contains the value of j+1. -

-

- If more than one argument has to be transferred, the signature of the context-function - is simply extended. -

-
boost::context::execution_context<int,int> ctx1([](boost::context::execution_context<int,int> && ctx2,int i,int j){
-            std::printf("inside ctx1,i==%d,j==%d\n",i,j);
-            std::tie(ctx2,i,j)=ctx2(i+j,i-j);
-            return std::move(ctx2);
-        });
-int i=2,j=1;
-std::tie(ctx1,i,j)=ctx1(i,j);
-std::printf("i==%d,j==%d\n",i,j);
-
-output:
-    inside ctx1,i==2,j==1
-    i==3,j==1
-
-

- For use-cases, that require to transfer data of different type in each direction, - boost::variant<> could be used. -

-
class X{
-private:
-    std::exception_ptr excptr_;
-    boost::context::execution_context<boost::variant<int,std::string>> ctx_;
-
-public:
-    X():
-        excptr_(),
-        ctx_([=](boost::context::execution_context<boost::variant<int,std::string>> && ctx,boost::variant<int,std::string> data){
-                try {
-                    for (;;) {
-                        int i=boost::get<int>(data);
-                        data=boost::lexical_cast<std::string>(i);
-                        auto result=ctx(data);
-                        ctx=std::move(std::get<0>(result));
-                        data=std::get<1>(result);
-                } catch (std::bad_cast const&) {
-                    excptr_=std::current_exception();
-                }
-                return std::move(ctx);
-             })
-    {}
-
-    std::string operator()(int i){
-        boost::variant<int,std::string> data=i;
-        auto result=ctx_(data);
-        ctx_=std::move(std::get<0>(result));
-        data=std::get<1>(result);
-        if(excptr_){
-            std::rethrow_exception(excptr_);
-        }
-        return boost::get<std::string>(data);
-    }
-};
-
-X x;
-std::cout << x(7) << std::endl;
-
-output:
-7
-
-

- In the case of unidirectional transfer of data, boost::optional<> - or a pointer are appropriate. -

-

- - exception - handling -

-

- If the function executed inside a execution_context emits - an exception, the application is terminated by calling std::terminate(). - std::exception_ptr can be used to transfer exceptions - between different execution contexts. -

-
- - - - - -
[Important]Important

- Do not jump from inside a catch block and then re-throw the exception in - another execution context. -

-

- - Executing - function on top of a context -

-

- Sometimes it is useful to execute a new function on top of a resumed context. - For this purpose execution_context::operator() with first - argument exec_ontop_arg has - to be used. The function passed as argument must return a tuple of execution_context - and arguments. -

-
boost::context::execution_context<int> f1(boost::context::execution_context<int> && ctx,int data) {
-    std::cout << "f1: entered first time: " << data << std::endl;
-    std::tie(ctx,data)=ctx(data+1);
-    std::cout << "f1: entered second time: " << data << std::endl;
-    std::tie(ctx,data)=ctx(data+1);
-    std::cout << "f1: entered third time: " << data << std::endl;
-    return std::move(ctx);
-}
-
-int f2(int data) {
-    std::cout << "f2: entered: " << data << std::endl;
-    return -1;
-}
-
-int data=0;
-boost::context::execution_context< int > ctx(f1);
-std::tie(ctx,data)=ctx(data+1);
-std::cout << "f1: returned first time: " << data << std::endl;
-std::tie(ctx,data)=ctx(data+1);
-std::cout << "f1: returned second time: " << data << std::endl;
-std::tie(ctx,data)=ctx(ctx::exec_ontop_arg,f2,data+1);
-
-output:
-    f1: entered first time: 1
-    f1: returned first time: 2
-    f1: entered second time: 3
-    f1: returned second time: 4
-    f2: entered: 5
-    f1: entered third time: -1
-
-

- The expression ctx(ctx::exec_ontop_arg,f2,data+1) executes f2() on top of context ctx, - e.g. an additional stack frame is allocated on top of the context stack (in - front of f1()). - f2() - returns argument -1 - that will returned by the second invocation of ctx(data+1) in f1(). -

-

-

-
- - - Destructor -
-

-

-
~execution_context();
-
-
-

-
-
Effects:
-

- Destructs the associated stack if *this is a valid context, e.g. execution_context::operator - bool() returns true. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - constructor -
-

-

-
execution_context( execution_context && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves underlying capture record to *this. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - assignment operator -
-

-

-
execution_context & operator=( execution_context && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves the state of other - to *this - using move semantics. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator bool() -
-

-

-
explicit operator bool() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this points to a capture record. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator!() -
-

-

-
bool operator!() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this does not point to a capture record. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator()() -
-

-

-
std::tuple< execution_context< Args ... >, Args ... > operator()( Args ... args); // member of generic execution_context template
-
-execution_context< void > operator()(); // member of execution_context< void >
-
-
-

-
-
Effects:
-

- Stores internally the current context data (stack pointer, instruction - pointer, and CPU registers) of the current active context and restores - the context data from *this, which implies jumping to *this's - context. The arguments, ... args, are passed to the current context - to be returned by the most recent call to execution_context::operator() in the same thread. -

-
Returns:
-

- The tuple of execution_context and returned arguments passed to the most - recent call to execution_context::operator(), if any and a execution_context representing - the context that has been suspended. -

-
Note:
-

- The returned execution_context indicates if the suspended context has - terminated (return from context-function) via bool - operator(). - If the returned execution_context has terminated no data are transferred - in the returned tuple. -

-
-
-

-

-
- - - Member - function operator()() -
-

-

-
template< typename Fn >
-std::tuple< execution_context< Args ... >, Args ... > operator()( exec_ontop_arg_t, Fn && fn, Args ... args); // member of generic execution_context
-
-template< typename Fn >
-execution_context< void > operator()( exec_ontop_arg_t, Fn && fn); // member of execution_context< void >
-
-
-

-
-
Effects:
-

- Same as execution_context::operator(). Additionally, - function fn is executed - in the context of *this - (e.g. the stack frame of fn - is allocated on stack of *this). -

-
Returns:
-

- The tuple of execution_context and returned arguments passed to the most - recent call to execution_context::operator(), if any and a execution_context representing - the context that has been suspended . -

-
Note:
-

- The tuple of execution_context and returned arguments from fn are passed as arguments to the context-function - of resumed context (if the context is entered the first time) or those - arguments are returned from execution_context::operator() within the resumed context. -

-
Note:
-

- Function fn needs to - return a tuple of arguments (see description). -

-
Note:
-

- The context calling this function must not be destroyed before the arguments, - that will be returned from fn, - are preserved at least in the stack frame of the resumed context. -

-
Note:
-

- The returned execution_context indicates if the suspended context has - terminated (return from context-function) via bool - operator(). - If the returned execution_context has terminated no data are transferred - in the returned tuple. -

-
-
-

-

-
- - - Member - function operator==() -
-

-

-
bool operator==( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this and other - represent the same execution context, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator!=() -
-

-

-
bool operator!=( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other == * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<() -
-

-

-
bool operator<( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this != other is true and the implementation-defined - total order of execution_context - values places *this - before other, false otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>() -
-

-

-
bool operator>( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- other < - * this -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator<=() -
-

-

-
bool operator<=( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other < - * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>=() -
-

-

-
bool operator>=( execution_context const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (* - this < - other) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Non-member function operator<<() -
-

-

-
template< typename charT, class traitsT >
-std::basic_ostream< charT, traitsT > &
-operator<<( std::basic_ostream< charT, traitsT > & os, execution_context const& other);
-
-
-

-
-
Effects:
-

- Writes the representation of other - to stream os. -

-
Returns:
-

- os -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/ff.html b/doc/html/context/ff.html deleted file mode 100644 index 7a0d120b..00000000 --- a/doc/html/context/ff.html +++ /dev/null @@ -1,522 +0,0 @@ - - - -Context switching with fibers - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- - - - - -
[Note]Note

- fiber is the reference implementation of C++ proposal - P0876R0: - fibers without scheduler. -

-

- A fiber represents the state of the control flow of a - program at a given point in time. Fibers can be suspended and resumed later - in order to change the control flow of a program. -

-

- Modern micro-processors are registers machines; the content of processor registers - represent a fiber of the executed program at a given point in time. Operating - systems simulate parallel execution of programs on a single processor by switching - between programs (context switch) by preserving and restoring the fiber, e.g. - the content of all registers. -

-

- - fiber -

-

- fiber captures the current fiber - (the rest of the computation; code after fiber) - and triggers a context switch. The context switch is achieved by preserving - certain registers (including instruction and stack pointer), defined by the - calling convention of the ABI, of the current fiber and restoring those registers - of the resumed fiber. The control flow of the resumed fiber continues. The - current fiber is suspended and passed as argument to the resumed fiber. -

-

- fiber expects a context-function - with signature 'fiber(fiber && f)'. - The parameter f represents - the current fiber from which this fiber was resumed (e.g. that has called - fiber). -

-

- On return the context-function of the current fiber has - to specify an fiber to which - the execution control is transferred after termination of the current fiber. -

-

- If an instance with valid state goes out of scope and the context-function - has not yet returned, the stack is traversed in order to access the control - structure (address stored at the first stack frame) and fiber's stack is deallocated - via the StackAllocator. -

-
- - - - - -
[Note]Note

- Segmented stacks are - supported by fiber using - ucontext_t. -

-

- fiber represents a fiber; - it contains the content of preserved registers and manages the associated stack - (allocation/deallocation). fiber - is a one-shot fiber - it can be used only once, after calling continuation::resume() - or continuation::resume_with() it is invalidated. -

-

- fiber is only move-constructible - and move-assignable. -

-

- As a first-class object fiber - can be applied to and returned from a function, assigned to a variable or stored - in a container. -

-

- A fiber is continued by calling resume()/resume_with(). -

-

- - Usage -

-
namespace ctx=boost::context;
-int a;
-ctx::fiber source{[&a](ctx::fiber&& sink){
-    a=0;
-    int b=1;
-    for(;;){
-        sink=std::move(sink).resume();
-        int next=a+b;
-        a=b;
-        b=next;
-    }
-    return std::move(sink);
-}};
-for (int j=0;j<10;++j) {
-    source=std::move(source).resume();
-    std::cout << a << " ";
-}
-
-output:
-    0 1 1 2 3 5 8 13 21 34
-
-

- This simple example demonstrates the basic usage of fiber - as a generator. The fiber sink - represents the main-fiber (function main()). sink - is captured (current-fiber) by invoking fiber - and passed as parameter to the lambda. -

-

- Because the state is invalidated (one-shot fiber) by each call of continuation::resume(), - the new state of the fiber, - returned by continuation::resume(), needs to be assigned - to sink after each call. In - order to express the invalidation of the resumed fiber, the member functions - resume() - and resume_with() - are rvalue-ref qualified. Both functions bind only to rvalues. Thus an lvalue - fiber must be casted to an rvalue via std::move(). -

-

- The lambda that calculates the Fibonacci numbers is executed inside the fiber - represented by source. Calculated - Fibonacci numbers are transferred between the two fibers via variable a (lambda capture reference). -

-

- The locale variables b and - next remain their values during - each context switch. This is possible due source - has its own stack and the stack is exchanged by each context switch. -

-

- - Parameter - passing -

-

- Data can be transferred between two fibers via global pointers, calling wrappers - (like std::bind) or lambda captures. -

-
namespace ctx=boost::context;
-int i=1;
-ctx::fiber f1{[&i](ctx::fiber&& f2){
-    std::printf("inside f1,i==%d\n",i);
-    i+=1;
-    return std::move(f2).resume();
-}};
-f1=std::move(f1).resume();
-std::printf("i==%d\n",i);
-
-output:
-    inside c1,i==1
-    i==2
-
-

- f1.resume() - enters the lambda in fiber represented by f1 - with lambda capture reference i=1. The expression - f2.resume() - resumes the fiber f2. On return - of f1.resume(), - the variable i has the value - of i+1. -

-

- - Exception - handling -

-

- If the function executed inside a context-function emits - an exception, the application is terminated by calling std::terminate(). std::exception_ptr - can be used to transfer exceptions between different fibers. -

-
- - - - - -
[Important]Important

- Do not jump from inside a catch block and then re-throw the exception in - another fiber. -

-

- - Executing - function on top of a fiber -

-

- Sometimes it is useful to execute a new function on top of a resumed fiber. - For this purpose continuation::resume_with() has to be - used. The function passed as argument must accept a rvalue reference to fiber and return void. -

-
namespace ctx=boost::context;
-int data=0;
-ctx::fiber f1{[&data](ctx::fiber&& f2) {
-    std::cout << "f1: entered first time: " << data << std::endl;
-    data+=1;
-    f2=std::move(f2).resume();
-    std::cout << "f1: entered second time: " << data << std::endl;
-    data+=1;
-    f2=std::move(f2).resume();
-    std::cout << "f1: entered third time: " << data << std::endl;
-    return std::move(f2);
-}};
-f1=std::move(f1).resume();
-std::cout << "f1: returned first time: " << data << std::endl;
-data+=1;
-f1=std::move(f1).resume();
-std::cout << "f1: returned second time: " << data << std::endl;
-data+=1;
-f1=f1.resume_with([&data](ctx::fiber&& f2){
-    std::cout << "f2: entered: " << data << std::endl;
-    data=-1;
-    return std::move(f2);
-});
-std::cout << "f1: returned third time" << std::endl;
-
-output:
-    f1: entered first time: 0
-    f1: returned first time: 1
-    f1: entered second time: 2
-    f1: returned second time: 3
-    f2: entered: 4
-    f1: entered third time: -1
-    f1: returned third time
-
-

- The expression f1.resume_with(...) - executes a lambda on top of fiber f1, - e.g. an additional stack frame is allocated on top of the stack. This lambda - assigns -1 - to data and returns to the - second invocation of f1.resume(). -

-

- Another option is to execute a function on top of the fiber that throws an - exception. -

-
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_) } {
-    }
-};
-
-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 {};
-});
-
-output:
-    entered
-    my_exception: abc
-
-

- In this exception my_exception - is throw from a function invoked on-top of fiber f - and catched inside the for-loop. -

-

- - Stack - unwinding -

-

- On construction of fiber a stack - is allocated. If the context-function returns the stack - will be destructed. If the context-function has not yet - returned and the destructor of an valid fiber - instance (e.g. fiber::operator bool() returns true) is called, the stack will be destructed - too. -

-
- - - - - -
[Important]Important

- Code executed by context-function must not prevent the - propagation ofs the detail::forced_unwind exception. - Absorbing that exception will cause stack unwinding to fail. Thus, any code - that catches all exceptions must re-throw any pending detail::forced_unwind - exception. -

-

- - Allocating - control structures on top of stack -

-

- Allocating control structures on top of the stack requires to allocated the - stack_context and create the control structure with placement - new before fiber is created. -

-
- - - - - -
[Note]Note

- The user is responsible for destructing the control structure at the top - of the stack. -

-
namespace ctx=boost::context;
-// stack-allocator used for (de-)allocating stack
-fixedsize_stack salloc(4048);
-// allocate stack space
-stack_context sctx(salloc.allocate());
-// reserve space for control structure on top of the stack
-void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure);
-std::size_t size=sctx.size-sizeof(my_control_structure);
-// placement new creates control structure on reserved space
-my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc);
-...
-// destructing the control structure
-cs->~my_control_structure();
-...
-struct my_control_structure  {
-    // captured fiber
-    ctx::fiber   f;
-
-    template< typename StackAllocator >
-    my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) :
-        // create captured fiber
-        f{std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func} {
-    }
-    ...
-};
-
-

- - Inverting - the control flow -

-
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");
-      }
-   }
-};
-
-std::istringstream is("1+1");
-// user-code pulls parsed data from parser
-// invert control flow
-char c;
-bool done=false;
-// execute parser in new fiber
-ctx::fiber source{[&is,&c,&done](ctx::fiber&& sink){
-    // create parser with callback function
-    Parser p(is,
-             [&sink,&c](char c_){
-                // resume main fiber
-                c=c_;
-                sink=std::move(sink).resume();
-             });
-        // start recursive parsing
-        p.run();
-        // signal termination
-        done=true;
-        // resume main fiber
-        return std::move(sink);
-}};
-source=std::move(source).resume();
-while(!done){
-    printf("Parsed: %c\n",c);
-    source=std::Move(source).resume();
-}
-
-output:
-    Parsed: 1
-    Parsed: +
-    Parsed: 1
-
-

- In this example a recursive descent parser uses a callback to emit a newly - passed symbol. Using fiber the - control flow can be inverted, e.g. the user-code pulls parsed symbols from - the parser - instead to get pushed from the parser (via callback). -

-

- The data (character) is transferred between the two fibers. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/ff/class__fiber_.html b/doc/html/context/ff/class__fiber_.html deleted file mode 100644 index c8820e71..00000000 --- a/doc/html/context/ff/class__fiber_.html +++ /dev/null @@ -1,506 +0,0 @@ - - - -Class fiber - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
#include <boost/context/fiber.hpp>
-
-class fiber {
-public:
-    fiber() noexcept;
-
-    template<typename Fn>
-    fiber(Fn && fn);
-
-    template<typename StackAlloc, typename Fn>
-    fiber(std::allocator_arg_t, StackAlloc && salloc, Fn && fn);
-
-    ~fiber();
-
-    fiber(fiber && other) noexcept;
-
-    fiber & operator=(fiber && other) noexcept;
-
-    fiber(fiber const& other) noexcept = delete;
-    fiber & operator=(fiber const& other) noexcept = delete;
-
-    fiber resume() &&;
-
-    template<typename Fn>
-    fiber resume_with(Fn && fn) &&;
-
-    explicit operator bool() const noexcept;
-
-    bool operator!() const noexcept;
-
-    bool operator==(fiber const& other) const noexcept;
-
-    bool operator!=(fiber const& other) const noexcept;
-
-    bool operator<(fiber const& other) const noexcept;
-
-    bool operator>(fiber const& other) const noexcept;
-
-    bool operator<=(fiber const& other) const noexcept;
-
-    bool operator>=(fiber const& other) const noexcept;
-
-    template<typename charT,class traitsT>
-    friend std::basic_ostream<charT,traitsT> &
-    operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other) {
-
-    void swap(fiber & other) noexcept;
-};
-
-

-

-
- - - Constructor -
-

-

-
fiber() noexcept;
-
-
-

-
-
Effects:
-

- Creates a invalid fiber. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Constructor -
-

-

-
template<typename Fn>
-fiber(Fn && fn);
-
-template<typename StackAlloc, typename Fn>
-fiber(std::allocator_arg_t, StackAlloc && salloc, Fn && fn);
-
-
-

-
-
Effects:
-

- Creates a new fiber and prepares the context to execute fn. fixedsize_stack - is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()). - The constructor with argument type preallocated, - is used to create a user defined data (for - instance additional control structures) on top of the stack. -

-
-
-

-

-
- - - Destructor -
-

-

-
~fiber();
-
-
-

-
-
Effects:
-

- Destructs the associated stack if *this is a valid fiber, e.g. fiber::operator - bool() returns true. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - constructor -
-

-

-
fiber(fiber && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves underlying capture fiber to *this. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move assignment - operator -
-

-

-
fiber & operator=(fiber && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves the state of other - to *this - using move semantics. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator()() -
-

-

-
fiber resume() &&;
-
-template<typename Fn>
-fiber resume_with(Fn && fn) &&;
-
-
-

-
-
Effects:
-

- Captures current fiber and resumes *this. The function resume_with, - is used to execute function fn - in the execution context of *this (e.g. the stack frame of fn is allocated on stack of *this). -

-
Returns:
-

- The fiber representing the fiber that has been suspended. -

-
Note:
-

- Because *this - gets invalidated, resume() and resume_with() are rvalue-ref qualified and bind - only to rvalues. -

-
Note:
-

- Function fn needs to - return fiber. -

-
Note:
-

- The returned fiber indicates if the suspended fiber has terminated - (return from context-function) via bool - operator(). -

-
-
-

-

-
- - - Member function - operator bool() -
-

-

-
explicit operator bool() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - points to a captured fiber. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function operator!() -
-

-

-
bool operator!() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - does not point to a captured fiber. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator==() -
-

-

-
bool operator==(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - and other represent - the same fiber, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator!=() -
-

-

-
bool operator!=(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other == * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<() -
-

-

-
bool operator<(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this != other - is true and the implementation-defined total order of fiber values places *this - before other, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>() -
-

-

-
bool operator>(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- other < - * this -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<=() -
-

-

-
bool operator<=(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other < - * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>=() -
-

-

-
bool operator>=(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (* - this < - other) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Non-member function operator<<() -
-

-

-
template<typename charT,class traitsT>
-std::basic_ostream<charT,traitsT> &
-operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other);
-
-
-

-
-
Effects:
-

- Writes the representation of other - to stream os. -

-
Returns:
-

- os -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html b/doc/html/context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html deleted file mode 100644 index 248c7257..00000000 --- a/doc/html/context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -Implementations: fcontext_t, ucontext_t and WinFiber - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - fcontext_t -
-

- The implementation uses fcontext_t per default. fcontext_t - is based on assembler and not available for all platforms. It provides a - much better performance than ucontext_t (the context - switch takes two magnitudes of order less CPU cycles; see section performance) - and WinFiber. -

-
- - - - - -
[Note]Note

- Because the TIB (thread information block on Windows) is not fully described - in the MSDN, it might be possible that not all required TIB-parts are swapped. - Using WinFiber implementation might be an alternative. -

-
- - ucontext_t -
-

- As an alternative, ucontext_t - can be used by compiling with BOOST_USE_UCONTEXT - and b2 property context-impl=ucontext. - ucontext_t might be available on a broader range of - POSIX-platforms but has some disadvantages - (for instance deprecated since POSIX.1-2003, not C99 conform). -

-
- - - - - -
[Note]Note

- fiber supports Segmented - stacks only with ucontext_t as its - implementation. -

-
- - WinFiber -
-

- With BOOST_USE_WINFIB and - b2 property context-impl=winfib - Win32-Fibers are used as implementation for fiber. -

-
- - - - - -
[Note]Note

- The first call of fiber - converts the thread into a Windows fiber by invoking ConvertThreadToFiber(). If desired, ConvertFiberToThread() has to be called by the user explicitly - in order to release resources allocated by ConvertThreadToFiber() (e.g. after using boost.context). -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/fib.html b/doc/html/context/fib.html deleted file mode 100644 index 6e3051a6..00000000 --- a/doc/html/context/fib.html +++ /dev/null @@ -1,512 +0,0 @@ - - - -Context switching with fibers - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- - - - - -
[Note]Note

- __fiber__ is the reference implementation of C++ proposal P0876R0: - fibers without scheduler. -

-

- A fiber represents the state of the control flow of a program at a given point - in time. Fibers can be suspended and resumed later in order to change the control - flow of a program. -

-

- Modern micro-processors are registers machines; the content of processor registers - represent a fiber of the executed program at a given point in time. Operating - systems simulate parallel execution of programs on a single processor by switching - between programs (context switch) by preserving and restoring the fiber, e.g. - the content of all registers. -

-

- - __fiber__ -

-

- __fiber__ captures the current fiber (the rest of the computation; code after - __fiber__) and triggers a context switch. The context switch is achieved by - preserving certain registers (including instruction and stack pointer), defined - by the calling convention of the ABI, of the current fiber and restoring those - registers of the resumed fiber. The control flow of the resumed fiber continues. - The current fiber is suspended and passed as argument to the resumed fiber. -

-

- __fiber__ expects a context-function with signature 'fiber(fiber && f)'. The parameter f represents the current fiber from which - this fiber was resumed (e.g. that has called __fiber__). -

-

- On return the context-function of the current fiber has - to specify an continuation to - which the execution control is transferred after termination of the current - fiber. -

-

- If an instance with valid state goes out of scope and the context-function - has not yet returned, the stack is traversed in order to access the control - structure (address stored at the first stack frame) and fiber's stack is deallocated - via the StackAllocator. -

-
- - - - - -
[Note]Note

- Segmented stacks are - supported by __fiber__ using ucontext_t. -

-

- continuation represents a fiber; - it contains the content of preserved registers and manages the associated stack - (allocation/deallocation). continuation - is a one-shot fiber - it can be used only once, after calling continuation::resume() - or continuation::resume_with() it is invalidated. -

-

- continuation is only move-constructible - and move-assignable. -

-

- As a first-class object continuation - can be applied to and returned from a function, assigned to a variable or stored - in a container. -

-

- A fiber is continued by calling resume()/resume_with(). -

-

- - Usage -

-
namespace ctx=boost::context;
-int a;
-ctx::fiber source{[&a](ctx::fiber && sink){
-    a=0;
-    int b=1;
-    for(;;){
-        sink=sink.resume();
-        int next=a+b;
-        a=b;
-        b=next;
-    }
-    return std::move(sink);
-}};
-for (int j=0;j<10;++j) {
-    source=source.resume();
-    std::cout << a << " ";
-}
-
-output:
-    0 1 1 2 3 5 8 13 21 34
-
-

- This simple example demonstrates the basic usage of __fiber__ as a generator. - The fiber sink represents the - main-fiber (function main()). sink - is captured (current-fiber) by invoking __fiber__ and passed as parameter to - the lambda. -

-

- Because the state is invalidated (one-shot fiber) by each call of continuation::resume(), - the new state of the continuation, - returned by continuation::resume(), needs to be assigned - to sink after each call. -

-

- The lambda that calculates the Fibonacci numbers is executed inside the fiber - represented by source. Calculated - Fibonacci numbers are transferred between the two fibers via variable a (lambda capture reference). -

-

- The locale variables b and - next remain their values during - each context switch. This is possible due source - has its own stack and the stack is exchanged by each context switch. -

-

- - Parameter - passing -

-

- Data can be transferred between two fibers via global pointers, calling wrappers - (like std::bind) or lambda captures. -

-
namespace ctx=boost::context;
-int i=1;
-ctx::fiber f1{[&i](ctx::fiber && f2){
-    std::printf("inside f1,i==%d\n",i);
-    i+=1;
-    return f2.resume();
-}};
-f1=f1.resume();
-std::printf("i==%d\n",i);
-
-output:
-    inside c1,i==1
-    i==2
-
-

- callcc(<lambda>) - enters the lambda in fiber represented by c1 - with lambda capture reference i=1. The expression - c2.resume() - resumes the fiber c2. On return - of callcc(<lambda>), - the variable i has the value - of i+1. -

-

- - Exception - handling -

-

- If the function executed inside a context-function emits - an exception, the application is terminated by calling std::terminate(). std::exception_ptr - can be used to transfer exceptions between different fibers. -

-
- - - - - -
[Important]Important

- Do not jump from inside a catch block and then re-throw the exception in - another fiber. -

-

- - Executing - function on top of a fiber -

-

- Sometimes it is useful to execute a new function on top of a resumed fiber. - For this purpose continuation::resume_with() has to be - used. The function passed as argument must accept a rvalue reference to continuation and return void. -

-
namespace ctx=boost::context;
-int data=0;
-ctx::fiber f1{[&data](ctx::fiber && f2) {
-    std::cout << "f1: entered first time: " << data << std::endl;
-    data+=1;
-    f2=f2.resume();
-    std::cout << "f1: entered second time: " << data << std::endl;
-    data+=1;
-    f2=f2.resume();
-    std::cout << "f1: entered third time: " << data << std::endl;
-    return std::move(f2);
-}};
-f1=f1.resume();
-std::cout << "f1: returned first time: " << data << std::endl;
-data+=1;
-f1=f1.resume();
-std::cout << "f1: returned second time: " << data << std::endl;
-data+=1;
-f1=f1.resume_with([&data](ctx::fiber && f2){
-    std::cout << "f2: entered: " << data << std::endl;
-    data=-1;
-    return std::move( f2);
-});
-std::cout << "f1: returned third time" << std::endl;
-
-output:
-    f1: entered first time: 0
-    f1: returned first time: 1
-    f1: entered second time: 2
-    f1: returned second time: 3
-    f2: entered: 4
-    f1: entered third time: -1
-    f1: returned third time
-
-

- The expression f1.resume_with(...) - executes a lambda on top of fiber f1, - e.g. an additional stack frame is allocated on top of the stack. This lambda - assigns -1 - to data and returns to the - second invocation of f1.resume(). -

-

- Another option is to execute a function on top of the fiber that throws an - exception. -

-
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_) } {
-    }
-};
-
-ctx::fiber f{[](ctx::fiber && f) ->ctx::fiber {
-    std::cout << "entered" << std::endl;
-    try {
-        f=f.resume();
-    } catch (my_exception & ex) {
-        std::cerr << "my_exception: " << ex.what() << std::endl;
-        return std::move(ex.f);
-    }
-    return {};
-});
-f = f.resume();
-f = f.resume_with([](ctx::fiber && f) ->ctx::fiber {
-    throw my_exception(std::move(f),"abc");
-    return {};
-});
-
-output:
-    entered
-    my_exception: abc
-
-

- In this exception my_exception - is throw from a function invoked on-top of fiber c - and catched inside the for-loop. -

-

- - Stack - unwinding -

-

- On construction of continuation - a stack is allocated. If the context-function returns - the stack will be destructed. If the context-function - has not yet returned and the destructor of an valid continuation - instance (e.g. fiber::operator bool() returns true) is called, the stack will be destructed - too. -

-
- - - - - -
[Important]Important

- Code executed by context-function must not prevent the - propagation ofs the detail::forced_unwind exception. - Absorbing that exception will cause stack unwinding to fail. Thus, any code - that catches all exceptions must re-throw any pending detail::forced_unwind - exception. -

-

- - Allocating - control structures on top of stack -

-

- Allocating control structures on top of the stack requires to allocated the - stack_context and create the control structure with placement - new before continuation is created. -

-
- - - - - -
[Note]Note

- The user is responsible for destructing the control structure at the top - of the stack. -

-
namespace ctx=boost::context;
-// stack-allocator used for (de-)allocating stack
-fixedsize_stack salloc(4048);
-// allocate stack space
-stack_context sctx(salloc.allocate());
-// reserve space for control structure on top of the stack
-void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure);
-std::size_t size=sctx.size-sizeof(my_control_structure);
-// placement new creates control structure on reserved space
-my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc);
-...
-// destructing the control structure
-cs->~my_control_structure();
-...
-struct my_control_structure  {
-    // captured fiber
-    ctx::fiber   f;
-
-    template< typename StackAllocator >
-    my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) :
-        // create captured fiber
-        f{std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func} {
-    }
-    ...
-};
-
-

- - Inverting - the control flow -

-
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");
-      }
-   }
-};
-
-std::istringstream is("1+1");
-// user-code pulls parsed data from parser
-// invert control flow
-char c;
-bool done=false;
-// execute parser in new fiber
-ctx::fiber source{[&is,&c,&done](ctx::fiber && sink){
-    // create parser with callback function
-    Parser p(is,
-             [&sink,&c](char c_){
-                // resume main fiber
-                c=c_;
-                sink=sink.resume();
-             });
-        // start recursive parsing
-        p.run();
-        // signal termination
-        done=true;
-        // resume main fiber
-        return std::move(sink);
-}};
-source = source.resume();
-while(!done){
-    printf("Parsed: %c\n",c);
-    source=source.resume();
-}
-
-output:
-    Parsed: 1
-    Parsed: +
-    Parsed: 1
-
-

- In this example a recursive descent parser uses a callback to emit a newly - passed symbol. Using __fiber__ the control flow can be inverted, e.g. the user-code - pulls parsed symbols from the parser - instead to get pushed from the parser - (via callback). -

-

- The data (character) is transferred between the two fibers. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/fib/class__fiber_.html b/doc/html/context/fib/class__fiber_.html deleted file mode 100644 index b1e13182..00000000 --- a/doc/html/context/fib/class__fiber_.html +++ /dev/null @@ -1,467 +0,0 @@ - - - -Class fiber - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
#include <boost/context/fiber.hpp>
-
-class fiber {
-public:
-    fiber() noexcept = default;
-
-    ~fiber();
-
-    fiber(fiber && other) noexcept;
-
-    fiber & operator=(fiber && other) noexcept;
-
-    fiber(fiber const& other) noexcept = delete;
-    fiber & operator=(fiber const& other) noexcept = delete;
-
-    fiber resume();
-
-    template<typename Fn>
-    fiber resume_with(Fn && fn);
-
-    explicit operator bool() const noexcept;
-
-    bool operator!() const noexcept;
-
-    bool operator==(fiber const& other) const noexcept;
-
-    bool operator!=(fiber const& other) const noexcept;
-
-    bool operator<(fiber const& other) const noexcept;
-
-    bool operator>(fiber const& other) const noexcept;
-
-    bool operator<=(fiber const& other) const noexcept;
-
-    bool operator>=(fiber const& other) const noexcept;
-
-    template<typename charT,class traitsT>
-    friend std::basic_ostream<charT,traitsT> &
-    operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other) {
-
-    void swap(fiber & other) noexcept;
-};
-
-

-

-
- - - Constructor -
-

-

-
fiber() noexcept;
-
-
-

-
-
Effects:
-

- Creates a invalid fiber. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Destructor -
-

-

-
~fiber();
-
-
-

-
-
Effects:
-

- Destructs the associated stack if *this is a valid fiber, e.g. fiber::operator - bool() returns true. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - constructor -
-

-

-
fiber(fiber && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves underlying capture fiber to *this. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Move - assignment operator -
-

-

-
fiber & operator=(fiber && other) noexcept;
-
-
-

-
-
Effects:
-

- Moves the state of other - to *this - using move semantics. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator()() -
-

-

-
fiber resume();
-
-template<typename Fn>
-fiber resume_with(Fn && fn);
-
-
-

-
-
Effects:
-

- Captures current fiber and resumes *this. The function resume_with, - is used to execute function fn - in the execution context of *this (e.g. the stack frame of fn is allocated on stack of *this). -

-
Returns:
-

- The fiber representing the fiber that has been suspended. -

-
Note:
-

- Function fn needs to - return fiber. -

-
Note:
-

- The returned fiber indicates if the suspended fiber has terminated - (return from context-function) via bool - operator(). -

-
-
-

-

-
- - - Member function - operator bool() -
-

-

-
explicit operator bool() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - points to a captured fiber. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator!() -
-

-

-
bool operator!() const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - does not point to a captured fiber. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator==() -
-

-

-
bool operator==(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this - and other represent - the same fiber, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator!=() -
-

-

-
bool operator!=(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other == * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member function - operator<() -
-

-

-
bool operator<(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- true if *this != other - is true and the implementation-defined total order of fiber values places *this - before other, false - otherwise. -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>() -
-

-

-
bool operator>(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- other < - * this -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator<=() -
-

-

-
bool operator<=(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (other < - * this) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Member - function operator>=() -
-

-

-
bool operator>=(fiber const& other) const noexcept;
-
-
-

-
-
Returns:
-

- ! (* - this < - other) -

-
Throws:
-

- Nothing. -

-
-
-

-

-
- - - Non-member function operator<<() -
-

-

-
template<typename charT,class traitsT>
-std::basic_ostream<charT,traitsT> &
-operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other);
-
-
-

-
-
Effects:
-

- Writes the representation of other - to stream os. -

-
Returns:
-

- os -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/fib/implementations__fcontext_t__ucontext_t_and_winfiber.html b/doc/html/context/fib/implementations__fcontext_t__ucontext_t_and_winfiber.html deleted file mode 100644 index 627c6e4e..00000000 --- a/doc/html/context/fib/implementations__fcontext_t__ucontext_t_and_winfiber.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -Implementations: fcontext_t, ucontext_t and WinFiber - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - fcontext_t -
-

- The implementation uses fcontext_t per default. fcontext_t - is based on assembler and not available for all platforms. It provides a - much better performance than ucontext_t (the context - switch takes two magnitudes of order less CPU cycles; see section performance) - and WinFiber. -

-
- - - - - -
[Note]Note

- Because the TIB (thread information block on Windows) is not fully described - in the MSDN, it might be possible that not all required TIB-parts are swapped. - Using WinFiber implementation might be an alternative. -

-
- - ucontext_t -
-

- As an alternative, ucontext_t - can be used by compiling with BOOST_USE_UCONTEXT - and b2 property context-impl=ucontext. - ucontext_t might be available on a broader range of - POSIX-platforms but has some disadvantages - (for instance deprecated since POSIX.1-2003, not C99 conform). -

-
- - - - - -
[Note]Note

- __fiber__ supports Segmented stacks - only with ucontext_t as its implementation. -

-
- - WinFiber -
-

- With BOOST_USE_WINFIB and - b2 property context-impl=winfib - Win32-Fibers are used as implementation for __fiber__. -

-
- - - - - -
[Note]Note

- The first call of __fiber__ converts the thread into a Windows fiber by - invoking ConvertThreadToFiber(). If desired, ConvertFiberToThread() has to be called by the user explicitly - in order to release resources allocated by ConvertThreadToFiber() (e.g. after using boost.context). -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/overview.html b/doc/html/context/overview.html deleted file mode 100644 index 14779ec1..00000000 --- a/doc/html/context/overview.html +++ /dev/null @@ -1,96 +0,0 @@ - - - -Overview - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Boost.Context is a foundational library that - provides a sort of cooperative multitasking on a single thread. By providing - an abstraction of the current execution state in the current thread, including - the stack (with local variables) and stack pointer, all registers and CPU flags, - and the instruction pointer, a execution context represents a specific point - in the application's execution path. This is useful for building higher-level - abstractions, like coroutines, cooperative threads - (userland threads) or an equivalent to C# - keyword yield in C++. -

-

- callcc()/continuation - provides the means to suspend the current execution path and to transfer execution - control, thereby permitting another context to run on the current thread. This - state full transfer mechanism enables a context to suspend execution from within - nested functions and, later, to resume from where it was suspended. While the - execution path represented by a continuation - only runs on a single thread, it can be migrated to another thread at any given - time. -

-

- A context switch - between threads requires system calls (involving the OS kernel), which can - cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring control - vias callcc()/continuation - requires only few CPU cycles because it does not involve system calls as it - is done within a single thread. -

-

- All functions and classes are contained in the namespace boost::context. -

-
- - - - - -
[Note]Note

- This library requires C++11! -

-
- - - - - -
[Important]Important

- Windows using fcontext_t: turn off global program optimization (/GL) and - change /EHsc (compiler assumes that functions declared as extern "C" - never throw a C++ exception) to /EHs (tells compiler assumes that functions - declared as extern "C" may throw an exception). -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/performance.html b/doc/html/context/performance.html deleted file mode 100644 index 8f0805bf..00000000 --- a/doc/html/context/performance.html +++ /dev/null @@ -1,94 +0,0 @@ - - - -Performance - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Performance measurements were taken using std::chrono::highresolution_clock, - with overhead corrections. The code was compiled with gcc-6.3.1, using build - options: variant = release, optimization = speed. Tests were executed on dual - Intel XEON E5 2620v4 2.2GHz, 16C/32T, 64GB RAM, running Linux (x86_64). -

-
-

Table 1.1. Performance of context switch

-
----- - - - - - - - - - - -
-

- callcc()/continuation (fcontext_t) -

-
-

- callcc()/continuation (ucontext_t) -

-
-

- callcc()/continuation (Windows-Fiber) -

-
-

- 9 ns / 19 CPU cycles -

-
-

- 547 ns / 1130 CPU cycles -

-
-

- 49 ns / 98 CPU cycles -

-
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/rationale.html b/doc/html/context/rationale.html deleted file mode 100644 index 472681ee..00000000 --- a/doc/html/context/rationale.html +++ /dev/null @@ -1,86 +0,0 @@ - - - -Rationale - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -

- - No - inline-assembler -

-

- Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support - inline assembler. [1]. Inlined assembler generates code bloating which is not welcome - on embedded systems. -

-

- - fcontext_t -

-

- Boost.Context provides the low level API fcontext_t - which is implemented in assembler to provide context swapping operations. fcontext_t - is the part to port to new platforms. -

-
- - - - - -
[Note]Note

- Context switches do not preserve the signal mask on UNIX systems. -

-

- fcontext_t is an opaque pointer. -

- -
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/rationale/other_apis_.html b/doc/html/context/rationale/other_apis_.html deleted file mode 100644 index ff9959c5..00000000 --- a/doc/html/context/rationale/other_apis_.html +++ /dev/null @@ -1,117 +0,0 @@ - - - -Other APIs - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - setjmp()/longjmp() -
-

- C99 defines setjmp()/longjmp() - to provide non-local jumps but it does not require that longjmp() - preserves the current stack frame. Therefore, jumping into a function which - was exited via a call to longjmp() is undefined [2]. -

-
- - ucontext_t -
-

- Since POSIX.1-2004 ucontext_t - is deprecated and was removed in POSIX.1-2008! The function signature of - makecontext() - is: -

-
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
-
-

- The third argument of makecontext() specifies the number of integer arguments - that follow which will require function pointer cast if func - will accept those arguments which is undefined in C99 [3]. -

-

- The arguments in the var-arg list are required to be integers, passing pointers - in var-arg list is not guaranteed to work, especially it will fail for architectures - where pointers are larger than integers. -

-

- ucontext_t preserves signal - mask between context switches which involves system calls consuming a lot - of CPU cycles (ucontext_t is slower; a context switch takes two - magnitutes of order more CPU cycles more than fcontext_t). -

-
- - Windows - fibers -
-

- A drawback of Windows Fiber API is that CreateFiber() does not accept a pointer to user allocated - stack space preventing the reuse of stacks for other context instances. Because - the Windows Fiber API requires to call ConvertThreadToFiber() if SwitchFiber() is called for a thread which has not been - converted to a fiber. For the same reason ConvertFiberToThread() must be called after return from SwitchFiber() - if the thread was forced to be converted to a fiber before (which is inefficient). -

-
if ( ! is_a_fiber() )
-{
-    ConvertThreadToFiber( 0);
-    SwitchToFiber( ctx);
-    ConvertFiberToThread();
-}
-
-

- If the condition _WIN32_WINNT >= _WIN32_WINNT_VISTA - is met function IsThreadAFiber() is provided in order to detect if the current - thread was already converted. Unfortunately Windows XP + SP 2/3 defines - _WIN32_WINNT >= - _WIN32_WINNT_VISTA without providing - IsThreadAFiber(). -

-
-

-

[2] - ISO/IEC 9899:1999, 2005, 7.13.2.1:2 -

-

[3] - ISO/IEC 9899:1999, 2005, J.2 -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/rationale/x86_and_floating_point_env.html b/doc/html/context/rationale/x86_and_floating_point_env.html deleted file mode 100644 index ef2d6a78..00000000 --- a/doc/html/context/rationale/x86_and_floating_point_env.html +++ /dev/null @@ -1,124 +0,0 @@ - - - -x86 and floating-point env - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - i386 -
-

- "The FpCsr and the MxCsr register must be saved and restored before - any call or return by any procedure that needs to modify them ..." - [4]. -

-
- - x86_64 -
-
- - Windows -
-

- MxCsr - "A callee that modifies any of the non-volatile fields within - MxCsr must restore them before returning to its caller. Furthermore, a caller - that has modified any of these fields must restore them to their standard - values before invoking a callee ..." [5]. -

-

- FpCsr - "A callee that modifies any of the fields within FpCsr must - restore them before returning to its caller. Furthermore, a caller that has - modified any of these fields must restore them to their standard values before - invoking a callee ..." [6]. -

-

- "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved - across context switches. There is no explicit calling convention for these - registers." [7]. -

-

- "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7". - [8]. -

-

- "XMM6-XMM15 must be preserved" [9] -

-
- - SysV -
-

- "The control bits of the MxCsr register are callee-saved (preserved - across calls), while the status bits are caller-saved (not preserved). The - x87 status word register is caller-saved, whereas the x87 control word (FpCsr) - is callee-saved." [10]. -

-
-

-

[4] - 'Calling Conventions', Agner Fog -

- - - -

[8] - 'Calling Conventions', Agner Fog -

- -

[10] - SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, - 3.2.1 -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/reference.html b/doc/html/context/reference.html deleted file mode 100644 index 6bb01403..00000000 --- a/doc/html/context/reference.html +++ /dev/null @@ -1,104 +0,0 @@ - - - -Reference - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- - ARM -

-
    -
  • - AAPCS ABI: Procedure Call Standard for the ARM Architecture -
  • -
  • - AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement -
  • -
-

- - MIPS -

-
  • - O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement -
-

- - PowerPC32 -

-
  • - SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement -
-

- - PowerPC64 -

-
  • - SYSV ABI: PowerPC User Instruction Set Architecture, Book I -
-

- - X86-32 -

-
    -
  • - SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture - Processor Supplement -
  • -
  • - MS PE: Calling - Conventions -
  • -
-

- - X86-64 -

-
    -
  • - SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor - Supplement -
  • -
  • - MS PE: x64 - Software Conventions -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/requirements.html b/doc/html/context/requirements.html deleted file mode 100644 index ae8492f9..00000000 --- a/doc/html/context/requirements.html +++ /dev/null @@ -1,112 +0,0 @@ - - - -Requirements - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- If Boost.Context uses fcontext_t (the default) - as its implementation, it must be built for the particular compiler(s) and - CPU architecture(s) being targeted. Using fcontext_t, - Boost.Context includes assembly code and, - therefore, requires GNU as and GNU preprocessor for supported POSIX systems, - MASM for Windows/x86 systems and ARMasm for Windows/arm systems. -

-
- - - - - -
[Note]Note

- MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit. -

-
- - - - - -
[Important]Important

- Please note that address-model=64 must be - given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit - code will be generated. -

-
- - - - - -
[Important]Important

- For cross-compiling the lib you must specify certain additional properties - at bjam command line: target-os, abi, binary-format, - architecture and address-model. -

-
- - - - - -
[Important]Important

- Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must - be specified at bjam command line. -

-
- - - - - -
[Important]Important

- Windows using fcontext_t: turn off global program optimization (/GL) and - change /EHsc (compiler assumes that functions declared as extern "C" - never throw a C++ exception) to /EHs (tells compiler assumes that functions - declared as extern "C" may throw an exception). -

-

- Because this library uses C++11 extensively, it requires a compatible compiler. - Known minimum working versions are as follows: Microsoft Visual Studio 2015 - (msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other - compilers may work, if they support the following language features: auto declarations, - constexpr, defaulted functions, final, hdr thread, hdr tuple, lambdas, noexcept, - nullptr, rvalue references, template aliases. thread local, variadic templates. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack.html b/doc/html/context/stack.html deleted file mode 100644 index 1c6c303b..00000000 --- a/doc/html/context/stack.html +++ /dev/null @@ -1,177 +0,0 @@ - - - -Stack allocation - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -

- The memory used by the stack is allocated/deallocated via a StackAllocator - which is required to model a stack-allocator concept. -

-

- - stack-allocator - concept -

-

- A StackAllocator must satisfy the stack-allocator - concept requirements shown in the following table, in which a is an object of a StackAllocator - type, sctx is a stack_context, and size - is a std::size_t: -

-
----- - - - - - - - - - - - - - - - - - - - - - - -
-

- expression -

-
-

- return type -

-
-

- notes -

-
-

- a(size) -

-
- -

- creates a stack allocator -

-
-

- a.allocate() -

-
-

- stack_context -

-
-

- creates a stack -

-
-

- a.deallocate( - sctx) -

-
-

- void -

-
-

- deallocates the stack created by a.allocate() -

-
-
- - - - - -
[Important]Important

- The implementation of allocate() might include logic to protect against - exceeding the context's available stack size rather than leaving it as undefined - behaviour. -

-
- - - - - -
[Important]Important

- Calling deallocate() - with a stack_context not - set by allocate() - results in undefined behaviour. -

-
- - - - - -
[Note]Note

- Depending on the architecture allocate() stores an address from the top of the stack - (growing downwards) or the bottom of the stack (growing upwards). -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/fixedsize.html b/doc/html/context/stack/fixedsize.html deleted file mode 100644 index 57c0fda5..00000000 --- a/doc/html/context/stack/fixedsize.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -Class fixedsize_stack - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Boost.Context provides the class fixedsize_stack - which models the stack-allocator concept. In contrast - to protected_fixedsize_stack it does not append a guard - page at the end of each stack. The memory is simply managed by std::malloc() and std::free(). -

-
#include <boost/context/fixedsize_stack.hpp>
-
-template< typename traitsT >
-struct basic_fixedsize_stack {
-    typedef traitT  traits_type;
-
-    basic_fixesize_stack(std::size_t size = traits_type::default_size());
-
-    stack_context allocate();
-
-    void deallocate( stack_context &);
-}
-
-typedef basic_fixedsize_stack< stack_traits > fixedsize_stack;
-
-
- - stack_context allocate() -
-
-

-
-
Preconditions:
-

- traits_type::minimum:size() - <= size - and ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= size). -

-
Effects:
-

- Allocates memory of at least size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. -

-
-
-
- - void deallocate( stack_context - & sctx) -
-
-

-
-
Preconditions:
-

- sctx.sp is valid, traits_type::minimum:size() <= sctx.size and ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). -

-
Effects:
-

- Deallocates the stack space. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/pooled_fixedsize.html b/doc/html/context/stack/pooled_fixedsize.html deleted file mode 100644 index 870cca78..00000000 --- a/doc/html/context/stack/pooled_fixedsize.html +++ /dev/null @@ -1,137 +0,0 @@ - - - -Class pooled_fixedsize_stack - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Boost.Context provides the class pooled_fixedsize_stack - which models the stack-allocator concept. In contrast - to protected_fixedsize_stack it does not append a guard - page at the end of each stack. The memory is managed internally by boost::pool<>. -

-
#include <boost/context/pooled_fixedsize_stack.hpp>
-
-template< typename traitsT >
-struct basic_pooled_fixedsize_stack {
-    typedef traitT  traits_type;
-
-    basic_pooled_fixedsize_stack(std::size_t stack_size = traits_type::default_size(), std::size_t next_size = 32, std::size_t max_size = 0);
-
-    stack_context allocate();
-
-    void deallocate( stack_context &);
-}
-
-typedef basic_pooled_fixedsize_stack< stack_traits > pooled_fixedsize_stack;
-
-
- - basic_pooled_fixedsize_stack(std::size_t - stack_size, - std::size_t next_size, std::size_t max_size) -
-
-

-
-
Preconditions:
-

- ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= stack_size) - and 0 < - nest_size. -

-
Effects:
-

- Allocates memory of at least stack_size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. Argument next_size - determines the number of stacks to request from the system the first - time that *this - needs to allocate system memory. The third argument max_size - controls how many memory might be allocated for stacks - a value of - zero means no upper limit. -

-
-
-
- - stack_context allocate() -
-
-

-
-
Preconditions:
-

- ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= stack_size). -

-
Effects:
-

- Allocates memory of at least stack_size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. -

-
-
-
- - void deallocate( stack_context - & sctx) -
-
-

-
-
Preconditions:
-

- sctx.sp is valid, ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). -

-
Effects:
-

- Deallocates the stack space. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/protected_fixedsize.html b/doc/html/context/stack/protected_fixedsize.html deleted file mode 100644 index edb1accb..00000000 --- a/doc/html/context/stack/protected_fixedsize.html +++ /dev/null @@ -1,132 +0,0 @@ - - - -Class protected_fixedsize - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Boost.Context provides the class protected_fixedsize_stack - which models the stack-allocator concept. It appends - a guard page at the end of each stack to protect against exceeding the stack. - If the guard page is accessed (read or write operation) a segmentation fault/access - violation is generated by the operating system. -

-
- - - - - -
[Important]Important

- Using protected_fixedsize_stack is expensive. That - is, launching a new coroutine with a new stack is expensive; the allocated - stack is just as efficient to use as any other stack. -

-
- - - - - -
[Note]Note

- The appended guard page - is not mapped to physical memory, only - virtual addresses are used. -

-
#include <boost/context/protected_fixedsize.hpp>
-
-template< typename traitsT >
-struct basic_protected_fixedsize {
-    typedef traitT  traits_type;
-
-    basic_protected_fixesize(std::size_t size = traits_type::default_size());
-
-    stack_context allocate();
-
-    void deallocate( stack_context &);
-}
-
-typedef basic_protected_fixedsize< stack_traits > protected_fixedsize
-
-
- - stack_context allocate() -
-
-

-
-
Preconditions:
-

- traits_type::minimum:size() - <= size - and ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= size). -

-
Effects:
-

- Allocates memory of at least size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. -

-
-
-
- - void deallocate( stack_context - & sctx) -
-
-

-
-
Preconditions:
-

- sctx.sp is valid, traits_type::minimum:size() <= sctx.size and ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). -

-
Effects:
-

- Deallocates the stack space. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/sanitizers.html b/doc/html/context/stack/sanitizers.html deleted file mode 100644 index 06d3b0e7..00000000 --- a/doc/html/context/stack/sanitizers.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Support for sanitizers - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Sanitizers (GCC/Clang) are confused by the stack switches. The library is - required to be compiled with property (b2 command-line) context-impl=ucontext and compilers sanitizer options. - Users must define BOOST_USE_ASAN - before including any Boost.Context headers when linking against Boost binaries. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/segmented.html b/doc/html/context/stack/segmented.html deleted file mode 100644 index b2cf3f3f..00000000 --- a/doc/html/context/stack/segmented.html +++ /dev/null @@ -1,151 +0,0 @@ - - - -Class segmented_stack - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Boost.Context supports usage of a segmented_stack, e. g. the - size of the stack grows on demand. The coroutine is created with a minimal - stack size and will be increased as required. Class segmented_stack - models the stack-allocator concept. In contrast to - protected_fixedsize_stack and fixedsize_stack - it creates a stack which grows on demand. -

-
- - - - - -
[Note]Note

- Segmented stacks are currently only supported by gcc - from version 4.7 clang - from version 3.4 onwards. In order to - use a segmented_stack Boost.Context - must be built with property segmented-stacks, - e.g. toolset=gcc segmented-stacks=on and - applying BOOST_USE_SEGMENTED_STACKS - at b2/bjam command line. -

-
- - - - - -
[Note]Note

- Segmented stacks can only be used with callcc() - (using ucontext_t) -

-

- . -

-
#include <boost/context/segmented_stack.hpp>
-
-template< typename traitsT >
-struct basic_segmented_stack {
-    typedef traitT  traits_type;
-
-    basic_segmented_stack(std::size_t size = traits_type::default_size());
-
-    stack_context allocate();
-
-    void deallocate( stack_context &);
-}
-
-typedef basic_segmented_stack< stack_traits > segmented_stack;
-
-
- - stack_context allocate() -
-
-

-
-
Preconditions:
-

- traits_type::minimum:size() - <= size - and ! traits_type::is_unbounded() && - ( traits_type::maximum:size() >= size). -

-
Effects:
-

- Allocates memory of at least size - Bytes and stores a pointer to the stack and its actual size in sctx. Depending on the architecture - (the stack grows downwards/upwards) the stored address is the highest/lowest - address of the stack. -

-
-
-
- - void deallocate( stack_context - & sctx) -
-
-

-
-
Preconditions:
-

- sctx.sp is valid, traits_type::minimum:size() <= sctx.size and ! - traits_type::is_unbounded() - && ( - traits_type::maximum:size() - >= sctx.size). -

-
Effects:
-

- Deallocates the stack space. -

-
-
-
- - - - - -
[Note]Note

- If the library is compiled for segmented stacks, segmented_stack - is the only available stack allocator. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/stack_context.html b/doc/html/context/stack/stack_context.html deleted file mode 100644 index 76040719..00000000 --- a/doc/html/context/stack/stack_context.html +++ /dev/null @@ -1,84 +0,0 @@ - - - -Class stack_context - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Boost.Context provides the class stack_context - which will contain the stack pointer and the size of the stack. In case of - a segmented_stack, - stack_context contains some extra control structures. -

-
struct stack_context {
-    void    *   sp;
-    std::size_t size;
-
-    // might contain additional control structures
-    // for segmented stacks
-}
-
-
- - void * sp -
-
-

-
-
Value:
-

- Pointer to the beginning of the stack. -

-
-
-
- - std::size_t - size -
-
-

-
-
Value:
-

- Actual size of the stack. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/stack_traits.html b/doc/html/context/stack/stack_traits.html deleted file mode 100644 index b33c6441..00000000 --- a/doc/html/context/stack/stack_traits.html +++ /dev/null @@ -1,157 +0,0 @@ - - - -Class stack_traits - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- stack_traits models a stack-traits - providing a way to access certain properties defined by the environment. Stack - allocators use stack-traits to allocate stacks. -

-
#include <boost/context/stack_traits.hpp>
-
-struct stack_traits {
-    static bool is_unbounded() noexcept;
-
-    static std::size_t page_size() noexcept;
-
-    static std::size_t default_size() noexcept;
-
-    static std::size_t minimum_size() noexcept;
-
-    static std::size_t maximum_size() noexcept;
-}
-
-
- - static bool is_unbounded() -
-
-

-
-
Returns:
-

- Returns true if the environment - defines no limit for the size of a stack. -

-
Throws:
-

- Nothing. -

-
-
-
- - static std::size_t page_size() -
-
-

-
-
Returns:
-

- Returns the page size in bytes. -

-
Throws:
-

- Nothing. -

-
-
-
- - static std::size_t default_size() -
-
-

-
-
Returns:
-

- Returns a default stack size, which may be platform specific. If the - stack is unbounded then the present implementation returns the maximum - of 64 kB - and minimum_size(). -

-
Throws:
-

- Nothing. -

-
-
-
- - static std::size_t minimum_size() -
-
-

-
-
Returns:
-

- Returns the minimum size in bytes of stack defined by the environment - (Win32 4kB/Win64 8kB, defined by rlimit on POSIX). -

-
Throws:
-

- Nothing. -

-
-
-
- - static std::size_t maximum_size() -
-
-

-
-
Preconditions:
-

- is_unbounded() - returns false. -

-
Returns:
-

- Returns the maximum size in bytes of stack defined by the environment. -

-
Throws:
-

- Nothing. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/stack/valgrind.html b/doc/html/context/stack/valgrind.html deleted file mode 100644 index 7602c2dd..00000000 --- a/doc/html/context/stack/valgrind.html +++ /dev/null @@ -1,51 +0,0 @@ - - - -Support for valgrind - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Running programs that switch stacks under valgrind causes problems. Property - (b2 command-line) valgrind=on let - valgrind treat the memory regions as stack space which suppresses the errors. - Users must define BOOST_USE_VALGRIND - before including any Boost.Context headers when linking against Boost binaries - compiled with valgrind=on. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context/struct__preallocated_.html b/doc/html/context/struct__preallocated_.html deleted file mode 100644 index b89ad8ac..00000000 --- a/doc/html/context/struct__preallocated_.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -Struct preallocated - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
struct preallocated {
-    void        *   sp;
-    std::size_t     size;
-    stack_context   sctx;
-
-    preallocated( void * sp, std:size_t size, stack_allocator sctx) noexcept;
-};
-
-

- - Constructor -

-
preallocated( void * sp, std:size_t size, stack_allocator sctx) noexcept;
-
-
-

-
-
Effects:
-

- Creates an object of preallocated. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/context_HTML.manifest b/doc/html/context_HTML.manifest deleted file mode 100644 index 51f19f9e..00000000 --- a/doc/html/context_HTML.manifest +++ /dev/null @@ -1,27 +0,0 @@ -index.html -context/overview.html -context/requirements.html -context/ff.html -context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html -context/ff/class__fiber_.html -context/cc.html -context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html -context/cc/class__continuation_.html -context/stack.html -context/stack/protected_fixedsize.html -context/stack/pooled_fixedsize.html -context/stack/fixedsize.html -context/stack/segmented.html -context/stack/stack_traits.html -context/stack/stack_context.html -context/stack/valgrind.html -context/stack/sanitizers.html -context/struct__preallocated_.html -context/performance.html -context/architectures.html -context/architectures/crosscompiling.html -context/rationale.html -context/rationale/other_apis_.html -context/rationale/x86_and_floating_point_env.html -context/reference.html -context/acknowledgements.html diff --git a/doc/html/index.html b/doc/html/index.html deleted file mode 100644 index 4c25fa5f..00000000 --- a/doc/html/index.html +++ /dev/null @@ -1,87 +0,0 @@ - - - -Chapter 1. Context - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
Next
-
-
-

-Chapter 1. Context

-

-Oliver Kowalke -

-
-
-

- 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) -

-
-
- -
- - - -

Last revised: October 02, 2019 at 06:15:46 GMT

-
-
Next
- - From 6a720b19eeccfe00d8094aca38cfd6e8a7a37735 Mon Sep 17 00:00:00 2001 From: Mateusz Jakub Fila Date: Wed, 19 Aug 2026 09:06:37 +0200 Subject: [PATCH 2/2] fix grammar in documentation --- doc/callcc.qbk | 4 ++-- doc/fiber.qbk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/callcc.qbk b/doc/callcc.qbk index 0b097092..4c2f146f 100644 --- a/doc/callcc.qbk +++ b/doc/callcc.qbk @@ -234,7 +234,7 @@ an exception. my_exception: abc In this exception `my_exception` is throw from a function invoked on-top of -continuation `c` and catched inside the `for`-loop. +continuation `c` and caught inside the `for`-loop. [heading Stack unwinding] On construction of __con__ a stack is allocated. @@ -397,7 +397,7 @@ of the stack.] In this example a recursive descent parser uses a callback to emit a newly passed symbol. Using __callcc__ the control flow can be inverted, e.g. the -user-code pulls parsed symbols from the parser - instead to get pushed from the +user-code pulls parsed symbols from the parser - instead of getting pushed from the parser (via callback). The data (character) is transferred between the two continuations. diff --git a/doc/fiber.qbk b/doc/fiber.qbk index 656cd251..6be3f10f 100644 --- a/doc/fiber.qbk +++ b/doc/fiber.qbk @@ -220,7 +220,7 @@ an exception. my_exception: abc In this exception `my_exception` is throw from a function invoked on-top of -fiber `f` and catched inside the `for`-loop. +fiber `f` and caught inside the `for`-loop. [heading Stack unwinding] On construction of __fib__ a stack is allocated. @@ -381,7 +381,7 @@ of the stack.] In this example a recursive descent parser uses a callback to emit a newly passed symbol. Using __fib__ the control flow can be inverted, e.g. the -user-code pulls parsed symbols from the parser - instead to get pushed from the +user-code pulls parsed symbols from the parser - instead of getting pushed from the parser (via callback). The data (character) is transferred between the two fibers.