Page MenuHomeFreeBSD

D27571.id80585.diff
No OneTemporary

D27571.id80585.diff

Index: sys/kern/kern_tc.c
===================================================================
--- sys/kern/kern_tc.c
+++ sys/kern/kern_tc.c
@@ -1245,7 +1245,7 @@
* when we booted.
*/
void
-tc_setclock(struct timespec *ts)
+tc_setclock(struct timespec *ts, bool abs)
{
struct timespec tbef, taft;
struct bintime bt, bt2;
@@ -1254,8 +1254,10 @@
nanotime(&tbef);
mtx_lock_spin(&tc_setclock_mtx);
cpu_tick_calibrate(1);
- binuptime(&bt2);
- bintime_sub(&bt, &bt2);
+ if (abs) {
+ binuptime(&bt2);
+ bintime_sub(&bt, &bt2);
+ }
/* XXX fiddle all the little crinkly bits around the fiords... */
tc_windup(&bt);
Index: sys/kern/kern_time.c
===================================================================
--- sys/kern/kern_time.c
+++ sys/kern/kern_time.c
@@ -86,6 +86,7 @@
*/
static int settime(struct thread *, struct timeval *);
+static int steptime(struct thread *, struct timeval *, bool abs);
static void timevalfix(struct timeval *);
static int user_clock_nanosleep(struct thread *td, clockid_t clock_id,
int flags, const struct timespec *ua_rqtp,
@@ -120,7 +121,6 @@
{
struct timeval delta, tv1, tv2;
static struct timeval maxtime, laststep;
- struct timespec ts;
microtime(&tv1);
delta = *tv;
@@ -161,9 +161,17 @@
}
}
+ return (steptime(td, tv, true));
+}
+
+static int
+steptime(struct thread *td, struct timeval *tv, bool abs)
+{
+ struct timespec ts;
+
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000;
- tc_setclock(&ts);
+ tc_setclock(&ts, abs);
resettodr();
return (0);
}
@@ -405,18 +413,29 @@
if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0)
return (error);
- if (clock_id != CLOCK_REALTIME)
- return (EINVAL);
- if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000 ||
- ats->tv_sec < 0)
- return (EINVAL);
- if (!allow_insane_settime &&
- (ats->tv_sec > 8000ULL * 365 * 24 * 60 * 60 ||
- ats->tv_sec < utc_offset()))
- return (EINVAL);
- /* XXX Don't convert nsec->usec and back */
- TIMESPEC_TO_TIMEVAL(&atv, ats);
- error = settime(td, &atv);
+ error = EINVAL;
+ switch (clock_id) {
+ case CLOCK_ADJUST_REALTIME:
+ if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000 ||
+ (!allow_insane_settime && (ats->tv_sec > 3600 ||
+ ats->tv_sec < -3600)))
+ break;
+ TIMESPEC_TO_TIMEVAL(&atv, ats);
+ error = steptime(td, &atv, false);
+ break;
+ case CLOCK_REALTIME:
+ if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000 ||
+ ats->tv_sec < 0)
+ break;
+ if (!allow_insane_settime &&
+ (ats->tv_sec > 8000ULL * 365 * 24 * 60 * 60 ||
+ ats->tv_sec < utc_offset()))
+ error = EINVAL;
+ /* XXX Don't convert nsec->usec and back */
+ TIMESPEC_TO_TIMEVAL(&atv, ats);
+ error = settime(td, &atv);
+ break;
+ }
return (error);
}
Index: sys/kern/subr_rtc.c
===================================================================
--- sys/kern/subr_rtc.c
+++ sys/kern/subr_rtc.c
@@ -361,7 +361,7 @@
}
if (ts.tv_sec >= 0) {
- tc_setclock(&ts);
+ tc_setclock(&ts, true);
#ifdef FFCLOCK
ffclock_reset_clock(&ts);
#endif
Index: sys/sys/time.h
===================================================================
--- sys/sys/time.h
+++ sys/sys/time.h
@@ -480,6 +480,7 @@
#define CLOCK_SECOND 13 /* FreeBSD-specific. */
#define CLOCK_THREAD_CPUTIME_ID 14
#define CLOCK_PROCESS_CPUTIME_ID 15
+#define CLOCK_ADJUST_REALTIME 16 /* FreeBSD-specific. */
#endif
#ifndef TIMER_ABSTIME
Index: sys/sys/timetc.h
===================================================================
--- sys/sys/timetc.h
+++ sys/sys/timetc.h
@@ -88,7 +88,7 @@
u_int64_t tc_getfrequency(void);
void tc_init(struct timecounter *tc);
-void tc_setclock(struct timespec *ts);
+void tc_setclock(struct timespec *ts, bool abs);
void tc_ticktock(int cnt);
void cpu_tick_calibration(void);

File Metadata

Mime Type
text/plain
Expires
Tue, May 19, 10:43 AM (7 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33308268
Default Alt Text
D27571.id80585.diff (3 KB)

Event Timeline