Deleted Added
full compact
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 ---