1 /* Watchdog timer management. These functions in this file provide a 2 * convenient interface to the timers library that manages a list of 3 * watchdog timers. All details of scheduling an alarm at the CLOCK task 4 * are hidden behind this interface. 5 * 6 * The entry points into this file are: 7 * init_timer: initialize a timer structure 8 * set_timer: reset and existing or set a new watchdog timer 9 * cancel_timer: remove a timer from the list of timers 10 * expire_timers: check for expired timers and run watchdog functions 11 * 12 */ 13 14 #include "syslib.h" 15 #include <minix/timers.h> 16 #include <minix/sysutil.h> 17 18 static minix_timer_t *timers = NULL; 19 static int expiring = 0; 20 21 /*===========================================================================* 22 * init_timer * 23 *===========================================================================*/ 24 void init_timer(minix_timer_t *tp) 25 { 26 tmr_inittimer(tp); 27 } 28 29 /*===========================================================================* 30 * set_timer * 31 *===========================================================================*/ 32 void set_timer(minix_timer_t *tp, int ticks, tmr_func_t watchdog, int arg) 33 { 34 int r; 35 clock_t now, prev_time = 0, next_time; 36 37 if ((r = getticks(&now)) != OK) 38 panic("set_timer: couldn't get uptime"); 39 40 /* Set timer argument and add timer to the list. */ 41 tmr_arg(tp)->ta_int = arg; 42 prev_time = tmrs_settimer(&timers, tp, now+ticks, watchdog, &next_time); 43 44 /* Reschedule our synchronous alarm if necessary. */ 45 if (expiring == 0 && (! prev_time || prev_time > next_time)) { 46 if (sys_setalarm(next_time, 1) != OK) 47 panic("set_timer: couldn't set alarm"); 48 } 49 } 50 51 /*===========================================================================* 52 * cancel_timer * 53 *===========================================================================*/ 54 void cancel_timer(minix_timer_t *tp) 55 { 56 clock_t next_time, prev_time; 57 prev_time = tmrs_clrtimer(&timers, tp, &next_time); 58 59 /* If the earliest timer has been removed, we have to set the alarm to 60 * the next timer, or cancel the alarm altogether if the last timer 61 * has been cancelled (next_time will be 0 then). 62 */ 63 if (expiring == 0 && (prev_time < next_time || ! next_time)) { 64 if (sys_setalarm(next_time, 1) != OK) 65 panic("cancel_timer: couldn't set alarm"); 66 } 67 } 68 69 /*===========================================================================* 70 * expire_timers * 71 *===========================================================================*/ 72 void expire_timers(clock_t now) 73 { 74 clock_t next_time; 75 76 /* Check for expired timers. Use a global variable to indicate that 77 * watchdog functions are called, so that sys_setalarm() isn't called 78 * more often than necessary when set_timer or cancel_timer are called 79 * from these watchdog functions. */ 80 expiring = 1; 81 tmrs_exptimers(&timers, now, &next_time); 82 expiring = 0; 83 84 /* Reschedule an alarm if necessary. */ 85 if (next_time > 0) { 86 if (sys_setalarm(next_time, 1) != OK) 87 panic("expire_timers: couldn't set alarm"); 88 } 89 } 90