FreeBSD/sys/kern/kern_tc.c
/*
 * Initialize a new timecounter and possibly use it.
 */
Initialize a new timecounter and possibly use it.
Initialize a new timecounter and possibly use it .
void
tc_init(struct timecounter *tc)
{
	u_int u;
	struct sysctl_oid *tc_root;
	u = tc->tc_frequency / tc->tc_counter_mask;
	u *= 11;
	u /= 10;
	if (u > hz && tc->tc_quality >= 0) {
		tc->tc_quality = -2000;
		if (bootverbose) {
			printf("Timecounter \"%s\" frequency %ju Hz",
			    tc->tc_name, (uintmax_t)tc->tc_frequency);
			printf(" -- Insufficient hz, needs at least %u\n", u);
		}
	} else if (tc->tc_quality >= 0 || bootverbose) {
		printf("Timecounter \"%s\" frequency %ju Hz quality %d\n",
		    tc->tc_name, (uintmax_t)tc->tc_frequency,
		    tc->tc_quality);
	}
	tc->tc_next = timecounters;
	timecounters = tc;
	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_U64 | CTLFLAG_RD, tc, sizeof(*tc),
	     sysctl_kern_timecounter_freq, "QU", "timecounter frequency");
	SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO,
	    "quality", CTLFLAG_RD, &(tc->tc_quality), 0,
	    "goodness of time counter");
	if (tc_chosen)
		return;
	if (tc->tc_quality < 0)
		return;
	if (tc->tc_quality < timecounter->tc_quality)
		return;
	if (tc->tc_quality == timecounter->tc_quality &&
	    tc->tc_frequency < timecounter->tc_frequency)
		return;
	(void)tc->tc_get_timecount(tc);
	(void)tc->tc_get_timecount(tc);
	timecounter = tc;
}
void tc_init ( struct timecounter * tc ) { u_int u ; struct sysctl_oid * tc_root ; u = tc -> tc_frequency / tc -> tc_counter_mask ; u *= 11 ; u /= 10 ; if ( u > hz && tc -> tc_quality >= 0 ) { tc -> tc_quality = -2000 ; if ( bootverbose ) { printf ( " \" \" " , tc -> tc_name , ( uintmax_t ) tc -> tc_frequency ) ; printf ( " \n " , u ) ; } } else if ( tc -> tc_quality >= 0 || bootverbose ) { printf ( " \" \" \n " , tc -> tc_name , ( uintmax_t ) tc -> tc_frequency , tc -> tc_quality ) ; } tc -> tc_next = timecounters ; timecounters = tc ; tc_root = SYSCTL_ADD_NODE ( NULL , SYSCTL_STATIC_CHILDREN ( _kern_timecounter_tc ) , OID_AUTO , tc -> tc_name , CTLFLAG_RW , 0 , " " ) ; SYSCTL_ADD_UINT ( NULL , SYSCTL_CHILDREN ( tc_root ) , OID_AUTO , " " , CTLFLAG_RD , & ( tc -> tc_counter_mask ) , 0 , " " ) ; SYSCTL_ADD_PROC ( NULL , SYSCTL_CHILDREN ( tc_root ) , OID_AUTO , " " , CTLTYPE_UINT | CTLFLAG_RD , tc , sizeof ( * tc ) , sysctl_kern_timecounter_get , " " , " " ) ; SYSCTL_ADD_PROC ( NULL , SYSCTL_CHILDREN ( tc_root ) , OID_AUTO , " " , CTLTYPE_U64 | CTLFLAG_RD , tc , sizeof ( * tc ) , sysctl_kern_timecounter_freq , " " , " " ) ; SYSCTL_ADD_INT ( NULL , SYSCTL_CHILDREN ( tc_root ) , OID_AUTO , " " , CTLFLAG_RD , & ( tc -> tc_quality ) , 0 , " " ) ; if ( tc_chosen ) return ; if ( tc -> tc_quality < 0 ) return ; if ( tc -> tc_quality < timecounter -> tc_quality ) return ; if ( tc -> tc_quality == timecounter -> tc_quality && tc -> tc_frequency < timecounter -> tc_frequency ) return ; ( void ) tc -> tc_get_timecount ( tc ) ; ( void ) tc -> tc_get_timecount ( tc ) ; timecounter = tc ; }
Initialize a new timecounter and possibly use it.
Initialize a new timecounter and possibly use it .
/* XXX: We need some margin here, 10% is a guess */ /*
	 * Set up sysctl tree for this counter.
	 */ /*
	 * Do not automatically switch if the current tc was specifically
	 * chosen.  Never automatically use a timecounter with negative quality.
	 * Even though we run on the dummy counter, switching here may be
	 * worse since this timecounter may not be monotonic.
	 */