diff options
author | David Xu <davidxu@FreeBSD.org> | 2003-02-20 08:18:15 +0000 |
---|---|---|
committer | David Xu <davidxu@FreeBSD.org> | 2003-02-20 08:18:15 +0000 |
commit | eb117d5cb06e941bf9b91687966063db4750edbc (patch) | |
tree | 401288c5feee9a5b4aefd2c3518465123a82a17e /sys/kern | |
parent | 344c6212b8fa09d0c5175db2ab6a50703cf45f10 (diff) | |
download | src-eb117d5cb06e941bf9b91687966063db4750edbc.tar.gz src-eb117d5cb06e941bf9b91687966063db4750edbc.zip |
Add a timeout parameter to kse_release.
Notes
Notes:
svn path=/head/; revision=111169
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/init_sysent.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_kse.c | 38 | ||||
-rw-r--r-- | sys/kern/kern_thread.c | 38 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 2 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 2 |
5 files changed, 58 insertions, 26 deletions
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 0c22f981314e..22dfec8c7387 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.140 2003/01/04 11:41:12 davidxu Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.143 2003/01/26 20:09:34 alfred Exp */ #include "opt_compat.h" @@ -411,7 +411,7 @@ struct sysent sysent[] = { { SYF_MPSAFE | AS(kse_wakeup_args), (sy_call_t *)kse_wakeup }, /* 380 = kse_wakeup */ { AS(kse_create_args), (sy_call_t *)kse_create }, /* 381 = kse_create */ { SYF_MPSAFE | AS(kse_thr_interrupt_args), (sy_call_t *)kse_thr_interrupt }, /* 382 = kse_thr_interrupt */ - { SYF_MPSAFE | 0, (sy_call_t *)kse_release }, /* 383 = kse_release */ + { SYF_MPSAFE | AS(kse_release_args), (sy_call_t *)kse_release }, /* 383 = kse_release */ { SYF_MPSAFE | AS(__mac_get_proc_args), (sy_call_t *)__mac_get_proc }, /* 384 = __mac_get_proc */ { SYF_MPSAFE | AS(__mac_set_proc_args), (sy_call_t *)__mac_set_proc }, /* 385 = __mac_set_proc */ { SYF_MPSAFE | AS(__mac_get_fd_args), (sy_call_t *)__mac_get_fd }, /* 386 = __mac_get_fd */ diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index fc021ac2ec43..7bd1c29346d4 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -465,7 +465,7 @@ kse_exit(struct thread *td, struct kse_exit_args *uap) */ /* struct kse_release_args { - register_t dummy; + struct timespec *timeout; }; */ int @@ -473,6 +473,9 @@ kse_release(struct thread *td, struct kse_release_args *uap) { struct proc *p; struct ksegrp *kg; + struct timespec ts, ts2, ts3, timeout; + struct timeval tv; + int error; p = td->td_proc; kg = td->td_ksegrp; @@ -483,25 +486,38 @@ kse_release(struct thread *td, struct kse_release_args *uap) if ((td->td_mailbox != NULL) || (td->td_ksegrp->kg_numupcalls == 0)) return (EINVAL); KASSERT((td->td_upcall != NULL), ("%s: not own an upcall", __func__)); - - PROC_LOCK(p); + if (uap->timeout != NULL) { + if ((error = copyin(uap->timeout, &timeout, sizeof(timeout)))) + return (error); + getnanouptime(&ts); + timespecadd(&ts, &timeout); + TIMESPEC_TO_TIMEVAL(&tv, &timeout); + } mtx_lock_spin(&sched_lock); /* Change OURSELF to become an upcall. */ td->td_flags = TDF_UPCALLING; if (p->p_sflag & PS_NEEDSIGCHK) td->td_flags |= TDF_ASTPENDING; - if ((td->td_upcall->ku_flags & KUF_DOUPCALL) == 0 && - (kg->kg_completed == NULL)) { + mtx_unlock_spin(&sched_lock); + PROC_LOCK(p); + while ((td->td_upcall->ku_flags & KUF_DOUPCALL) == 0 && + (kg->kg_completed == NULL)) { kg->kg_upsleeps++; - mtx_unlock_spin(&sched_lock); - msleep(&kg->kg_completed, &p->p_mtx, PPAUSE|PCATCH, "ksepause", - NULL); + error = msleep(&kg->kg_completed, &p->p_mtx, PPAUSE|PCATCH, + "kse_rel", (uap->timeout ? tvtohz(&tv) : 0)); kg->kg_upsleeps--; PROC_UNLOCK(p); - } else { - mtx_unlock_spin(&sched_lock); - PROC_UNLOCK(p); + if (uap->timeout == NULL || error != EWOULDBLOCK) + return (0); + getnanouptime(&ts2); + if (timespeccmp(&ts2, &ts, >=)) + return (0); + ts3 = ts; + timespecsub(&ts3, &ts2); + TIMESPEC_TO_TIMEVAL(&tv, &ts3); + PROC_LOCK(p); } + PROC_UNLOCK(p); return (0); } diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index fc021ac2ec43..7bd1c29346d4 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -465,7 +465,7 @@ kse_exit(struct thread *td, struct kse_exit_args *uap) */ /* struct kse_release_args { - register_t dummy; + struct timespec *timeout; }; */ int @@ -473,6 +473,9 @@ kse_release(struct thread *td, struct kse_release_args *uap) { struct proc *p; struct ksegrp *kg; + struct timespec ts, ts2, ts3, timeout; + struct timeval tv; + int error; p = td->td_proc; kg = td->td_ksegrp; @@ -483,25 +486,38 @@ kse_release(struct thread *td, struct kse_release_args *uap) if ((td->td_mailbox != NULL) || (td->td_ksegrp->kg_numupcalls == 0)) return (EINVAL); KASSERT((td->td_upcall != NULL), ("%s: not own an upcall", __func__)); - - PROC_LOCK(p); + if (uap->timeout != NULL) { + if ((error = copyin(uap->timeout, &timeout, sizeof(timeout)))) + return (error); + getnanouptime(&ts); + timespecadd(&ts, &timeout); + TIMESPEC_TO_TIMEVAL(&tv, &timeout); + } mtx_lock_spin(&sched_lock); /* Change OURSELF to become an upcall. */ td->td_flags = TDF_UPCALLING; if (p->p_sflag & PS_NEEDSIGCHK) td->td_flags |= TDF_ASTPENDING; - if ((td->td_upcall->ku_flags & KUF_DOUPCALL) == 0 && - (kg->kg_completed == NULL)) { + mtx_unlock_spin(&sched_lock); + PROC_LOCK(p); + while ((td->td_upcall->ku_flags & KUF_DOUPCALL) == 0 && + (kg->kg_completed == NULL)) { kg->kg_upsleeps++; - mtx_unlock_spin(&sched_lock); - msleep(&kg->kg_completed, &p->p_mtx, PPAUSE|PCATCH, "ksepause", - NULL); + error = msleep(&kg->kg_completed, &p->p_mtx, PPAUSE|PCATCH, + "kse_rel", (uap->timeout ? tvtohz(&tv) : 0)); kg->kg_upsleeps--; PROC_UNLOCK(p); - } else { - mtx_unlock_spin(&sched_lock); - PROC_UNLOCK(p); + if (uap->timeout == NULL || error != EWOULDBLOCK) + return (0); + getnanouptime(&ts2); + if (timespeccmp(&ts2, &ts, >=)) + return (0); + ts3 = ts; + timespecsub(&ts3, &ts2); + TIMESPEC_TO_TIMEVAL(&tv, &ts3); + PROC_LOCK(p); } + PROC_UNLOCK(p); return (0); } diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 62c90f554618..0a61dadb64ef 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.140 2003/01/04 11:41:12 davidxu Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.143 2003/01/26 20:09:34 alfred Exp */ const char *syscallnames[] = { diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 1cca3bd361bc..10981a0cf8b9 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -555,7 +555,7 @@ 381 STD BSD { int kse_create(struct kse_mailbox *mbx, \ int newgroup); } 382 MSTD BSD { int kse_thr_interrupt(struct kse_thr_mailbox *tmbx); } -383 MSTD BSD { int kse_release(void); } +383 MSTD BSD { int kse_release(struct timespec *timeout); } 384 MSTD BSD { int __mac_get_proc(struct mac *mac_p); } 385 MSTD BSD { int __mac_set_proc(struct mac *mac_p); } 386 MSTD BSD { int __mac_get_fd(int fd, struct mac *mac_p); } |