summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortanimura <tanimura@FreeBSD.org>2002-07-30 10:12:11 +0000
committertanimura <tanimura@FreeBSD.org>2002-07-30 10:12:11 +0000
commitbc06c086d90619821468298585e079c8e4bb00d8 (patch)
tree6cffc87dd24add379660621fde853c6bca98ed93
parentb1cd18ff699cd07fc243c1fe1439a3ab978e622a (diff)
downloadFreeBSD-src-bc06c086d90619821468298585e079c8e4bb00d8.zip
FreeBSD-src-bc06c086d90619821468298585e079c8e4bb00d8.tar.gz
In endtsleep() and cv_timedwait_end(), a thread marked TDF_TIMEOUT may
be swapped out. Do not put such the thread directly back to the run queue. Spotted by: David Xu <davidx@viasoft.com.cn> While I am here, s/PS_TIMEOUT/TDF_TIMEOUT/.
-rw-r--r--sys/kern/kern_condvar.c11
-rw-r--r--sys/kern/kern_synch.c13
2 files changed, 21 insertions, 3 deletions
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c
index 55fba60..1a99686 100644
--- a/sys/kern/kern_condvar.c
+++ b/sys/kern/kern_condvar.c
@@ -612,7 +612,16 @@ cv_timedwait_end(void *arg)
mtx_lock_spin(&sched_lock);
if (td->td_flags & TDF_TIMEOUT) {
td->td_flags &= ~TDF_TIMEOUT;
- setrunqueue(td);
+ if (td->td_proc->p_sflag & PS_INMEM) {
+ setrunqueue(td);
+ maybe_resched(td);
+ } else {
+ td->td_state = TDS_SWAPPED;
+ if ((td->td_proc->p_sflag & PS_SWAPPINGIN) == 0) {
+ td->td_proc->p_sflag |= PS_SWAPINREQ;
+ wakeup(&proc0);
+ }
+ }
} else if (td->td_wchan != NULL) {
if (td->td_state == TDS_SLP) /* XXXKSE */
setrunnable(td);
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 9e60459..e32a681 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -621,12 +621,21 @@ endtsleep(arg)
mtx_lock_spin(&sched_lock);
/*
* This is the other half of the synchronization with msleep()
- * described above. If the PS_TIMEOUT flag is set, we lost the
+ * described above. If the TDS_TIMEOUT flag is set, we lost the
* race and just need to put the process back on the runqueue.
*/
if ((td->td_flags & TDF_TIMEOUT) != 0) {
td->td_flags &= ~TDF_TIMEOUT;
- setrunqueue(td);
+ if (td->td_proc->p_sflag & PS_INMEM) {
+ setrunqueue(td);
+ maybe_resched(td);
+ } else {
+ td->td_state = TDS_SWAPPED;
+ if ((td->td_proc->p_sflag & PS_SWAPPINGIN) == 0) {
+ td->td_proc->p_sflag |= PS_SWAPINREQ;
+ wakeup(&proc0);
+ }
+ }
} else if (td->td_wchan != NULL) {
if (td->td_state == TDS_SLP) /* XXXKSE */
setrunnable(td);
OpenPOWER on IntegriCloud