Added a sysctl "kern.timecounter.hardware" for selecting the hardware

used for timecounting.  The possible values are the names of the
physically present harware timecounters ("i8254" and "TSC" on i386's).

Fixed some nearby bitrot in comments in <sys/time.h>.

Reviewed by:	phk
This commit is contained in:
Bruce Evans 1999-07-18 15:07:20 +00:00
parent e9bd3a37e8
commit 6b6ef746e5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=48887
4 changed files with 98 additions and 20 deletions

View File

@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $Id: kern_clock.c,v 1.94 1999/04/25 08:59:59 phk Exp $
* $Id: kern_clock.c,v 1.95 1999/07/18 01:35:26 jdp Exp $
*/
#include "opt_ntp.h"
@ -679,7 +679,14 @@ init_timecounter(struct timecounter *tc)
tc->tc_tweak = tc;
tco_setscales(tc);
tc->tc_offset_count = tc->tc_get_timecount(tc);
if (timecounter == &dummy_timecounter)
tc->tc_avail = tc;
else {
tc->tc_avail = timecounter->tc_tweak->tc_avail;
timecounter->tc_tweak->tc_avail = tc;
}
MALLOC(t1, struct timecounter *, sizeof *t1, M_TIMECOUNTER, M_WAITOK);
tc->tc_other = t1;
*t1 = *tc;
t2 = t1;
for (i = 1; i < NTIMECOUNTER; i++) {
@ -720,9 +727,7 @@ set_timecounter(struct timespec *ts)
tco_forward(1);
}
#if 0 /* Currently unused */
void
static void
switch_timecounter(struct timecounter *newtc)
{
int s;
@ -731,19 +736,20 @@ switch_timecounter(struct timecounter *newtc)
s = splclock();
tc = timecounter;
if (newtc == tc || newtc == tc->tc_other) {
if (newtc->tc_tweak == tc->tc_tweak) {
splx(s);
return;
}
newtc = newtc->tc_tweak->tc_other;
nanouptime(&ts);
newtc->tc_offset_sec = ts.tv_sec;
newtc->tc_offset_nano = (u_int64_t)ts.tv_nsec << 32;
newtc->tc_offset_micro = ts.tv_nsec / 1000;
newtc->tc_offset_count = newtc->tc_get_timecount(newtc);
tco_setscales(newtc);
timecounter = newtc;
splx(s);
}
#endif
static struct timecounter *
sync_other_counter(void)
@ -825,6 +831,35 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, method, CTLFLAG_RW, &tco_method, 0,
);
static int
sysctl_kern_timecounter_hardware SYSCTL_HANDLER_ARGS
{
char newname[32];
struct timecounter *newtc, *tc;
int error;
tc = timecounter->tc_tweak;
strncpy(newname, tc->tc_name, sizeof(newname));
error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
if (error == 0 && req->newptr != NULL &&
strcmp(newname, tc->tc_name) != 0) {
for (newtc = tc->tc_avail; newtc != tc; newtc = tc->tc_avail) {
if (strcmp(newname, newtc->tc_name) == 0) {
/* Warm up new timecounter. */
(void)newtc->tc_get_timecount(newtc);
switch_timecounter(newtc);
return (0);
}
}
return (EINVAL);
}
return (error);
}
SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
0, 0, sysctl_kern_timecounter_hardware, "A", "");
int
pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)

View File

