New alarm(2) timers mechanism.
Kernel no longer keeps track of user alarms on behalf of the PM. Instead, the PM maintains its own list of watchdog timers, and uses one synchronous alarm (at the kernel) to get notifications for expired user timers.
This commit is contained in:
parent
2c730e8a8c
commit
eba45510a9
1 changed files with 77 additions and 0 deletions
77
servers/pm/timers.c
Normal file
77
servers/pm/timers.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* PM watchdog timer management.
|
||||
*/
|
||||
|
||||
#include "pm.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#include <timers.h>
|
||||
#include <minix/syslib.h>
|
||||
#include <minix/com.h>
|
||||
|
||||
PRIVATE timer_t *pm_timers = NULL;
|
||||
|
||||
PUBLIC void pm_set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
|
||||
{
|
||||
int r;
|
||||
clock_t now, old_head = 0, new_head;
|
||||
|
||||
if((r = getuptime(&now)) != OK)
|
||||
panic(__FILE__, "PM couldn't get uptime from system task.", NO_NUM);
|
||||
|
||||
tmr_inittimer(tp);
|
||||
tmr_arg(tp)->ta_int = arg;
|
||||
|
||||
old_head = tmrs_settimer(&pm_timers, tp, now+ticks, watchdog, &new_head);
|
||||
|
||||
/* reschedule our synchronous alarm if necessary */
|
||||
if(! old_head || old_head > new_head) {
|
||||
if(sys_syncalrm(SELF, new_head, 1) != OK)
|
||||
panic(__FILE__, "PM set timer couldn't set synchronous alarm.", NO_NUM);
|
||||
#if VERBOSE
|
||||
else
|
||||
printf("timers: after setting, set synalarm to %d -> %d\n", old_head, new_head);
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PUBLIC void pm_expire_timers(clock_t now)
|
||||
{
|
||||
clock_t new_head;
|
||||
tmrs_exptimers(&pm_timers, now, &new_head);
|
||||
if(new_head > 0) {
|
||||
if(sys_syncalrm(SELF, new_head, 1) != OK)
|
||||
panic(__FILE__, "PM expire timer couldn't set synchronous alarm.", NO_NUM);
|
||||
#if VERBOSE
|
||||
else
|
||||
printf("timers: after expiry, set synalarm to %d\n", new_head);
|
||||
#endif
|
||||
}
|
||||
#if VERBOSE
|
||||
else printf("after expiry, no new timer set\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
PUBLIC void pm_cancel_timer(timer_t *tp)
|
||||
{
|
||||
clock_t new_head, old_head;
|
||||
old_head = tmrs_clrtimer(&pm_timers, tp, &new_head);
|
||||
|
||||
/* if the earliest timer has been removed, we have to set
|
||||
* the synalarm to the next timer, or cancel the synalarm
|
||||
* altogether if th last time has been cancelled (new_head
|
||||
* will be 0 then).
|
||||
*/
|
||||
if(old_head < new_head || ! new_head) {
|
||||
if(sys_syncalrm(SELF, new_head, 1) != OK)
|
||||
panic(__FILE__, "PM expire timer couldn't set synchronous alarm.", NO_NUM);
|
||||
#if VERBOSE
|
||||
printf("timers: after cancelling, set synalarm to %d -> %d\n", old_head, new_head);
|
||||
#endif
|
||||
}
|
||||
#if VERBOSE
|
||||
else printf("timers: after cancelling no new timer\n");
|
||||
#endif
|
||||
}
|
Loading…
Reference in a new issue