Boost logo

Boost :

Subject: Re: [boost] [thread] countdown_latch
From: Gaetano Mendola (mendola_at_[hidden])
Date: 2013-05-26 13:20:54


On 26/05/2013 17.30, Vicente J. Botet Escriba wrote:
> Le 26/05/13 15:07, Gaetano Mendola a écrit :
>> On 26/05/2013 09.53, Vicente J. Botet Escriba wrote:
>>> Le 25/05/13 15:51, Gaetano Mendola a écrit :
>>>> On 25/05/2013 15.26, Vicente J. Botet Escriba wrote:
>>>>> Le 25/05/13 14:45, Gaetano Mendola a écrit :
>>>>>> On 21/05/2013 07.13, Vicente J. Botet Escriba wrote:
>>>>>>> Le 20/05/13 22:09, Gaetano Mendola a écrit :
>>>>>>>>
>>>>>>>> What's the plan for this countdown_latch is it candidate to be
>>>>>>>> included
>>>>>>>> in version 1.54 ?
>>>>>>>>
>>>>>>>>
>>>>>>> No, documentation and tests are missing. I hope it will be ready for
>>>>>>> 1.55. This and other addition will be experimental and its interface
>>>>>>> will be subject to some changes.
>>>>>>> E.g. I have not decided yet how to provide cyclic latches.
>>>>>>
>>>>>> Given the fact I have my own implementation of a latch, can you
>>>>>> please
>>>>>> explain what a cyclic latch is, to see if my latch already provide
>>>>>> the feature. I will propose my implementation of latch.
>>>>>>
>>>>>>
>>>>> boost::barrier resets the counter once all the threads synchronize, so
>>>>> that the barrier can be reused again. In order to do that the barrier
>>>>> store the initial counter value and reuse it at each cycle.
>>>>>
>>>>> I don't know if I all the latched must support this feature
>>>>> (possibly by
>>>>> a configuration parameter) or if it is better to have a separated
>>>>> cyclic_latch.
>>>>
>>>> So what are you proposing is a latch that as soon have reached 0 it
>>>> will
>>>> reset to the initial value and permitting a wait to continue without
>>>> stopping if it arrives after the reset or to block waiting for a reset.
>>>> My latch doesn't provide such feature, but isn't enough to keep a
>>>> counter (reset_counter) increased at each reset and decreased at each
>>>> wait() (before exiting from it). This way the wait shall be a blocking
>>>> call if the "reset counter" is > 0.
>>>>
>>>> I would make two different names: latch and cyclic_latch
>>> Thanks for your advice.
>>> The alternative is to have a bool parameter on the constructor and make
>>> use of a "restore counter" when "reset counter" is > 0 which is not too
>>> expensive. This needs however to store another integer for the "restore
>>> counter". I want to be sure that this doesn't adds any additional
>>> constraint to the class.
>>>>
>>>> I'm also to remove the precondition counter > 0 on the
>>>> latc::count_down.
>>>>
>>> I don't see yet the case of a thread using countdown several times the
>>> same latch as a valid use case. But maybe if you post a concrete (real)
>>> example, it could make me change.
>>
>> Do you really need a real example?
>>
> Yes. As having a real example we could see if the solution you propose
> would be used by the user or if it would implement its own class to
> solve the problem more efficiently.
>> I don't have a real example but again, having two threads calling
>> latch::count_down on the same latch instance is going to be an headache
>> for the user, immagine a multi producer/single consumer application
>> where the consumer as to start when at least N items are ready.
> I will not use a latch for that. I would build a at least n messages on
> the queue data type and use the usual wait on this queue.

If the buffer is a general purpose buffer the wait on it will return as
soon someone puts stuffs on it. As you know there are multiple way to
achieve the same even without the usage of latch.

I'm fine with leaving the precondition after all people have to read
the manual, I have also see you have added a BOOST_ASSERT( count_ > 0).

About the cyclic_latch instead of the bool to drive the counter reset
I would template the latch using two different policies for reset or
not, then I would expose a typedef of it, something like this:

template <class COUNTER_POLICY>
class Latch {

     bool count_down(unique_lock<mutex> &lk)
     /// pre_condition (count_ > 0)
     {
       BOOST_ASSERT(count_ > 0);
       if (--count_ == 0)
       {
         counter_policy_.reset(count_);
         ++generation_;
         lk.unlock();
         cond_.notify_all();
         return true;
       }
       return false;
     }

   private:
     COUNTER_POLICY counter_policy_;
};

typedef Latch<NoResetPolicy> latch;
typedef Latch<ResetPolicy> cyclic_latch;

Regards
Gaetano Mendola


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk