Boost logo

Boost :

Subject: Re: [boost] [afio] Formal review of Boost.AFIO
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2015-09-01 12:23:21


On 1 Sep 2015 4:06 pm, "Agustín K-ballo Bergé" <kaballo86_at_[hidden]>
wrote:
>
> On 9/1/2015 11:43 AM, Giovanni Piero Deretta wrote:
>>
>> On 1 Sep 2015 2:15 pm, "Agustín K-ballo Bergé" <kaballo86_at_[hidden]>
>> wrote:
>>>
>>>
>>> On 9/1/2015 9:35 AM, Giovanni Piero Deretta wrote:
>>>>
>>>>
>>>> On 30 Aug 2015 10:04 pm, "Agustín K-ballo Bergé" <kaballo86_at_[hidden]
>
>>>> wrote:
>>>
>>>
>>>>> The situation gets trickier for `wait_for/until`, where you need to
>>
>> remove
>>>>>
>>>>> the fake continuation on a timeout without racing.
>>>>>
>>>>
>>>> Also needed to implement wait any.
>>>
>>>
>>>
>>> Once `wait` returns the shared-state is ready. You don't even need to
>>
>> remove the fake continuation pointer, it will never be looked up again.
>>
>> You do if you want to implement a wait_any interface that blocks until
the
>> first of a number of futures is ready. In that case you must be able to
>> reissue another wait at a later time. Think 'select'.
>
>
> I did not understood what you meant by "wait any" the first time around.
I do now, but I still don't see why would you ever want to wait on an
already ready future. If you do, it would just return immediately; it
should not even touch callbacks, continuations, condition variables, etc.
>

Uh? You do not wait on a ready future. You might wait for one of the other
futures that are not ready.

>>
>> Only if you use shared state. I'm looking at optimising unique futures.
My
>> shared future implementation currently is internally N unique futures
plus
>> a multiplexer.
>
>
> You always have a shared state (the concept, in one form or the other),
it is part of the specification of the semantics.
>

Sorry, sloppy writing on my part. I meant shared_future, not shared state.
Unique futures also have shared state of course.

>
>> Also for waits you can always allocate the waiter/signaler on the stack.
>> The tricky part is handling the race between a dismissal and a signal.
>
>
> This is exactly the trickiness I was referring to for `wait_for/until` vs
`wait`.
>
>
>> To implement the generic 'then' I do always heap allocate, but I put the
>> callback inline with the returned future shared state. I use the pointer
>> sized dismissible 'then' to chain the two shared states.
>
>
> Nod, and after the allocation you can attach the pointer to the callback
in a lock free way. You can further chain multiple continuations for a
`shared_future` in a similar way.
>

Yes, that work perfectly if you never 'unwait'. Timed waits and wait_any
make things a lot more complex. I do not think is worth keeping this case
lock free; I'm instead thinking of borrowing one bit from the chain head
pointer as a spinlock to guarantee mutual exclusion for shared removals. I
have yet to try to implement this though.

-- gpd


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