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/libpthread/thread/thr_kern.c | |
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/libpthread/thread/thr_kern.c')
-rw-r--r-- | lib/libpthread/thread/thr_kern.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index 54d9dd7..815f04d 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/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 |