How to not wait a function until it ends? - asynchronous

I have two functions:
function f1(a:String) {
// long processes with a...
}
function f2() {
f1("Hey");
...
}
What I want is:
when I call f1 from f2, I don't want to make f2 blocked. Neither I don't want, at some point in code, for f1's finishing (like joining threads)
I just want to call it and forget. It runs itself and finishes itself.
How can I manage this in Haxe? Thanks!

With Haxe < 4, this is a bit cumbersome. It works the same as with Haxe 4, but there isn't one cross-platform Thread type, making everything a little harder (cpp.vm.Thread, neko.vm.Thread etc).
With Haxe 4 - even in its current release candidate state, you would achieve this with sys.thread.Thread. Every time you want to create a thread to execute your function, simply call Thread.create. One thing to notice is that this function takes a function with no argument that returns nothing. If your function takes one or more arguments, you can call its bind method as explained here : https://haxe.org/manual/lf-function-bindings.html .
Long story short :
import sys.thread.Thread;
function f2() {
var f1thread = Thread.create(f1.bind("Hey")); // runs instantly
}
Needless to say, you should check that the platform you are compiling for has threads.

Related

Single threaded asynchronous event loop with `winit`

I'm trying to build an NES emulator using winit, which entails building a game loop which should run exactly 60 times per second.
At first, I used std::thread to create a separate thread where the game loop would run and wait 16 milliseconds before running again. This worked quite well, until I tried to compile the program again targeting WebAssembly. I then found out that both winit::window::Window and winit::event_loop::EventLoopProxy are not Send when targeting Wasm, and that std::thread::spawn panics in Wasm.
After some struggle, I decided to try to do the same thing using task::spawn_local from one of the main asynchronous runtimes. Ultimately, I went with async_std.
I'm not used to asynchronous programming, so I'm not even sure if what I'm trying to do could work.
My idea is to do something like this:
use winit::{window::WindowBuilder, event_loop::EventLoop};
use std::time::Duration;
fn main() {
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
.build(&event_loop);
async_std::task::spawn_local(async {
// game loop goes here
loop {
// [update game state]
// [update frame buffer]
// [send render event with EventLoopProxy]
async_std::task::sleep(Duration::from_millis(16)).await;
// ^ note: I'll be using a different sleep function with Wasm
}
});
event_loop.run(move |event, _, control_flow| {
control_flow.set_wait();
match event {
// ...
_ => ()
}
});
}
The problem with this approach is that the game loop will never run. If I'm not mistaken, some asynchronous code in the main thread would need to be blocked (by calling .await) for the runtime to poll other Futures, such as the one spawned by the spawn_local function. I can't do this easily, since event_loop.run is not asynchronous.
Having time to await other events shouldn't be a problem, since the control flow is set to wait.
Testing this on native code, nothing inside the game loop ever runs. Testing this on Wasm code (with wasm_timer::Delay as the sleep function), the game loop does run, but at a very low framerate and with long intervals of halting.
Having explained my situation, I would like to ask: is it possible to do what I'm trying to do, and if it is, how would I approach it? I will also accept answers telling me how I could try to do this differently, such as by using web workers.
Thanks in advance!

How do I do jumps to a label in an enclosing function in LLVM IR?

