thr_suspend_np.c revision 113658
1178172Simp/* 2178172Simp * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. 3178172Simp * All rights reserved. 4178172Simp * 5178172Simp * Redistribution and use in source and binary forms, with or without 6178172Simp * modification, are permitted provided that the following conditions 7178172Simp * are met: 8178172Simp * 1. Redistributions of source code must retain the above copyright 9178172Simp * notice, this list of conditions and the following disclaimer. 10178172Simp * 2. Redistributions in binary form must reproduce the above copyright 11178172Simp * notice, this list of conditions and the following disclaimer in the 12178172Simp * documentation and/or other materials provided with the distribution. 13178172Simp * 3. All advertising materials mentioning features or use of this software 14178172Simp * must display the following acknowledgement: 15178172Simp * This product includes software developed by John Birrell. 16178172Simp * 4. Neither the name of the author nor the names of any co-contributors 17178172Simp * may be used to endorse or promote products derived from this software 18178172Simp * without specific prior written permission. 19178172Simp * 20178172Simp * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 21178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23178172Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28178172Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30178172Simp * SUCH DAMAGE. 31178172Simp * 32178172Simp * $FreeBSD: head/lib/libkse/thread/thr_suspend_np.c 113658 2003-04-18 05:04:16Z deischen $ 33178172Simp */ 34178172Simp#include <errno.h> 35178172Simp#include <pthread.h> 36178172Simp#include "thr_private.h" 37178172Simp 38178172Simpstatic void suspend_common(struct pthread *thread); 39178172Simp 40178172Simp__weak_reference(_pthread_suspend_np, pthread_suspend_np); 41178172Simp__weak_reference(_pthread_suspend_all_np, pthread_suspend_all_np); 42232449Sjmallett 43232449Sjmallett/* Suspend a thread: */ 44232449Sjmallettint 45232449Sjmallett_pthread_suspend_np(pthread_t thread) 46178172Simp{ 47178172Simp struct pthread *curthread = _get_curthread(); 48178172Simp int ret; 49178172Simp 50178172Simp /* Suspending the current thread doesn't make sense. */ 51178172Simp if (thread == _get_curthread()) 52178172Simp ret = EDEADLK; 53178172Simp 54178172Simp /* Add a reference to the thread: */ 55211862Sjchandra else if ((ret = _thr_ref_add(curthread, thread, /*include dead*/0)) 56211862Sjchandra == 0) { 57178172Simp /* Lock the threads scheduling queue: */ 58178172Simp THR_SCHED_LOCK(curthread, thread); 59178172Simp 60202031Simp suspend_common(thread); 61211862Sjchandra 62178172Simp /* Unlock the threads scheduling queue: */ 63232449Sjmallett THR_SCHED_UNLOCK(curthread, thread); 64232449Sjmallett 65232449Sjmallett /* Don't forget to remove the reference: */ 66232449Sjmallett _thr_ref_delete(curthread, thread); 67232449Sjmallett } 68232449Sjmallett return (ret); 69232449Sjmallett} 70232449Sjmallett 71232449Sjmallettvoid 72232449Sjmallett_pthread_suspend_all_np(void) 73232449Sjmallett{ 74232449Sjmallett struct pthread *curthread = _get_curthread(); 75232449Sjmallett struct pthread *thread; 76232584Sjmallett kse_critical_t crit; 77232449Sjmallett 78232449Sjmallett /* Take the thread list lock: */ 79232449Sjmallett crit = _kse_critical_enter(); 80232449Sjmallett KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock); 81232449Sjmallett 82232449Sjmallett TAILQ_FOREACH(thread, &_thread_list, tle) { 83232449Sjmallett if ((thread != curthread) && 84232449Sjmallett (thread->state != PS_DEAD) && 85232449Sjmallett (thread->state != PS_DEADLOCK) && 86232449Sjmallett ((thread->flags & THR_FLAGS_EXITING) == 0)) { 87232449Sjmallett THR_SCHED_LOCK(curthread, thread); 88178172Simp suspend_common(thread); 89232449Sjmallett THR_SCHED_UNLOCK(curthread, thread); 90178172Simp } 91204557Simp } 92204557Simp 93204557Simp /* Release the thread list lock: */ 94202031Simp KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock); 95204557Simp _kse_critical_leave(crit); 96202031Simp} 97204557Simp 98178172Simpvoid 99178172Simpsuspend_common(struct pthread *thread) 100202031Simp{ 101178172Simp thread->flags |= THR_FLAGS_SUSPENDED; 102178172Simp if (thread->flags & THR_FLAGS_IN_RUNQ) { 103178172Simp THR_RUNQ_REMOVE(thread); 104178172Simp THR_SET_STATE(thread, PS_SUSPENDED); 105178172Simp } 106178172Simp} 107178172Simp