summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_threads.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-07-06 02:40:43 +0000
committerdyson <dyson@FreeBSD.org>1997-07-06 02:40:43 +0000
commit532dea9042abf44b0a21290e3e3e16fba10a32f7 (patch)
tree146db6ef5fca639767cd3930dc626eb15ba19366 /sys/kern/kern_threads.c
parent31a3731a3f467232acb34d2bb58c8a652018afd6 (diff)
downloadFreeBSD-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.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