Boost logo

Boost :

Subject: Re: [boost] Futures (was: Re: [compute] Some remarks)
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2015-01-12 16:50:18

On Mon, Jan 12, 2015 at 3:30 PM, Niall Douglas
<s_sourceforge_at_[hidden]> wrote:
> On 7 Jan 2015 at 12:40, Thomas Heller wrote:
>> Exactly, this could be easily achieved by defining an appropriate API for the
>> shared state of asynchronous operations, the wait functions would then just
>> use the async result objects, which in turn use to wait the functionality as
>> implemented in the shared state.
> You still seem to be assuming the existence of a shared state in wait
> objects :(
> I suppose it depends on how you define a shared state, but for that
> non-allocating design of mine the (a better name) "notification
> target" is the promise if get_future() has never been called, and the
> future if get_future() has ever been called. The notification target
> is kept by an atomic pointer, if he is set he points at a future
> somewhere, if he is null then either the promise is broken or the
> target is the promise.

Hi Neal,

I have been following the thread with interest, and I wanted to know
more about your non-allocating future/promise pair. As far as I
understand, your future and promise have a pointer to each other and
they update the other side every time they are moved, right?

My question is, as you need to do the remote update with an atomic
operation (exchange in the best case), and you usually perform at
least a few moves (when composing futures for example), wouldn't a
fast allocator outperform this solution?

>> A portable, universal kernel wait object is
>> not really necessary for that.
> I think a portable, universal C API kernel wait object is very
> necessary if C++ is to style itself as a first tier systems
> programming language.

For what is worth I'm working on a proof-of-concept future/promise
pair that is wait strategy agnostic. The only function that needs to
know about the wait strategy are the
future::wait{,_for,_untill,_any,_all} family and of course
future::get, in case it needs to call wait. In fact the wait functions
are parametrized on the wait strategy (be it a futex, condition
variable, posix fd, posix semaphore, coroutine yield, etc) and the
wait object can be stack allocated.

If I get everything right, all other functions, in particular
promise::set_value and future::then should be lock-free (or wait
free, depending on the underlying hardware).

The shared state should also have a nice minimal API.

The idea is fairly obvious in retrospect, I hope to be able to share
some code soon.

-- gpd

Boost list run by bdawes at, gregod at, cpdaniel at, john at