mirror of
https://github.com/boostorg/context.git
synced 2026-01-19 04:02:17 +00:00
rename class fiber to fiber_context
This commit is contained in:
@@ -869,7 +869,7 @@ alias impl_sources
|
||||
|
||||
# ucontext_t
|
||||
alias impl_sources
|
||||
: fiber.cpp
|
||||
: fiber_context.cpp
|
||||
: <context-impl>ucontext
|
||||
[ requires cxx11_auto_declarations
|
||||
cxx11_constexpr
|
||||
@@ -888,7 +888,7 @@ alias impl_sources
|
||||
|
||||
# WinFiber
|
||||
alias impl_sources
|
||||
: fiber.cpp
|
||||
: fiber_context.cpp
|
||||
: <context-impl>winfib
|
||||
[ requires cxx11_auto_declarations
|
||||
cxx11_constexpr
|
||||
|
||||
@@ -15,7 +15,7 @@ import os ;
|
||||
import toolset ;
|
||||
import architecture ;
|
||||
|
||||
project boost/context/example/fiber
|
||||
project boost/context/example/fiber_context
|
||||
: requirements
|
||||
<library>/boost/context//boost_context
|
||||
<target-os>linux,<toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <libunwind.h>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
@@ -45,13 +45,13 @@ void foo() {
|
||||
bar();
|
||||
}
|
||||
|
||||
ctx::fiber f1( ctx::fiber && c) {
|
||||
ctx::fiber_context f1( ctx::fiber_context && c) {
|
||||
foo();
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::fiber{ f1 }.resume();
|
||||
ctx::fiber_context{ f1 }.resume();
|
||||
std::cout << "main: done" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -8,13 +8,13 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
int main() {
|
||||
ctx::fiber f1, f2, f3;
|
||||
f3 = ctx::fiber{[&](ctx::fiber && f)->ctx::fiber{
|
||||
ctx::fiber_context f1, f2, f3;
|
||||
f3 = ctx::fiber_context{[&](ctx::fiber_context && f)->ctx::fiber_context{
|
||||
f2 = std::move( f);
|
||||
for (;;) {
|
||||
std::cout << "f3\n";
|
||||
@@ -22,7 +22,7 @@ int main() {
|
||||
}
|
||||
return {};
|
||||
}};
|
||||
f2 = ctx::fiber{[&](ctx::fiber && f)->ctx::fiber{
|
||||
f2 = ctx::fiber_context{[&](ctx::fiber_context && f)->ctx::fiber_context{
|
||||
f1 = std::move( f);
|
||||
for (;;) {
|
||||
std::cout << "f2\n";
|
||||
@@ -30,7 +30,7 @@ int main() {
|
||||
}
|
||||
return {};
|
||||
}};
|
||||
f1 = ctx::fiber{[&](ctx::fiber && /*main*/)->ctx::fiber{
|
||||
f1 = ctx::fiber_context{[&](ctx::fiber_context && /*main*/)->ctx::fiber_context{
|
||||
for (;;) {
|
||||
std::cout << "f1\n";
|
||||
f3 = std::move( f2).resume();
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <iostream>
|
||||
#include <emmintrin.h>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
@@ -28,8 +28,8 @@ void echoSSE( int i) {
|
||||
|
||||
int main( int argc, char * argv[]) {
|
||||
int i = 0;
|
||||
ctx::fiber f{
|
||||
[&i](ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[&i](ctx::fiber_context && f) {
|
||||
for (;;) {
|
||||
std::cout << i;
|
||||
echoSSE( i);
|
||||
@@ -7,11 +7,11 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::fiber bar( ctx::fiber && f) {
|
||||
ctx::fiber_context bar( ctx::fiber_context && f) {
|
||||
do {
|
||||
std::cout << "bar\n";
|
||||
f = std::move( f).resume();
|
||||
@@ -20,7 +20,7 @@ ctx::fiber bar( ctx::fiber && f) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::fiber f{ bar };
|
||||
ctx::fiber_context f{ bar };
|
||||
do {
|
||||
std::cout << "foo\n";
|
||||
f = std::move( f).resume();
|
||||
@@ -8,14 +8,14 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
int main() {
|
||||
int a;
|
||||
ctx::fiber f{
|
||||
[&a](ctx::fiber && f){
|
||||
ctx::fiber_context f{
|
||||
[&a](ctx::fiber_context && f){
|
||||
a=0;
|
||||
int b=1;
|
||||
for(;;){
|
||||
@@ -7,14 +7,14 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
int main() {
|
||||
int data = 1;
|
||||
ctx::fiber f{
|
||||
[&data](ctx::fiber && f){
|
||||
ctx::fiber_context f{
|
||||
[&data](ctx::fiber_context && f){
|
||||
std::cout << "entered first time: " << data << std::endl;
|
||||
data += 2;
|
||||
f = std::move( f).resume();
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
@@ -40,8 +40,8 @@ public:
|
||||
|
||||
int main() {
|
||||
moveable data{ 1 };
|
||||
ctx::fiber f{ std::allocator_arg, ctx::fixedsize_stack{},
|
||||
[&data](ctx::fiber && f){
|
||||
ctx::fiber_context f{ std::allocator_arg, ctx::fixedsize_stack{},
|
||||
[&data](ctx::fiber_context && f){
|
||||
std::cout << "entered first time: " << data.value << std::endl;
|
||||
data = std::move( moveable{ 3 });
|
||||
f = std::move( f).resume();
|
||||
@@ -7,11 +7,11 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::fiber f1( ctx::fiber && f) {
|
||||
ctx::fiber_context f1( ctx::fiber_context && f) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
f = std::move( f).resume();
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
@@ -19,7 +19,7 @@ ctx::fiber f1( ctx::fiber && f) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::fiber f{ f1 };
|
||||
ctx::fiber_context f{ f1 };
|
||||
f = std::move( f).resume();
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
f = std::move( f).resume();
|
||||
@@ -8,13 +8,13 @@
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
int main() {
|
||||
int data = 0;
|
||||
ctx::fiber f{ [&data](ctx::fiber && f) {
|
||||
ctx::fiber_context f{ [&data](ctx::fiber_context && f) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
data += 1;
|
||||
f = std::move( f).resume();
|
||||
@@ -30,7 +30,7 @@ int main() {
|
||||
f = std::move( f).resume();
|
||||
std::cout << "f1: returned second time: " << data << std::endl;
|
||||
data += 1;
|
||||
f = std::move( f).resume_with([&data](ctx::fiber && f){
|
||||
f = std::move( f).resume_with([&data](ctx::fiber_context && f){
|
||||
std::cout << "f2: entered: " << data << std::endl;
|
||||
data = -1;
|
||||
return std::move( f);
|
||||
@@ -8,11 +8,11 @@
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::fiber f1( ctx::fiber && f) {
|
||||
ctx::fiber_context f1( ctx::fiber_context && f) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
f = std::move( f).resume();
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
@@ -21,13 +21,13 @@ ctx::fiber f1( ctx::fiber && f) {
|
||||
return std::move( f);
|
||||
}
|
||||
|
||||
ctx::fiber f2( ctx::fiber && f) {
|
||||
ctx::fiber_context f2( ctx::fiber_context && f) {
|
||||
std::cout << "f2: entered" << std::endl;
|
||||
return std::move( f);
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::fiber f{ f1 };
|
||||
ctx::fiber_context f{ f1 };
|
||||
f = std::move( f).resume();
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
f = std::move( f).resume();
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
@@ -98,7 +98,7 @@ int main() {
|
||||
char c;
|
||||
bool done = false;
|
||||
// execute parser in new execution context
|
||||
ctx::fiber source{[&is,&c,&done](ctx::fiber && sink){
|
||||
ctx::fiber_context source{[&is,&c,&done](ctx::fiber_context && sink){
|
||||
// create parser with callback function
|
||||
Parser p( is,
|
||||
[&sink,&c](char c_){
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
@@ -41,8 +41,8 @@ int main() {
|
||||
std::cout << "initial stack size = " << ctx::fixedsize_stack::traits_type::default_size() / 1024 << "kB" << std::endl;
|
||||
std::cout << "application might fail" << std::endl;
|
||||
#endif
|
||||
ctx::fiber{
|
||||
[count](ctx::fiber && f){
|
||||
ctx::fiber_context{
|
||||
[count](ctx::fiber_context && f){
|
||||
bar( count);
|
||||
return std::move( f);
|
||||
}}.resume();
|
||||
@@ -10,20 +10,20 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
struct my_exception : public std::runtime_error {
|
||||
ctx::fiber f;
|
||||
my_exception( ctx::fiber && f_, std::string const& what) :
|
||||
ctx::fiber_context f;
|
||||
my_exception( ctx::fiber_context && f_, std::string const& what) :
|
||||
std::runtime_error{ what },
|
||||
f{ std::move( f_) } {
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
ctx::fiber f{[](ctx::fiber && f) ->ctx::fiber {
|
||||
ctx::fiber_context f{[](ctx::fiber_context && f) ->ctx::fiber_context {
|
||||
std::cout << "entered" << std::endl;
|
||||
try {
|
||||
f = std::move( f).resume();
|
||||
@@ -34,7 +34,7 @@ int main() {
|
||||
return {};
|
||||
}};
|
||||
f = std::move( f).resume();
|
||||
f = std::move( f).resume_with([](ctx::fiber && f) ->ctx::fiber {
|
||||
f = std::move( f).resume_with([](ctx::fiber_context && f) ->ctx::fiber_context {
|
||||
throw my_exception(std::move( f), "abc");
|
||||
return {};
|
||||
});
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
extern "C" {
|
||||
void __sanitizer_start_switch_fiber( void **, const void *, size_t);
|
||||
void __sanitizer_finish_switch_fiber( void *, const void **, size_t *);
|
||||
void __sanitizer_start_switch_fiber_context( void **, const void *, size_t);
|
||||
void __sanitizer_finish_switch_fiber_context( void *, const void **, size_t *);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if defined(BOOST_USE_UCONTEXT)
|
||||
#include <boost/context/fiber_ucontext.hpp>
|
||||
#include <boost/context/fiber_context_ucontext.hpp>
|
||||
#elif defined(BOOST_USE_WINFIB)
|
||||
#include <boost/context/fiber_winfib.hpp>
|
||||
#include <boost/context/fiber_context_winfib.hpp>
|
||||
#else
|
||||
#include <boost/context/fiber_fcontext.hpp>
|
||||
#include <boost/context/fiber_context_fcontext.hpp>
|
||||
#endif
|
||||
@@ -65,13 +65,13 @@ namespace context {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
transfer_t fiber_unwind( transfer_t t) {
|
||||
transfer_t fiber_context_unwind( transfer_t t) {
|
||||
throw forced_unwind( t.fctx);
|
||||
return { nullptr, nullptr };
|
||||
}
|
||||
|
||||
template< typename Rec >
|
||||
transfer_t fiber_exit( transfer_t t) noexcept {
|
||||
transfer_t fiber_context_exit( transfer_t t) noexcept {
|
||||
Rec * rec = static_cast< Rec * >( t.data);
|
||||
#if BOOST_CONTEXT_SHADOW_STACK
|
||||
// destory shadow stack
|
||||
@@ -85,7 +85,7 @@ transfer_t fiber_exit( transfer_t t) noexcept {
|
||||
}
|
||||
|
||||
template< typename Rec >
|
||||
void fiber_entry( transfer_t t) noexcept {
|
||||
void fiber_context_entry( transfer_t t) noexcept {
|
||||
// transfer control structure to the context-stack
|
||||
Rec * rec = static_cast< Rec * >( t.data);
|
||||
BOOST_ASSERT( nullptr != t.fctx);
|
||||
@@ -100,16 +100,16 @@ void fiber_entry( transfer_t t) noexcept {
|
||||
}
|
||||
BOOST_ASSERT( nullptr != t.fctx);
|
||||
// destroy context-stack of `this`context on next context
|
||||
ontop_fcontext( t.fctx, rec, fiber_exit< Rec >);
|
||||
ontop_fcontext( t.fctx, rec, fiber_context_exit< Rec >);
|
||||
BOOST_ASSERT_MSG( false, "context already terminated");
|
||||
}
|
||||
|
||||
template< typename Ctx, typename Fn >
|
||||
transfer_t fiber_ontop( transfer_t t) {
|
||||
transfer_t fiber_context_ontop( transfer_t t) {
|
||||
BOOST_ASSERT( nullptr != t.data);
|
||||
auto p = *static_cast< Fn * >( t.data);
|
||||
t.data = nullptr;
|
||||
// execute function, pass fiber via reference
|
||||
// execute function, pass fiber_context via reference
|
||||
Ctx c = p( Ctx{ t.fctx } );
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
return { exchange( c.fctx_, nullptr), nullptr };
|
||||
@@ -119,31 +119,31 @@ transfer_t fiber_ontop( transfer_t t) {
|
||||
}
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
class fiber_record {
|
||||
class fiber_context_record {
|
||||
private:
|
||||
stack_context sctx_;
|
||||
typename std::decay< StackAlloc >::type salloc_;
|
||||
typename std::decay< Fn >::type fn_;
|
||||
|
||||
static void destroy( fiber_record * p) noexcept {
|
||||
static void destroy( fiber_context_record * p) noexcept {
|
||||
typename std::decay< StackAlloc >::type salloc = std::move( p->salloc_);
|
||||
stack_context sctx = p->sctx_;
|
||||
// deallocate fiber_record
|
||||
p->~fiber_record();
|
||||
// deallocate fiber_context_record
|
||||
p->~fiber_context_record();
|
||||
// destroy stack with stack allocator
|
||||
salloc.deallocate( sctx);
|
||||
}
|
||||
|
||||
public:
|
||||
fiber_record( stack_context sctx, StackAlloc && salloc,
|
||||
fiber_context_record( stack_context sctx, StackAlloc && salloc,
|
||||
Fn && fn) noexcept :
|
||||
sctx_( sctx),
|
||||
salloc_( std::forward< StackAlloc >( salloc)),
|
||||
fn_( std::forward< Fn >( fn) ) {
|
||||
}
|
||||
|
||||
fiber_record( fiber_record const&) = delete;
|
||||
fiber_record & operator=( fiber_record const&) = delete;
|
||||
fiber_context_record( fiber_context_record const&) = delete;
|
||||
fiber_context_record & operator=( fiber_context_record const&) = delete;
|
||||
|
||||
void deallocate() noexcept {
|
||||
destroy( this);
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
};
|
||||
|
||||
template< typename Record, typename StackAlloc, typename Fn >
|
||||
fcontext_t create_fiber1( StackAlloc && salloc, Fn && fn) {
|
||||
fcontext_t create_fiber_context1( StackAlloc && salloc, Fn && fn) {
|
||||
auto sctx = salloc.allocate();
|
||||
// reserve space for control structure
|
||||
void * storage = reinterpret_cast< void * >(
|
||||
@@ -201,14 +201,14 @@ fcontext_t create_fiber1( StackAlloc && salloc, Fn && fn) {
|
||||
*((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 8)) = (unsigned long) ss_base;
|
||||
*((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 16)) = ss_size;
|
||||
#endif
|
||||
const fcontext_t fctx = make_fcontext( stack_top, size, & fiber_entry< Record >);
|
||||
const fcontext_t fctx = make_fcontext( stack_top, size, & fiber_context_entry< Record >);
|
||||
BOOST_ASSERT( nullptr != fctx);
|
||||
// transfer control structure to context-stack
|
||||
return jump_fcontext( fctx, record).fctx;
|
||||
}
|
||||
|
||||
template< typename Record, typename StackAlloc, typename Fn >
|
||||
fcontext_t create_fiber2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
fcontext_t create_fiber_context2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
// reserve space for control structure
|
||||
void * storage = reinterpret_cast< void * >(
|
||||
( reinterpret_cast< uintptr_t >( palloc.sp) - static_cast< uintptr_t >( sizeof( Record) ) )
|
||||
@@ -242,7 +242,7 @@ fcontext_t create_fiber2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
*((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 8)) = (unsigned long) ss_base;
|
||||
*((unsigned long*)(reinterpret_cast< uintptr_t >( storage)- 16)) = ss_size;
|
||||
#endif
|
||||
const fcontext_t fctx = make_fcontext( stack_top, size, & fiber_entry< Record >);
|
||||
const fcontext_t fctx = make_fcontext( stack_top, size, & fiber_context_entry< Record >);
|
||||
BOOST_ASSERT( nullptr != fctx);
|
||||
// transfer control structure to context-stack
|
||||
return jump_fcontext( fctx, record).fctx;
|
||||
@@ -250,50 +250,50 @@ fcontext_t create_fiber2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
|
||||
}
|
||||
|
||||
class fiber {
|
||||
class fiber_context {
|
||||
private:
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend class detail::fiber_record;
|
||||
friend class detail::fiber_context_record;
|
||||
|
||||
template< typename Ctx, typename Fn >
|
||||
friend detail::transfer_t
|
||||
detail::fiber_ontop( detail::transfer_t);
|
||||
detail::fiber_context_ontop( detail::transfer_t);
|
||||
|
||||
detail::fcontext_t fctx_{ nullptr };
|
||||
|
||||
fiber( detail::fcontext_t fctx) noexcept :
|
||||
fiber_context( detail::fcontext_t fctx) noexcept :
|
||||
fctx_{ fctx } {
|
||||
}
|
||||
|
||||
public:
|
||||
fiber() noexcept = default;
|
||||
fiber_context() noexcept = default;
|
||||
|
||||
template< typename Fn, typename = detail::disable_overload< fiber, Fn > >
|
||||
fiber( Fn && fn) :
|
||||
fiber{ std::allocator_arg, fixedsize_stack(), std::forward< Fn >( fn) } {
|
||||
template< typename Fn, typename = detail::disable_overload< fiber_context, Fn > >
|
||||
fiber_context( Fn && fn) :
|
||||
fiber_context{ std::allocator_arg, fixedsize_stack(), std::forward< Fn >( fn) } {
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) :
|
||||
fctx_{ detail::create_fiber1< detail::fiber_record< fiber, StackAlloc, Fn > >(
|
||||
fiber_context( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) :
|
||||
fctx_{ detail::create_fiber_context1< detail::fiber_context_record< fiber_context, StackAlloc, Fn > >(
|
||||
std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) } {
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) :
|
||||
fctx_{ detail::create_fiber2< detail::fiber_record< fiber, StackAlloc, Fn > >(
|
||||
fiber_context( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) :
|
||||
fctx_{ detail::create_fiber_context2< detail::fiber_context_record< fiber_context, StackAlloc, Fn > >(
|
||||
palloc, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) } {
|
||||
}
|
||||
|
||||
#if defined(BOOST_USE_SEGMENTED_STACKS)
|
||||
template< typename Fn >
|
||||
fiber( std::allocator_arg_t, segmented_stack, Fn &&);
|
||||
fiber_context( std::allocator_arg_t, segmented_stack, Fn &&);
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, preallocated, segmented_stack, Fn &&);
|
||||
fiber_context( std::allocator_arg_t, preallocated, segmented_stack, Fn &&);
|
||||
#endif
|
||||
|
||||
~fiber() {
|
||||
~fiber_context() {
|
||||
if ( BOOST_UNLIKELY( nullptr != fctx_) ) {
|
||||
detail::ontop_fcontext(
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
@@ -302,26 +302,26 @@ public:
|
||||
std::exchange( fctx_, nullptr),
|
||||
#endif
|
||||
nullptr,
|
||||
detail::fiber_unwind);
|
||||
detail::fiber_context_unwind);
|
||||
}
|
||||
}
|
||||
|
||||
fiber( fiber && other) noexcept {
|
||||
fiber_context( fiber_context && other) noexcept {
|
||||
swap( other);
|
||||
}
|
||||
|
||||
fiber & operator=( fiber && other) noexcept {
|
||||
fiber_context & operator=( fiber_context && other) noexcept {
|
||||
if ( BOOST_LIKELY( this != & other) ) {
|
||||
fiber tmp = std::move( other);
|
||||
fiber_context tmp = std::move( other);
|
||||
swap( tmp);
|
||||
}
|
||||
return * this;
|
||||
}
|
||||
|
||||
fiber( fiber const& other) noexcept = delete;
|
||||
fiber & operator=( fiber const& other) noexcept = delete;
|
||||
fiber_context( fiber_context const& other) noexcept = delete;
|
||||
fiber_context & operator=( fiber_context const& other) noexcept = delete;
|
||||
|
||||
fiber resume() && {
|
||||
fiber_context resume() && {
|
||||
BOOST_ASSERT( nullptr != fctx_);
|
||||
return { detail::jump_fcontext(
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
@@ -333,7 +333,7 @@ public:
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
fiber resume_with( Fn && fn) && {
|
||||
fiber_context resume_with( Fn && fn) && {
|
||||
BOOST_ASSERT( nullptr != fctx_);
|
||||
auto p = std::forward< Fn >( fn);
|
||||
return { detail::ontop_fcontext(
|
||||
@@ -343,7 +343,7 @@ public:
|
||||
std::exchange( fctx_, nullptr),
|
||||
#endif
|
||||
& p,
|
||||
detail::fiber_ontop< fiber, decltype(p) >).fctx };
|
||||
detail::fiber_context_ontop< fiber_context, decltype(p) >).fctx };
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
@@ -354,7 +354,7 @@ public:
|
||||
return nullptr == fctx_;
|
||||
}
|
||||
|
||||
bool operator<( fiber const& other) const noexcept {
|
||||
bool operator<( fiber_context const& other) const noexcept {
|
||||
return fctx_ < other.fctx_;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
friend std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other) {
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other) {
|
||||
if ( nullptr != other.fctx_) {
|
||||
return os << other.fctx_;
|
||||
} else {
|
||||
@@ -374,11 +374,11 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
friend std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other);
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other);
|
||||
|
||||
#endif
|
||||
|
||||
void swap( fiber & other) noexcept {
|
||||
void swap( fiber_context & other) noexcept {
|
||||
std::swap( fctx_, other.fctx_);
|
||||
}
|
||||
};
|
||||
@@ -387,7 +387,7 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
inline std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other) {
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other) {
|
||||
if ( nullptr != other.fctx_) {
|
||||
return os << other.fctx_;
|
||||
} else {
|
||||
@@ -398,12 +398,10 @@ public:
|
||||
#endif
|
||||
|
||||
inline
|
||||
void swap( fiber & l, fiber & r) noexcept {
|
||||
void swap( fiber_context & l, fiber_context & r) noexcept {
|
||||
l.swap( r);
|
||||
}
|
||||
|
||||
typedef fiber fiber_context;
|
||||
|
||||
}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
@@ -68,12 +68,12 @@ namespace detail {
|
||||
// is resumed for the first time
|
||||
template <typename Record>
|
||||
#ifdef BOOST_OS_MACOS
|
||||
static void fiber_entry_func(std::uint32_t data_high,
|
||||
static void fiber_context_entry_func(std::uint32_t data_high,
|
||||
std::uint32_t data_low) noexcept {
|
||||
auto data =
|
||||
reinterpret_cast<void *>(std::uint64_t(data_high) << 32 | data_low);
|
||||
#else
|
||||
static void fiber_entry_func(void *data) noexcept {
|
||||
static void fiber_context_entry_func(void *data) noexcept {
|
||||
#endif
|
||||
Record *record = static_cast<Record *>(data);
|
||||
BOOST_ASSERT(nullptr != record);
|
||||
@@ -81,12 +81,12 @@ static void fiber_entry_func(void *data) noexcept {
|
||||
record->run();
|
||||
}
|
||||
|
||||
struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
struct BOOST_CONTEXT_DECL fiber_context_activation_record {
|
||||
ucontext_t uctx{};
|
||||
stack_context sctx{};
|
||||
bool main_ctx{ true };
|
||||
fiber_activation_record * from{ nullptr };
|
||||
std::function< fiber_activation_record*(fiber_activation_record*&) > ontop{};
|
||||
fiber_context_activation_record * from{ nullptr };
|
||||
std::function< fiber_context_activation_record*(fiber_context_activation_record*&) > ontop{};
|
||||
bool terminated{ false };
|
||||
bool force_unwind{ false };
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
@@ -96,15 +96,15 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_USE_TSAN)
|
||||
void * tsan_fiber{ nullptr };
|
||||
bool destroy_tsan_fiber{ true };
|
||||
void * tsan_fiber_context{ nullptr };
|
||||
bool destroy_tsan_fiber_context{ true };
|
||||
#endif
|
||||
|
||||
static fiber_activation_record *& current() noexcept;
|
||||
static fiber_context_activation_record *& current() noexcept;
|
||||
|
||||
// used for toplevel-context
|
||||
// (e.g. main context, thread-entry context)
|
||||
fiber_activation_record() {
|
||||
fiber_context_activation_record() {
|
||||
if ( BOOST_UNLIKELY( 0 != ::getcontext( & uctx) ) ) {
|
||||
throw std::system_error(
|
||||
std::error_code( errno, std::system_category() ),
|
||||
@@ -112,31 +112,31 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
}
|
||||
|
||||
#if defined(BOOST_USE_TSAN)
|
||||
tsan_fiber = __tsan_get_current_fiber();
|
||||
destroy_tsan_fiber = false;
|
||||
tsan_fiber_context = __tsan_get_current_fiber_context();
|
||||
destroy_tsan_fiber_context = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
fiber_activation_record( stack_context sctx_) noexcept :
|
||||
fiber_context_activation_record( stack_context sctx_) noexcept :
|
||||
sctx( sctx_ ),
|
||||
main_ctx( false ) {
|
||||
}
|
||||
|
||||
virtual ~fiber_activation_record() {
|
||||
virtual ~fiber_context_activation_record() {
|
||||
#if defined(BOOST_USE_TSAN)
|
||||
if (destroy_tsan_fiber)
|
||||
__tsan_destroy_fiber(tsan_fiber);
|
||||
if (destroy_tsan_fiber_context)
|
||||
__tsan_destroy_fiber_context(tsan_fiber_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
fiber_activation_record( fiber_activation_record const&) = delete;
|
||||
fiber_activation_record & operator=( fiber_activation_record const&) = delete;
|
||||
fiber_context_activation_record( fiber_context_activation_record const&) = delete;
|
||||
fiber_context_activation_record & operator=( fiber_context_activation_record const&) = delete;
|
||||
|
||||
bool is_main_context() const noexcept {
|
||||
return main_ctx;
|
||||
}
|
||||
|
||||
fiber_activation_record * resume() {
|
||||
fiber_context_activation_record * resume() {
|
||||
from = current();
|
||||
// store `this` in static, thread local pointer
|
||||
// `this` will become the active (running) context
|
||||
@@ -148,18 +148,18 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
#endif
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
if ( terminated) {
|
||||
__sanitizer_start_switch_fiber( nullptr, stack_bottom, stack_size);
|
||||
__sanitizer_start_switch_fiber_context( nullptr, stack_bottom, stack_size);
|
||||
} else {
|
||||
__sanitizer_start_switch_fiber( & from->fake_stack, stack_bottom, stack_size);
|
||||
__sanitizer_start_switch_fiber_context( & from->fake_stack, stack_bottom, stack_size);
|
||||
}
|
||||
#endif
|
||||
#if defined (BOOST_USE_TSAN)
|
||||
__tsan_switch_to_fiber(tsan_fiber, 0);
|
||||
__tsan_switch_to_fiber_context(tsan_fiber_context, 0);
|
||||
#endif
|
||||
// context switch from parent context to `this`-context
|
||||
::swapcontext( & from->uctx, & uctx);
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
__sanitizer_finish_switch_fiber( current()->fake_stack,
|
||||
__sanitizer_finish_switch_fiber_context( current()->fake_stack,
|
||||
(const void **) & current()->from->stack_bottom,
|
||||
& current()->from->stack_size);
|
||||
#endif
|
||||
@@ -171,15 +171,15 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
}
|
||||
|
||||
template< typename Ctx, typename Fn >
|
||||
fiber_activation_record * resume_with( Fn && fn) {
|
||||
fiber_context_activation_record * resume_with( Fn && fn) {
|
||||
from = current();
|
||||
// store `this` in static, thread local pointer
|
||||
// `this` will become the active (running) context
|
||||
// returned by fiber::current()
|
||||
// returned by fiber_context::current()
|
||||
current() = this;
|
||||
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
|
||||
current()->ontop = std::bind(
|
||||
[](typename std::decay< Fn >::type & fn, fiber_activation_record *& ptr){
|
||||
[](typename std::decay< Fn >::type & fn, fiber_context_activation_record *& ptr){
|
||||
Ctx c{ ptr };
|
||||
c = fn( std::move( c) );
|
||||
if ( ! c) {
|
||||
@@ -194,7 +194,7 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
std::forward< Fn >( fn),
|
||||
std::placeholders::_1);
|
||||
#else
|
||||
current()->ontop = [fn=std::forward<Fn>(fn)](fiber_activation_record *& ptr){
|
||||
current()->ontop = [fn=std::forward<Fn>(fn)](fiber_context_activation_record *& ptr){
|
||||
Ctx c{ ptr };
|
||||
c = fn( std::move( c) );
|
||||
if ( ! c) {
|
||||
@@ -213,15 +213,15 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
__splitstack_setcontext( sctx.segments_ctx);
|
||||
#endif
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
__sanitizer_start_switch_fiber( & from->fake_stack, stack_bottom, stack_size);
|
||||
__sanitizer_start_switch_fiber_context( & from->fake_stack, stack_bottom, stack_size);
|
||||
#endif
|
||||
#if defined (BOOST_USE_TSAN)
|
||||
__tsan_switch_to_fiber(tsan_fiber, 0);
|
||||
__tsan_switch_to_fiber_context(tsan_fiber_context, 0);
|
||||
#endif
|
||||
// context switch from parent context to `this`-context
|
||||
::swapcontext( & from->uctx, & uctx);
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
__sanitizer_finish_switch_fiber( current()->fake_stack,
|
||||
__sanitizer_finish_switch_fiber_context( current()->fake_stack,
|
||||
(const void **) & current()->from->stack_bottom,
|
||||
& current()->from->stack_size);
|
||||
#endif
|
||||
@@ -236,37 +236,37 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
}
|
||||
};
|
||||
|
||||
struct BOOST_CONTEXT_DECL fiber_activation_record_initializer {
|
||||
fiber_activation_record_initializer() noexcept;
|
||||
~fiber_activation_record_initializer();
|
||||
struct BOOST_CONTEXT_DECL fiber_context_activation_record_initializer {
|
||||
fiber_context_activation_record_initializer() noexcept;
|
||||
~fiber_context_activation_record_initializer();
|
||||
};
|
||||
|
||||
struct forced_unwind {
|
||||
fiber_activation_record * from{ nullptr };
|
||||
fiber_context_activation_record * from{ nullptr };
|
||||
|
||||
forced_unwind( fiber_activation_record * from_) noexcept :
|
||||
forced_unwind( fiber_context_activation_record * from_) noexcept :
|
||||
from{ from_ } {
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
class fiber_capture_record : public fiber_activation_record {
|
||||
class fiber_context_capture_record : public fiber_context_activation_record {
|
||||
private:
|
||||
typename std::decay< StackAlloc >::type salloc_;
|
||||
typename std::decay< Fn >::type fn_;
|
||||
|
||||
static void destroy( fiber_capture_record * p) noexcept {
|
||||
static void destroy( fiber_context_capture_record * p) noexcept {
|
||||
typename std::decay< StackAlloc >::type salloc = std::move( p->salloc_);
|
||||
stack_context sctx = p->sctx;
|
||||
// deallocate activation record
|
||||
p->~fiber_capture_record();
|
||||
p->~fiber_context_capture_record();
|
||||
// destroy stack with stack allocator
|
||||
salloc.deallocate( sctx);
|
||||
}
|
||||
|
||||
public:
|
||||
fiber_capture_record( stack_context sctx, StackAlloc && salloc, Fn && fn) noexcept :
|
||||
fiber_activation_record{ sctx },
|
||||
fiber_context_capture_record( stack_context sctx, StackAlloc && salloc, Fn && fn) noexcept :
|
||||
fiber_context_activation_record{ sctx },
|
||||
salloc_{ std::forward< StackAlloc >( salloc) },
|
||||
fn_( std::forward< Fn >( fn) ) {
|
||||
}
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
|
||||
void run() {
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
__sanitizer_finish_switch_fiber( fake_stack,
|
||||
__sanitizer_finish_switch_fiber_context( fake_stack,
|
||||
(const void **) & from->stack_bottom,
|
||||
& from->stack_size);
|
||||
#endif
|
||||
@@ -299,13 +299,13 @@ public:
|
||||
terminated = true;
|
||||
force_unwind = false;
|
||||
std::move( c).resume();
|
||||
BOOST_ASSERT_MSG( false, "fiber already terminated");
|
||||
BOOST_ASSERT_MSG( false, "fiber_context already terminated");
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
static fiber_activation_record * create_fiber1( StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
static fiber_context_activation_record * create_fiber_context1( StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_context_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
|
||||
auto sctx = salloc.allocate();
|
||||
// reserve space for control structure
|
||||
@@ -338,11 +338,11 @@ static fiber_activation_record * create_fiber1( StackAlloc && salloc, Fn && fn)
|
||||
record->uctx.uc_link = nullptr;
|
||||
#ifdef BOOST_OS_MACOS
|
||||
const auto integer = std::uint64_t(record);
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_entry_func<capture_t>, 2,
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_context_entry_func<capture_t>, 2,
|
||||
std::uint32_t((integer >> 32) & 0xFFFFFFFF),
|
||||
std::uint32_t(integer));
|
||||
#else
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_entry_func<capture_t>, 1,
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_context_entry_func<capture_t>, 1,
|
||||
record);
|
||||
#endif
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
@@ -350,14 +350,14 @@ static fiber_activation_record * create_fiber1( StackAlloc && salloc, Fn && fn)
|
||||
record->stack_size = record->uctx.uc_stack.ss_size;
|
||||
#endif
|
||||
#if defined (BOOST_USE_TSAN)
|
||||
record->tsan_fiber = __tsan_create_fiber(0);
|
||||
record->tsan_fiber_context = __tsan_create_fiber_context(0);
|
||||
#endif
|
||||
return record;
|
||||
}
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
static fiber_activation_record * create_fiber2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
static fiber_context_activation_record * create_fiber_context2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_context_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
|
||||
// reserve space for control structure
|
||||
void * storage = reinterpret_cast< void * >(
|
||||
@@ -389,11 +389,11 @@ static fiber_activation_record * create_fiber2( preallocated palloc, StackAlloc
|
||||
record->uctx.uc_link = nullptr;
|
||||
#ifdef BOOST_OS_MACOS
|
||||
const auto integer = std::uint64_t(record);
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_entry_func<capture_t>, 2,
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_context_entry_func<capture_t>, 2,
|
||||
std::uint32_t((integer >> 32) & 0xFFFFFFFF),
|
||||
std::uint32_t(integer));
|
||||
#else
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_entry_func<capture_t>, 1,
|
||||
::makecontext(&record->uctx, (void (*)()) & fiber_context_entry_func<capture_t>, 1,
|
||||
record);
|
||||
#endif
|
||||
#if defined(BOOST_USE_ASAN)
|
||||
@@ -401,38 +401,38 @@ static fiber_activation_record * create_fiber2( preallocated palloc, StackAlloc
|
||||
record->stack_size = record->uctx.uc_stack.ss_size;
|
||||
#endif
|
||||
#if defined (BOOST_USE_TSAN)
|
||||
record->tsan_fiber = __tsan_create_fiber(0);
|
||||
record->tsan_fiber_context = __tsan_create_fiber_context(0);
|
||||
#endif
|
||||
return record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BOOST_CONTEXT_DECL fiber {
|
||||
class BOOST_CONTEXT_DECL fiber_context {
|
||||
private:
|
||||
friend struct detail::fiber_activation_record;
|
||||
friend struct detail::fiber_context_activation_record;
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend class detail::fiber_capture_record;
|
||||
friend class detail::fiber_context_capture_record;
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend detail::fiber_activation_record * detail::create_fiber1( StackAlloc &&, Fn &&);
|
||||
friend detail::fiber_context_activation_record * detail::create_fiber_context1( StackAlloc &&, Fn &&);
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend detail::fiber_activation_record * detail::create_fiber2( preallocated, StackAlloc &&, Fn &&);
|
||||
friend detail::fiber_context_activation_record * detail::create_fiber_context2( preallocated, StackAlloc &&, Fn &&);
|
||||
|
||||
detail::fiber_activation_record * ptr_{ nullptr };
|
||||
detail::fiber_context_activation_record * ptr_{ nullptr };
|
||||
|
||||
fiber( detail::fiber_activation_record * ptr) noexcept :
|
||||
fiber_context( detail::fiber_context_activation_record * ptr) noexcept :
|
||||
ptr_{ ptr } {
|
||||
}
|
||||
|
||||
public:
|
||||
fiber() = default;
|
||||
fiber_context() = default;
|
||||
|
||||
template< typename Fn, typename = detail::disable_overload< fiber, Fn > >
|
||||
fiber( Fn && fn) :
|
||||
fiber{
|
||||
template< typename Fn, typename = detail::disable_overload< fiber_context, Fn > >
|
||||
fiber_context( Fn && fn) :
|
||||
fiber_context{
|
||||
std::allocator_arg,
|
||||
#if defined(BOOST_USE_SEGMENTED_STACKS)
|
||||
segmented_stack(),
|
||||
@@ -443,18 +443,18 @@ public:
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber1< fiber >(
|
||||
fiber_context( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber_context1< fiber_context >(
|
||||
std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) } {
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber2< fiber >(
|
||||
fiber_context( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber_context2< fiber_context >(
|
||||
palloc, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) } {
|
||||
}
|
||||
|
||||
~fiber() {
|
||||
~fiber_context() {
|
||||
if ( BOOST_UNLIKELY( nullptr != ptr_) && ! ptr_->main_ctx) {
|
||||
if ( BOOST_LIKELY( ! ptr_->terminated) ) {
|
||||
ptr_->force_unwind = true;
|
||||
@@ -465,52 +465,52 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
fiber( fiber const&) = delete;
|
||||
fiber & operator=( fiber const&) = delete;
|
||||
fiber_context( fiber_context const&) = delete;
|
||||
fiber_context & operator=( fiber_context const&) = delete;
|
||||
|
||||
fiber( fiber && other) noexcept {
|
||||
fiber_context( fiber_context && other) noexcept {
|
||||
swap( other);
|
||||
}
|
||||
|
||||
fiber & operator=( fiber && other) noexcept {
|
||||
fiber_context & operator=( fiber_context && other) noexcept {
|
||||
if ( BOOST_LIKELY( this != & other) ) {
|
||||
fiber tmp = std::move( other);
|
||||
fiber_context tmp = std::move( other);
|
||||
swap( tmp);
|
||||
}
|
||||
return * this;
|
||||
}
|
||||
|
||||
fiber resume() && {
|
||||
fiber_context resume() && {
|
||||
BOOST_ASSERT( nullptr != ptr_);
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
detail::fiber_activation_record * ptr = detail::exchange( ptr_, nullptr)->resume();
|
||||
detail::fiber_context_activation_record * ptr = detail::exchange( ptr_, nullptr)->resume();
|
||||
#else
|
||||
detail::fiber_activation_record * ptr = std::exchange( ptr_, nullptr)->resume();
|
||||
detail::fiber_context_activation_record * ptr = std::exchange( ptr_, nullptr)->resume();
|
||||
#endif
|
||||
if ( BOOST_UNLIKELY( detail::fiber_activation_record::current()->force_unwind) ) {
|
||||
if ( BOOST_UNLIKELY( detail::fiber_context_activation_record::current()->force_unwind) ) {
|
||||
throw detail::forced_unwind{ ptr};
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_activation_record::current()->ontop = nullptr;
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_context_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_context_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_context_activation_record::current()->ontop = nullptr;
|
||||
}
|
||||
return { ptr };
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
fiber resume_with( Fn && fn) && {
|
||||
fiber_context resume_with( Fn && fn) && {
|
||||
BOOST_ASSERT( nullptr != ptr_);
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
detail::fiber_activation_record * ptr =
|
||||
detail::exchange( ptr_, nullptr)->resume_with< fiber >( std::forward< Fn >( fn) );
|
||||
detail::fiber_context_activation_record * ptr =
|
||||
detail::exchange( ptr_, nullptr)->resume_with< fiber_context >( std::forward< Fn >( fn) );
|
||||
#else
|
||||
detail::fiber_activation_record * ptr =
|
||||
std::exchange( ptr_, nullptr)->resume_with< fiber >( std::forward< Fn >( fn) );
|
||||
detail::fiber_context_activation_record * ptr =
|
||||
std::exchange( ptr_, nullptr)->resume_with< fiber_context >( std::forward< Fn >( fn) );
|
||||
#endif
|
||||
if ( BOOST_UNLIKELY( detail::fiber_activation_record::current()->force_unwind) ) {
|
||||
if ( BOOST_UNLIKELY( detail::fiber_context_activation_record::current()->force_unwind) ) {
|
||||
throw detail::forced_unwind{ ptr};
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_activation_record::current()->ontop = nullptr;
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_context_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_context_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_context_activation_record::current()->ontop = nullptr;
|
||||
}
|
||||
return { ptr };
|
||||
}
|
||||
@@ -523,7 +523,7 @@ public:
|
||||
return nullptr == ptr_ || ptr_->terminated;
|
||||
}
|
||||
|
||||
bool operator<( fiber const& other) const noexcept {
|
||||
bool operator<( fiber_context const& other) const noexcept {
|
||||
return ptr_ < other.ptr_;
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
friend std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other) {
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other) {
|
||||
if ( nullptr != other.ptr_) {
|
||||
return os << other.ptr_;
|
||||
} else {
|
||||
@@ -543,11 +543,11 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
friend std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other);
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other);
|
||||
|
||||
#endif
|
||||
|
||||
void swap( fiber & other) noexcept {
|
||||
void swap( fiber_context & other) noexcept {
|
||||
std::swap( ptr_, other.ptr_);
|
||||
}
|
||||
};
|
||||
@@ -556,7 +556,7 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
inline std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other) {
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other) {
|
||||
if ( nullptr != other.ptr_) {
|
||||
return os << other.ptr_;
|
||||
} else {
|
||||
@@ -567,12 +567,10 @@ public:
|
||||
#endif
|
||||
|
||||
inline
|
||||
void swap( fiber & l, fiber & r) noexcept {
|
||||
void swap( fiber_context & l, fiber_context & r) noexcept {
|
||||
l.swap( r);
|
||||
}
|
||||
|
||||
typedef fiber fiber_context;
|
||||
|
||||
}}
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
@@ -55,72 +55,72 @@ namespace detail {
|
||||
// entered if the execution context
|
||||
// is resumed for the first time
|
||||
template< typename Record >
|
||||
static VOID WINAPI fiber_entry_func( LPVOID data) noexcept {
|
||||
static VOID WINAPI fiber_context_entry_func( LPVOID data) noexcept {
|
||||
Record * record = static_cast< Record * >( data);
|
||||
BOOST_ASSERT( nullptr != record);
|
||||
// start execution of toplevel context-function
|
||||
record->run();
|
||||
}
|
||||
|
||||
struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
LPVOID fiber{ nullptr };
|
||||
struct BOOST_CONTEXT_DECL fiber_context_activation_record {
|
||||
LPVOID fiber_context{ nullptr };
|
||||
stack_context sctx{};
|
||||
bool main_ctx{ true };
|
||||
fiber_activation_record * from{ nullptr };
|
||||
std::function< fiber_activation_record*(fiber_activation_record*&) > ontop{};
|
||||
fiber_context_activation_record * from{ nullptr };
|
||||
std::function< fiber_context_activation_record*(fiber_context_activation_record*&) > ontop{};
|
||||
bool terminated{ false };
|
||||
bool force_unwind{ false };
|
||||
|
||||
static fiber_activation_record *& current() noexcept;
|
||||
static fiber_context_activation_record *& current() noexcept;
|
||||
|
||||
// used for toplevel-context
|
||||
// (e.g. main context, thread-entry context)
|
||||
fiber_activation_record() noexcept {
|
||||
fiber_context_activation_record() noexcept {
|
||||
#if ( _WIN32_WINNT > 0x0600)
|
||||
if ( ::IsThreadAFiber() ) {
|
||||
fiber = ::GetCurrentFiber();
|
||||
fiber_context = ::GetCurrentFiber();
|
||||
} else {
|
||||
fiber = ::ConvertThreadToFiber( nullptr);
|
||||
fiber_context = ::ConvertThreadToFiber( nullptr);
|
||||
}
|
||||
#else
|
||||
fiber = ::ConvertThreadToFiber( nullptr);
|
||||
if ( BOOST_UNLIKELY( nullptr == fiber) ) {
|
||||
fiber_context = ::ConvertThreadToFiber( nullptr);
|
||||
if ( BOOST_UNLIKELY( nullptr == fiber_context) ) {
|
||||
BOOST_ASSERT( ERROR_ALREADY_FIBER == ::GetLastError());
|
||||
fiber = ::GetCurrentFiber();
|
||||
BOOST_ASSERT( nullptr != fiber);
|
||||
BOOST_ASSERT( reinterpret_cast< LPVOID >( 0x1E00) != fiber);
|
||||
fiber_context = ::GetCurrentFiber();
|
||||
BOOST_ASSERT( nullptr != fiber_context);
|
||||
BOOST_ASSERT( reinterpret_cast< LPVOID >( 0x1E00) != fiber_context);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fiber_activation_record( stack_context sctx_) noexcept :
|
||||
fiber_context_activation_record( stack_context sctx_) noexcept :
|
||||
sctx{ sctx_ },
|
||||
main_ctx{ false } {
|
||||
}
|
||||
|
||||
virtual ~fiber_activation_record() {
|
||||
virtual ~fiber_context_activation_record() {
|
||||
if ( BOOST_UNLIKELY( main_ctx) ) {
|
||||
::ConvertFiberToThread();
|
||||
} else {
|
||||
::DeleteFiber( fiber);
|
||||
::DeleteFiber( fiber_context);
|
||||
}
|
||||
}
|
||||
|
||||
fiber_activation_record( fiber_activation_record const&) = delete;
|
||||
fiber_activation_record & operator=( fiber_activation_record const&) = delete;
|
||||
fiber_context_activation_record( fiber_context_activation_record const&) = delete;
|
||||
fiber_context_activation_record & operator=( fiber_context_activation_record const&) = delete;
|
||||
|
||||
bool is_main_context() const noexcept {
|
||||
return main_ctx;
|
||||
}
|
||||
|
||||
fiber_activation_record * resume() {
|
||||
fiber_context_activation_record * resume() {
|
||||
from = current();
|
||||
// store `this` in static, thread local pointer
|
||||
// `this` will become the active (running) context
|
||||
current() = this;
|
||||
// context switch from parent context to `this`-context
|
||||
// context switch
|
||||
::SwitchToFiber( fiber);
|
||||
::SwitchToFiber( fiber_context);
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
return detail::exchange( current()->from, nullptr);
|
||||
#else
|
||||
@@ -129,15 +129,15 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
}
|
||||
|
||||
template< typename Ctx, typename Fn >
|
||||
fiber_activation_record * resume_with( Fn && fn) {
|
||||
fiber_context_activation_record * resume_with( Fn && fn) {
|
||||
from = current();
|
||||
// store `this` in static, thread local pointer
|
||||
// `this` will become the active (running) context
|
||||
// returned by fiber::current()
|
||||
// returned by fiber_context::current()
|
||||
current() = this;
|
||||
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
|
||||
current()->ontop = std::bind(
|
||||
[](typename std::decay< Fn >::type & fn, fiber_activation_record *& ptr){
|
||||
[](typename std::decay< Fn >::type & fn, fiber_context_activation_record *& ptr){
|
||||
Ctx c{ ptr };
|
||||
c = fn( std::move( c) );
|
||||
if ( ! c) {
|
||||
@@ -152,7 +152,7 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
std::forward< Fn >( fn),
|
||||
std::placeholders::_1);
|
||||
#else
|
||||
current()->ontop = [fn=std::forward<Fn>(fn)](fiber_activation_record *& ptr){
|
||||
current()->ontop = [fn=std::forward<Fn>(fn)](fiber_context_activation_record *& ptr){
|
||||
Ctx c{ ptr };
|
||||
c = fn( std::move( c) );
|
||||
if ( ! c) {
|
||||
@@ -166,7 +166,7 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
};
|
||||
#endif
|
||||
// context switch
|
||||
::SwitchToFiber( fiber);
|
||||
::SwitchToFiber( fiber_context);
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
return detail::exchange( current()->from, nullptr);
|
||||
#else
|
||||
@@ -178,37 +178,37 @@ struct BOOST_CONTEXT_DECL fiber_activation_record {
|
||||
}
|
||||
};
|
||||
|
||||
struct BOOST_CONTEXT_DECL fiber_activation_record_initializer {
|
||||
fiber_activation_record_initializer() noexcept;
|
||||
~fiber_activation_record_initializer();
|
||||
struct BOOST_CONTEXT_DECL fiber_context_activation_record_initializer {
|
||||
fiber_context_activation_record_initializer() noexcept;
|
||||
~fiber_context_activation_record_initializer();
|
||||
};
|
||||
|
||||
struct forced_unwind {
|
||||
fiber_activation_record * from{ nullptr };
|
||||
fiber_context_activation_record * from{ nullptr };
|
||||
|
||||
explicit forced_unwind( fiber_activation_record * from_) :
|
||||
explicit forced_unwind( fiber_context_activation_record * from_) :
|
||||
from{ from_ } {
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
class fiber_capture_record : public fiber_activation_record {
|
||||
class fiber_context_capture_record : public fiber_context_activation_record {
|
||||
private:
|
||||
typename std::decay< StackAlloc >::type salloc_;
|
||||
typename std::decay< Fn >::type fn_;
|
||||
|
||||
static void destroy( fiber_capture_record * p) noexcept {
|
||||
static void destroy( fiber_context_capture_record * p) noexcept {
|
||||
typename std::decay< StackAlloc >::type salloc = std::move( p->salloc_);
|
||||
stack_context sctx = p->sctx;
|
||||
// deallocate activation record
|
||||
p->~fiber_capture_record();
|
||||
p->~fiber_context_capture_record();
|
||||
// destroy stack with stack allocator
|
||||
salloc.deallocate( sctx);
|
||||
}
|
||||
|
||||
public:
|
||||
fiber_capture_record( stack_context sctx, StackAlloc && salloc, Fn && fn) noexcept :
|
||||
fiber_activation_record( sctx),
|
||||
fiber_context_capture_record( stack_context sctx, StackAlloc && salloc, Fn && fn) noexcept :
|
||||
fiber_context_activation_record( sctx),
|
||||
salloc_( std::forward< StackAlloc >( salloc)),
|
||||
fn_( std::forward< Fn >( fn) ) {
|
||||
}
|
||||
@@ -236,13 +236,13 @@ public:
|
||||
terminated = true;
|
||||
force_unwind = false;
|
||||
std::move( c).resume();
|
||||
BOOST_ASSERT_MSG( false, "fiber already terminated");
|
||||
BOOST_ASSERT_MSG( false, "fiber_context already terminated");
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
static fiber_activation_record * create_fiber1( StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
static fiber_context_activation_record * create_fiber_context1( StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_context_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
|
||||
auto sctx = salloc.allocate();
|
||||
BOOST_ASSERT( ( sizeof( capture_t) ) < sctx.size);
|
||||
@@ -254,13 +254,13 @@ static fiber_activation_record * create_fiber1( StackAlloc && salloc, Fn && fn)
|
||||
capture_t * record = new ( storage) capture_t{
|
||||
sctx, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) };
|
||||
// create user-context
|
||||
record->fiber = ::CreateFiber( sctx.size, & detail::fiber_entry_func< capture_t >, record);
|
||||
record->fiber_context = ::CreateFiber( sctx.size, & detail::fiber_context_entry_func< capture_t >, record);
|
||||
return record;
|
||||
}
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
static fiber_activation_record * create_fiber2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
static fiber_context_activation_record * create_fiber_context2( preallocated palloc, StackAlloc && salloc, Fn && fn) {
|
||||
typedef fiber_context_capture_record< Ctx, StackAlloc, Fn > capture_t;
|
||||
|
||||
BOOST_ASSERT( ( sizeof( capture_t) ) < palloc.size);
|
||||
// reserve space for control structure
|
||||
@@ -271,54 +271,54 @@ static fiber_activation_record * create_fiber2( preallocated palloc, StackAlloc
|
||||
capture_t * record = new ( storage) capture_t{
|
||||
palloc.sctx, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) };
|
||||
// create user-context
|
||||
record->fiber = ::CreateFiber( palloc.sctx.size, & detail::fiber_entry_func< capture_t >, record);
|
||||
record->fiber_context = ::CreateFiber( palloc.sctx.size, & detail::fiber_context_entry_func< capture_t >, record);
|
||||
return record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BOOST_CONTEXT_DECL fiber {
|
||||
class BOOST_CONTEXT_DECL fiber_context {
|
||||
private:
|
||||
friend struct detail::fiber_activation_record;
|
||||
friend struct detail::fiber_context_activation_record;
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend class detail::fiber_capture_record;
|
||||
friend class detail::fiber_context_capture_record;
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend detail::fiber_activation_record * detail::create_fiber1( StackAlloc &&, Fn &&);
|
||||
friend detail::fiber_context_activation_record * detail::create_fiber_context1( StackAlloc &&, Fn &&);
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend detail::fiber_activation_record * detail::create_fiber2( preallocated, StackAlloc &&, Fn &&);
|
||||
friend detail::fiber_context_activation_record * detail::create_fiber_context2( preallocated, StackAlloc &&, Fn &&);
|
||||
|
||||
detail::fiber_activation_record * ptr_{ nullptr };
|
||||
detail::fiber_context_activation_record * ptr_{ nullptr };
|
||||
|
||||
fiber( detail::fiber_activation_record * ptr) noexcept :
|
||||
fiber_context( detail::fiber_context_activation_record * ptr) noexcept :
|
||||
ptr_{ ptr } {
|
||||
}
|
||||
|
||||
public:
|
||||
fiber() = default;
|
||||
fiber_context() = default;
|
||||
|
||||
template< typename Fn, typename = detail::disable_overload< fiber, Fn > >
|
||||
fiber( Fn && fn) :
|
||||
fiber{ std::allocator_arg,
|
||||
template< typename Fn, typename = detail::disable_overload< fiber_context, Fn > >
|
||||
fiber_context( Fn && fn) :
|
||||
fiber_context{ std::allocator_arg,
|
||||
fixedsize_stack(),
|
||||
std::forward< Fn >( fn) } {
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber1< fiber >(
|
||||
fiber_context( std::allocator_arg_t, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber_context1< fiber_context >(
|
||||
std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) } {;
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
fiber( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber2< fiber >(
|
||||
fiber_context( std::allocator_arg_t, preallocated palloc, StackAlloc && salloc, Fn && fn) :
|
||||
ptr_{ detail::create_fiber_context2< fiber_context >(
|
||||
palloc, std::forward< StackAlloc >( salloc), std::forward< Fn >( fn) ) } {
|
||||
}
|
||||
|
||||
~fiber() {
|
||||
~fiber_context() {
|
||||
if ( BOOST_UNLIKELY( nullptr != ptr_) && ! ptr_->main_ctx) {
|
||||
if ( BOOST_LIKELY( ! ptr_->terminated) ) {
|
||||
ptr_->force_unwind = true;
|
||||
@@ -329,52 +329,52 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
fiber( fiber const&) = delete;
|
||||
fiber & operator=( fiber const&) = delete;
|
||||
fiber_context( fiber_context const&) = delete;
|
||||
fiber_context & operator=( fiber_context const&) = delete;
|
||||
|
||||
fiber( fiber && other) noexcept {
|
||||
fiber_context( fiber_context && other) noexcept {
|
||||
swap( other);
|
||||
}
|
||||
|
||||
fiber & operator=( fiber && other) noexcept {
|
||||
fiber_context & operator=( fiber_context && other) noexcept {
|
||||
if ( BOOST_LIKELY( this != & other) ) {
|
||||
fiber tmp = std::move( other);
|
||||
fiber_context tmp = std::move( other);
|
||||
swap( tmp);
|
||||
}
|
||||
return * this;
|
||||
}
|
||||
|
||||
fiber resume() && {
|
||||
fiber_context resume() && {
|
||||
BOOST_ASSERT( nullptr != ptr_);
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
detail::fiber_activation_record * ptr = detail::exchange( ptr_, nullptr)->resume();
|
||||
detail::fiber_context_activation_record * ptr = detail::exchange( ptr_, nullptr)->resume();
|
||||
#else
|
||||
detail::fiber_activation_record * ptr = std::exchange( ptr_, nullptr)->resume();
|
||||
detail::fiber_context_activation_record * ptr = std::exchange( ptr_, nullptr)->resume();
|
||||
#endif
|
||||
if ( BOOST_UNLIKELY( detail::fiber_activation_record::current()->force_unwind) ) {
|
||||
if ( BOOST_UNLIKELY( detail::fiber_context_activation_record::current()->force_unwind) ) {
|
||||
throw detail::forced_unwind{ ptr};
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_activation_record::current()->ontop = nullptr;
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_context_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_context_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_context_activation_record::current()->ontop = nullptr;
|
||||
}
|
||||
return { ptr };
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
fiber resume_with( Fn && fn) && {
|
||||
fiber_context resume_with( Fn && fn) && {
|
||||
BOOST_ASSERT( nullptr != ptr_);
|
||||
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
|
||||
detail::fiber_activation_record * ptr =
|
||||
detail::exchange( ptr_, nullptr)->resume_with< fiber >( std::forward< Fn >( fn) );
|
||||
detail::fiber_context_activation_record * ptr =
|
||||
detail::exchange( ptr_, nullptr)->resume_with< fiber_context >( std::forward< Fn >( fn) );
|
||||
#else
|
||||
detail::fiber_activation_record * ptr =
|
||||
std::exchange( ptr_, nullptr)->resume_with< fiber >( std::forward< Fn >( fn) );
|
||||
detail::fiber_context_activation_record * ptr =
|
||||
std::exchange( ptr_, nullptr)->resume_with< fiber_context >( std::forward< Fn >( fn) );
|
||||
#endif
|
||||
if ( BOOST_UNLIKELY( detail::fiber_activation_record::current()->force_unwind) ) {
|
||||
if ( BOOST_UNLIKELY( detail::fiber_context_activation_record::current()->force_unwind) ) {
|
||||
throw detail::forced_unwind{ ptr};
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_activation_record::current()->ontop = nullptr;
|
||||
} else if ( BOOST_UNLIKELY( nullptr != detail::fiber_context_activation_record::current()->ontop) ) {
|
||||
ptr = detail::fiber_context_activation_record::current()->ontop( ptr);
|
||||
detail::fiber_context_activation_record::current()->ontop = nullptr;
|
||||
}
|
||||
return { ptr };
|
||||
}
|
||||
@@ -387,7 +387,7 @@ public:
|
||||
return nullptr == ptr_ || ptr_->terminated;
|
||||
}
|
||||
|
||||
bool operator<( fiber const& other) const noexcept {
|
||||
bool operator<( fiber_context const& other) const noexcept {
|
||||
return ptr_ < other.ptr_;
|
||||
}
|
||||
|
||||
@@ -395,7 +395,7 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
friend std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other) {
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other) {
|
||||
if ( nullptr != other.ptr_) {
|
||||
return os << other.ptr_;
|
||||
} else {
|
||||
@@ -407,11 +407,11 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
friend std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other);
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other);
|
||||
|
||||
#endif
|
||||
|
||||
void swap( fiber & other) noexcept {
|
||||
void swap( fiber_context & other) noexcept {
|
||||
std::swap( ptr_, other.ptr_);
|
||||
}
|
||||
};
|
||||
@@ -420,7 +420,7 @@ public:
|
||||
|
||||
template< typename charT, class traitsT >
|
||||
inline std::basic_ostream< charT, traitsT > &
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber const& other) {
|
||||
operator<<( std::basic_ostream< charT, traitsT > & os, fiber_context const& other) {
|
||||
if ( nullptr != other.ptr_) {
|
||||
return os << other.ptr_;
|
||||
} else {
|
||||
@@ -431,12 +431,10 @@ public:
|
||||
#endif
|
||||
|
||||
inline
|
||||
void swap( fiber & l, fiber & r) noexcept {
|
||||
void swap( fiber_context & l, fiber_context & r) noexcept {
|
||||
l.swap( r);
|
||||
}
|
||||
|
||||
typedef fiber fiber_context;
|
||||
|
||||
}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
@@ -45,7 +45,7 @@
|
||||
;* ------------------------------------------------- *
|
||||
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
|
||||
;* ------------------------------------------------- *
|
||||
;* | fiber data| base | limit | dealloc | *
|
||||
;* | fiber_context data| base | limit | dealloc | *
|
||||
;* ------------------------------------------------- *
|
||||
;* ------------------------------------------------- *
|
||||
;* | 48 | 49 | 50 | 51 | | | *
|
||||
@@ -84,7 +84,7 @@ jump_fcontext proc
|
||||
; save current stack base and limit
|
||||
ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
|
||||
stp x5, x6, [sp, #0xa0]
|
||||
; save current fiber data and deallocation stack
|
||||
; save current fiber_context data and deallocation stack
|
||||
ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
|
||||
ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h
|
||||
stp x5, x6, [sp, #0xb0]
|
||||
@@ -98,7 +98,7 @@ jump_fcontext proc
|
||||
; restore stack base and limit
|
||||
ldp x5, x6, [sp, #0xa0]
|
||||
stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
|
||||
; restore fiber data and deallocation stack
|
||||
; restore fiber_context data and deallocation stack
|
||||
ldp x5, x6, [sp, #0xb0]
|
||||
str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
|
||||
str x6, [x18, #0x20] ; TeFiberData at ksarm64.h
|
||||
|
||||
@@ -47,7 +47,7 @@ _jump_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movl %fs:(0x18), %edx
|
||||
/* load fiber local storage */
|
||||
/* load fiber_context local storage */
|
||||
movl 0x10(%edx), %eax
|
||||
movl %eax, 0x8(%esp)
|
||||
/* load current dealloction stack */
|
||||
@@ -86,7 +86,7 @@ _jump_fcontext:
|
||||
|
||||
/* restore NT_TIB into EDX */
|
||||
movl %fs:(0x18), %edx
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movl 0x8(%esp), %ecx
|
||||
movl %ecx, 0x10(%edx)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -47,7 +47,7 @@ _jump_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movl %fs:(0x18), %edx
|
||||
/* load fiber local storage */
|
||||
/* load fiber_context local storage */
|
||||
movl 0x10(%edx), %eax
|
||||
movl %eax, 0x8(%esp)
|
||||
/* load current dealloction stack */
|
||||
@@ -86,7 +86,7 @@ _jump_fcontext:
|
||||
|
||||
/* restore NT_TIB into EDX */
|
||||
movl %fs:(0x18), %edx
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movl 0x8(%esp), %ecx
|
||||
movl %ecx, 0x10(%edx)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -39,7 +39,7 @@ ENDIF
|
||||
; load NT_TIB into ECX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
; load fiber local storage
|
||||
; load fiber_context local storage
|
||||
mov eax, [edx+010h]
|
||||
mov [esp+08h], eax
|
||||
; load current deallocation stack
|
||||
@@ -80,7 +80,7 @@ ENDIF
|
||||
; load NT_TIB into EDX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
; restore fiber local storage
|
||||
; restore fiber_context local storage
|
||||
mov ecx, [esp+08h]
|
||||
mov [edx+010h], ecx
|
||||
; restore current deallocation stack
|
||||
|
||||
@@ -115,7 +115,7 @@ jump_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* save fiber local storage */
|
||||
/* save fiber_context local storage */
|
||||
movq 0x20(%r10), %rax
|
||||
movq %rax, 0xb0(%rsp)
|
||||
/* save current deallocation stack */
|
||||
@@ -163,7 +163,7 @@ jump_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movq 0xb0(%rsp), %rax
|
||||
movq %rax, 0x20(%r10)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -115,7 +115,7 @@ jump_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* save fiber local storage */
|
||||
/* save fiber_context local storage */
|
||||
movq 0x20(%r10), %rax
|
||||
movq %rax, 0xb0(%rsp)
|
||||
/* save current deallocation stack */
|
||||
@@ -163,7 +163,7 @@ jump_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movq 0xb0(%rsp), %rax
|
||||
movq %rax, 0x20(%r10)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -110,7 +110,7 @@ ENDIF
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; save fiber local storage
|
||||
; save fiber_context local storage
|
||||
mov rax, [r10+020h]
|
||||
mov [rsp+0b0h], rax
|
||||
; save current deallocation stack
|
||||
@@ -160,7 +160,7 @@ ENDIF
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; restore fiber local storage
|
||||
; restore fiber_context local storage
|
||||
mov rax, [rsp+0b0h]
|
||||
mov [r10+020h], rax
|
||||
; restore current deallocation stack
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
;* ------------------------------------------------- *
|
||||
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
|
||||
;* ------------------------------------------------- *
|
||||
;* | base | limit | dealloc | fiber data| *
|
||||
;* | base | limit | dealloc | fiber_context data| *
|
||||
;* ------------------------------------------------- *
|
||||
;* ------------------------------------------------- *
|
||||
;* | 48 | 49 | 50 | 51 | | | *
|
||||
@@ -76,7 +76,7 @@ make_fcontext proc
|
||||
; save bottom address of context-stack as 'limit' and 'dealloction stack'
|
||||
sub x3, x3, x1
|
||||
stp x3, x3, [x0, #0xa8]
|
||||
; save 0 as 'fiber data'
|
||||
; save 0 as 'fiber_context data'
|
||||
str xzr, [x0, #0xb8]
|
||||
|
||||
; third arg of make_fcontext() == address of context-function
|
||||
|
||||
@@ -70,7 +70,7 @@ _make_fcontext:
|
||||
movl %ecx, 0x10(%eax)
|
||||
/* save bottom address of context-stack as 'dealloction stack' */
|
||||
movl %ecx, 0xc(%eax)
|
||||
/* set fiber-storage to zero */
|
||||
/* set fiber_context-storage to zero */
|
||||
xorl %ecx, %ecx
|
||||
movl %ecx, 0x8(%eax)
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ _make_fcontext:
|
||||
movl %ecx, 0x10(%eax)
|
||||
/* save bottom address of context-stack as 'dealloction stack' */
|
||||
movl %ecx, 0xc(%eax)
|
||||
/* set fiber-storage to zero */
|
||||
/* set fiber_context-storage to zero */
|
||||
xorl %ecx, %ecx
|
||||
movl %ecx, 0x8(%eax)
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ make_fcontext PROC BOOST_CONTEXT_EXPORT
|
||||
mov [eax+010h], ecx
|
||||
; save bottom address of context-stack as 'dealloction stack'
|
||||
mov [eax+0ch], ecx
|
||||
; set fiber-storage to zero
|
||||
; set fiber_context-storage to zero
|
||||
xor ecx, ecx
|
||||
mov [eax+08h], ecx
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ make_fcontext:
|
||||
movq %rcx, 0xc0(%rax)
|
||||
/* save address of context stack limit as 'dealloction stack' */
|
||||
movq %rcx, 0xb8(%rax)
|
||||
/* set fiber-storage to zero */
|
||||
/* set fiber_context-storage to zero */
|
||||
xorq %rcx, %rcx
|
||||
movq %rcx, 0xb0(%rax)
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ make_fcontext:
|
||||
movq %rcx, 0xc0(%rax)
|
||||
/* save address of context stack limit as 'dealloction stack' */
|
||||
movq %rcx, 0xb8(%rax)
|
||||
/* set fiber-storage to zero */
|
||||
/* set fiber_context-storage to zero */
|
||||
xorq %rcx, %rcx
|
||||
movq %rcx, 0xb0(%rax)
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ make_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
|
||||
mov [rax+0c0h], rcx
|
||||
; save address of context stack limit as 'dealloction stack'
|
||||
mov [rax+0b8h], rcx
|
||||
; set fiber-storage to zero
|
||||
; set fiber_context-storage to zero
|
||||
xor rcx, rcx
|
||||
mov [rax+0b0h], rcx
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
;* ------------------------------------------------- *
|
||||
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
|
||||
;* ------------------------------------------------- *
|
||||
;* | fiber data| base | limit | dealloc | *
|
||||
;* | fiber_context data| base | limit | dealloc | *
|
||||
;* ------------------------------------------------- *
|
||||
;* ------------------------------------------------- *
|
||||
;* | 48 | 49 | 50 | 51 | | | *
|
||||
@@ -84,7 +84,7 @@ ontop_fcontext proc BOOST_CONTEXT_EXPORT
|
||||
; save current stack base and limit
|
||||
ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
|
||||
stp x5, x6, [sp, #0xa0]
|
||||
; save current fiber data and deallocation stack
|
||||
; save current fiber_context data and deallocation stack
|
||||
ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
|
||||
ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h
|
||||
stp x5, x6, [sp, #0xb0]
|
||||
@@ -98,7 +98,7 @@ ontop_fcontext proc BOOST_CONTEXT_EXPORT
|
||||
; restore stack base and limit
|
||||
ldp x5, x6, [sp, #0xa0]
|
||||
stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
|
||||
; restore fiber data and deallocation stack
|
||||
; restore fiber_context data and deallocation stack
|
||||
ldp x5, x6, [sp, #0xb0]
|
||||
str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
|
||||
str x6, [x18, #0x20] ; TeFiberData at ksarm64.h
|
||||
|
||||
@@ -47,7 +47,7 @@ _ontop_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movl %fs:(0x18), %edx
|
||||
/* load fiber local storage */
|
||||
/* load fiber_context local storage */
|
||||
movl 0x10(%edx), %eax
|
||||
movl %eax, 0x8(%esp)
|
||||
/* load current dealloction stack */
|
||||
@@ -98,7 +98,7 @@ _ontop_fcontext:
|
||||
|
||||
/* restore NT_TIB into EDX */
|
||||
movl %fs:(0x18), %edx
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movl 0x8(%esp), %eax
|
||||
movl %eax, 0x10(%edx)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -47,7 +47,7 @@ _ontop_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movl %fs:(0x18), %edx
|
||||
/* load fiber local storage */
|
||||
/* load fiber_context local storage */
|
||||
movl 0x10(%edx), %eax
|
||||
movl %eax, 0x8(%esp)
|
||||
/* load current dealloction stack */
|
||||
@@ -98,7 +98,7 @@ _ontop_fcontext:
|
||||
|
||||
/* restore NT_TIB into EDX */
|
||||
movl %fs:(0x18), %edx
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movl 0x8(%esp), %eax
|
||||
movl %eax, 0x10(%edx)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -39,7 +39,7 @@ ENDIF
|
||||
; load NT_TIB into ECX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
; load fiber local storage
|
||||
; load fiber_context local storage
|
||||
mov eax, [edx+010h]
|
||||
mov [esp+08h], eax
|
||||
; load current deallocation stack
|
||||
@@ -92,7 +92,7 @@ ENDIF
|
||||
; load NT_TIB into EDX
|
||||
mov edx, fs:[018h]
|
||||
assume fs:error
|
||||
; restore fiber local storage
|
||||
; restore fiber_context local storage
|
||||
mov eax, [esp+08h]
|
||||
mov [edx+010h], eax
|
||||
; restore current deallocation stack
|
||||
|
||||
@@ -115,7 +115,7 @@ ontop_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* save fiber local storage */
|
||||
/* save fiber_context local storage */
|
||||
movq 0x20(%r10), %rax
|
||||
movq %rax, 0xb0(%rsp)
|
||||
/* save current deallocation stack */
|
||||
@@ -163,7 +163,7 @@ ontop_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movq 0xb0(%rsp), %rax
|
||||
movq %rax, 0x20(%r10)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -115,7 +115,7 @@ ontop_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* save fiber local storage */
|
||||
/* save fiber_context local storage */
|
||||
movq 0x20(%r10), %rax
|
||||
movq %rax, 0xb0(%rsp)
|
||||
/* save current deallocation stack */
|
||||
@@ -163,7 +163,7 @@ ontop_fcontext:
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* restore fiber local storage */
|
||||
/* restore fiber_context local storage */
|
||||
movq 0xb0(%rsp), %rax
|
||||
movq %rax, 0x20(%r10)
|
||||
/* restore current deallocation stack */
|
||||
|
||||
@@ -110,7 +110,7 @@ ENDIF
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; save fiber local storage
|
||||
; save fiber_context local storage
|
||||
mov rax, [r10+020h]
|
||||
mov [rsp+0b0h], rax
|
||||
; save current deallocation stack
|
||||
@@ -160,7 +160,7 @@ ENDIF
|
||||
|
||||
; load NT_TIB
|
||||
mov r10, gs:[030h]
|
||||
; restore fiber local storage
|
||||
; restore fiber_context local storage
|
||||
mov rax, [rsp+0b0h]
|
||||
mov [r10+020h], rax
|
||||
; restore current deallocation stack
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if defined(BOOST_USE_UCONTEXT)
|
||||
#include "boost/context/fiber_ucontext.hpp"
|
||||
#include "boost/context/fiber_context_ucontext.hpp"
|
||||
#elif defined(BOOST_USE_WINFIB)
|
||||
#include "boost/context/fiber_winfib.hpp"
|
||||
#include "boost/context/fiber_context_winfib.hpp"
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
@@ -21,17 +21,17 @@ namespace context {
|
||||
namespace detail {
|
||||
|
||||
// zero-initialization
|
||||
thread_local fiber_activation_record * fib_current_rec;
|
||||
thread_local fiber_context_activation_record * fib_current_rec;
|
||||
thread_local static std::size_t counter;
|
||||
|
||||
// schwarz counter
|
||||
fiber_activation_record_initializer::fiber_activation_record_initializer() noexcept {
|
||||
fiber_context_activation_record_initializer::fiber_context_activation_record_initializer() noexcept {
|
||||
if ( 0 == counter++) {
|
||||
fib_current_rec = new fiber_activation_record();
|
||||
fib_current_rec = new fiber_context_activation_record();
|
||||
}
|
||||
}
|
||||
|
||||
fiber_activation_record_initializer::~fiber_activation_record_initializer() {
|
||||
fiber_context_activation_record_initializer::~fiber_context_activation_record_initializer() {
|
||||
if ( 0 == --counter) {
|
||||
BOOST_ASSERT( fib_current_rec->is_main_context() );
|
||||
delete fib_current_rec;
|
||||
@@ -42,10 +42,10 @@ fiber_activation_record_initializer::~fiber_activation_record_initializer() {
|
||||
|
||||
namespace detail {
|
||||
|
||||
fiber_activation_record *&
|
||||
fiber_activation_record::current() noexcept {
|
||||
fiber_context_activation_record *&
|
||||
fiber_context_activation_record::current() noexcept {
|
||||
// initialized the first time control passes; per thread
|
||||
thread_local static fiber_activation_record_initializer initializer;
|
||||
thread_local static fiber_context_activation_record_initializer initializer;
|
||||
return fib_current_rec;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ test-suite minimal :
|
||||
cxx11_thread_local
|
||||
cxx11_variadic_templates ] ]
|
||||
|
||||
[ run test_fiber.cpp :
|
||||
[ run test_fiber_context.cpp :
|
||||
: :
|
||||
<context-impl>fcontext
|
||||
[ requires cxx11_auto_declarations
|
||||
@@ -105,9 +105,9 @@ test-suite minimal :
|
||||
cxx11_template_aliases
|
||||
cxx11_thread_local
|
||||
cxx11_variadic_templates ]
|
||||
: test_fiber_asm ]
|
||||
: test_fiber_context_asm ]
|
||||
|
||||
[ run test_fiber.cpp :
|
||||
[ run test_fiber_context.cpp :
|
||||
: :
|
||||
<conditional>@native-impl
|
||||
[ requires cxx11_auto_declarations
|
||||
@@ -123,9 +123,9 @@ test-suite minimal :
|
||||
cxx11_template_aliases
|
||||
cxx11_thread_local
|
||||
cxx11_variadic_templates ]
|
||||
: test_fiber_native ]
|
||||
: test_fiber_context_native ]
|
||||
|
||||
[ run test_fiber.cpp :
|
||||
[ run test_fiber_context.cpp :
|
||||
: :
|
||||
<context-impl>ucontext
|
||||
$(only-when-segmented-stack-is-available)
|
||||
@@ -142,7 +142,7 @@ test-suite minimal :
|
||||
cxx11_template_aliases
|
||||
cxx11_thread_local
|
||||
cxx11_variadic_templates ]
|
||||
: test_fiber_segmented ] ;
|
||||
: test_fiber_context_segmented ] ;
|
||||
|
||||
test-suite full :
|
||||
minimal ;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include <boost/context/fiber.hpp>
|
||||
#include <boost/context/fiber_context.hpp>
|
||||
#include <boost/context/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
@@ -50,7 +50,7 @@ std::string value2;
|
||||
double value3 = 0.;
|
||||
|
||||
struct X {
|
||||
ctx::fiber foo( ctx::fiber && f, int i) {
|
||||
ctx::fiber_context foo( ctx::fiber_context && f, int i) {
|
||||
value1 = i;
|
||||
return std::move( f);
|
||||
}
|
||||
@@ -109,8 +109,8 @@ public:
|
||||
};
|
||||
|
||||
struct my_exception : public std::runtime_error {
|
||||
ctx::fiber f;
|
||||
my_exception( ctx::fiber && f_, char const* what) :
|
||||
ctx::fiber_context f;
|
||||
my_exception( ctx::fiber_context && f_, char const* what) :
|
||||
std::runtime_error( what),
|
||||
f{ std::move( f_) } {
|
||||
}
|
||||
@@ -134,8 +134,8 @@ void test_move() {
|
||||
value1 = 0;
|
||||
int i = 1;
|
||||
BOOST_CHECK_EQUAL( 0, value1);
|
||||
ctx::fiber f1{
|
||||
[&i](ctx::fiber && f) {
|
||||
ctx::fiber_context f1{
|
||||
[&i](ctx::fiber_context && f) {
|
||||
value1 = i;
|
||||
f = std::move( f).resume();
|
||||
value1 = i;
|
||||
@@ -144,7 +144,7 @@ void test_move() {
|
||||
f1 = std::move( f1).resume();
|
||||
BOOST_CHECK_EQUAL( 1, value1);
|
||||
BOOST_CHECK( f1);
|
||||
ctx::fiber f2;
|
||||
ctx::fiber_context f2;
|
||||
BOOST_CHECK( ! f2);
|
||||
f2 = std::move( f1);
|
||||
BOOST_CHECK( ! f1);
|
||||
@@ -159,7 +159,7 @@ void test_move() {
|
||||
void test_bind() {
|
||||
value1 = 0;
|
||||
X x;
|
||||
ctx::fiber f{ std::bind( & X::foo, x, std::placeholders::_1, 7) };
|
||||
ctx::fiber_context f{ std::bind( & X::foo, x, std::placeholders::_1, 7) };
|
||||
f = std::move( f).resume();
|
||||
BOOST_CHECK_EQUAL( 7, value1);
|
||||
}
|
||||
@@ -167,8 +167,8 @@ void test_bind() {
|
||||
void test_exception() {
|
||||
{
|
||||
const char * what = "hello world";
|
||||
ctx::fiber f{
|
||||
[&what](ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[&what](ctx::fiber_context && f) {
|
||||
try {
|
||||
throw std::runtime_error( what);
|
||||
} catch ( std::runtime_error const& e) {
|
||||
@@ -184,7 +184,7 @@ void test_exception() {
|
||||
{
|
||||
bool catched = false;
|
||||
std::thread([&catched](){
|
||||
ctx::fiber f{ [&catched](ctx::fiber && f){
|
||||
ctx::fiber_context f{ [&catched](ctx::fiber_context && f){
|
||||
seh( catched);
|
||||
return std::move( f);
|
||||
}};
|
||||
@@ -199,8 +199,8 @@ void test_exception() {
|
||||
void test_fp() {
|
||||
value3 = 0.;
|
||||
double d = 7.13;
|
||||
ctx::fiber f{
|
||||
[&d]( ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[&d]( ctx::fiber_context && f) {
|
||||
d += 3.45;
|
||||
value3 = d;
|
||||
return std::move( f);
|
||||
@@ -213,10 +213,10 @@ void test_fp() {
|
||||
void test_stacked() {
|
||||
value1 = 0;
|
||||
value3 = 0.;
|
||||
ctx::fiber f{
|
||||
[](ctx::fiber && f) {
|
||||
ctx::fiber f1{
|
||||
[](ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[](ctx::fiber_context && f) {
|
||||
ctx::fiber_context f1{
|
||||
[](ctx::fiber_context && f) {
|
||||
value1 = 3;
|
||||
return std::move( f);
|
||||
}};
|
||||
@@ -237,9 +237,9 @@ void test_prealloc() {
|
||||
void * sp = static_cast< char * >( sctx.sp) - 10;
|
||||
std::size_t size = sctx.size - 10;
|
||||
int i = 7;
|
||||
ctx::fiber f{
|
||||
ctx::fiber_context f{
|
||||
std::allocator_arg, ctx::preallocated( sp, size, sctx), alloc,
|
||||
[&i]( ctx::fiber && f) {
|
||||
[&i]( ctx::fiber_context && f) {
|
||||
value1 = i;
|
||||
return std::move( f);
|
||||
}};
|
||||
@@ -251,7 +251,7 @@ void test_prealloc() {
|
||||
void test_ontop() {
|
||||
{
|
||||
int i = 3;
|
||||
ctx::fiber f{ [&i](ctx::fiber && f) {
|
||||
ctx::fiber_context f{ [&i](ctx::fiber_context && f) {
|
||||
for (;;) {
|
||||
i *= 10;
|
||||
f = std::move( f).resume();
|
||||
@@ -260,7 +260,7 @@ void test_ontop() {
|
||||
}};
|
||||
f = std::move( f).resume();
|
||||
// Pass fn by reference to see if the types are properly decayed.
|
||||
auto fn = [&i](ctx::fiber && f){
|
||||
auto fn = [&i](ctx::fiber_context && f){
|
||||
i -= 10;
|
||||
return std::move( f);
|
||||
};
|
||||
@@ -269,15 +269,15 @@ void test_ontop() {
|
||||
BOOST_CHECK_EQUAL( i, 200);
|
||||
}
|
||||
{
|
||||
ctx::fiber f1;
|
||||
ctx::fiber f{ [&f1](ctx::fiber && f) {
|
||||
ctx::fiber_context f1;
|
||||
ctx::fiber_context f{ [&f1](ctx::fiber_context && f) {
|
||||
f = std::move( f).resume();
|
||||
BOOST_CHECK( ! f);
|
||||
return std::move( f1);
|
||||
}};
|
||||
f = std::move( f).resume();
|
||||
f = std::move( f).resume_with(
|
||||
[&f1](ctx::fiber && f){
|
||||
[&f1](ctx::fiber_context && f){
|
||||
f1 = std::move( f);
|
||||
return std::move( f);
|
||||
});
|
||||
@@ -287,7 +287,7 @@ void test_ontop() {
|
||||
void test_ontop_exception() {
|
||||
value1 = 0;
|
||||
value2 = "";
|
||||
ctx::fiber f{ [](ctx::fiber && f){
|
||||
ctx::fiber_context f{ [](ctx::fiber_context && f){
|
||||
for (;;) {
|
||||
value1 = 3;
|
||||
try {
|
||||
@@ -303,7 +303,7 @@ void test_ontop_exception() {
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
const char * what = "hello world";
|
||||
f = std::move( f).resume_with(
|
||||
[what](ctx::fiber && f){
|
||||
[what](ctx::fiber_context && f){
|
||||
throw my_exception( std::move( f), what);
|
||||
return std::move( f);
|
||||
});
|
||||
@@ -314,8 +314,8 @@ void test_ontop_exception() {
|
||||
void test_termination1() {
|
||||
{
|
||||
value1 = 0;
|
||||
ctx::fiber f{
|
||||
[](ctx::fiber && f){
|
||||
ctx::fiber_context f{
|
||||
[](ctx::fiber_context && f){
|
||||
Y y;
|
||||
f = std::move( f).resume();
|
||||
return std::move(f);
|
||||
@@ -327,8 +327,8 @@ void test_termination1() {
|
||||
{
|
||||
value1 = 0;
|
||||
BOOST_CHECK_EQUAL( 0, value1);
|
||||
ctx::fiber f{
|
||||
[](ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[](ctx::fiber_context && f) {
|
||||
value1 = 3;
|
||||
return std::move( f);
|
||||
}};
|
||||
@@ -340,8 +340,8 @@ void test_termination1() {
|
||||
value1 = 0;
|
||||
BOOST_CHECK_EQUAL( 0, value1);
|
||||
int i = 3;
|
||||
ctx::fiber f{
|
||||
[&i](ctx::fiber && f){
|
||||
ctx::fiber_context f{
|
||||
[&i](ctx::fiber_context && f){
|
||||
value1 = i;
|
||||
f = std::move( f).resume();
|
||||
value1 = i;
|
||||
@@ -362,8 +362,8 @@ void test_termination2() {
|
||||
{
|
||||
value1 = 0;
|
||||
value3 = 0.0;
|
||||
ctx::fiber f{
|
||||
[](ctx::fiber && f){
|
||||
ctx::fiber_context f{
|
||||
[](ctx::fiber_context && f){
|
||||
Y y;
|
||||
value1 = 3;
|
||||
value3 = 4.;
|
||||
@@ -385,8 +385,8 @@ void test_termination2() {
|
||||
}
|
||||
|
||||
void test_sscanf() {
|
||||
ctx::fiber{
|
||||
[]( ctx::fiber && f) {
|
||||
ctx::fiber_context{
|
||||
[]( ctx::fiber_context && f) {
|
||||
{
|
||||
double n1 = 0;
|
||||
double n2 = 0;
|
||||
@@ -413,8 +413,8 @@ void test_sscanf() {
|
||||
}
|
||||
|
||||
void test_snprintf() {
|
||||
ctx::fiber{
|
||||
[]( ctx::fiber && f) {
|
||||
ctx::fiber_context{
|
||||
[]( ctx::fiber_context && f) {
|
||||
{
|
||||
const char *fmt = "sqrt(2) = %f";
|
||||
char buf[19];
|
||||
@@ -435,8 +435,8 @@ void test_snprintf() {
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
void test_bug12215() {
|
||||
ctx::fiber{
|
||||
[](ctx::fiber && f) {
|
||||
ctx::fiber_context{
|
||||
[](ctx::fiber_context && f) {
|
||||
char buffer[MAX_PATH];
|
||||
GetModuleFileName( nullptr, buffer, MAX_PATH);
|
||||
return std::move( f);
|
||||
@@ -448,8 +448,8 @@ void test_goodcatch() {
|
||||
value1 = 0;
|
||||
value3 = 0.0;
|
||||
{
|
||||
ctx::fiber f{
|
||||
[]( ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[]( ctx::fiber_context && f) {
|
||||
Y y;
|
||||
value3 = 2.;
|
||||
f = std::move( f).resume();
|
||||
@@ -483,8 +483,8 @@ void test_badcatch() {
|
||||
value1 = 0;
|
||||
value3 = 0.;
|
||||
{
|
||||
ctx::fiber f{
|
||||
[]( ctx::fiber && f) {
|
||||
ctx::fiber_context f{
|
||||
[]( ctx::fiber_context && f) {
|
||||
Y y;
|
||||
try {
|
||||
value3 = 3.;
|
||||
Reference in New Issue
Block a user