Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Stack allocation

Support for valgrind
Support for sanitizers

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

stack-allocator concept

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

a(size)

creates a stack allocator

a.allocate()

stack_context

creates a stack

a.deallocate( sctx)

void

deallocates the stack created by a.allocate()

[Important] Important

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

[Important] Important

Calling deallocate() with a stack_context not obtained from allocate() results in undefined behaviour.

[Note] 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.

Class 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] Important

Using protected_fixedsize_stack is expensive. Launching a new fiber with a stack of this type incurs the overhead of setting the memory protection; once allocated, this stack is just as efficient to use as fixedsize_stack.

[Note] Note

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

#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 &);
}

}}

Member function allocate()

stack_context allocate();

Preconditions:

traits_type::minimum_size() <= size and traits_type::is_unbounded() || ( size <= traits_type::maximum_size() ).

Effects:

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

Member function deallocate()

void deallocate( stack_context & sctx);

Preconditions:

sctx.sp is valid, traits_type::minimum_size() <= sctx.size and traits_type::is_unbounded() || ( sctx.size <= traits_type::maximum_size() ).

Effects:

Deallocates the stack space.

Class 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 &);
}

}}

Constructor

pooled_fixedsize_stack(std::size_t stack_size, std::size_t next_size, std::size_t max_size);

Preconditions:

traits_type::is_unbounded() || ( traits_type::maximum_size() >= stack_size) and 0 < next_size.

Effects:

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

Member function allocate()

stack_context allocate();

Preconditions:

traits_type::is_unbounded() || ( traits_type::maximum_size() >= stack_size).

Effects:

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

Member function deallocate()

void deallocate( stack_context & sctx);

Preconditions:

sctx.sp is valid, traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size).

Effects:

Deallocates the stack space.

[Note] Note

This stack allocator is not thread safe.

Class 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 &);
}

}}

Member function allocate()

stack_context allocate();

Preconditions:

traits_type::minimum_size() <= size and traits_type::is_unbounded() || ( traits_type::maximum_size() >= size).

Effects:

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

Member function deallocate()

void deallocate( stack_context & sctx);

Preconditions:

sctx.sp is valid, traits_type::minimum_size() <= sctx.size and traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size).

Effects:

Deallocates the stack space.

Class 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] 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 segmented_stack Boost.Fiber must be built with property segmented-stacks, e.g. toolset=gcc segmented-stacks=on and applying BOOST_USE_SEGMENTED_STACKS at b2/bjam command line.

[Note] Note

Segmented stacks can only be used with callcc() using property context-impl=ucontext.

#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 &);
}

}}

Member function allocate()

stack_context allocate();

Preconditions:

traits_type::minimum_size() <= size and traits_type::is_unbounded() || ( traits_type::maximum_size() >= size).

Effects:

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

Member function deallocate()

void deallocate( stack_context & sctx);

Preconditions:

sctx.sp is valid, traits_type::minimum_size() <= sctx.size and traits_type::is_unbounded() || ( traits_type::maximum_size() >= sctx.size).

Effects:

Deallocates the stack space.

[Note] Note

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


PrevUpHomeNext