2 * Watchdog timer management. These functions in this file provide a
3 * convenient interface to the timers library that manages a list of
4 * watchdog timers. All details of scheduling an alarm at the CLOCK task
5 * are hidden behind this interface.
7 * The entry points into this file are:
8 * init_timer: initialize a timer structure
9 * set_timer: reset and existing or set a new watchdog timer
10 * cancel_timer: remove a timer from the list of timers
11 * expire_timers: check for expired timers and run watchdog functions
16 #include <minix/timers.h>
17 #include <minix/sysutil.h>
19 static minix_timer_t
*timers
= NULL
;
20 static int expiring
= FALSE
;
23 * Initialize the timer 'tp'.
26 init_timer(minix_timer_t
* tp
)
33 * Set the timer 'tp' to trigger 'ticks' clock ticks in the future. When it
34 * triggers, call function 'watchdog' with argument 'arg'. The given timer
35 * object must have been initialized with init_timer(3) already. The given
36 * number of ticks must be between 0 and TMRDIFF_MAX inclusive. A ticks value
37 * of zero will cause the alarm to trigger on the next clock tick. If the
38 * timer was already set, it will be canceled first.
41 set_timer(minix_timer_t
*tp
, clock_t ticks
, tmr_func_t watchdog
, int arg
)
43 clock_t prev_time
, next_time
;
46 if (ticks
> TMRDIFF_MAX
)
47 panic("set_timer: ticks value too large: %u", (int)ticks
);
49 /* Add the timer to the list. */
50 had_timers
= tmrs_settimer(&timers
, tp
, getticks() + ticks
, watchdog
,
51 arg
, &prev_time
, &next_time
);
53 /* Reschedule our synchronous alarm if necessary. */
54 if (!expiring
&& (!had_timers
|| next_time
!= prev_time
)) {
55 if ((r
= sys_setalarm(next_time
, TRUE
/*abs_time*/)) != OK
)
56 panic("set_timer: couldn't set alarm: %d", r
);
61 * Cancel the timer 'tp'. The timer object must have been initialized with
62 * init_timer(3) first. If the timer was not set before, the call is a no-op.
65 cancel_timer(minix_timer_t
* tp
)
67 clock_t next_time
, prev_time
;
73 have_timers
= tmrs_clrtimer(&timers
, tp
, &prev_time
, &next_time
);
76 * If the earliest timer has been removed, we have to set the alarm to
77 * the next timer, or cancel the alarm altogether if the last timer
82 r
= sys_setalarm(0, FALSE
/*abs_time*/);
83 else if (prev_time
!= next_time
)
84 r
= sys_setalarm(next_time
, TRUE
/*abs_time*/);
89 panic("cancel_timer: couldn't set alarm: %d", r
);
94 * Expire all timers that were set to expire before/at the given current time.
97 expire_timers(clock_t now
)
103 * Check for expired timers. Use a global variable to indicate that
104 * watchdog functions are called, so that sys_setalarm() isn't called
105 * more often than necessary when set_timer or cancel_timer are called
106 * from these watchdog functions.
109 have_timers
= tmrs_exptimers(&timers
, now
, &next_time
);
112 /* Reschedule an alarm if necessary. */
114 if ((r
= sys_setalarm(next_time
, TRUE
/*abs_time*/)) != OK
)
115 panic("expire_timers: couldn't set alarm: %d", r
);