| Home | Libraries | People | FAQ | More

## Rationale

#### preprocessor defines

Table 1.6. preopcessor defines

BOOST_FIBERS_NO_ATOMICS | no `std::atomic<>` used, inter-thread synchronization disabled
BOOST_FIBERS_SPINLOCK_STD_MUTEX | use `std::mutex` as spinlock instead of default `XCHG`-sinlock with backoff
BOOST_FIBERS_SPIN_BACKOFF | limit determines when to used `std::this_thread::yield()` instead of mnemonic `pause/yield` during busy wait (apllies on to `XCHG`-spinlock)
BOOST_FIBERS_SINGLE_CORE | allways call `std::this_thread::yield()` without backoff during busy wait (apllies on to `XCHG`-spinlock)

#### distinction between coroutines and fibers

The fiber library extends the coroutine library by adding a scheduler and synchronization mechanisms.

- a coroutine yields
- a fiber blocks

When a coroutine yields, it passes control directly to its caller (or, in the case of symmetric coroutines, a designated other coroutine). When a fiber blocks, it implicitly passes control to the fiber scheduler. Coroutines have no scheduler because they need no scheduler.[12].

#### what about transactional memory

GCC supports transactional memory since version 4.7. Unfortunately tests show that transactional memory is slower (ca. 4x) than spinlocks using atomics. Once transactional memory is improved (supporting hybrid tm), spinlocks will be replaced by __transaction_atomic{} statements surrounding the critical sections.

#### synchronization between fibers running in different threads

Synchronization classes from Boost.Thread block the entire thread. In contrast, the synchronization classes from Boost.Fiber block only specific fibers, so that the scheduler can still keep the thread busy running other fibers in the meantime. The synchronization classes from Boost.Fiber are designed to be thread-safe, i.e. it is possible to synchronize fibers running in different threads as well as fibers running in the same thread. (However, there is a build option to disable cross-thread fiber synchronization support; see this description.)

#### spurious wakeup

Spurious wakeup can happen when using `std::condition_variable`: the condition variable appears to be have been signaled while the awaited condition may still be false. Spurious wakeup can happen repeatedly and is caused on some multiprocessor systems where making `std::condition_variable` wakeup completely predictable would slow down all `std::condition_variable` operations.[13]

`condition_variable` is not subject to spurious wakeup. Nonetheless it is prudent to test the business-logic condition in a `wait()` loop — or, equivalently, use one of the `wait( lock, predicate )` overloads.

See also No Spurious Wakeups.

#### migrating fibers between threads

Support for migrating fibers between threads has been integrated. The user-defined scheduler must call `context::detach()` on a fiber-context on the source thread and `context::attach()` on the destination thread, passing the fiber-context to migrate. (For more information about custom schedulers, see Customization.) Examples `work_sharing` and `work_stealing` in directory `examples` might be used as a blueprint.

See also Migrating fibers between threads.

#### support for Boost.Asio

Support for Boost.Asio’s async-result is not part of the official API. However, to integrate with a `boost::asio::io_service`, see Sharing a Thread with Another Main Loop. To interface smoothly with an arbitrary Asio async I/O operation, see Then There’s Boost.Asio.

#### tested compilers

The library was tested with GCC-5.1.1, Clang-3.6.0 and MSVC-14.0 in c++11-mode.

#### supported architectures

Boost.Fiber depends on Boost.Context - the list of supported architectures can be found here.

[12] 'N4024: Distinguishing coroutines and fibers'

[13] David R. Butenhof “Programming with POSIX Threads”