Subject: Re: [boost] Boost.Fiber review January 6-15
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2014-01-09 13:54:37
Le 09/01/14 08:42, Oliver Kowalke a écrit :
> 2014/1/8 Vicente J. Botet Escriba <vicente.botet_at_[hidden]>
>> Hi Oliver,
> hello Vicente
>> The interface must at least follows the interface of the standard thread
>> library and if there are some limitations, they must be explicitly
>> Any difference respect Boost.Thread must also documented and the rational
> OK - section rational
>> std::thread is not copyable by design, that is only one owner. WHy
>> boost::fibers::fiber is copyable?
> boost::fibers::fiber should be movable only - it is derived from
> boost::noncopyable and uses BOOST_MOVABLE_BUT_NOT_COPYABLE
Sorry, I don't find now from where I read that fiber is copyable. Maybe
I was tired :(
>> Why the exceptions throw by the function given to a fiber is consumed by
>> the framework instead of terminate the program as std::thread?
> the trampoline-function used for the context does following:
> - in a try-cactch-block execute the fiber-code (fiber-function given by the
> - catch exception forced_unwind from boost.coroutine -> release the fiber
> and continue unwinding the stack
> - catch fiber_interrupted -> stored inside boost::exception_ptr (might be
> re-thrown in fiber::join() )
> - catch all other exceptions and call std::terminate()
> I though this would let to an equivalent behaviour as std::thread
Then you should be more explicit in this paragraph
"Exceptions thrown by the function or callable object passed to the
constructor are consumed by the framework. If you need to know which
exception was thrown, use |future<>|
>> Which exception is thrown when the Error Conditions:resource_deadlock_would_occurand
>> invalid_argument are signaled?
> I use BOOST_ASSERT instead of exception
Where is this documented?
>> Why priority and thread_affinity are not part of the fiber attributes?
> you referre to class attributes passed to fiber's ctor? this class is a
> vehicle for passing special parameter (for instance stack-size) to
> boost::coroutine - if you use
> the segmented-stack feature you usually don't need it.
> priority() and thread_affinity() are member-functions of
> boost::fibers::fiber to make the modifications those parameters for an
> instance more explicit
What do you think about adding them to the class atributes also?
>> The interface let me think that the affinity can be changed by the owned
>> of the thread and the thred itself. Is this by design?
> thread_affinity() expresses if the fiber is bound to the thread - this is
> required for fiber-stealing, e.g. a fiber which is bound to its running
> will not be selected as candidate for fiber-stealing.
This doesn't respond to my question. Why the change of thread_affinity
need to be changed by the thread itself and by the fiber owner?
>> Please don't document get/set functions as thread_affinity altogether.
>> The safe_bool idiom should be replaced by a explict operator bool.
> hmm - I thought using 'operator bool' is dangerous (I remind on some
> discussion of this issue by Scott Meyers).
Could you explain why it is dangerous and how it is more dangerous than
using the safe bool idiom?
> do you have other infos?
>> Why is the scheduling algorithm global? Could it be threads specific?
> It is thread specific (using boost::thread_specific_ptr)
How the user selects the thread to which the scheduling algorithm is
applied? the current thread?
If yes, what about adding the function on a this_thread namespace?
boost::fibers::this_thread::set_scheduling_algorithm( & mfs);
>> BTW i sthere an exmple showing the |thread_specific_ptr trick mentioned
>> on the documentation. |
> which trick? maybe you referring to
|set_scheduling_algorithm()| does /not/ take ownership of the passed
|algorithm*|: *Boost.Fiber* does not claim responsibility for the
lifespan of the referenced |scheduler| object. The caller must
eventually destroy the passed |scheduler|, just as it must allocate
it in the first place. (Storing the pointer in a
|boost::thread_specific_ptr| is one way to ensure that the instance
is destroyed on thread termination.)"
> algorithm *
> if ( ! instance_.get() )
> default_algo_.reset( new round_robin() );
> instance_.reset( default_algo_.get() );
> return instance_.get();
>> Why the time related function are limited to a specific clock?
> it is a typedef to steady_clock (if avaliable) or system_clock - one of the
> main reasons is that you would have made the schedulers be templates.
Maybe schedulers need to take care of a single time_point, but the other
classes should provide an time related interface using any clock.
>> The interface of fiber_group based on old and deprecated thread_group is
>> not based on move semantics. Have you take a look at the proposal
>> N3711 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3711.pdf>
>> Task Groups As a Lower Level C++ Library Solution To Fork-Join Parallelism
> no - but I've no problems to remove it form the library
>> Maybe it is worth adapting it to fibers.
>> Boost.Thread has deprecated the use of the nested type scoped_lock as it
>> introduce unnecessary dependencies. DO you think it is worth maintaining it?
> oh - I wasn't aware of this issue - I've no preferrence to scoped_lock
> (which is a typedef to unique_lock, AFAIK)
>> I made some adaptations to boost::barrier that could also have a sens for
> OK - what are those adaptations?
>> I don't know if a single class could be defined that takes care of both
>> contexts for high level classes as the barrier?
> a problem is raised by the mutex implementations - thread's mutexes are
> blocking the thread while fiber's mutexes do
> only suspend the current fiber while keep the thread running (so other
> fibers are able to run instead)
> I was thinking on a combination of sync. primitives for threads and fibers
> too , but it is not that easy to implement (with a clean interface)
Ok. Glad to see that you have tried it.
>> Boost.Thread would deliver two synchronized bounded and unbounded queue
>> soon based on
>> N3533 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3533.html>
>> C++ Concurrent Queues
>> Have you tried to follow the same interface?
> I did look at the proposal of C++ Concurrent Queues - but I didn't adapt
> the complete interface.
> for instance Element queue::value_pop(); -> queue_op_status queue::pop(
> Element &);
Could you explain the rationale?
can be used with no default constructible types
queue_op_status queue::pop(Element &);
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk