Real Time Timers

When installing a real-time (itimer_real) timer, it is first necessary to preserve the properties of a possibly existing old timer (they will be returned to userland once the new timer has been installed) and cancel the timer with hrtimer_try_to_cancel. Installing a timer "overwrites" previous values.

The timer period is stored in the task-specific signal_struct->it_real_incr field (if this field is zero, then the timer is not periodic, but only activated once), and hrtimer_start starts a timer that expires at the desired time.

No handler routine is executed in userspace when a dynamic timer expires. Instead, a signal is generated that results in the invocation of a signal handler and thus indirectly to the invocation of a callback function. How does the kernel ensure that the signal is sent, and how is the timer made periodic?

The kernel uses the callback handler it_real_fn, which is executed for all userspace real-time timers. This function sends the sigalrm signal to the process that installed the timer, but does not reinstall the signal handler to make the signal periodic.

Instead, the timer is reinstalled when the signal is delivered in process context (in dequeue_signal, to be precise). After forwarding the expiration time with hrtimer_forward, the timer is restarted with hrtimer_restart.

What keeps the kernel from reactivating the timer immediately after it has expired? Earlier kernel versions did, in fact, choose this approach, but problems arise if high-resolution timers are active. A process can choose a very short repetition interval that would cause timers to expire over and over — resulting in excessive time spent in the timer code. Put less politely, one could also call this a denial-of-service attack, and the current approach avoids this.

Continue reading here: Getting the Current Time

Was this article helpful?

0 0