I want to do an LLVM compiler for a very old language, PL/M. This has some peculiar features, not least of which is having nested functions with the ability to jump out of an enclosing function. In pseudocode:
toplevel() {
nested() {
if (something)
goto label;
}
nested();
label:
print("finished!");
}
The constraints here are:
you can only jump into the top-level function, luckily
the stack does get unwound (the language does not support destructors, so this is easy)
you do not have to have executed the statement at label before jumping (so the naive setjmp/longjmp method doesn't work).
code at label can be executed normally, i.e. it's not like catch
LLVM has a number of non-local jump mechanisms, such as the exception handling system, but I've never used that. Can this be implemented using LLVM exceptions, or are they not suitable for this? Is there an easier way?
If you want the stack to get unwound, you'll likely want it to be in a separate function, at least a separate LLVM IR function. (The only real exception is if your language does not have a construct like C's "alloca()" and you don't allow calling a nested function by address in which case you could inline it.)
That part of the problem you mentioned, jumping out of an enclosing function, is best handled by having some way for the callee to communicate "how it exited" to the caller, and the caller having a "switch()" on that value. You could stick it in the return value (if it already returns a value, make it a struct of both values), you could add a pointer parameter that it writes to, you could add it a thread-local global variable and fill that in before calling longjmp, or you could use exceptions.
Exceptions, they're complex (I can't describe how to make them work offhand but the docs are here: https://llvm.org/docs/ExceptionHandling.html ) and slow when the exception path is taken, and really intended for exceptional situations, not for normal code. Setjmp/longjmp does the same thing as exceptions except simpler to use and without the performance trade-off when executed, but unfortunately there are miscompiles in LLVM which you need will be the one to fix if you start using them in earnest (see the postscript at the end of the answer).
Those two options cover the ways you can do it without changing the function signature, which may be necessary if your language allows the address to be taken then called later.
If you do need to take the address of nested, then LLVM supports trampolines. See https://llvm.org/docs/LangRef.html#trampoline-intrinsics . Trampolines solve the problem of accessing the local variables of the calling function from the callee, even when the function is called by address.
PS. LLVM miscompiles setjmp/longjmp today. The current model is that a call to setjmp may return twice, and only functions with the returns_twice attribute may return twice. Note that this doesn't affect the whole call stack, only the direct caller of a function that returns twice has to deal with the twice-returning call-- just because function F calls setjmp does not mean that F itself can return twice. So far, so good.
The problem is that in a function with a setjmp, all function calls may themselves call longjmp. I'd say "unless proven otherwise" as with all things in optimizers, but there is no attribute in LLVM doesnotlongjmp or any code within LLVM that attempts to answer the question of whether a function could call longjmp. Adding that would be a good optimization, but it's a separate issue from the miscompile.
If you have code like this pseudo-code:
%entry block:
allocate val
val <- 0
setjmpret <- call setjmp
br i1 setjmpret, %first setjmp return block, %second setjmp return block
%first setjmp return block:
val <- 1;
call foo();
goto after;
%second setjmp return block:
call print(val);
goto after;
%after:
return
The control flow graph shows that is no path from val <- 0 to val <- 1 to print(val). The only path with "print(val)" has "val <- 0" before it therefore constant propagation may turn print(val) into print(0). The problem here is a missing control flow edge from foo() back to the %second setjmp return block. In a function that contains a setjmp, all calls which may call longjmp must have a CFG edge to the second setjmp return block. In LLVM that control flow edge is missing and LLVM miscompiles code because of it.
This problem also manifests in the backend. The first time I heard of this problem it was in the context of the backend losing track of the placement of variables on the stack, and this issue was the underlying root cause.
For the most part setjmp/longjmp seems to work because LLVM isn't usually able to analyze what calling foo() might do and can't perform the optimization. For instance if val was not a fresh allocation but was a pointer, then who's to say that foo() doesn't have access to the same pointer, and then performs "val <- 1" on it? If LLVM can't prove that impossible, that precludes the transform to print(0). Secondly, setjmp/longjmp are just not used often in real code.

Should every function which calls itself be considered a recursive function?

I understand what recursive functions are, but consider the following example of a function meant to get the local version of data on an item, check if there is new data about it available online based on locally stored cache time, and if there is, updating the local data with the new version, returning up-to-date data about it either way.
function getItemData(id){
var local=getLocalItemData(id);
if(!local.cacheTime.upToDate()){
var newData=getOnlineItemData(id);
updateLocalItemData(id, newData);
return getItemData(id);
}
else{
return local.returnHumanReadable();
}
}
My argument against considering it a recursive function is the fact that it will only end up calling itself on rare occasions when the cache time indicates the data has expired, and that the function only calls itself for convenience.
Instead of using return getLocalItemData(id).returnHumanReadable(); I can use return getItemData(id); because it will return the same result, as the newly saved data won't need to be refreshed again in the several microseconds it will take the function to call itself. Also, it is much shorter: in the actual code, I would use lower level commands instead of those function calls, resulting in code duplication which would make the entire function harder to read and maintain.
So, do you think that my argument makes any sense, or do you consider this to be nothing more than a matter of code organization?
The short answer is: yes it is recursive
It becomes important if you consider a platform that does not support recursion
Since it can call itself, your code will not work on that platform because it is technically recursion
For a trivial case like this replacing the recursive call with getLocalItemData(id).returnHumanReadable(); will allow it to work on this platform. In fact, you can change your code to:
function getItemData(id){
var local=getLocalItemData(id);
if(!local.cacheTime.upToDate()){
var newData=getOnlineItemData(id);
updateLocalItemData(id, newData);
local=getLocalItemData(id);
}
return local.returnHumanReadable();
}
NOTE: If you cannot 100% guarantee that only one call is needed, change the if to while

Defer a function call in Qt

I have a function in Qt 4.8 (windows), which has 3 things to do, like this:
void f()
{
//1. Do initialization
//2. Defer g() for next event (on the same thread) so that it may execute after f() is over
//3. Call h() which is time consuming
}
Now, I am not sure how to implement the 2nd step i.e. how to ensure that g() is called after the call to f() is complete, on the same thread (but on the different stack). I tried using QTimer but if I provide a short time say 10 ms, the function g() is called even when f() has not completed execution. So, relying on timers does not seem to be a reliable idea. Please help, any ideas are much appreciated.
Make g() a slot or a Q_INVOKABLE. Then use QMetaObject::invokeMethod(this, "g", Qt::QueuedConnection).
If I understand correctly, it's needed simply to call g() after f(), but on the next message loop cycle, after all Qt events issued from f() would be processed. In this case I suggest the following trick:
f();
QApplication::processEvents();
g();

Design suggestion needed to convert synchronous qtdbus calls to asynchronous

The applications in my project were until now communicating over qtdbus using synchronous calls. However I now need to convert a few of these calls to asynchronous.
For that I chose to use this API available in qtdbus
QDBusAbstractInterface::callWithCallback
But the problem is that the current implementation has these qtdbus sync calls scattered in a lot of places in the code and the code snippets which follow these sync calls assume that the control only reaches them when the preceding call has been successfully serviced and a reply is obtained.
This will no longer be the case when the calls change to async. Moreover the calls are made in different contexts, so I will be required to maintain the state of the system before each qtdbus call, so that I know what to do when I receive the reply.
Is there any chance really to somehow convert the calls to async without rupturing the fabric of the current code in a big way?
One approach I can think of is to use the FSM pattern.
Any hints or design suggestions will be much appreciated.
Thanks!
The way I am understanding is that you will need to call the same method and then process the return value differently based on the state at the time of the call. Such as
void function()
{
//do stuff
value = SynchronousCall();
if (state == 1)
{
doSomething(value);
}
else
{
doSomethingElse(value);
}
}
I would recommend instead of a full implementation of the Finite State Machine pattern which can make a mess with the number of classes that it adds, add separate methods for each state
void function()
{
//do stuff
if (state == 1)
{
callback = *doSomething(ValueType);
}
else
{
callback = *doSomethingElse(ValueType);
}
callWithCallback(method,args, receiver,callback,error);
}
Then in each method you can assume the state and process the return value accordingly.
Another slightly (very) hacky way would be to simply have a spin wait after all the asynchronous calls and use a QThread:: yield() in the loop while you wait for the value to return. That way it is still technically an asynchronous call but it acts synchronous.

Resources