diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-01-08 01:48:51 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-01-08 01:48:51 +0000 |
commit | 4c4f33983827d1da23453594c50654560d6dd725 (patch) | |
tree | d0c455616764c94468a7a9e2a8a58f6d891b59a6 /lib | |
parent | 8cadc45453d8b5d8b6d25bf6960b7053dc7bbb97 (diff) | |
download | FreeBSD-src-4c4f33983827d1da23453594c50654560d6dd725.zip FreeBSD-src-4c4f33983827d1da23453594c50654560d6dd725.tar.gz |
Try to reduce total time needed for suspending all threads,
first broadcast signals to all threads, then enter a wait loop.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libthr/thread/thr_suspend_np.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/libthr/thread/thr_suspend_np.c b/lib/libthr/thread/thr_suspend_np.c index b22a736..cc424f9 100644 --- a/lib/libthr/thread/thr_suspend_np.c +++ b/lib/libthr/thread/thr_suspend_np.c @@ -76,21 +76,33 @@ _pthread_suspend_all_np(void) struct pthread *thread; int ret; -restart: THREAD_LIST_LOCK(curthread); TAILQ_FOREACH(thread, &_thread_list, tle) { if (thread != curthread) { THR_THREAD_LOCK(curthread, thread); + if (thread->state != PS_DEAD && + !(thread->flags & THR_FLAGS_SUSPENDED)) + thread->flags |= THR_FLAGS_NEED_SUSPEND; + THR_THREAD_UNLOCK(curthread, thread); + } + } + thr_kill(-1, SIGCANCEL); + +restart: + TAILQ_FOREACH(thread, &_thread_list, tle) { + if (thread != curthread) { /* First try to suspend the thread without waiting */ + THR_THREAD_LOCK(curthread, thread); ret = suspend_common(curthread, thread, 0); if (ret == 0) { - /* Can not suspended, try to wait */ + /* Can not suspend, try to wait */ thread->refcount++; THREAD_LIST_UNLOCK(curthread); suspend_common(curthread, thread, 1); THR_THREAD_UNLOCK(curthread, thread); - _thr_ref_delete(curthread, thread); + THREAD_LIST_LOCK(curthread); + _thr_ref_delete_unlocked(curthread, thread); /* * Because we were blocked, things may have * been changed, we have to restart the @@ -114,13 +126,14 @@ suspend_common(struct pthread *curthread, struct pthread *thread, while (thread->state != PS_DEAD && !(thread->flags & THR_FLAGS_SUSPENDED)) { thread->flags |= THR_FLAGS_NEED_SUSPEND; + THR_THREAD_UNLOCK(curthread, thread); _thr_send_sig(thread, SIGCANCEL); if (waitok) { tmp = thread->cycle; - THR_THREAD_UNLOCK(curthread, thread); _thr_umtx_wait(&thread->cycle, tmp, NULL); THR_THREAD_LOCK(curthread, thread); } else { + THR_THREAD_LOCK(curthread, thread); return (0); } } |