Boost logo

Boost :

Subject: Re: [boost] Futures
From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2015-01-14 12:04:19

On Wed, Jan 14, 2015 at 7:02 AM, Niall Douglas
<s_sourceforge_at_[hidden]> wrote:
> On 13 Jan 2015 at 12:57, Gottlob Frege wrote:
>> Let's see if I've captured everything:
> Let me rewrite your rewrite ...
>> - we want to get a value from (likely) another THREAD, and WAIT if it
>> is not yet ready UNTIL it is ready, (whatever THREAD WAIT UNTIL mean)
>> - a future (boost:: or std:: or hpx:: etc) is a (high-level!) wrapping
>> of that concept
>> - to be inter-operable we need the lower level concepts (in ALL-CAPS) exposed
>> we actually don't need to completely define what "another" THREAD is,
>> we only need a partial definition of our OWN THREAD. ie the *thread of
>> execution* of the current code,
>> because any code (that we assume at some point runs) runs in some
>> "thread of execution" - whether user mode thread, kernel thread, HPX,
>> whatever...
> If you replaced the word THREAD with EXECUTION CONTEXT,

Yes, re-reading what I wrote, I think that was my point (whether
planned or not) - we don't need to think about threads, but execution

> where that means any of the following:
> 1. Kernel thread (stackful, 1:1 mapping, probably with some real
> hardware concurrency, cooperative context switching preferred but if
> too long elapses you get preempted by a timer)
> 2. Process thread (stackful, M:N mapping onto kernel threads,
> cooperative context switching though the cooperative part may be done
> for you by a local process runtime e.g. Fiber, ASIO, HPX, WinRT)
> 3. Functional/monadic call sequence (stateful though stackless,
> because functional call sequence is always constexpr and must only
> propagate state changes forwards, it can be safely suspended at any
> time without issue e.g. Hana, Expected, future-promise incidentally)
> 4. Stackless coroutine (an elaboration of item 5, but you get to
> write your code in a slightly less fragmented way which may aid
> maintainability e.g. Coroutine, ASIO's duff device macros
> implementing these)
> 5. Event callback handler (stackless, state is usually passed via a
> single void * or equivalent (std::function), almost always a local
> process runtime calls you when something happens e.g. NT Kernel APCs,

yep, that's the idea.

> This may explain why I am so keen that the compiler can optimise a
> future-promise down to single digit opcodes. For EXECUTION CONTEXT 3
> and 5 the compiler's optimiser is fully and partially available, and
> can collapse whole sections of code.
>> What we really need is access to the _controller_ of that thread of
>> execution - ie typically the scheduler, but not a full scheduler
>> interface. In recent C++ proposals this has been called the
>> "execution agent", although I've been pushing for EXECUTION CONTEXT -
>> the C++ object/interface that controls the context of the execution of
>> the current set of instructions.
> This is what the Executors concept was supposed to provide. I've
> always felt that ASIO is THE standard C++ executor and indeed event
> handling and dispatch framework, so go standardise on that instead of
> reinventing wheels no one wants nor uses.
>> WAIT:
>> The running code needs to be able to get at its EXECUTION CONTEXT in
>> order to be able to ask it WAIT.
>> For a given EXECUTION CONTEXT, WAIT means stop "running" - stop using
>> CPU, etc. No further PROGRESS (which turns out to be a hard term to
>> define, but the committee is working on that)
> The key really is PROGRESS rather than wait. A future wait() or get()
> halts PROGRESS of the calling EXECUTION CONTEXT

sure but how does it halt - via some kernel/system/library/...
mechanism, or does it call ExecutionContext->WAIT()?

> until the PROGRESS of some other EXECUTION CONTEXT calls promise.set_value() or
> set_exception().

until some other code does whatever it wants, setting whatever it
wants, and calls ExecutionContext->RESUME()

ie separate the setting the value from the resuming of the execution.

(The tricky part: while still maintaining atomicity where necessary)

> PROGRESS applies equally to all five ways of doing tasklets above.
>> Some *other* EXECUTION CONTEXT needs to be able to tell the
>> aforementioned EXECUTION CONTEXT to RESUME.
> Personally I'd add ABORT here too. Some ASIO operations which ought
> to count as tasklets can be aborted, indeed so can kernel threads on
> POSIX. I am unsure if i/o operations ought to be included in the five
> types of EXECUTION CONTEXT above.
>> The value is orthogonal - the value is just a memory location (unless
>> we abstract that away!) and can be set via atomic operations or
>> whatever. Once the value is set, you then call RESUME on the execution
>> agent. From a value point-of-view, what you want is just an
>> ObservableValue. ie when value is changed, call this callable
>> (function, lambda, whatever). Given an ObservableValue, and an
>> ExecutionAgent you can build a promise.
> Sounds good.
> Niall
> --
> ned Productions Limited Consulting
> _______________________________________________
> Unsubscribe & other changes:

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