In the paper about resumable functions, in the section about restrictions three restrictions are listed:
- Resumable functions cannot use a variable number of arguments. For situations where varargs are necessary,the argument unwrapping may be placed in a function that calls a resumable function after doing the unwrapping of arguments.
- The return type of a resumable function must be
future<T>
orshared_future<T>
. The restrictions on T are defined bystd::future
, not this proposal, butT
must be a copyable or movable type, or ‘void
’. It must also be possible to construct a variable ofT
without an argument; that is, it has to have an accessible (implicit or explicit) default constructor if it is of a class type.- Await expressions may not appear within the body of an exception handler and should not be executed while a lock on any kind is being held by the executing thread.
There must be a reason behind this restrictions and due to my lack of knowledge about concurrency I cannot deduce what reasons are. Could someone enlight me about this topic?
This restriction is referring to the C-style variadic functions or the C++11 variadic template ones?
va_*
macros?In both cases, I thought that the compiler could be smart enough to deduce which function to use.
I understand the reason behind returning a std::future
or std::shared_future
, but I'm guessing that the reason of the limitation behind the usable types is related to the types that the futures could use.
So, the paper is proposing to extend the language with two new keywords (resumable and await) that provides the behaviour of resumable functions but in the end it trust on existent constructs to transfer the return values of resumable functions between the function and the caller.
Why not propose some kind of language extension for the return values too? that could (maybe) release the limitation to default constructible and copyable/movable types and fix the assimetry between the return type and the returned type:
It should thus be noted that there is an asymmetry between the function’s observed behavior from the outside (caller) and the inside: the outside perspective is that function returns a value of type
future<T>
at the first suspension point, while the inside perspective is that the function returns a value of typeT
via a return statement (...)
I guess that awaiting something while catching an exception have no sense, but I haven't any clue about the limitation of the locked threads.
I'm pretty sure all of these restrictions are related to the fact that the context of a resumable function has to be "saved" and "resumed" - I expect the mechanism will create a temporary "copy of the stack" or something similar. So:
Variable number of arguments
This really means things using va_arg
functionality - not because the macros involved, but because it's impossible for an outside agent to know the number of actual arguments - for printf
, you'd have to read the format string, for some others the last one is marked with NULL
. So how much context needs to be saved away?
Locked threads
So we have just said "we don't want this thread to be interrupted", and then we go and say "Now lets run something else". That's like saying "Please, under no circumstances shall I be interrupted while I take my bath" while stepping into the bath and at the same time say "Can you phone me in 2 minutes..." - assuming the bath takes more than 2 minutes, one of those will be untrue.
Default constructible
I'm pretty sure the logic here is that it would make the whole concept quite complex if the return value to be constructed has to have arguments passed to the constructor. How would you even describe such a thing? And you would also have to "hold on to" those arguments while in suspended state. Again, making the saving of the context more complex.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With