...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
A fiber
uses internally an __econtext__ which manages a set of registers
and a stack. The memory used by the stack is allocated/deallocated via a stack_allocator
which is required to model a stack-allocator
concept.
A stack_allocator can be passed to fiber::fiber()
or to fibers::async()
.
A stack_allocator must satisfy the stack-allocator
concept requirements shown in the following table, in which a
is an object of a stack_allocator
type, sctx
is a stack_context
, and size
is a std::size_t
:
expression |
return type |
notes |
---|---|---|
|
creates a stack allocator |
|
|
creates a stack |
|
|
|
deallocates the stack created by |
Important | |
---|---|
The implementation of |
Important | |
---|---|
Calling |
Note | |
---|---|
The memory for the stack is not required to be aligned; alignment takes place inside __econtext__. |
See also Boost.Context
stack allocation. In particular, traits_type
methods are as described for boost::context::stack_traits
.
protected_fixedsize_stack
Boost.Fiber 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 | |
---|---|
Using |
Note | |
---|---|
The appended |
#include <boost/fiber/protected_fixedsize.hpp> namespace boost { namespace fibers { struct protected_fixedsize { protected_fixesize(std::size_t size = traits_type::default_size()); stack_context allocate(); void deallocate( stack_context &); } }}
allocate
()
stack_context allocate();
traits_type::minimum_size()
<= size
and traits_type::is_unbounded()
|| (
size <=
traits_type::maximum_size()
)
.
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.
deallocate
()
void deallocate( stack_context & sctx);
sctx.sp
is valid, traits_type::minimum_size() <= sctx.size
and traits_type::is_unbounded() || ( sctx.size <= traits_type::maximum_size() )
.
Deallocates the stack space.
pooled_fixedsize_stack
Boost.Fiber 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/fiber/pooled_fixedsize_stack.hpp> namespace boost { namespace fibers { struct pooled_fixedsize_stack { 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 &); } }}
pooled_fixedsize_stack(std::size_t stack_size, std::size_t next_size, std::size_t max_size);
traits_type::is_unbounded()
|| (
traits_type::maximum_size()
>= stack_size)
and 0
< next_size
.
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 much memory might be allocated for stacks — a value of zero
means no upper limit.
allocate
()
stack_context allocate();
traits_type::is_unbounded()
|| (
traits_type::maximum_size()
>= stack_size)
.
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.
deallocate
()
void deallocate( stack_context & sctx);
sctx.sp
is valid, traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size)
.
Deallocates the stack space.
Note | |
---|---|
This stack allocator is not thread safe. |
fixedsize_stack
Boost.Fiber 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> namespace boost { namespace fibers { struct fixedsize_stack { fixedsize_stack(std::size_t size = traits_type::default_size()); stack_context allocate(); void deallocate( stack_context &); } }}
allocate
()
stack_context allocate();
traits_type::minimum_size()
<= size
and traits_type::is_unbounded()
|| (
traits_type::maximum_size()
>= size)
.
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.
deallocate
()
void deallocate( stack_context & sctx);
sctx.sp
is valid, traits_type::minimum_size() <= sctx.size
and traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size)
.
Deallocates the stack space.
segmented_stack
Boost.Fiber supports usage of a segmented_stack
,
i.e. the stack grows on demand. The fiber is created with a minimal stack size
which 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 | |
---|---|
Segmented stacks are currently only supported by gcc
from version 4.7 and clang
from version 3.4 onwards. In order to use
a |
Note | |
---|---|
Segmented stacks can only be used with callcc() using property |
#include <boost/fiber/segmented_stack.hpp> namespace boost { namespace fibers { struct segmented_stack { segmented_stack(std::size_t stack_size = traits_type::default_size()); stack_context allocate(); void deallocate( stack_context &); } }}
allocate
()
stack_context allocate();
traits_type::minimum_size()
<= size
and traits_type::is_unbounded()
|| (
traits_type::maximum_size()
>= size)
.
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.
deallocate
()
void deallocate( stack_context & sctx);
sctx.sp
is valid, traits_type::minimum_size() <= sctx.size
and traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size)
.
Deallocates the stack space.
Note | |
---|---|
If the library is compiled for segmented stacks, |