summaryrefslogtreecommitdiffstats
path: root/lib/libpthread
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-09-29 06:25:04 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-09-29 06:25:04 +0000
commita0841bce6f6fa62d2ff56a02b7566c1d4c08da86 (patch)
tree64fa40925848fc9ecdd4d95ba5418861dff540a8 /lib/libpthread
parent921b5057a6283feba768192daa0f779a260e8078 (diff)
downloadFreeBSD-src-a0841bce6f6fa62d2ff56a02b7566c1d4c08da86.zip
FreeBSD-src-a0841bce6f6fa62d2ff56a02b7566c1d4c08da86.tar.gz
When concurrency level is reduced and a kse is exiting, make sure no other
threads are still referencing the kse by migrating them to initial kse. Reviewed by: deischen
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/thread/thr_kern.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c
index 68d533e..167700c 100644
--- a/lib/libpthread/thread/thr_kern.c
+++ b/lib/libpthread/thread/thr_kern.c
@@ -1805,6 +1805,7 @@ kse_fini(struct kse *kse)
{
/* struct kse_group *free_kseg = NULL; */
struct timespec ts;
+ struct pthread *td;
/*
* Check to see if this is one of the main kses.
@@ -1844,10 +1845,22 @@ kse_fini(struct kse *kse)
KSE_SCHED_LOCK(kse, kse->k_kseg);
TAILQ_REMOVE(&kse->k_kseg->kg_kseq, kse, k_kgqe);
kse->k_kseg->kg_ksecount--;
+ /*
+ * Migrate thread to _kse_initial if its lastest
+ * kse it ran on is the kse.
+ */
+ td = TAILQ_FIRST(&kse->k_kseg->kg_threadq);
+ while (td != NULL) {
+ if (td->kse == kse)
+ td->kse = _kse_initial;
+ td = TAILQ_NEXT(td, kle);
+ }
KSE_SCHED_UNLOCK(kse, kse->k_kseg);
KSE_LOCK_ACQUIRE(kse, &kse_lock);
kse_free_unlocked(kse);
KSE_LOCK_RELEASE(kse, &kse_lock);
+ /* Make sure there is always at least one is awake */
+ KSE_WAKEUP(_kse_initial);
kse_exit();
/* Never returns. */
PANIC("kse_exit() failed for initial kseg");
OpenPOWER on IntegriCloud