1 /* This library provides generic watchdog timer management functionality.
2 * The functions operate on a timer queue provided by the caller. Note that
3 * the timers must use absolute time to allow sorting. The library provides:
5 * tmrs_settimer: (re)set a new watchdog timer in the timers queue
6 * tmrs_clrtimer: remove a timer from both the timers queue
7 * tmrs_exptimers: check for expired timers and run watchdog functions
10 * Jorrit N. Herder <jnherder@cs.vu.nl>
11 * Adapted from tmr_settimer and tmr_clrtimer in src/kernel/clock.c.
12 * Last modified: September 30, 2004.
14 #ifndef _MINIX_TIMERS_H
15 #define _MINIX_TIMERS_H
19 #include <sys/types.h>
20 #include <minix/u64.h>
21 #include <minix/minlib.h>
22 #include <minix/endpoint.h>
25 typedef void (*tmr_func_t
)(struct minix_timer
*tp
);
26 typedef union { int ta_int
; long ta_long
; void *ta_ptr
; } tmr_arg_t
;
28 /* A minix_timer_t variable must be declare for each distinct timer to be used.
29 * The timers watchdog function and expiration time are automatically set
30 * by the library function tmrs_settimer, but its argument is not.
32 typedef struct minix_timer
34 struct minix_timer
*tmr_next
; /* next in a timer chain */
35 clock_t tmr_exp_time
; /* expiration time */
36 tmr_func_t tmr_func
; /* function to call when expired */
37 tmr_arg_t tmr_arg
; /* random argument */
40 /* Used when the timer is not active. */
41 #define TMR_NEVER ((clock_t) -1 < 0) ? ((clock_t) LONG_MAX) : ((clock_t) -1)
43 #define TMR_NEVER ((clock_t) LONG_MAX)
45 /* These definitions can be used to set or get data from a timer variable. */
46 #define tmr_arg(tp) (&(tp)->tmr_arg)
47 #define tmr_exp_time(tp) (&(tp)->tmr_exp_time)
49 /* Timers should be initialized once before they are being used. Be careful
50 * not to reinitialize a timer that is in a list of timers, or the chain
53 #define tmr_inittimer(tp) (void)((tp)->tmr_exp_time = TMR_NEVER, \
54 (tp)->tmr_next = NULL)
56 /* The following generic timer management functions are available. They
57 * can be used to operate on the lists of timers. Adding a timer to a list
58 * automatically takes care of removing it.
60 clock_t tmrs_clrtimer(minix_timer_t
**tmrs
, minix_timer_t
*tp
, clock_t *new_head
);
61 void tmrs_exptimers(minix_timer_t
**tmrs
, clock_t now
, clock_t *new_head
);
62 clock_t tmrs_settimer(minix_timer_t
**tmrs
, minix_timer_t
*tp
, clock_t exp_time
,
63 tmr_func_t watchdog
, clock_t *new_head
);
65 #define PRINT_STATS(cum_spenttime, cum_instances) { \
66 if(ex64hi(cum_spenttime)) { util_stacktrace(); printf(" ( ??? %lu %lu)\n", \
67 ex64hi(cum_spenttime), ex64lo(cum_spenttime)); } \
68 printf("%s:%d,%lu,%lu\n", \
69 __FILE__, __LINE__, cum_instances, \
70 ex64lo(cum_spenttime)); \
73 #define RESET_STATS(starttime, cum_instances, cum_spenttime, cum_starttime) { \
75 cum_starttime = starttime; \
76 cum_spenttime = make64(0,0); \
79 #define TIME_BLOCK_VAR(timed_code_block, time_interval) do { \
80 static u64_t _cum_spenttime, _cum_starttime; \
81 static int _cum_instances; \
82 u64_t _next_cum_spent, _starttime, _endtime, _dt, _cum_dt; \
84 read_tsc_64(&_starttime); \
85 do { timed_code_block } while(0); \
86 read_tsc_64(&_endtime); \
87 _dt = _endtime - _starttime; \
88 if(_cum_instances == 0) { \
89 RESET_STATS(_starttime, _cum_instances, _cum_spenttime, _cum_starttime); \
91 _next_cum_spent = add64(_cum_spenttime, _dt); \
92 if(ex64hi(_next_cum_spent)) { \
93 PRINT_STATS(_cum_spenttime, _cum_instances); \
94 RESET_STATS(_starttime, _cum_instances, _cum_spenttime, _cum_starttime); \
96 _cum_spenttime = add64(_cum_spenttime, _dt); \
98 _cum_dt = _endtime - _cum_starttime; \
99 if(_cum_dt > make64(0, 120)) { \
100 PRINT_STATS(_cum_spenttime, _cum_instances); \
101 RESET_STATS(_starttime, _cum_instances, _cum_spenttime, _cum_starttime); \
105 #define TIME_BLOCK(timed_code_block) TIME_BLOCK_VAR(timed_code_block, 100)
106 #define TIME_BLOCK_T(timed_code_block, t) TIME_BLOCK_VAR(timed_code_block, t)
108 /* Timers abstraction for system processes. This would be in minix/sysutil.h
109 * if it weren't for naming conflicts.
112 void init_timer(minix_timer_t
*tp
);
113 void set_timer(minix_timer_t
*tp
, int ticks
, tmr_func_t watchdog
, int arg
);
114 void cancel_timer(minix_timer_t
*tp
);
115 void expire_timers(clock_t now
);
117 #endif /* _MINIX_TIMERS_H */