espruino / Espruino

The Espruino JavaScript interpreter - Official Repo
http://www.espruino.com/
Other
2.76k stars 741 forks source link

JS 'software interrupt' #2281

Open gfwilliams opened 1 year ago

gfwilliams commented 1 year ago

Right now, we don't run JS in an interrupt because ensuring preemption works reliably in all cases has proven too difficult. We do have setWatch(...{irq:true}) but this only works for compiled functions (and even then can be unreliable if they access JS variables)

The lack of code in IRQs can cause problems for things that need to be a bit more real-time (eg scanning displays) and it'd be nice to be able to get sections of JS code to run closer to the correct times.

Internally, we already do a check before executing every statement to see if we need to enter the debugger. I'd propose we extend that to allow us to interrupt JS execution every new statement, but to also execute that JS in the main thread (just as if it was a normal function call). This would be a lot better than currently, but is still not perfect - built-in functions that took a while to execute like file accesses would still not allow any interruption.

Ideally we'd expose the functionality with setInterval and setWatch (although internally setInterval would end up using jstimer.c and not the interval handling loop in jsinteractive.c - maybe it could return negative numbers to quickly differentiate).

Maybe:

setInterval(myFunction, { period:20, instant:true });
setWatch(myFunction, BTN, { instant:true });

I'm open to suggestions here - having setInterval do two different things seems less than ideal - maybe it's better to just have a new function for it. Extending setWatch on the other hand should be reasonably straightforward