diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2006-10-30 20:19:34 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2006-10-30 20:19:34 +0000 |
commit | 0eb59e835bf1485b257d8544f2cbdd5d903f159c (patch) | |
tree | 95041ce9006d30192cc08d000490a8315f9d9cc8 | |
parent | 23c7d2e7742edb7f7d49bbf29ee8d93c39b9922c (diff) |
Timecounter based implementation of adjfreq(2). Largely from art@
Tested by various using not (yet) committed amd64 timecounter code.
ok deraadt@
-rw-r--r-- | sys/kern/kern_tc.c | 15 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 16 | ||||
-rw-r--r-- | sys/sys/timetc.h | 5 |
3 files changed, 30 insertions, 6 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 52094aa620c..2a7d7d3efee 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $OpenBSD: kern_tc.c,v 1.5 2005/05/03 11:10:56 hshoexer Exp $ + * $OpenBSD: kern_tc.c,v 1.6 2006/10/30 20:19:33 otto Exp $ * $FreeBSD: src/sys/kern/kern_tc.c,v 1.148 2003/03/18 08:45:23 phk Exp $ */ @@ -600,5 +600,18 @@ ntp_update_second(int64_t *adjust, time_t *sec) adj.tv_usec = MAX(-500, adjtimedelta.tv_usec - 1000000); timersub(&adjtimedelta, &adj, &adjtimedelta); *adjust = ((int64_t)adj.tv_usec * 1000) << 32; + *adjust += timecounter->tc_freq_adj; +} + +int +tc_adjfreq(int64_t *old, int64_t *new) +{ + if (old != NULL) { + *old = timecounter->tc_freq_adj; + } + if (new != NULL) { + timecounter->tc_freq_adj = *new; + } + return 0; } #endif /* __HAVE_TIMECOUNTER */ diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 3f1e10b57dd..a0933e65577 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.59 2006/06/29 19:52:47 kettenis Exp $ */ +/* $OpenBSD: kern_time.c,v 1.60 2006/10/30 20:19:33 otto Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -389,9 +389,17 @@ sys_adjfreq(struct proc *p, void *v, register_t *retval) } #else if (SCARG(uap, oldfreq)) { - f = 0; - if ((error = copyout((void *)&f, (void *)SCARG(uap, oldfreq), - sizeof(int64_t)))) + if ((error = tc_adjfreq(&f, NULL)) != 0) + return (error); + if ((error = copyout(&f, SCARG(uap, oldfreq), sizeof(f))) != 0) + return (error); + } + if (SCARG(uap, freq)) { + if ((error = suser(p, 0))) + return (error); + if ((error = copyin(SCARG(uap, freq), &f, sizeof(f))) != 0) + return (error); + if ((error = tc_adjfreq(NULL, &f)) != 0) return (error); } #endif diff --git a/sys/sys/timetc.h b/sys/sys/timetc.h index bbc532aec3e..54daeeea88a 100644 --- a/sys/sys/timetc.h +++ b/sys/sys/timetc.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $OpenBSD: timetc.h,v 1.1 2004/07/28 17:15:12 tholo Exp $ + * $OpenBSD: timetc.h,v 1.2 2006/10/30 20:19:33 otto Exp $ * $FreeBSD: src/sys/sys/timetc.h,v 1.57 2003/04/10 23:07:24 des Exp $ */ @@ -62,6 +62,8 @@ struct timecounter { /* Pointer to the timecounter's private parts. */ struct timecounter *tc_next; /* Pointer to the next timecounter. */ + int64_t tc_freq_adj; + /* Current frequency adjustment. */ }; extern struct timecounter *timecounter; @@ -72,5 +74,6 @@ void tc_setclock(struct timespec *ts); void tc_ticktock(void); void inittimecounter(void); int sysctl_tc(int *, u_int, void *, size_t *, void *, size_t); +int tc_adjfreq(int64_t *, int64_t *); #endif /* !_SYS_TIMETC_H_ */ |