kern_condvar.c (83658) | kern_condvar.c (87594) |
---|---|
1/*- 2 * Copyright (c) 2000 Jake Burkholder <jake@freebsd.org>. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2000 Jake Burkholder <jake@freebsd.org>. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/kern/kern_condvar.c 83658 2001-09-19 02:53:59Z peter $ | 26 * $FreeBSD: head/sys/kern/kern_condvar.c 87594 2001-12-10 05:51:45Z obrien $ |
27 */ 28 29#include "opt_ktrace.h" 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/lock.h> 34#include <sys/mutex.h> --- 7 unchanged lines hidden (view full) --- 42#include <sys/uio.h> 43#include <sys/ktrace.h> 44#endif 45 46/* 47 * Common sanity checks for cv_wait* functions. 48 */ 49#define CV_ASSERT(cvp, mp, td) do { \ | 27 */ 28 29#include "opt_ktrace.h" 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/lock.h> 34#include <sys/mutex.h> --- 7 unchanged lines hidden (view full) --- 42#include <sys/uio.h> 43#include <sys/ktrace.h> 44#endif 45 46/* 47 * Common sanity checks for cv_wait* functions. 48 */ 49#define CV_ASSERT(cvp, mp, td) do { \ |
50 KASSERT((td) != NULL, ("%s: curthread NULL", __FUNCTION__)); \ 51 KASSERT((td)->td_proc->p_stat == SRUN, ("%s: not SRUN", __FUNCTION__)); \ 52 KASSERT((cvp) != NULL, ("%s: cvp NULL", __FUNCTION__)); \ 53 KASSERT((mp) != NULL, ("%s: mp NULL", __FUNCTION__)); \ | 50 KASSERT((td) != NULL, ("%s: curthread NULL", __func__)); \ 51 KASSERT((td)->td_proc->p_stat == SRUN, ("%s: not SRUN", __func__)); \ 52 KASSERT((cvp) != NULL, ("%s: cvp NULL", __func__)); \ 53 KASSERT((mp) != NULL, ("%s: mp NULL", __func__)); \ |
54 mtx_assert((mp), MA_OWNED | MA_NOTRECURSED); \ 55} while (0) 56 57#ifdef CV_DEBUG 58#define CV_WAIT_VALIDATE(cvp, mp) do { \ 59 if (TAILQ_EMPTY(&(cvp)->cv_waitq)) { \ 60 /* Only waiter. */ \ 61 (cvp)->cv_mtx = (mp); \ 62 } else { \ 63 /* \ 64 * Other waiter; assert that we're using the \ 65 * same mutex. \ 66 */ \ 67 KASSERT((cvp)->cv_mtx == (mp), \ | 54 mtx_assert((mp), MA_OWNED | MA_NOTRECURSED); \ 55} while (0) 56 57#ifdef CV_DEBUG 58#define CV_WAIT_VALIDATE(cvp, mp) do { \ 59 if (TAILQ_EMPTY(&(cvp)->cv_waitq)) { \ 60 /* Only waiter. */ \ 61 (cvp)->cv_mtx = (mp); \ 62 } else { \ 63 /* \ 64 * Other waiter; assert that we're using the \ 65 * same mutex. \ 66 */ \ 67 KASSERT((cvp)->cv_mtx == (mp), \ |
68 ("%s: Multiple mutexes", __FUNCTION__)); \ | 68 ("%s: Multiple mutexes", __func__)); \ |
69 } \ 70} while (0) 71#define CV_SIGNAL_VALIDATE(cvp) do { \ 72 if (!TAILQ_EMPTY(&(cvp)->cv_waitq)) { \ 73 KASSERT(mtx_owned((cvp)->cv_mtx), \ | 69 } \ 70} while (0) 71#define CV_SIGNAL_VALIDATE(cvp) do { \ 72 if (!TAILQ_EMPTY(&(cvp)->cv_waitq)) { \ 73 KASSERT(mtx_owned((cvp)->cv_mtx), \ |
74 ("%s: Mutex not owned", __FUNCTION__)); \ | 74 ("%s: Mutex not owned", __func__)); \ |
75 } \ 76} while (0) 77#else 78#define CV_WAIT_VALIDATE(cvp, mp) 79#define CV_SIGNAL_VALIDATE(cvp) 80#endif 81 82static void cv_timedwait_end(void *arg); --- 13 unchanged lines hidden (view full) --- 96/* 97 * Destroy a condition variable. The condition variable must be re-initialized 98 * in order to be re-used. 99 */ 100void 101cv_destroy(struct cv *cvp) 102{ 103 | 75 } \ 76} while (0) 77#else 78#define CV_WAIT_VALIDATE(cvp, mp) 79#define CV_SIGNAL_VALIDATE(cvp) 80#endif 81 82static void cv_timedwait_end(void *arg); --- 13 unchanged lines hidden (view full) --- 96/* 97 * Destroy a condition variable. The condition variable must be re-initialized 98 * in order to be re-used. 99 */ 100void 101cv_destroy(struct cv *cvp) 102{ 103 |
104 KASSERT(cv_waitq_empty(cvp), ("%s: cv_waitq non-empty", __FUNCTION__)); | 104 KASSERT(cv_waitq_empty(cvp), ("%s: cv_waitq non-empty", __func__)); |
105} 106 107/* 108 * Common code for cv_wait* functions. All require sched_lock. 109 */ 110 111/* 112 * Switch context. --- 353 unchanged lines hidden (view full) --- 466 */ 467static __inline void 468cv_wakeup(struct cv *cvp) 469{ 470 struct thread *td; 471 472 mtx_assert(&sched_lock, MA_OWNED); 473 td = TAILQ_FIRST(&cvp->cv_waitq); | 105} 106 107/* 108 * Common code for cv_wait* functions. All require sched_lock. 109 */ 110 111/* 112 * Switch context. --- 353 unchanged lines hidden (view full) --- 466 */ 467static __inline void 468cv_wakeup(struct cv *cvp) 469{ 470 struct thread *td; 471 472 mtx_assert(&sched_lock, MA_OWNED); 473 td = TAILQ_FIRST(&cvp->cv_waitq); |
474 KASSERT(td->td_wchan == cvp, ("%s: bogus wchan", __FUNCTION__)); 475 KASSERT(td->td_flags & TDF_CVWAITQ, ("%s: not on waitq", __FUNCTION__)); | 474 KASSERT(td->td_wchan == cvp, ("%s: bogus wchan", __func__)); 475 KASSERT(td->td_flags & TDF_CVWAITQ, ("%s: not on waitq", __func__)); |
476 TAILQ_REMOVE(&cvp->cv_waitq, td, td_slpq); 477 td->td_flags &= ~TDF_CVWAITQ; 478 td->td_wchan = 0; 479 if (td->td_proc->p_stat == SSLEEP) { 480 /* OPTIMIZED EXPANSION OF setrunnable(td); */ 481 CTR3(KTR_PROC, "cv_signal: thread %p (pid %d, %s)", 482 td, td->td_proc->p_pid, td->td_proc->p_comm); 483 if (td->td_ksegrp->kg_slptime > 1) /* XXXKSE */ --- 18 unchanged lines hidden (view full) --- 502 * sleeping process in. Note that this may also result in additional threads 503 * being made runnable. Should be called with the same mutex as was passed to 504 * cv_wait held. 505 */ 506void 507cv_signal(struct cv *cvp) 508{ 509 | 476 TAILQ_REMOVE(&cvp->cv_waitq, td, td_slpq); 477 td->td_flags &= ~TDF_CVWAITQ; 478 td->td_wchan = 0; 479 if (td->td_proc->p_stat == SSLEEP) { 480 /* OPTIMIZED EXPANSION OF setrunnable(td); */ 481 CTR3(KTR_PROC, "cv_signal: thread %p (pid %d, %s)", 482 td, td->td_proc->p_pid, td->td_proc->p_comm); 483 if (td->td_ksegrp->kg_slptime > 1) /* XXXKSE */ --- 18 unchanged lines hidden (view full) --- 502 * sleeping process in. Note that this may also result in additional threads 503 * being made runnable. Should be called with the same mutex as was passed to 504 * cv_wait held. 505 */ 506void 507cv_signal(struct cv *cvp) 508{ 509 |
510 KASSERT(cvp != NULL, ("%s: cvp NULL", __FUNCTION__)); | 510 KASSERT(cvp != NULL, ("%s: cvp NULL", __func__)); |
511 mtx_lock_spin(&sched_lock); 512 if (!TAILQ_EMPTY(&cvp->cv_waitq)) { 513 CV_SIGNAL_VALIDATE(cvp); 514 cv_wakeup(cvp); 515 } 516 mtx_unlock_spin(&sched_lock); 517} 518 519/* 520 * Broadcast a signal to a condition variable. Wakes up all waiting threads. 521 * Should be called with the same mutex as was passed to cv_wait held. 522 */ 523void 524cv_broadcast(struct cv *cvp) 525{ 526 | 511 mtx_lock_spin(&sched_lock); 512 if (!TAILQ_EMPTY(&cvp->cv_waitq)) { 513 CV_SIGNAL_VALIDATE(cvp); 514 cv_wakeup(cvp); 515 } 516 mtx_unlock_spin(&sched_lock); 517} 518 519/* 520 * Broadcast a signal to a condition variable. Wakes up all waiting threads. 521 * Should be called with the same mutex as was passed to cv_wait held. 522 */ 523void 524cv_broadcast(struct cv *cvp) 525{ 526 |
527 KASSERT(cvp != NULL, ("%s: cvp NULL", __FUNCTION__)); | 527 KASSERT(cvp != NULL, ("%s: cvp NULL", __func__)); |
528 mtx_lock_spin(&sched_lock); 529 CV_SIGNAL_VALIDATE(cvp); 530 while (!TAILQ_EMPTY(&cvp->cv_waitq)) 531 cv_wakeup(cvp); 532 mtx_unlock_spin(&sched_lock); 533} 534 535/* --- 43 unchanged lines hidden --- | 528 mtx_lock_spin(&sched_lock); 529 CV_SIGNAL_VALIDATE(cvp); 530 while (!TAILQ_EMPTY(&cvp->cv_waitq)) 531 cv_wakeup(cvp); 532 mtx_unlock_spin(&sched_lock); 533} 534 535/* --- 43 unchanged lines hidden --- |