summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_threads.c')
-rw-r--r--sys/kern/kern_threads.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/sys/kern/kern_threads.c b/sys/kern/kern_threads.c
index 30e15c9..1e0b659 100644
--- a/sys/kern/kern_threads.c
+++ b/sys/kern/kern_threads.c
@@ -46,7 +46,7 @@
* in Germany will I accept domestic beer. This code may or may not work
* and I certainly make no claims as to its fitness for *any* purpose.
*
- * $Id$
+ * $Id: kern_threads.c,v 1.1 1997/06/16 00:27:26 dyson Exp $
*/
#include <sys/param.h>
@@ -80,13 +80,12 @@
*/
int
thr_sleep(struct proc *p, struct thr_sleep_args *uap, int *retval) {
- int sleepStart;
- long long sleeptime;
- int sleepclocks;
+ int sleepstart;
struct timespec ts;
- int error;
+ struct timeval atv, utv;
+ int error, s, timo;
- sleepclocks = 0;
+ timo = 0;
if (uap->timeout != 0) {
/*
* Get timespec struct
@@ -95,24 +94,33 @@ thr_sleep(struct proc *p, struct thr_sleep_args *uap, int *retval) {
p->p_wakeup = 0;
return error;
}
- sleeptime = (long long) (hz * ts.tv_nsec);
- sleeptime /= 1000000000LL;
- sleeptime += ts.tv_sec * hz;
- sleepclocks = sleeptime;
- if (sleepclocks != sleeptime) {
+ if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000) {
p->p_wakeup = 0;
- retval[0] = EINVAL;
- return 0;
+ return (EINVAL);
+ }
+ TIMESPEC_TO_TIMEVAL(&atv, &ts)
+ if (itimerfix(&atv)) {
+ p->p_wakeup = 0;
+ return (EINVAL);
}
- if (sleepclocks == 0)
- sleepclocks = 1;
+
+ /*
+ * XXX this is not as careful as settimeofday() about minimising
+ * interrupt latency. The hzto() interface is inconvenient as usual.
+ */
+ s = splclock();
+ timevaladd(&atv, &time);
+ timo = hzto(&atv);
+ splx(s);
+ if (timo == 0)
+ timo = 1;
}
retval[0] = 0;
if (p->p_wakeup == 0) {
- sleepStart = ticks;
+ sleepstart = ticks;
p->p_flag |= P_SINTR;
- error = tsleep(p, PUSER, "thrslp", sleepclocks);
+ error = tsleep(p, PUSER, "thrslp", timo);
p->p_flag &= ~P_SINTR;
if (error == EWOULDBLOCK) {
p->p_wakeup = 0;
@@ -120,7 +128,7 @@ thr_sleep(struct proc *p, struct thr_sleep_args *uap, int *retval) {
return 0;
}
if (uap->timeout == 0)
- retval[0] = ticks - sleepStart;
+ retval[0] = ticks - sleepstart;
}
p->p_wakeup = 0;
return (0);
OpenPOWER on IntegriCloud