diff options
author | 2009-11-27 19:45:53 +0000 | |
---|---|---|
committer | 2009-11-27 19:45:53 +0000 | |
commit | f7123e65102a0fe1394d8065255f50f9361e2bb3 (patch) | |
tree | 294717502867640ebf4c89d68c07d814889bd58a /sys/kern/kern_time.c | |
parent | Convert thrsigdivert to (almost) be sigtimedwait by adding siginfo_t (diff) | |
download | wireguard-openbsd-f7123e65102a0fe1394d8065255f50f9361e2bb3.tar.xz wireguard-openbsd-f7123e65102a0fe1394d8065255f50f9361e2bb3.zip |
Convert thrsleep() to an absolute timeout with clockid to eliminate a
race condition and prep for later support of pthread_condattr_setclock()
"get it in" deraadt@, tedu@, cheers by others
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r-- | sys/kern/kern_time.c | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 82a805cffd8..6cb2aa8a320 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.67 2009/10/16 19:29:41 martynas Exp $ */ +/* $OpenBSD: kern_time.c,v 1.68 2009/11/27 19:45:53 guenther Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -156,32 +156,39 @@ settime(struct timespec *ts) } #endif -/* ARGSUSED */ int -sys_clock_gettime(struct proc *p, void *v, register_t *retval) +clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) { - struct sys_clock_gettime_args /* { - syscallarg(clockid_t) clock_id; - syscallarg(struct timespec *) tp; - } */ *uap = v; - clockid_t clock_id; - struct timespec ats; - - clock_id = SCARG(uap, clock_id); switch (clock_id) { case CLOCK_REALTIME: - nanotime(&ats); + nanotime(tp); break; case CLOCK_MONOTONIC: - nanouptime(&ats); + nanouptime(tp); break; case CLOCK_PROF: - ats.tv_sec = p->p_rtime.tv_sec; - ats.tv_nsec = p->p_rtime.tv_usec * 1000; + tp->tv_sec = p->p_rtime.tv_sec; + tp->tv_nsec = p->p_rtime.tv_usec * 1000; break; default: return (EINVAL); } + return (0); +} + +/* ARGSUSED */ +int +sys_clock_gettime(struct proc *p, void *v, register_t *retval) +{ + struct sys_clock_gettime_args /* { + syscallarg(clockid_t) clock_id; + syscallarg(struct timespec *) tp; + } */ *uap = v; + struct timespec ats; + int error; + + if ((error = clock_gettime(p, SCARG(uap, clock_id), &ats)) != 0) + return (error); return copyout(&ats, SCARG(uap, tp), sizeof(ats)); } @@ -688,6 +695,18 @@ realitexpire(void *arg) } /* + * Check that a timespec value is legit + */ +int +timespecfix(struct timespec *ts) +{ + if (ts->tv_sec < 0 || ts->tv_sec > 100000000 || + ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000) + return (EINVAL); + return (0); +} + +/* * Check that a proposed value to load into the .it_value or * .it_interval part of an interval timer is acceptable. */ |