docs/how-to-build.md: use proper markup for directory names
[unleashed/tickless.git] / include / sys / condvar_impl.h
bloba5b8038b3927ef623c1127945e514ea87370505a
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _SYS_CONDVAR_IMPL_H
28 #define _SYS_CONDVAR_IMPL_H
31 * Implementation-private definitions for condition variables
34 #ifndef _ASM
35 #include <sys/types.h>
36 #include <sys/thread.h>
37 #endif /* _ASM */
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
43 #ifndef _ASM
46 * Condtion variables.
49 typedef struct _condvar_impl {
50 ushort_t cv_waiters;
51 } condvar_impl_t;
53 #define CV_HAS_WAITERS(cvp) (((condvar_impl_t *)(cvp))->cv_waiters != 0)
55 #endif /* _ASM */
59 * The cvwaitlock_t structure and associated macros provide an implementation
60 * of a locking mechanism that allows recursion on the reader lock without
61 * danger of a pending write lock elsewhere being able to cause a deadlock.
62 * The provision for supporting recursion is necessary for use with the
63 * netinfo (neti) kernel module when processing network data.
65 * Support for recursion (giving precedence to readers and allowing them
66 * to enter even when a write is blocked) can result in write starvation.
67 * There is no priority inheritence for this locking interface.
69 typedef struct cvwaitlock_s {
70 kmutex_t cvw_lock;
71 kcondvar_t cvw_waiter;
72 int cvw_refcnt;
73 } cvwaitlock_t;
76 #define CVW_INIT(_c) { \
77 mutex_init(&(_c)->cvw_lock, NULL, MUTEX_DRIVER, NULL); \
78 cv_init(&(_c)->cvw_waiter, NULL, CV_DRIVER, NULL); \
79 (_c)->cvw_refcnt = 0; \
82 #define CVW_ENTER_READ(_c) { \
83 mutex_enter(&(_c)->cvw_lock); \
84 while ((_c)->cvw_refcnt < 0) \
85 cv_wait(&((_c)->cvw_waiter), &(_c)->cvw_lock); \
86 (_c)->cvw_refcnt++; \
87 mutex_exit(&(_c)->cvw_lock); \
90 #define CVW_ENTER_WRITE(_c) { \
91 mutex_enter(&(_c)->cvw_lock); \
92 while ((_c)->cvw_refcnt != 0) \
93 cv_wait(&((_c)->cvw_waiter), &(_c)->cvw_lock); \
94 (_c)->cvw_refcnt = -1; \
95 mutex_exit(&(_c)->cvw_lock); \
98 #define CVW_EXIT_READ(_c) { \
99 mutex_enter(&(_c)->cvw_lock); \
100 ASSERT((_c)->cvw_refcnt > 0); \
101 if ((--((_c)->cvw_refcnt)) == 0) \
102 cv_broadcast(&(_c)->cvw_waiter); \
103 mutex_exit(&(_c)->cvw_lock); \
106 #define CVW_EXIT_WRITE(_c) { \
107 mutex_enter(&(_c)->cvw_lock); \
108 ASSERT((_c)->cvw_refcnt == -1); \
109 (_c)->cvw_refcnt = 0; \
110 cv_broadcast(&(_c)->cvw_waiter); \
111 mutex_exit(&(_c)->cvw_lock); \
114 #define CVW_WRITE_TO_READ(_c) { \
115 mutex_enter(&(_c)->cvw_lock); \
116 ASSERT((_c)->cvw_refcnt == -1); \
117 (_c)->cvw_refcnt = 1; \
118 cv_broadcast(&(_c)->cvw_waiter); \
119 mutex_exit(&(_c)->cvw_lock); \
122 #define CVW_DESTROY(_c) { \
123 mutex_destroy(&(_c)->cvw_lock); \
124 cv_destroy(&(_c)->cvw_waiter); \
127 #ifdef __cplusplus
129 #endif
131 #endif /* _SYS_CONDVAR_IMPL_H */