From 2e1fa1a72740113ca261d6de540788545b355618 Mon Sep 17 00:00:00 2001 From: dwmalone Date: Fri, 16 Jun 2006 20:29:05 +0000 Subject: [PATCH] Add a kern.timecounter.tc sysctl tree that contains the mask, frequency, quality and current value of each available time counter. At the moment all of these are read-only, but it might make sense to make some of these read-write in the future. MFC after: 3 months --- sys/kern/kern_tc.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 1cca947d2a24..74392e490ece 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -97,6 +97,7 @@ SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD, NULL, 0, sysctl_kern_boottime, "S,timeval", "System boottime"); SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, ""); +SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, CTLFLAG_RW, 0, ""); static int timestepwarnings; SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, @@ -133,6 +134,26 @@ sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) return SYSCTL_OUT(req, &boottime, sizeof(boottime)); } +static int +sysctl_kern_timecounter_get(SYSCTL_HANDLER_ARGS) +{ + u_int ncount; + struct timecounter *tc = arg1; + + ncount = tc->tc_get_timecount(tc); + return sysctl_handle_int(oidp, &ncount, sizeof(ncount), req); +} + +static int +sysctl_kern_timecounter_freq(SYSCTL_HANDLER_ARGS) +{ + u_int64_t freq; + struct timecounter *tc = arg1; + + freq = tc->tc_frequency; + return sysctl_handle_int(oidp, &freq, sizeof(freq), req); +} + /* * Return the difference between the timehands' counter value now and what * was when we copied it to the timehands' offset_count. @@ -309,6 +330,7 @@ void tc_init(struct timecounter *tc) { u_int u; + struct sysctl_oid *tc_root; u = tc->tc_frequency / tc->tc_counter_mask; /* XXX: We need some margin here, 10% is a guess */ @@ -329,6 +351,24 @@ tc_init(struct timecounter *tc) tc->tc_next = timecounters; timecounters = tc; + /* + * Set up sysctl tree for this counter. + */ + tc_root = SYSCTL_ADD_NODE(NULL, + SYSCTL_STATIC_CHILDREN(_kern_timecounter_tc), OID_AUTO, tc->tc_name, + CTLFLAG_RW, 0, "timecounter description"); + SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, + "mask", CTLFLAG_RD, &(tc->tc_counter_mask), 0, + "mask for implemented bits"); + SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, + "counter", CTLTYPE_UINT | CTLFLAG_RD, tc, sizeof(*tc), + sysctl_kern_timecounter_get, "IU", "current timecounter value"); + SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, + "frequency", CTLTYPE_QUAD | CTLFLAG_RD, tc, sizeof(*tc), + sysctl_kern_timecounter_freq, "IU", "timecounter frequency"); + SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, + "quality", CTLFLAG_RD, &(tc->tc_quality), 0, + "goodness of time counter"); /* * Never automatically use a timecounter with negative quality. * Even though we run on the dummy counter, switching here may be