aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMike Makonnen <mtm@FreeBSD.org>2004-03-27 14:30:43 +0000
committerMike Makonnen <mtm@FreeBSD.org>2004-03-27 14:30:43 +0000
commit1713a5166114266306e1432c4859e94ac60268ec (patch)
tree9c17af5f370619a122d8ae2a80b0fb91ab84efc2 /sys/kern
parent9af414d15680e83e60cab977e43c239cce6264de (diff)
Notes
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_thr.c61
-rw-r--r--sys/kern/syscalls.master2
2 files changed, 63 insertions, 0 deletions
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index eef25acbdf88..24aaaac02751 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -254,3 +254,64 @@ out:
PROC_UNLOCK(p);
return (error);
}
+
+int
+thr_suspend(struct thread *td, struct thr_suspend_args *uap)
+ /* const struct timespec *timeout */
+{
+ struct timespec ts;
+ struct timeval tv;
+ int error;
+ int hz;
+
+ hz = 0;
+ error = 0;
+ if (uap->timeout != NULL) {
+ error = copyin((const void *)uap->timeout, (void *)&ts,
+ sizeof(struct timespec));
+ if (error != 0)
+ return (error);
+ if (ts.tv_nsec < 0 || ts.tv_nsec > 1000000000)
+ return (EINVAL);
+ if (ts.tv_sec == 0 && ts.tv_nsec == 0)
+ return (ETIMEDOUT);
+ TIMESPEC_TO_TIMEVAL(&tv, &ts);
+ hz = tvtohz(&tv);
+ }
+ PROC_LOCK(td->td_proc);
+ mtx_lock_spin(&sched_lock);
+ if ((td->td_flags & TDF_THRWAKEUP) == 0) {
+ mtx_unlock_spin(&sched_lock);
+ error = msleep((void *)td, &td->td_proc->p_mtx,
+ td->td_priority | PCATCH, "lthr", hz);
+ mtx_lock_spin(&sched_lock);
+ }
+ td->td_flags &= ~TDF_THRWAKEUP;
+ mtx_unlock_spin(&sched_lock);
+ PROC_UNLOCK(td->td_proc);
+ return (error == EWOULDBLOCK ? ETIMEDOUT : error);
+}
+
+int
+thr_wake(struct thread *td, struct thr_wake_args *uap)
+ /* thr_id_t id */
+{
+ struct thread *tdsleeper, *ttd;
+
+ tdsleeper = ((struct thread *)uap->id);
+ PROC_LOCK(tdsleeper->td_proc);
+ FOREACH_THREAD_IN_PROC(tdsleeper->td_proc, ttd) {
+ if (ttd == tdsleeper)
+ break;
+ }
+ if (ttd == NULL) {
+ PROC_UNLOCK(tdsleeper->td_proc);
+ return (ESRCH);
+ }
+ mtx_lock_spin(&sched_lock);
+ tdsleeper->td_flags |= TDF_THRWAKEUP;
+ mtx_unlock_spin(&sched_lock);
+ wakeup_one((void *)tdsleeper);
+ PROC_UNLOCK(tdsleeper->td_proc);
+ return (0);
+}
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index ceddb974ef15..a5380b6c0af7 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -629,5 +629,7 @@
440 MSTD { int kse_switchin(const struct __mcontext *mcp, \
long val, long *loc); }
441 MNOSTD { int ksem_timedwait(semid_t id, struct timespec *abstime); }
+442 MSTD { int thr_suspend(const struct timespec *timeout); }
+443 MSTD { int thr_wake(thr_id_t id); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master