summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2004-03-27 14:30:43 +0000
committermtm <mtm@FreeBSD.org>2004-03-27 14:30:43 +0000
commitadb111ed69292eafc661e12b3c5d2f896c4ed0f4 (patch)
tree9c17af5f370619a122d8ae2a80b0fb91ab84efc2
parentd0f528517f0489962410016e9c56667312efb492 (diff)
downloadFreeBSD-src-adb111ed69292eafc661e12b3c5d2f896c4ed0f4.zip
FreeBSD-src-adb111ed69292eafc661e12b3c5d2f896c4ed0f4.tar.gz
Separate thread synchronization from signals in libthr. Instead
use msleep() and wakeup_one(). Discussed with: jhb, peter, tjr
-rw-r--r--sys/compat/freebsd32/syscalls.master2
-rw-r--r--sys/kern/kern_thr.c61
-rw-r--r--sys/kern/syscalls.master2
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/sys/thr.h2
5 files changed, 68 insertions, 0 deletions
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 42e98f2..c6e9550 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -604,3 +604,5 @@
439 UNIMPL extattr_list_link
440 UNIMPL kse_switchin
441 UNIMPL ksem_timedwait
+442 MNOPROTO { int thr_suspend(const struct timespec *timeout); }
+443 MNOPROTO { int thr_wake(thr_id_t id); }
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index eef25ac..24aaaac 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 ceddb97..a5380b6 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
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 0534b87..e067d3c 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -356,6 +356,7 @@ struct thread {
#define TDF_NEEDSIGCHK 0x020000 /* Thread may need signal delivery. */
#define TDF_SA 0x040000 /* A scheduler activation based thread. */
#define TDF_UMTXWAKEUP 0x080000 /* Libthr thread must not sleep on a umtx. */
+#define TDF_THRWAKEUP 0x100000 /* Libthr thread must not suspend itself. */
#define TDF_DEADLKTREAT 0x800000 /* Lock aquisition - deadlock treatment. */
/* "private" flags kept in td_pflags */
diff --git a/sys/sys/thr.h b/sys/sys/thr.h
index 9869ce3..cd0e732 100644
--- a/sys/sys/thr.h
+++ b/sys/sys/thr.h
@@ -46,6 +46,8 @@ int thr_create(ucontext_t *ctx, thr_id_t *id, int flags);
int thr_self(thr_id_t *id);
void thr_exit(void);
int thr_kill(thr_id_t id, int sig);
+int thr_suspend(const struct timespec *timeout);
+int thr_wake(thr_id_t id);
#endif /* !_KERNEL */
OpenPOWER on IntegriCloud