[threadpool] new version - with rescheduling of current task

Hi, I've uploaded a new version of boost.threadpool. It contains a free function this_task_reschedule_until() which lets the current task reschedule until a condition (passed to the fucntion) becomes true. This allows to synchronize with other async events without blocking the worker-thread (thx to Vicente). I've also added two function in order to wait for multiple tasks (it uses Anthonies future lib wait_for_any()/wait_for_all() ). Oliver

Hi, ----- Original Message ----- From: <k-oli@gmx.de> To: <boost@lists.boost.org> Sent: Saturday, February 28, 2009 12:18 AM Subject: [boost] [threadpool] new version - with rescheduling of current task
Hi, I've uploaded a new version of boost.threadpool. It contains a free function this_task_reschedule_until() which lets the current task reschedule until a condition (passed to the fucntion) becomes true. This allows to synchronize with other async events without blocking the worker-thread (thx to Vicente).
Hi, I was expecting that fro a long time. I was tried to do that, but the time goes on. Thanks a lot Oliver, I will take a deep look in.
I've also added two function in order to wait for multiple tasks (it uses Anthonies future lib wait_for_any()/wait_for_all() ).
So you don't need any more to provide get_future, isn't it? Thanks again, Vicente

BTW, the doc html is not included Vicente ----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Saturday, February 28, 2009 12:28 AM Subject: Re: [boost] [threadpool] new version - with rescheduling of currenttask
Hi, ----- Original Message ----- From: <k-oli@gmx.de> To: <boost@lists.boost.org> Sent: Saturday, February 28, 2009 12:18 AM Subject: [boost] [threadpool] new version - with rescheduling of current task
Hi, I've uploaded a new version of boost.threadpool. It contains a free function this_task_reschedule_until() which lets the current task reschedule until a condition (passed to the fucntion) becomes true. This allows to synchronize with other async events without blocking the worker-thread (thx to Vicente).
Hi, I was expecting that fro a long time. I was tried to do that, but the time goes on. Thanks a lot Oliver, I will take a deep look in.
I've also added two function in order to wait for multiple tasks (it uses Anthonies future lib wait_for_any()/wait_for_all() ).
So you don't need any more to provide get_future, isn't it?
Thanks again, Vicente
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hello Vicente, Am Saturday 28 February 2009 01:24:43 schrieb vicente.botet:
BTW, the doc html is not included
sorry - I'll add this soon
I was expecting that fro a long time. I was tried to do that, but the time goes on. Thanks a lot Oliver, I will take a deep look in.
I've also added two function in order to wait for multiple tasks (it uses Anthonies future lib wait_for_any()/wait_for_all() ).
So you don't need any more to provide get_future, isn't it?
Yes - the future should be an implementation detail for the task object. I believe the lib should provide a this_task::get_thread_pool() too (as you suggested). I've also some concerns about this_task::reschedule_until( function< bool() > const&) because the passed function object could block in bool operator()() (->for instance blocking in locking a mutex etc.). Maybe reschedule_until() should only accept futures?! Or schould I remove this function because pool::submit() called inside of a worker-thread would reschedule too. Oliver

