]> Zhao Yanbai Git Server - minix.git/commitdiff
New alarm(2) timers mechanism.
authorJorrit Herder <jnherder@minix3.org>
Thu, 14 Jul 2005 15:30:12 +0000 (15:30 +0000)
committerJorrit Herder <jnherder@minix3.org>
Thu, 14 Jul 2005 15:30:12 +0000 (15:30 +0000)
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.

servers/pm/timers.c [new file with mode: 0644]

diff --git a/servers/pm/timers.c b/servers/pm/timers.c
new file mode 100644 (file)
index 0000000..c052b29
--- /dev/null
@@ -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
+}