diff options
author | davidxu <davidxu@FreeBSD.org> | 2003-09-29 06:25:04 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2003-09-29 06:25:04 +0000 |
commit | a0841bce6f6fa62d2ff56a02b7566c1d4c08da86 (patch) | |
tree | 64fa40925848fc9ecdd4d95ba5418861dff540a8 /lib | |
parent | 921b5057a6283feba768192daa0f779a260e8078 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | lib/libkse/thread/thr_kern.c | 13 | ||||
-rw-r--r-- | lib/libpthread/thread/thr_kern.c | 13 |
2 files changed, 26 insertions, 0 deletions
diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index 68d533e..167700c 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/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"); 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"); |