summaryrefslogtreecommitdiffstats
path: root/lib/libpthread
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2003-05-04 16:17:01 +0000
committerdeischen <deischen@FreeBSD.org>2003-05-04 16:17:01 +0000
commitca059a5aeaae9d5813d714fca45f1aad81e33e85 (patch)
tree3d8c66d5e73ff5869e8a7e1754ef39d0b512e848 /lib/libpthread
parent03349278af97760ebfaacb5221dad9cb7aff9b88 (diff)
downloadFreeBSD-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')
-rw-r--r--lib/libpthread/thread/thr_create.c4
-rw-r--r--lib/libpthread/thread/thr_kern.c44
-rw-r--r--lib/libpthread/thread/thr_private.h5
-rw-r--r--lib/libpthread/thread/thr_resume_np.c23
-rw-r--r--lib/libpthread/thread/thr_sig.c9
-rw-r--r--lib/libpthread/thread/thr_suspend_np.c5
6 files changed, 47 insertions, 43 deletions
diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c
index 0c9edbd..4cc1b6c 100644
--- a/lib/libpthread/thread/thr_create.c
+++ b/lib/libpthread/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/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
diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h
index 22d2445..f1b7fd9 100644
--- a/lib/libpthread/thread/thr_private.h
+++ b/lib/libpthread/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/libpthread/thread/thr_resume_np.c b/lib/libpthread/thread/thr_resume_np.c
index ceb2cde..1276311 100644
--- a/lib/libpthread/thread/thr_resume_np.c
+++ b/lib/libpthread/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/libpthread/thread/thr_sig.c b/lib/libpthread/thread/thr_sig.c
index cd699db..ba31073 100644
--- a/lib/libpthread/thread/thr_sig.c
+++ b/lib/libpthread/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/libpthread/thread/thr_suspend_np.c b/lib/libpthread/thread/thr_suspend_np.c
index 7530dd0..4813de1 100644
--- a/lib/libpthread/thread/thr_suspend_np.c
+++ b/lib/libpthread/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)
/* ??? */
OpenPOWER on IntegriCloud