_____
---' __\_______
______) Interruptible poke
__)
__)
---._______)
Jose E. Marchesi
March 02, 2020
Poke has loops. It also does IO (yeah, right :D). On one hand, this
means that Poke programs that never finish are definitely possible
(here is one: `while (1) {}') and, on the other, a Poke program acting
on an enormous amount of data may take a long time to finish,
depending on what it does. Maybe hours, maybe even days?
So there are reasons for wanting to interrupt a running Poke program.
Since this weekend, this is as easy as pressing `Ctrl-C' in the
command line while a Poke program is running, or sending `SIGQUIT' to
it:
(poke) while (1) { }
Ctrl-C
(poke)
How does this work? First, Luca got some simple infrastructure for
this in Jitter, in the form of an array called
JITTER_PENDING_NOTIFICATIONS that contains a counter for every
possible signal. Every time poke runs some PVM code, it temporarily
installs a handler for SIGQUIT that notes the signal in the pending
notifications array.
How is the running program made aware of the presence of the signal?
The Poke compiler generates `sync' instructions in strategic places,
such as before the backward jump in loops:
(poke) fun foo = void: { while (1) {} }
(poke) .vm dis f foo
note <span class="string">"foo"</span>
$L1:
prolog
pushf
$L3:
push <span class="integer">0x1</span>
bzi $L10
drop
pushf
popf 1
sync
ba $L3
$L10:
drop
popf 1
push null
return
exitvm
When the `sync' instruction is executed, it checks
'JITTER_PENDING_NOTIFICATIONS', and raises a `PVM_E_SIGNAL' exception.
The default signal handler handles this exception just exiting the
program silently.
Happy poking!