----- Original Message ----- From: <k-oli@gmx.de> To: <boost@lists.boost.org> Sent: Saturday, February 28, 2009 8:28 AM Subject: Re: [boost] [threadpool] new version - with rescheduling ofcurrenttask
Hello Vicente,
Am Saturday 28 February 2009 01:24:43 schrieb vicente.botet:
BTW, the doc html is not included
sorry - I'll add this soon
Thanks.
I was expecting that fro a long time. I was tried to do that, but the time goes on. Thanks a lot Oliver, I will take a deep look in.
I've also added two function in order to wait for multiple tasks (it uses Anthonies future lib wait_for_any()/wait_for_all() ).
So you don't need any more to provide get_future, isn't it?
Yes - the future should be an implementation detail for the task object.
If I understand then we will have two function win the same name in different namespaces. Does ADL found the good one,i.e. if the user see boths overloadings, will wait_for_all(f1, f2) call the the future overloading and wait_for_all(t1, t2) calls the task overloading or do we need to prefix with the namespace?
I believe the lib should provide a this_task::get_thread_pool() too (as you suggested). I've also some concerns about this_task::reschedule_until( function< bool() > const&) because the passed function object could block in bool operator()() (->for instance blocking in locking a mutex etc.). Maybe reschedule_until() should only accept futures?! Or schould I remove this function because pool::submit() called inside of a worker-thread would reschedule too.
Well the question is, what happens if the condition don't retuns true? The task doing this will be blocked, but only this task. The worker thread will continue to schedule other tasks, of course testing each time this condition. It seems to me a good compromise. Oliver, I think that one of the use cases is to be able to implement with the public interface namespace this_task { void sleep_until(t); } namespace this_task { namespace detail { struct time_reached { system_time& abs_time_; time_reached(system_time& abs_time) : abs_time_(abs_time) {} bool operator()() { return boost::get_system_time() >= abs_time_; } }; } void sleep_until(system_time& abs_time) { detail::time_reached t(abs_time); this_task::reschedule_until(t); } } This sounds good, but do we want the code know if it is running on a thread_pool worker thread? In my opinion the code must be transparent, so in case the thread is not a worker we need just to sleep void sleep_until(system_time& abs_time) { if (this_task::pressent()) { detail::time_reached t(abs_time); this_task::reschedule_until(t); } else { this_thread::sleep(abs_time); } } So the function present() or any better name should be added. bool this_task::pressent() { return (tp::detail::pool_base::tss_worker_.get()!0); } BTW, the interface could be replaced void reschedule_until( function< bool() > const& cond) by this one that seems more efficient to me. template <typename Condition> void reschedule_until( Condition const cond); I have not yet tried to modify Boost.Interthreads to use the new interfaces. I'll do as soos as possible, to avoid divergencies. I think the library starts to be ready for review. Good work Oliver, Vicente

Am Saturday 28 February 2009 10:43:10 schrieb vicente.botet:
If I understand then we will have two function win the same name in different namespaces. Does ADL found the good one,i.e. if the user see boths overloadings, will wait_for_all(f1, f2) call the the future overloading and wait_for_all(t1, t2) calls the task overloading or do we need to prefix with the namespace?
I suggest to prefix it - but I could also rename the threadpool specific ones
Well the question is, what happens if the condition don't retuns true? The task doing this will be blocked, but only this task. The worker thread will continue to schedule other tasks, of course testing each time this condition. It seems to me a good compromise.
This is already provided by the task wait functionality (wait(), get() etc.). If task::get() or task::wait() would block because the associated future is not ready the worker thread automatically reschedules, e.g. executes other items from the pool channel. I think a explicit reschedule_until() is not required and dangerous. tp::task< int > t1( boost::this_task::get_thread_pool< pool_type >().submit( boost::bind( & fibo::par_, boost::ref( * this), n - 1) ) ); t1.get(); // rescheduling if t1.get() would block == until t1.get() would nont block other items from the pool channel are executed. regards, Oliver

