Pergunta

I'm trying to implement a safety feature that puts a timeout around a huge function call. Pretty simple, I thought, but it turned out much harder than expected; there's no built-ins for this in any of the C languages I've looked at, apparently because it's too complex under the hood. But JS engines do this all the time; they tell you that the page is unresponsive and asks if you want to wait a bit longer or terminate it.

How do they implement the "terminate" part, having jit'ed to machine code? Is there a ton of conditional jumps, e.g. one inside every loop and one in every function body? Do they run in a separate process, so the whole process can be shut down easily with help from the OS? Do they trigger a special exception?

I'm hoping I can draw some inspiration from some of the most optimized implementations of this in the world, since the requirements are pretty similar; effectively sandboxed code, relatively long timeout that almost never fires, relatively high performance requirements.

Foi útil?

Solução

Its not all that hard, watchdog timers are old technology. You set an asynchronous timer. If the timer goes off before some event occurs (such as the interpreter saying the script is finished, or at least has temporarily yielded the CPU) you kill that operation. How that happens can differ based on the implementation. If the JS interpreter is a separate process, just kill the process.

If its on a thread of your own process... well, its not generally safe to kill a thread from outside the thread. So you send a message to that thread saying that it needs to self terminate, and have that thread check for events regularly. The important thing is that you need the interpreter to check this flag, not the script. Since the interpreter is running the script, its easy to code it to check the flag every few instructions. When it sees it, it does any cleanup it needs, then kills its own thread.

The reason you can't do this as easily in C is that there's no interpreter to force the thread to check for a terminate signal. So there's no reliable way to do it. But the presence of a supervisor level of code assures you have a place to release resources and always check for terminals, avoiding the problems with bare metal code doing the same thing.

In firmware its actually not unusual for this to be implemented with a hardware timer causing a CPU reset, or if the device is sophisticated enough to have an OS to send an interrupt for the OS to terminate a process.

Licenciado em: CC-BY-SA com atribuição
scroll top