From 634fa3fe6a77f1aa621045d6def04a5ba856c0a5 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Nov 2013 15:28:46 -0500 Subject: [PATCH 1/7] Document desired behavior for fiber::thread_affinity(). Also clarify Preconditions for fiber::priority(). --- doc/fiber.qbk | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/fiber.qbk b/doc/fiber.qbk index cb2df755..c4a219fb 100644 --- a/doc/fiber.qbk +++ b/doc/fiber.qbk @@ -420,7 +420,8 @@ interruption enabled.]] void priority( int) noexcept; [variablelist -[[Effects:] [If `*this` refers to a fiber of execution, set its priority.]] +[[Preconditions:] [`*this` refers to a fiber of execution.]] +[[Effects:] [set priority for the fiber referenced by `*this`.]] [[Throws:] [Nothing]] [[Note:] [The meaning of particular `int` values is determined by the specific `algorithm` passed to `set_scheduling_algorithm()`. `round_robin` ignores @@ -432,7 +433,8 @@ interruption enabled.]] int priority() const noexcept; [variablelist -[[Effects:] [If `*this` refers to a fiber of execution, return its priority.]] +[[Preconditions:] [`*this` refers to a fiber of execution.]] +[[Returns:] [priority for the fiber referenced by `*this`.]] [[Throws:] [Nothing]] ] @@ -441,10 +443,14 @@ interruption enabled.]] void thread_affinity( bool) noexcept; [variablelist -[[Effects:] [If `*this` refers to a fiber of execution, set its thread affinity.]] +[[Preconditions:] [`*this` refers to a fiber of execution.]] +[[Effects:] [Set thread affinity for the fiber referenced by `*this`.]] [[Throws:] [Nothing]] -[[Note:] [A value of `false` prevents migrating the fiber to another scheduler -running in a different thread.]] +[[Note:] ["Thread affinity" is only meaningful for certain scheduler +algorithms, such as `round_robin_ws'. Many schedulers ignore this fiber +attribute. With a scheduler that might potentially migrate a fiber from its +initial thread to another, the value `true` prevents migration: the fiber +will always run on its current thread.]] ] [heading Member function `thread_affinity()`] @@ -452,7 +458,8 @@ running in a different thread.]] bool thread_affinity() const noexcept; [variablelist -[[Effects:] [If `*this` refers to a fiber of execution, return its thread affinity.]] +[[Preconditions:] [`*this` refers to a fiber of execution.]] +[[Returns:] [thread affinity for the fiber referenced by `*this`.]] [[Throws:] [Nothing]] ] From 919a2993c25c75242a18935b297e2e802782c22e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Nov 2013 15:53:34 -0500 Subject: [PATCH 2/7] Document new [un]bounded_queue API, plus a bit of guessing. Change certain [un]bounded_queue method signatures to return queue_op_status. Their previous signatures didn't provide any way to report a closed queue. For Note: interruption point, document Throws: fiber_interrupted. Write a few more words about bounded_queue's high water mark and low water mark. --- doc/queue.qbk | 243 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 169 insertions(+), 74 deletions(-) diff --git a/doc/queue.qbk b/doc/queue.qbk index 5175eeef..51a34a03 100644 --- a/doc/queue.qbk +++ b/doc/queue.qbk @@ -21,8 +21,9 @@ synchonize fibers via message passing. void recv( queue_t & queue) { - while ( ! queue.is_closed() ) - { std::cout << "received " << queue.value_pop() << std::endl; } + int i; + while ( queue.value_pop(i) == boost::fibers::queue_op_status::success ) + { std::cout << "received " << i << std::endl; } } queue_t queue; @@ -34,7 +35,7 @@ synchonize fibers via message passing. [heading Enumeration `queue_op_status`] -Queue-operations return the state of the queue. +Queue operations return the state of the queue. enum class queue_op_status { @@ -47,7 +48,7 @@ Queue-operations return the state of the queue. [heading `success`] [variablelist -[[Effects:] [Operation was successfull.]] +[[Effects:] [Operation was successful.]] ] [heading `empty`] @@ -67,7 +68,7 @@ Queue-operations return the state of the queue. [heading `timeout`] [variablelist -[[Effects:] [The operation did not become ready before timout has passed.]] +[[Effects:] [The operation did not become ready before specified timeout elapsed.]] ] [heading Template `unbounded_queue<>`] @@ -89,14 +90,14 @@ Queue-operations return the state of the queue. bool is_empty(); void push( value_type const& va); - void push( value_types &&) va); + void push( value_type && va); - value_type value_pop(); + queue_op_status value_pop( value_type & va); template< typename Rep, typename Period > queue_op_status wait_pop( value_type & va, - chrono::duration< Rep, Period > const& timeout_duration) + chrono::duration< Rep, Period > const& timeout_duration); queue_op_status wait_pop( value_type & va, - clock_type::time_point const& timeout_time) + clock_type::time_point const& timeout_time); queue_op_status try_pop( value_type & va); }; @@ -105,20 +106,21 @@ Queue-operations return the state of the queue. bool is_closed() const; [variablelist -[[Effects:] [Return `true` if queue was closed.]] +[[Returns:] [`true` if queue has been closed.]] [[Throws:] [Nothing.]] [[Note:] [The queue is not closed by default.]] ] -[heading Member function `closed()`] +[heading Member function `close()`] - void closed(); + void close(); [variablelist [[Effects:] [Deactivates the queue. No values can be put after calling -`this->close`. Fibers blocked in `this->value_pop()` will return.]] +`this->close()`. Fibers blocked in `this->value_pop()` or `this->wait_pop()` +will return `closed`.]] [[Throws:] [Nothing.]] -[[Note:] [`close()` is like closing a pipe. It informs waiting receivers +[[Note:] [`close()` is like closing a pipe. It informs waiting consumers that no more values will arrive.]] ] @@ -139,35 +141,52 @@ non-empty.]] void push( value_type && va); [variablelist -[[Effects:] [Enqueues the value in the queue and wakes up a fiber waiting -for new data available from the queue.]] +[[Effects:] [Enqueues the value in the queue and wakes up a fiber blocked on +`this->value_pop()` or `this->wait_pop()`.]] [[Throws:] [Nothing.]] ] -[heading Member function `take()`] +[heading Member function `value_pop()`] - bool take( boost::optional< T > & va); + queue_op_status value_pop( value_type & va); [variablelist -[[Effects:] [Dequeues a value from the queue. If no data is available from the -queue the fiber gets suspended until at least one new item is enqueued (return -value `true` and va contains dequeued value) or the queue gets deactivated and -the function returns `false`.]] -[[Throws:] [Nothing.]] -[[Note:] [interruption point]] +[[Effects:] [Dequeues a value from the queue. If the queue `is_empty()`, the +fiber gets suspended until at least one new item is `push()`ed (return value +`success` and `va` contains dequeued value) or the queue gets `close()`d +(return value `closed`).]] +[[Throws:] [__fiber_interrupted__]] ] -[heading Member function `try_take()`] +[heading Member function `wait_pop()`] - bool try_take( boost::optional< T > & va); + template< typename Rep, typename Period > + queue_op_status wait_pop( value_type & va, + chrono::duration< Rep, Period > const& timeout_duration) + queue_op_status wait_pop( value_type & va, + clock_type::time_point const& timeout_time) [variablelist -[[Effects:] [Dequeues a value from the queue. If no data can be retrieved from -the queue at this moment, the function returns `false`. Otherwise it returns -`true` and `va` contains the dequeued value.]] +[[Effects:] [First the overload accepting `chrono::duration` internally +computes a `clock_type::time_point` as `(clock_type::now() + +timeout_duration)`. If `(! this->is_empty())`, immediately dequeues a value +from the queue. Otherwise the fiber gets suspended until at least one new item +is `push()`ed (return value `success` and `va` contains dequeued value), or +the queue gets `close()`d (return value `closed`), or the time as reported by +`clock_type::now()` reaches the (passed or computed) `clock_type::time_point` +(return value `timeout`).]] +[[Throws:] [__fiber_interrupted__]] +] + +[heading Member function `try_pop()`] + + queue_op_status try_pop( value_type & va); + +[variablelist +[[Effects:] [If `this->is_empty()`, returns `empty`. If `this->is_closed()`, +returns `closed`. Otherwise it returns `success` and `va` contains the +dequeued value.]] [[Throws:] [Nothing.]] -[[Note:] [A return value of `false` does not distinguish between `empty()` and -`(! active())`.]] ] @@ -185,7 +204,6 @@ the queue at this moment, the function returns `false`. Otherwise it returns bounded_queue & operator=( bounded_queue const& other) = delete; bounded_queue( std::size_t wm); - bounded_queue( std::size_t hwm, std::size_t lwm); bool is_closed() const; @@ -194,8 +212,8 @@ the queue at this moment, the function returns `false`. Otherwise it returns bool is_empty(); bool is_full(); - void push( T const& t); - void push( T && t); + queue_op_status push( value_type const& va); + queue_op_status push( value_type && va); template< typename Rep, typename Period > queue_op_status wait_push( value_type const& va, chrono::duration< Rep, Period > const& timeout_duration); @@ -209,7 +227,7 @@ the queue at this moment, the function returns `false`. Otherwise it returns queue_op_status try_push( value_type const& va); queue_op_status try_push( value_type && va); - value_type value_pop(); + queue_op_status value_pop( value_type & va); template< typename Rep, typename Period > queue_op_status wait_pop( value_type & va, chrono::duration< Rep, Period > const& timeout_duration); @@ -224,85 +242,162 @@ the queue at this moment, the function returns `false`. Otherwise it returns bounded_queue( std::size_t hwm, std::size_t lwm); [variablelist -[[Effects:] [Constructs an object of class `bounded_queue` which will contain -a maximum of `wm` items. The constructor with two arguments constructs an object -of class `bounded_queue` which will contain a high-watermark of `hwm` and a -low-watermark of `lwm` items.]] +[[Preconditions:] [`hwm >= lwm`]] +[[Effects:] [Constructs an object of class `bounded_queue`. The constructor +with two arguments constructs an object of class `bounded_queue` with a +high-watermark of `hwm` and a low-watermark of `lwm` items. The constructor +with one argument effectively sets both `hwm` and `lwm` to the same value +`wm`.]] [[Throws:] [Nothing.]] +[[Notes:] [Once the number of values in the queue reaches `hwm`, any call to +`push()` or `wait_push()` will block until the number of values in the queue +has dropped below `lwm`. That is, if `lwm < hwm`, the queue can be in a state +in which `push()` or `wait_push()` calls will block (`is_full()` returns +`true`) even though the number of values in the queue is less than `hwm`.]] ] -[heading Member function `active()`] +[heading Member function `is_closed()`] - bool active() const; + bool is_closed() const; [variablelist -[[Effects:] [Return `true` if queue is still usable.]] +[[Returns:] [`true` if queue has been closed.]] [[Throws:] [Nothing.]] -[[Note:] [The queue is usable by default.]] +[[Note:] [The queue is not closed by default.]] ] -[heading Member function `deactivate()`] +[heading Member function `close()`] - void deactivate(); + void close(); [variablelist [[Effects:] [Deactivates the queue. No values can be put after calling -`this->deactivate`. Fibers blocked in `this->take()` will return.]] +`this->close()`. Fibers blocked in `this->value_pop()` or `this->wait_pop()` +will return `closed`.]] [[Throws:] [Nothing.]] -[[Note:] [`deactivate()` is like closing a pipe. It informs waiting receivers +[[Note:] [`close()` is like closing a pipe. It informs waiting consumers that no more values will arrive.]] ] -[heading Member function `empty()`] +[heading Member function `is_empty()`] - bool empty(); + bool is_empty(); [variablelist [[Effects:] [Returns `true` if the queue currently contains no data.]] [[Throws:] [Nothing.]] -[[Note:] [This condition is transient. An `empty()` queue can become +[[Note:] [This condition is transient. An `is_empty()` queue can become non-empty.]] -[[Note:] [Oliver: wouldn't it make sense to have a corresponding `full()` method?]] ] -[heading Member function `put()`] +[heading Member function `is_full()`] - void put( T const& t); + bool is_full(); [variablelist -[[Effects:] [Enqueues the value in the queue and wakes up a fiber waiting -for new data available from the queue. When the high water mark is reached, the -fiber putting the value will be supended until at least one item is -dequeued.]] +[[Effects:] [Returns `true` if the queue cannot accept more data at present. +This happens when the number of values in the queue reaches `wm` or `hwm`. +Once the queue becomes full, however, it continues refusing new values until +the number of values drops below `lwm`.]] [[Throws:] [Nothing.]] -[[Note:] [interruption point]] +[[Note:] [This condition is transient.]] ] -[heading Member function `take()`] +[heading Member function `push()`] - bool take( boost::optional< T > & va); + queue_op_status push( value_type const& va); + queue_op_status push( value_type && va); [variablelist -[[Effects:] [Dequeues a value from the queue. If no data is available from the -queue the fiber gets suspended until at least one new item is enqueued (return -value `true` and va contains dequeued value) or the queue gets deactivated and -the function returns `false`. Once the number of items remaining in the queue -drops below `lwm`, any fibers blocked on `put()` may resume.]] -[[Throws:] [Nothing.]] -[[Note:] [interruption point]] +[[Effects:] [If `this->is_closed()`, returns `closed`. If `(! +this->is_full())`, enqueues the value in the queue, wakes up a fiber blocked +on `this->value_pop()` or `this->wait_pop()` and returns `success`. Otherwise +the fiber gets suspended until the number of values in the queue drops below +`lwm` (return value `success`), or the queue is `close()`d (return value +`closed`).]] +[[Throws:] [__fiber_interrupted_]] ] -[heading Member function `try_take()`] +[heading Member function `wait_push()`] - bool try_take( boost::optional< T > & va); + template< typename Rep, typename Period > + queue_op_status wait_push( value_type const& va, + chrono::duration< Rep, Period > const& timeout_duration); + template< typename Rep, typename Period > + queue_op_status wait_push( value_type && va, + chrono::duration< Rep, Period > const& timeout_duration); + queue_op_status wait_push( value_type const& va, + clock_type::time_point const& timeout_time); + queue_op_status wait_push( value_type && va, + clock_type::time_point const& timeout_time); [variablelist -[[Effects:] [Dequeues a value from the queue. If no data can be retrieved from -the queue at this moment, the function returns `false`. Otherwise it returns -`true` and `va` contains the dequeued value.]] +[[Effects:] [First the overload accepting `chrono::duration` internally +computes a `clock_type::time_point` as `(clock_type::now() + +timeout_duration)`. If `this->is_closed()`, returns `closed`. If `(! +this->is_full())`, enqueues the value in the queue, wakes up a fiber blocked +on `this->value_pop()` or `this->wait_pop()` and returns `success`. Otherwise +the fiber gets suspended until the number of values in the queue drops below +`lwm` (return value `success`), the queue is `close()`d (return value +`closed`), or the time as reported by `clock_type::now()` reaches the (passed +or computed) `clock_type::time_point` (return value `timeout`).]] +[[Throws:] [__fiber_interrupted_]] +] + +[heading Member function `try_push()`] + + queue_op_status try_push( value_type const& va); + queue_op_status try_push( value_type && va); + +[variablelist +[[Effects:] [If `this->is_full()`, returns `full`. If `this->is_closed()`, +returns `closed`. Otherwise enqueues the value in the queue, wakes up a fiber +blocked on `this->value_pop()` or `this->wait_pop()` and returns `success`.]] +[[Throws:] [__fiber_interrupted_]] +] + +[heading Member function `value_pop()`] + + queue_op_status value_pop( value_type & va); + +[variablelist +[[Effects:] [Dequeues a value from the queue. If the queue `is_empty()`, the +fiber gets suspended until at least one new item is `push()`ed (return value +`success` and `va` contains dequeued value) or the queue gets `close()`d +(return value `closed`). Once the number of items remaining in the queue +drops below `lwm`, any fibers blocked on `push()` or `wait_push()` may resume.]] +[[Throws:] [__fiber_interrupted__]] +] + +[heading Member function `wait_pop()`] + + template< typename Rep, typename Period > + queue_op_status wait_pop( value_type & va, + chrono::duration< Rep, Period > const& timeout_duration) + queue_op_status wait_pop( value_type & va, + clock_type::time_point const& timeout_time) + +[variablelist +[[Effects:] [First the overload accepting `chrono::duration` internally +computes a `clock_type::time_point` as `(clock_type::now() + +timeout_duration)`. If `(! this->is_empty())`, immediately dequeues a value +from the queue. Otherwise the fiber gets suspended until at least one new item +is `push()`ed (return value `success` and `va` contains dequeued value), or +the queue gets `close()`d (return value `closed`), or the time as reported by +`clock_type::now()` reaches the (passed or computed) `clock_type::time_point` +(return value `timeout`).]] +[[Throws:] [__fiber_interrupted__]] +] + +[heading Member function `try_pop()`] + + queue_op_status try_pop( value_type & va); + +[variablelist +[[Effects:] [If `this->is_empty()`, returns `empty`. If `this->is_closed()`, +returns `closed`. Otherwise it returns `success` and `va` contains the +dequeued value.]] [[Throws:] [Nothing.]] -[[Note:] [A return value of `false` does not distinguish between `empty()` and -`(! active())`.]] ] [endsect] From 938de048299950eb709f12baa4ff3b4a75a82584 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Nov 2013 16:28:56 -0500 Subject: [PATCH 3/7] Document that bounded_queue constructor can in fact throw. --- doc/queue.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/queue.qbk b/doc/queue.qbk index 51a34a03..aa964e52 100644 --- a/doc/queue.qbk +++ b/doc/queue.qbk @@ -248,7 +248,7 @@ with two arguments constructs an object of class `bounded_queue` with a high-watermark of `hwm` and a low-watermark of `lwm` items. The constructor with one argument effectively sets both `hwm` and `lwm` to the same value `wm`.]] -[[Throws:] [Nothing.]] +[[Throws:] [`invalid_argument` if `lwm > hwm`.]] [[Notes:] [Once the number of values in the queue reaches `hwm`, any call to `push()` or `wait_push()` will block until the number of values in the queue has dropped below `lwm`. That is, if `lwm < hwm`, the queue can be in a state From d9c1272df6b1a179f8291b76be5ef19d23d9400a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Nov 2013 16:31:20 -0500 Subject: [PATCH 4/7] Describe this_fiber::thread_affinity() in terms of fiber::thread_affinity(). Also mention that fiber::thread_affinity() is off by default. --- doc/fiber.qbk | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/fiber.qbk b/doc/fiber.qbk index c4a219fb..51e44ed5 100644 --- a/doc/fiber.qbk +++ b/doc/fiber.qbk @@ -450,7 +450,8 @@ interruption enabled.]] algorithms, such as `round_robin_ws'. Many schedulers ignore this fiber attribute. With a scheduler that might potentially migrate a fiber from its initial thread to another, the value `true` prevents migration: the fiber -will always run on its current thread.]] +will always run on its current thread. The default is `false`: normally, with +an applicable scheduler, a fiber is allowed to migrate across threads.]] ] [heading Member function `thread_affinity()`] @@ -798,10 +799,10 @@ there are no guarantees about how soon after that it might resume.]] void thread_affinity( bool req) noexcept; [variablelist -[[Effects:] [Affects the abiblity to select a fiber for migraton to another -scheduler (running in another thread).]] +[[Effects:] [Set or report `fiber::thread_affinity()` for the currently +running fiber.]] [[Throws:] [Nothing.]] -[[Note:][Thread affinity is disabled by default.]] +[[Note:] [`fiber::thread_affinity()` is `false` by default.]] ] [heading Non-member function `interruption_point()`] From 32af998f3c6c88eeaafb43a7074bdca996e52e78 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Nov 2013 17:02:24 -0500 Subject: [PATCH 5/7] Fix markup error in fiber::thread_affinity() Note. --- doc/fiber.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fiber.qbk b/doc/fiber.qbk index 51e44ed5..9327c99a 100644 --- a/doc/fiber.qbk +++ b/doc/fiber.qbk @@ -447,7 +447,7 @@ interruption enabled.]] [[Effects:] [Set thread affinity for the fiber referenced by `*this`.]] [[Throws:] [Nothing]] [[Note:] ["Thread affinity" is only meaningful for certain scheduler -algorithms, such as `round_robin_ws'. Many schedulers ignore this fiber +algorithms, such as `round_robin_ws`. Many schedulers ignore this fiber attribute. With a scheduler that might potentially migrate a fiber from its initial thread to another, the value `true` prevents migration: the fiber will always run on its current thread. The default is `false`: normally, with From 7c7683ad415dfd0150713b0ed7b28eab2e82b2a3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Nov 2013 22:02:43 -0500 Subject: [PATCH 6/7] Start adding internal cross-references to fiber documentation --- doc/barrier.qbk | 2 +- doc/fiber.qbk | 6 +++--- doc/fibers.qbk | 23 ++++++++++++----------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/doc/barrier.qbk b/doc/barrier.qbk index 89f06da9..c80162d3 100644 --- a/doc/barrier.qbk +++ b/doc/barrier.qbk @@ -15,7 +15,7 @@ barrier they must wait until all `n` fibers have arrived. Once the `n`-th fiber has reached the barrier, all the waiting fibers can proceed, and the barrier is reset. -[heading Class `barrier`] +[heading Class barrier] #include diff --git a/doc/fiber.qbk b/doc/fiber.qbk index 9327c99a..ef0c4b85 100644 --- a/doc/fiber.qbk +++ b/doc/fiber.qbk @@ -349,7 +349,7 @@ value of `other.get_id()` prior to the assignment.]] the fiber is still joinable. See __detach__.]] ] -[heading Member function `joinable()`] +[heading Member function joinable] bool joinable() const noexcept; @@ -805,7 +805,7 @@ running fiber.]] [[Note:] [`fiber::thread_affinity()` is `false` by default.]] ] -[heading Non-member function `interruption_point()`] +[heading Non-member function interruption_point] #include void interruption_point(); @@ -841,7 +841,7 @@ __interruption_requested__ both return `true`.]] [[Note:][Interruption is enabled by default.]] ] -[heading Class `disable_interruption`] +[heading Class disable_interruption] #include diff --git a/doc/fibers.qbk b/doc/fibers.qbk index 336ecf78..5be12323 100644 --- a/doc/fibers.qbk +++ b/doc/fibers.qbk @@ -9,6 +9,7 @@ [quickbook 1.5] [authors [Kowalke, Oliver]] [copyright 2013 Oliver Kowalke] + [id fiber] [purpose C++ Library to cooperatively schedule and synchronize micro-threads] [category text] [license @@ -33,30 +34,30 @@ [def __not_a_fiber__ ['not-a-fiber]] [def __rendezvous__ ['rendezvous]] -[def __barrier__ `barrier`] -[def __condition__ `condition`] +[def __barrier__ [link fiber.synchronization.barriers.class_barrier `barrier`]] +[def __condition__ [link fiber.conditions.class_condition_variable `condition_variable`]] [def __coro__ ['coroutine]] [def __coro_allocator__ ['coroutine-allocator]] -[def __disable_interruption__ `disable_interruption`] -[def __enable_interruption__ `enable_interruption`] +[def __disable_interruption__ [link fiber.fiber_mgmt.this_fiber.class_disable_interruption `disable_interruption`]] +[def __enable_interruption__ [link fiber.fiber_mgmt.class_enable_interruption `enable_interruption`]] [def __fiber_exception__ `fiber_exception`] -[def __fiber__ `fiber`] -[def __fiber_group__ `fiber_group`] +[def __fiber__ [link fiber.fiber_mgmt.fiber `fiber`]] +[def __fiber_group__ [link fiber.fiber_mgmt.fiber_group `fiber_group`]] [def __fiber_interrupted__ `fiber_interrupted`] [def __fiber_resource_error__ `fiber_resource_error`] [def __fibers__ `fibers`] -[def __future__ `future`] +[def __future__ [link fiber.synchronization.futures.future `future`]] [def __future_error__ `future_error`] -[def __interruption_point__ `interruption_point`] +[def __interruption_point__ [link fiber.fiber_mgmt.this_fiber.non_member_function_interruption_point `interruption_point`]] [def __invalid_argument__ `std::invalid_argument`] -[def __joinable__ `joinable`] +[def __joinable__ [link fiber.fiber_mgmt.fiber.member_function_joinable `joinable`]] [def __lock_error__ `lock_error`] [def __mutex__ `mutex`] [def __packaged_task__ `packaged-task`] [def __promise__ `promise`] [def __recursive_mutex__ `recursive_mutex`] [def __recursive_timed_mutex__ `recursive_timed_mutex`] -[def __segmented_stack__ ['segemented-stack]] +[def __segmented_stack__ ['segmented-stack]] [def __shared_future__ `shared_future`] [def __stack_allocator_concept__ ['stack-allocator concept]] [def __stack_allocator__ ['stack-allocator]] @@ -78,7 +79,7 @@ [def __cond_wait_until__ `condition::wait_until()`] [def __detach__ `fiber::detach()`] [def __fiber_id__ `fiber::id`] -[def __fsp__ `fiber_specific_pointer`] +[def __fsp__ [link fiber.fls.class_fiber_specific_ptr `fiber_specific_pointer`]] [def __future_get__ `future<>::get()`] [def __get_id__ `fiber::get_id()`] [def __interrupt__ `fiber::interrupt()`] From d7b4be06c7a4992c8793cebdd5d06138e4d5c75c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 Nov 2013 08:22:58 -0500 Subject: [PATCH 7/7] Link this_fiber::thread_affinity() to fiber::thread_affinity(). Use [#named_anchor] QuickBook functionality rather than trying to predict the normalized link for [heading Member function `thread_affinity( bool)`], which looks like this: fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__thread_affinity__phrase__phrase_role__special_____phrase___phrase_role__keyword__bool__phrase__phrase_role__special_____phrase___code_ --- doc/fiber.qbk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fiber.qbk b/doc/fiber.qbk index ef0c4b85..81dd474d 100644 --- a/doc/fiber.qbk +++ b/doc/fiber.qbk @@ -438,6 +438,7 @@ interruption enabled.]] [[Throws:] [Nothing]] ] +[#fiber_thread_affinity] [heading Member function `thread_affinity( bool)`] void thread_affinity( bool) noexcept; @@ -799,7 +800,7 @@ there are no guarantees about how soon after that it might resume.]] void thread_affinity( bool req) noexcept; [variablelist -[[Effects:] [Set or report `fiber::thread_affinity()` for the currently +[[Effects:] [Set or report [link fiber_thread_affinity `fiber::thread_affinity()`] for the currently running fiber.]] [[Throws:] [Nothing.]] [[Note:] [`fiber::thread_affinity()` is `false` by default.]]