Subject: Re: [boost] [threadpool] relation with TR2 proposal
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2008-09-18 18:07:11


----- Original Message -----
From: "Johan Torp" <johan.torp_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Thursday, September 18, 2008 10:03 PM
Subject: Re: [boost] [threadpool] relation with TR2 proposal

>
>
>
> viboes wrote:
>>
>>> I mean that you want to intercept when a worker thread should have been
>>> blocked and process other tasks in the wait call:
>>>
>>> void some_user_level_task() {
>>> ...
>>> some_future.wait(); // Do not really wait, execute other tasks using
>>> the
>>> same call stack
>>> ...
>>> }
>>
>> Should this behaviour be extended to other synchronization functions like
>> mutex lock, condition wait, ... ?
>>
>
> It is a very interesting idea, here are my thoughts;
>
> First of all, I think even doing work in future::wait is a little to
> automagic and think we should investigate if we can't make it explicit
> somehow.
>
> You probably do not want to do work while waiting for mutexes. They are
> only
> supposed to help synchronize and order operations, waiting is just a side
> effect of that.

As far as the worker thread do a mutex lock, the thread will block,
reducing the parallelism. I need to think more on this issue.

> The idea of doing work while waiting on condition variables seems like a
> natural extension of doing the same for futures since futures also have
> the
> semantics of waiting for an event. Also, futures will most probably be
> built
> on top of condition variables.

What about yield and sleep?

> Perhaps some kind of policy with a default waiting behaviour;
>
> condition normal_condition_variable;
> condition<WorkWhileWaiting> cv;
> future<int> normal_future;
> future<int, WorkWhileWaiting> f;

I'll prefere something like that

namespace this_task
{
    void yield();

    void sleep(system_time const& abs_time);

    template<typename TimeDuration>
    inline void sleep(TimeDuration const& rel_time)
    {
        this_task::sleep(get_system_time()+rel_time);
    }

    template<typename T>
    shared_future_wrapper<T> wrap(shared_future<T>& f);

    condition_variable_wrapper wrap(boost::condition_variable& cond);
}

The user could then be able to

void some_user_level_task() {
    // ... sleep for a while while executing other tasks
    this_task::sleep(t);

    // use any of the blocking future functions while executing other tasks
    this_task::wrap(some_future).wait();
    // or
    this_task::shared_future_wrapper<T> w_some_future(some_future);
    w_some_future.wait();

    // yielding
    while (cnd) {
        // ...
        this_task::yield();
    }
}

> viboes wrote:
>>
>> In addition the threadpool should provide a one step scheduling on the
>> *current* worker thread.
>>
>
> There are certain subtle dangers with executing thread pool tasks
> belonging
> to other threads, but they might be acceptable if this behaviour is
> explicit
> (perhaps even if they aren't). IIRC, I discussed the matter with Peter
> Dimov
> here in boost.dev but can't seem to find the thread.

Which dangers do you have in mind?

Vicente