Note

Following a national ballot, the union, UCU, that represents staff in the higher education sector has called a strike on three days in late November, and also "action short of a strike" during a period that starts on Wednesday, 23 November. During this period, colleagues are invited to take various actions, including abstaining from voluntary activities. I view the maintenance of Spivey's Corner as an activity I undertake voluntarily and not part of any contract of employment, and I cannot guarantee that it will remain accessible during the period of the dispute. In addition, some materials on the site may pertain to lectures that are cancelled by myself or others as part of the strike, and we are asked not to make them available online. Further details of the reasons for the strike and how it affects teaching in Oxford are on a brief FAQ page.

Timeout API for micro:bian

From Spivey's Corner
Jump to navigation Jump to search

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)

where 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.