diff options
author | deischen <deischen@FreeBSD.org> | 2003-05-04 16:17:01 +0000 |
---|---|---|
committer | deischen <deischen@FreeBSD.org> | 2003-05-04 16:17:01 +0000 |
commit | ca059a5aeaae9d5813d714fca45f1aad81e33e85 (patch) | |
tree | 3d8c66d5e73ff5869e8a7e1754ef39d0b512e848 /lib/libkse/thread | |
parent | 03349278af97760ebfaacb5221dad9cb7aff9b88 (diff) | |
download | FreeBSD-src-ca059a5aeaae9d5813d714fca45f1aad81e33e85.zip FreeBSD-src-ca059a5aeaae9d5813d714fca45f1aad81e33e85.tar.gz |
Fix suspend and resume.
Submitted (in part) by: Kazuaki Oda <kaakun@highway.ne.jp>
Diffstat (limited to 'lib/libkse/thread')
-rw-r--r-- | lib/libkse/thread/thr_create.c | 4 | ||||
-rw-r--r-- | lib/libkse/thread/thr_kern.c | 44 | ||||
-rw-r--r-- | lib/libkse/thread/thr_private.h | 5 | ||||
-rw-r--r-- | lib/libkse/thread/thr_resume_np.c | 23 | ||||
-rw-r--r-- | lib/libkse/thread/thr_sig.c | 9 | ||||
-rw-r--r-- | lib/libkse/thread/thr_suspend_np.c | 5 |
6 files changed, 47 insertions, 43 deletions
diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c index 0c9edbd..4cc1b6c 100644 --- a/lib/libkse/thread/thr_create.c +++ b/lib/libkse/thread/thr_create.c @@ -259,8 +259,10 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, new_thread->flags = 0; new_thread->continuation = NULL; - if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) + if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { new_thread->state = PS_SUSPENDED; + new_thread->flags = THR_FLAGS_SUSPENDED; + } else new_thread->state = PS_RUNNING; diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index 54d9dd7..815f04d 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -914,10 +914,6 @@ kse_sched_multi(struct kse *curkse) signalcontext(&curthread->tmbx.tm_context, 0, (__sighandler_t *)thr_resume_wrapper); #endif -#ifdef GS_HACK - /* XXX - The kernel sometimes forgets to restore %gs properly. */ - _ksd_setprivate(&curkse->k_ksd); -#endif /* * Continue the thread at its current frame: */ @@ -1259,8 +1255,12 @@ kse_check_completed(struct kse *kse) thread, (thread->name == NULL) ? "none" : thread->name); thread->blocked = 0; - if (thread != kse->k_curthread) - KSE_RUNQ_INSERT_TAIL(kse, thread); + if (thread != kse->k_curthread) { + if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) + THR_SET_STATE(thread, PS_SUSPENDED); + else + KSE_RUNQ_INSERT_TAIL(kse, thread); + } completed = completed->tm_next; } } @@ -1293,8 +1293,12 @@ kse_check_waitq(struct kse *kse) pthread->timeout = 1; /* Add the thread to the priority queue: */ - THR_SET_STATE(pthread, PS_RUNNING); - KSE_RUNQ_INSERT_TAIL(kse, pthread); + if ((pthread->flags & THR_FLAGS_SUSPENDED) != 0) + THR_SET_STATE(pthread, PS_SUSPENDED); + else { + THR_SET_STATE(pthread, PS_RUNNING); + KSE_RUNQ_INSERT_TAIL(kse, pthread); + } } } @@ -1390,7 +1394,8 @@ kse_switchout_thread(struct kse *kse, struct pthread *thread) break; case PS_RUNNING: - /* Nothing to do here. */ + if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) + THR_SET_STATE(thread, PS_SUSPENDED); break; case PS_COND_WAIT: @@ -1662,16 +1667,23 @@ _thr_setrunnable(struct pthread *curthread, struct pthread *thread) void _thr_setrunnable_unlocked(struct pthread *thread) { - if ((thread->kseg->kg_flags & KGF_SINGLE_THREAD) != 0) + if ((thread->kseg->kg_flags & KGF_SINGLE_THREAD) != 0) { /* No silly queues for these threads. */ - THR_SET_STATE(thread, PS_RUNNING); - else if (thread->state != PS_RUNNING) { + if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) + THR_SET_STATE(thread, PS_SUSPENDED); + else + THR_SET_STATE(thread, PS_RUNNING); + }else if (thread->state != PS_RUNNING) { if ((thread->flags & THR_FLAGS_IN_WAITQ) != 0) KSE_WAITQ_REMOVE(thread->kse, thread); - THR_SET_STATE(thread, PS_RUNNING); - if ((thread->blocked == 0) && - (thread->flags & THR_FLAGS_IN_RUNQ) == 0) - THR_RUNQ_INSERT_TAIL(thread); + if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) + THR_SET_STATE(thread, PS_SUSPENDED); + else { + THR_SET_STATE(thread, PS_RUNNING); + if ((thread->blocked == 0) && + (thread->flags & THR_FLAGS_IN_RUNQ) == 0) + THR_RUNQ_INSERT_TAIL(thread); + } } /* * XXX - Threads are not yet assigned to specific KSEs; they are diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h index 22d2445..f1b7fd9 100644 --- a/lib/libkse/thread/thr_private.h +++ b/lib/libkse/thread/thr_private.h @@ -953,6 +953,11 @@ do { \ ((thrd)->kse != NULL) && ((thrd)->kse->k_curthread == (thrd)) #define THR_IN_SYNCQ(thrd) (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0) + +#define THR_IS_SUSPENDED(thrd) \ + (((thrd)->state == PS_SUSPENDED) || \ + (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0)) +#define THR_IS_EXITING(thrd) (((thrd)->flags & THR_FLAGS_EXITING) != 0) /* * Global variables for the pthread kernel. diff --git a/lib/libkse/thread/thr_resume_np.c b/lib/libkse/thread/thr_resume_np.c index ceb2cde..1276311 100644 --- a/lib/libkse/thread/thr_resume_np.c +++ b/lib/libkse/thread/thr_resume_np.c @@ -50,19 +50,10 @@ _pthread_resume_np(pthread_t thread) /* Add a reference to the thread: */ if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) == 0) { - /* Is it currently suspended? */ - if ((thread->flags & THR_FLAGS_SUSPENDED) != 0) { - /* Lock the threads scheduling queue: */ - THR_SCHED_LOCK(curthread, thread); - - if ((curthread->state != PS_DEAD) && - (curthread->state != PS_DEADLOCK) && - ((curthread->flags & THR_FLAGS_EXITING) != 0)) - resume_common(thread); - - /* Unlock the threads scheduling queue: */ - THR_SCHED_UNLOCK(curthread, thread); - } + /* Lock the threads scheduling queue: */ + THR_SCHED_LOCK(curthread, thread); + resume_common(thread); + THR_SCHED_UNLOCK(curthread, thread); _thr_ref_delete(curthread, thread); } return (ret); @@ -80,11 +71,7 @@ _pthread_resume_all_np(void) KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); TAILQ_FOREACH(thread, &_thread_list, tle) { - if ((thread != curthread) && - ((thread->flags & THR_FLAGS_SUSPENDED) != 0) && - (thread->state != PS_DEAD) && - (thread->state != PS_DEADLOCK) && - ((thread->flags & THR_FLAGS_EXITING) == 0)) { + if (thread != curthread) { THR_SCHED_LOCK(curthread, thread); resume_common(thread); THR_SCHED_UNLOCK(curthread, thread); diff --git a/lib/libkse/thread/thr_sig.c b/lib/libkse/thread/thr_sig.c index cd699db..ba31073 100644 --- a/lib/libkse/thread/thr_sig.c +++ b/lib/libkse/thread/thr_sig.c @@ -316,11 +316,10 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info) } else if ((pthread->state == PS_DEAD) || (pthread->state == PS_DEADLOCK) || - ((pthread->flags & THR_FLAGS_EXITING) != 0)) + THR_IS_EXITING(pthread) || THR_IS_SUSPENDED(pthread)) ; /* Skip this thread. */ else if ((handler_installed != 0) && - !sigismember(&pthread->tmbx.tm_context.uc_sigmask, sig) && - ((pthread->flags & THR_FLAGS_SUSPENDED) == 0)) { + !sigismember(&pthread->tmbx.tm_context.uc_sigmask, sig)) { if (pthread->state == PS_SIGSUSPEND) { if (suspended_thread == NULL) suspended_thread = pthread; @@ -710,9 +709,7 @@ thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) * will run the signal handler when it is resumed. */ pthread->active_priority |= THR_SIGNAL_PRIORITY; - if ((pthread->flags & THR_FLAGS_SUSPENDED) != 0) - THR_SET_STATE(pthread, PS_SUSPENDED); - else if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) + if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) THR_RUNQ_INSERT_TAIL(pthread); } } diff --git a/lib/libkse/thread/thr_suspend_np.c b/lib/libkse/thread/thr_suspend_np.c index 7530dd0..4813de1 100644 --- a/lib/libkse/thread/thr_suspend_np.c +++ b/lib/libkse/thread/thr_suspend_np.c @@ -97,9 +97,10 @@ suspend_common(struct pthread *thread) (thread->state != PS_DEADLOCK) && ((thread->flags & THR_FLAGS_EXITING) == 0)) { thread->flags |= THR_FLAGS_SUSPENDED; - if ((thread->flags & THR_FLAGS_IN_RUNQ) != 0) + if ((thread->flags & THR_FLAGS_IN_RUNQ) != 0) { THR_RUNQ_REMOVE(thread); - THR_SET_STATE(thread, PS_SUSPENDED); + THR_SET_STATE(thread, PS_SUSPENDED); + } #ifdef NOT_YET if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) /* ??? */ |