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 clock_t prev_time = 0, next_time; 35 36 /* Set timer argument and add timer to the list. */ 37 tmr_arg(tp)->ta_int = arg; 38 prev_time = tmrs_settimer(&timers, tp, getticks() + ticks, watchdog, 39 &next_time); 40 41 /* Reschedule our synchronous alarm if necessary. */ 42 if (expiring == 0 && (! prev_time || prev_time > next_time)) { 43 if (sys_setalarm(next_time, 1) != OK) 44 panic("set_timer: couldn't set alarm"); 45 } 46 } 47 48 /*===========================================================================* 49 * cancel_timer * 50 *===========================================================================*/ 51 void cancel_timer(minix_timer_t *tp) 52 { 53 clock_t next_time, prev_time; 54 prev_time = tmrs_clrtimer(&timers, tp, &next_time); 55 56 /* If the earliest timer has been removed, we have to set the alarm to 57 * the next timer, or cancel the alarm altogether if the last timer 58 * has been cancelled (next_time will be 0 then). 59 */ 60 if (expiring == 0 && (prev_time < next_time || ! next_time)) { 61 if (sys_setalarm(next_time, 1) != OK) 62 panic("cancel_timer: couldn't set alarm"); 63 } 64 } 65 66 /*===========================================================================* 67 * expire_timers * 68 *===========================================================================*/ 69 void expire_timers(clock_t now) 70 { 71 clock_t next_time; 72 73 /* Check for expired timers. Use a global variable to indicate that 74 * watchdog functions are called, so that sys_setalarm() isn't called 75 * more often than necessary when set_timer or cancel_timer are called 76 * from these watchdog functions. */ 77 expiring = 1; 78 tmrs_exptimers(&timers, now, &next_time); 79 expiring = 0; 80 81 /* Reschedule an alarm if necessary. */ 82 if (next_time > 0) { 83 if (sys_setalarm(next_time, 1) != OK) 84 panic("expire_timers: couldn't set alarm"); 85 } 86 } 87