@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $Id: kern_clock.c,v 1.94 1999/04/25 08:59:59 phk Exp $
* $Id: kern_clock.c,v 1.95 1999/07/18 01:35:26 jdp Exp $
*/
#include "opt_ntp.h"
@ -679,7 +679,14 @@ init_timecounter(struct timecounter *tc)
tc->tc_tweak = tc;
tco_setscales(tc);
tc->tc_offset_count = tc->tc_get_timecount(tc);
if (timecounter == &dummy_timecounter)
tc->tc_avail = tc;
else {
tc->tc_avail = timecounter->tc_tweak->tc_avail;
timecounter->tc_tweak->tc_avail = tc;
}
MALLOC(t1, struct timecounter *, sizeof *t1, M_TIMECOUNTER, M_WAITOK);
tc->tc_other = t1;
*t1 = *tc;
t2 = t1;
for (i = 1; i < NTIMECOUNTER; i++) {
@ -720,9 +727,7 @@ set_timecounter(struct timespec *ts)
tco_forward(1);
}
#if 0 /* Currently unused */
void
static void
switch_timecounter(struct timecounter *newtc)
{
int s;
@ -731,19 +736,20 @@ switch_timecounter(struct timecounter *newtc)
s = splclock();
tc = timecounter;
if (newtc == tc || newtc == tc->tc_other) {
if (newtc->tc_tweak == tc->tc_tweak) {
splx(s);
return;
}
newtc = newtc->tc_tweak->tc_other;
nanouptime(&ts);
newtc->tc_offset_sec = ts.tv_sec;
newtc->tc_offset_nano = (u_int64_t)ts.tv_nsec << 32;
newtc->tc_offset_micro = ts.tv_nsec / 1000;
newtc->tc_offset_count = newtc->tc_get_timecount(newtc);
tco_setscales(newtc);
timecounter = newtc;
splx(s);
}
#endif
static struct timecounter *
sync_other_counter(void)
@ -825,6 +831,35 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, method, CTLFLAG_RW, &tco_method, 0,
);
static int
sysctl_kern_timecounter_hardware SYSCTL_HANDLER_ARGS
{
char newname[32];
struct timecounter *newtc, *tc;
int error;
tc = timecounter->tc_tweak;
strncpy(newname, tc->tc_name, sizeof(newname));
error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
if (error == 0 && req->newptr != NULL &&
strcmp(newname, tc->tc_name) != 0) {
for (newtc = tc->tc_avail; newtc != tc; newtc = tc->tc_avail) {
if (strcmp(newname, newtc->tc_name) == 0) {
/* Warm up new timecounter. */
(void)newtc->tc_get_timecount(newtc);
switch_timecounter(newtc);
return (0);
}
}
return (EINVAL);
}
return (error);
}
SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
0, 0, sysctl_kern_timecounter_hardware, "A", "");
int
pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)time.h 8.5 (Berkeley) 5/4/95
* $Id: time.h,v 1.37 1999/03/11 15:09:41 phk Exp $
* $Id: time.h,v 1.38 1999/04/25 08:59:55 phk Exp $
*/
#ifndef _SYS_TIME_H_
@ -121,11 +121,14 @@ struct timezone {
* used in a safe way. Such changes may be adopted with a delay of up to 1/HZ,
* index one & two are used alternately for the actual timekeeping.
*
* `other' points to the opposite "work" timecounter, ie, in index one it
* points to index two and vice versa
* 'tc_avail' points to the next available (external) timecounter in a
* circular queue. This is only valid for index 0.
*
* `tweak' points to index zero.
* `tc_other' points to the next "work" timecounter in a circular queue,
* i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER.
* We also use it to point from index 0 to index 1.
*
* `tc_tweak' points to index 0.
*/
struct timecounter;
@ -151,6 +154,7 @@ struct timecounter {
u_int64_t tc_offset_nano;
struct timeval tc_microtime;
struct timespec tc_nanotime;
struct timecounter *tc_avail;
struct timecounter *tc_other;
struct timecounter *tc_tweak;
};

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)time.h 8.5 (Berkeley) 5/4/95
* $Id: time.h,v 1.37 1999/03/11 15:09:41 phk Exp $
* $Id: time.h,v 1.38 1999/04/25 08:59:55 phk Exp $
*/
#ifndef _SYS_TIME_H_
@ -121,11 +121,14 @@ struct timezone {
* used in a safe way. Such changes may be adopted with a delay of up to 1/HZ,
* index one & two are used alternately for the actual timekeeping.
*
* `other' points to the opposite "work" timecounter, ie, in index one it
* points to index two and vice versa
* 'tc_avail' points to the next available (external) timecounter in a
* circular queue. This is only valid for index 0.
*
* `tweak' points to index zero.
* `tc_other' points to the next "work" timecounter in a circular queue,
* i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER.
* We also use it to point from index 0 to index 1.
*
* `tc_tweak' points to index 0.
*/
struct timecounter;
@ -151,6 +154,7 @@ struct timecounter {
u_int64_t tc_offset_nano;
struct timeval tc_microtime;
struct timespec tc_nanotime;
struct timecounter *tc_avail;
struct timecounter *tc_other;
struct timecounter *tc_tweak;
};