----- Original Message ----- From: <k-oli@gmx.de> To: <boost@lists.boost.org> Sent: Saturday, February 28, 2009 12:36 PM Subject: Re: [boost] [threadpool] new version - with reschedulingofcurrenttask
Am Saturday 28 February 2009 10:43:10 schrieb vicente.botet:
If I understand then we will have two function win the same name in different namespaces. Does ADL found the good one,i.e. if the user see boths overloadings, will wait_for_all(f1, f2) call the the future overloading and wait_for_all(t1, t2) calls the task overloading or do we need to prefix with the namespace?
I suggest to prefix it - but I could also rename the threadpool specific ones
My concerns is how a generic algorithm can use wait_for_all on either futures or tasks or a mixture of them.The problem with boths wait_for_all implementations is that you can only wait for futures or wait for tasks. You can not wait for some futures and some task. If the task class provided a way to get the future it uses in its implementation, we can implement a wait_for_all that works with a mixture of tasks and futures, and why not the joiners of Boost.Interthreads? interthreads::wait_for_all allows that as soon as the ACT provided a way to get a future from it, and forwarding to the Boost.Futures wait_for_all. So the following is possible. unique_future<int> f; tp::task<string> t; interthreads::joiner<double> j; interthreads::wait_for_all(f,t,j); Hence my request to have a way to get a future from a task.
Well the question is, what happens if the condition don't retuns true? The task doing this will be blocked, but only this task. The worker thread will continue to schedule other tasks, of course testing each time this condition. It seems to me a good compromise.
This is already provided by the task wait functionality (wait(), get() etc.). If task::get() or task::wait() would block because the associated future is not ready the worker thread automatically reschedules, e.g. executes other items from the pool channel.
Yes I know that and it is very useful as far as the condition can be enabled by another task. But a task can not satisfy sleeping for a while without blocking the thread. Or waiting on a condition modifyed by another thread and having nothing to be with the ThreadPools library. I really think that the task on a ThreadPool frameworks need this kind of synchronization mechanism.
I think a explicit reschedule_until() is not required and dangerous.
Why do you consider that it is dangerous? I'm missing something?
tp::task< int > t1( boost::this_task::get_thread_pool< pool_type >().submit( boost::bind( & fibo::par_, boost::ref( * this), n - 1) ) );
t1.get(); // rescheduling if t1.get() would block == until t1.get() would nont block other items from the pool channel are executed.
The problem with this approach is that the task can not wait on a condition without blocking the worker thread, This is is exactly the role of reschedule_until(), poll a condition and do something else when the condition is not satisfied. Where is thedanger? Could you give an example? Best, Vicente

Am Saturday 28 February 2009 13:59:02 schrieb vicente.botet:
tp::task< int > t1( boost::this_task::get_thread_pool< pool_type >().submit( boost::bind( & fibo::par_, boost::ref( * this), n - 1) ) );
t1.get(); // rescheduling if t1.get() would block == until t1.get() would nont block other items from the pool channel are executed.
The problem with this approach is that the task can not wait on a condition without blocking the worker thread, No - it does not block the worker thread (as you can see in directory examples -> fork_join.cpp) the worker thread executes the next items from the queue until the blocking task is ready.
This is is exactly the role of reschedule_until(), poll a condition and do something else when the condition is not satisfied. Where is thedanger? Could you give an example?
First this is already implemented (see pool::reschedule_until_() will be executed from the internal future if the wait functions of this future would block). If a user does aprovide a blocking call inside condition::operator()() the the worker thread is blocked and this is not wanted. regards, Oliver

----- Original Message ----- From: <k-oli@gmx.de> To: <boost@lists.boost.org> Sent: Saturday, February 28, 2009 2:48 PM Subject: Re: [boost] [threadpool] new version - withreschedulingofcurrenttask
Am Saturday 28 February 2009 13:59:02 schrieb vicente.botet:
tp::task< int > t1( boost::this_task::get_thread_pool< pool_type >().submit( boost::bind( & fibo::par_, boost::ref( * this), n - 1) ) );
t1.get(); // rescheduling if t1.get() would block == until t1.get() would nont block other items from the pool channel are executed.
The problem with this approach is that the task can not wait on a condition without blocking the worker thread,
Soory, I should be more precise (condition not been possible to be satisfyed by a task)
No - it does not block the worker thread (as you can see in directory examples -> fork_join.cpp) the worker thread executes the next items from the queue until the blocking task is ready.
I know that. I have already signaled that this is good and useful.
This is is exactly the role of reschedule_until(), poll a condition and do something else when the condition is not satisfied. Where is thedanger? Could you give an example?
First this is already implemented (see pool::reschedule_until_() will be executed from the internal future if the wait functions of this future would block).
If a user does aprovide a blocking call inside condition::operator()() the the worker thread is blocked and this is not wanted.
Ok, I see now the danger. IMO we need just to document that condition::operator()() should not block. If the function block it will block the thread. That's all. Vicente
participants (2)
-
k-oli@gmx.de
-
vicente.botet