diff options
author | dyson <dyson@FreeBSD.org> | 1997-07-06 02:40:43 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1997-07-06 02:40:43 +0000 |
commit | 532dea9042abf44b0a21290e3e3e16fba10a32f7 (patch) | |
tree | 146db6ef5fca639767cd3930dc626eb15ba19366 /sys/kern/kern_threads.c | |
parent | 31a3731a3f467232acb34d2bb58c8a652018afd6 (diff) | |
download | FreeBSD-src-532dea9042abf44b0a21290e3e3e16fba10a32f7.zip FreeBSD-src-532dea9042abf44b0a21290e3e3e16fba10a32f7.tar.gz |
This is an upgrade so that the kernel supports the AIO calls from
POSIX.4. Additionally, there is some initial code that supports LIO.
This code supports AIO/LIO for all types of file descriptors, with
few if any restrictions. There will be a followup very soon that
will support significantly more efficient operation for VCHR type
files (raw.) This code is also dependent on some kernel features
that don't work under SMP yet. After I commit the changes to the
kernel to support proper address space sharing on SMP, this code
will also work under SMP.
Diffstat (limited to 'sys/kern/kern_threads.c')
-rw-r--r-- | sys/kern/kern_threads.c | 44 |
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); |