Timeout API for micro:bian
The idea is to provide a new version of
receive that takes a timeout value in milliseconds:
void receive_t(int type, message *msg, int timeout)
If no other message is received before the timeout happens, then a message is delivered with source
HARDWARE and type
TIMEOUT. The timeout is automatically cancelled on delivery of a genuine message, whether from
HARDWARE (i.e., an interrupt) or from a normal process. The type filter
type may have any value, not just
ANY; any timeout message is delivered even if the
receive call is specific to a different message type, so it's necessary for the receiving process to check on the message type.
A timer process can periodically invoke a new system call,
void tick(int ms)
ms is the number of milliseconds since the last invocation of
tick. This decrements all active timeout countdowns by the specified amount, and delivers
TIMEOUT messages to any that have gone off, making the corresponding processes ready to run. There is no need for an immediate context switch, since responding to a timeout presumably has a low priority.
Any micro:bian program that uses timeouts will need a timer process to trigger them, but programs that do not use timeouts can still be written with no need for a timer process. The guarantees are weak: a
receive_t will time out eventually (providing there is a timer process continually calling
tick), and it will do so in a time that is at least the one specified. In order to prevent premature timeouts, it will be best to deliver the message on the tick following the one where the timeout value is reached: that way, the message cannot be delivered early because of an initial short tick. We might allow
timeout=0 as a special case, meaning to deliver a message if one it waiting, otherwise to deliver an immediate timeout.
Ticks can be relatively infrequent, so it is OK to implement
tick() by looping over all processes checking for timeouts. Note that (depending on the device) an interrupt can arrive after the timeout message has been delivered, either before the process has been scheduled, or afterwards while it is dealing with the timeout; in either case, the interrupt will be queued and delivered on the next
receive. So it might be necessary to write the device driver carefully, so that unexpected interrupts are ignored.