27 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/sysctl.h>
33 #include <sys/systm.h>
34 #include <sys/queue.h>
35 #include <sys/timeet.h>
38 static struct et_eventtimers_list
eventtimers = SLIST_HEAD_INITIALIZER(et_eventtimers);
43 SYSCTL_NODE(_kern, OID_AUTO, eventtimer, CTLFLAG_RW, 0,
"Event timers");
44 static SYSCTL_NODE(_kern_eventtimer, OID_AUTO, et, CTLFLAG_RW, 0,
"");
52 struct eventtimer *tmp, *next;
55 if (et->et_frequency == 0) {
56 printf(
"Event timer \"%s\" quality %d\n",
57 et->et_name, et->et_quality);
59 printf(
"Event timer \"%s\" "
60 "frequency %ju Hz quality %d\n",
61 et->et_name, (uintmax_t)et->et_frequency,
65 et->et_sysctl = SYSCTL_ADD_NODE(NULL,
66 SYSCTL_STATIC_CHILDREN(_kern_eventtimer_et), OID_AUTO, et->et_name,
67 CTLFLAG_RW, 0,
"event timer description");
68 SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(et->et_sysctl), OID_AUTO,
69 "flags", CTLFLAG_RD, &(et->et_flags), 0,
70 "Event timer capabilities");
71 SYSCTL_ADD_UQUAD(NULL, SYSCTL_CHILDREN(et->et_sysctl), OID_AUTO,
72 "frequency", CTLFLAG_RD, &(et->et_frequency),
73 "Event timer base frequency");
74 SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(et->et_sysctl), OID_AUTO,
75 "quality", CTLFLAG_RD, &(et->et_quality), 0,
76 "Goodness of event timer");
79 SLIST_FIRST(&
eventtimers)->et_quality < et->et_quality) {
83 next = SLIST_NEXT(tmp, et_all);
84 if (next == NULL || next->et_quality < et->et_quality) {
85 SLIST_INSERT_AFTER(tmp, et, et_all);
102 if (et->et_deregister_cb != NULL) {
103 if ((err = et->et_deregister_cb(et, et->et_arg)) != 0)
108 SLIST_REMOVE(&
eventtimers, et, eventtimer, et_all);
120 struct eventtimer *et = NULL;
125 if (name != NULL && strcasecmp(et->et_name, name) != 0)
127 if (name == NULL && et->et_quality < 0)
129 if ((et->et_flags & check) != want)
140 et_init(
struct eventtimer *et, et_event_cb_t *event,
141 et_deregister_cb_t *deregister,
void *arg)
150 et->et_event_cb = event;
151 et->et_deregister_cb = deregister;
168 if (first == NULL && period == NULL)
170 if ((et->et_flags & ET_FLAGS_PERIODIC) == 0 &&
173 if ((et->et_flags & ET_FLAGS_ONESHOT) == 0 &&
177 if (first->sec < et->et_min_period.sec ||
178 (first->sec == et->et_min_period.sec &&
179 first->frac < et->et_min_period.frac))
180 first = &et->et_min_period;
181 if (first->sec > et->et_max_period.sec ||
182 (first->sec == et->et_max_period.sec &&
183 first->frac > et->et_max_period.frac))
184 first = &et->et_max_period;
186 if (period != NULL) {
187 if (period->sec < et->et_min_period.sec ||
188 (period->sec == et->et_min_period.sec &&
189 period->frac < et->et_min_period.frac))
190 period = &et->et_min_period;
191 if (period->sec > et->et_max_period.sec ||
192 (period->sec == et->et_max_period.sec &&
193 period->frac > et->et_max_period.frac))
194 period = &et->et_max_period;
197 return (et->et_start(et, first, period));
209 return (et->et_stop(et));
218 et->et_flags &= ~(ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT);
239 struct eventtimer *et;
248 off +=
snprintf(buf + off,
sizeof(buf) - off,
"%s%s(%d)",
249 spc, et->et_name, et->et_quality);
253 error = SYSCTL_OUT(req, buf, strlen(buf));
257 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
struct mtx et_eventtimers_mtx
int et_stop(struct eventtimer *et)
MTX_SYSINIT(et_eventtimers_init,&et_eventtimers_mtx,"et_mtx", MTX_DEF)
int snprintf(char *str, size_t size, const char *format,...)
int et_deregister(struct eventtimer *et)
struct eventtimer * et_find(const char *name, int check, int want)
int et_ban(struct eventtimer *et)
static int sysctl_kern_eventtimer_choice(SYSCTL_HANDLER_ARGS)
int et_init(struct eventtimer *et, et_event_cb_t *event, et_deregister_cb_t *deregister, void *arg)
int et_start(struct eventtimer *et, struct bintime *first, struct bintime *period)
int printf(const char *fmt,...)
void bintime(struct bintime *bt)
SYSCTL_NODE(_kern, OID_AUTO, eventtimer, CTLFLAG_RW, 0,"Event timers")
int et_free(struct eventtimer *et)
SLIST_HEAD(et_eventtimers_list, eventtimer)
int et_register(struct eventtimer *et)
SYSCTL_PROC(_kern_eventtimer, OID_AUTO, choice, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE, 0, 0, sysctl_kern_eventtimer_choice,"A","Present event timers")
int sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
static struct et_eventtimers_list eventtimers