]> git.saurik.com Git - apple/xnu.git/blob - osfmk/mach/flipc_locks.h
xnu-792.6.56.tar.gz
[apple/xnu.git] / osfmk / mach / flipc_locks.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * @OSF_COPYRIGHT@
25 *
26 */
27 /*
28 * HISTORY
29 *
30 * Revision 1.1.1.1 1998/09/22 21:05:30 wsanchez
31 * Import of Mac OS X kernel (~semeria)
32 *
33 * Revision 1.1.1.1 1998/03/07 02:25:45 wsanchez
34 * Import of OSF Mach kernel (~mburg)
35 *
36 * Revision 1.1.4.1 1995/06/13 18:20:29 sjs
37 * Merged from flipc_shared.
38 * [95/06/07 sjs]
39 *
40 * Revision 1.1.2.3 1995/03/09 19:42:30 rwd
41 * Move yield function out of macro and prototype.
42 * [1995/03/09 19:36:25 rwd]
43 *
44 * Revision 1.1.2.2 1995/02/21 17:23:11 randys
45 * Re-indented code to four space indentation
46 * [1995/02/21 16:25:39 randys]
47 *
48 * Revision 1.1.2.1 1994/12/20 19:02:06 randys
49 * Moved definition of flipc_simple_lock to flipc_cb.h
50 * [1994/12/20 17:34:44 randys]
51 *
52 * Separated the lock macros out into machine dependent and independent files;
53 * this is the machine independent file.
54 * [1994/12/20 16:43:38 randys]
55 *
56 * $EndLog$
57 */
58
59 /*
60 * mach/flipc_locks.h
61 *
62 * The machine independent part of the flipc_simple_locks definitions.
63 * Most of the locks definitions is in flipc_dep.h, but what isn't
64 * dependent on the platform being used is here.
65 */
66
67 /*
68 * Note that the locks defined in this file and in flipc_dep.h are only
69 * for use by user level code. The reason why this file is visible to
70 * the kernel is that the kernel section of flipc needs to initialize
71 * these locks.
72 */
73
74 #ifndef _MACH_FLIPC_LOCKS_H_
75 #define _MACH_FLIPC_LOCKS_H_
76
77 /* Get the simple lock type. */
78 #include <mach/flipc_cb.h>
79
80 /*
81 * Lock function prototypes. This needs to be before any lock definitions
82 * that happen to be macros.
83 */
84
85 /* Initializes lock. Always a macro (so that kernel code can use it without
86 library assistance). */
87 void flipc_simple_lock_init(flipc_simple_lock *lock);
88
89 /* Returns 1 if lock gained, 0 otherwise. */
90 int flipc_simple_lock_try(flipc_simple_lock *lock);
91
92 /* Returns 1 if lock is locked, 0 otherwise. */
93 int flipc_simple_lock_locked(flipc_simple_lock *lock);
94
95 /* Releases the lock. */
96 void flipc_simple_lock_release(flipc_simple_lock *lock);
97
98 /* Take the lock. */
99 void flipc_simple_lock_acquire(flipc_simple_lock *lock);
100
101 /* Take two locks. Does not hold one while spinning on the
102 other. */
103 void flipc_simple_lock_acquire_2(flipc_simple_lock *lock1,
104 flipc_simple_lock *lock2);
105
106 /* Get the machine dependent stuff. The things that need to be
107 * defined in a machine dependent fashion are:
108 *
109 * flipc_simple_lock_init (must be a macro)
110 * flipc_simple_lock_try
111 * flipc_simple_lock_locked
112 * flipc_simple_lock_release
113 *
114 * These last three don't necessarily have to be macros, but if they
115 * aren't definitions must be included in the machine dependent
116 * part of the user level library code.
117 */
118 #include <mach/machine/flipc_dep.h>
119
120 /*
121 * Set at flipc initialization time to thread_yield argument to
122 * FLIPC_domain_init
123 */
124
125 extern void (*flipc_simple_lock_yield_fn)(void);
126
127 /*
128 * Machine independent definitions; defined in terms of above routines.
129 */
130
131 /* Take the lock. Assumes an external define saying how long to
132 spin, and an external function to call when we've spun too long. */
133 #define flipc_simple_lock_acquire(lock) \
134 do { \
135 int __spin_count = 0; \
136 \
137 while (flipc_simple_lock_locked(lock) \
138 || !flipc_simple_lock_try(lock)) \
139 if (++__spin_count > LOCK_SPIN_LIMIT) { \
140 (*flipc_simple_lock_yield_fn)(); \
141 __spin_count = 0; \
142 } \
143 } while (0)
144
145 /* Take two locks. Hold neither while spinning on the other. */
146 #define flipc_simple_lock_acquire_2(lock1, lock2) \
147 do { \
148 int __spin_count = 0; \
149 \
150 while (1) { \
151 while (flipc_simple_lock_locked(lock1) \
152 || !flipc_simple_lock_try(lock1)) \
153 if (++__spin_count > LOCK_SPIN_LIMIT) { \
154 (*flipc_simple_lock_yield_fn)(); \
155 __spin_count = 0; \
156 } \
157 \
158 if (flipc_simple_lock_try(lock2)) \
159 break; \
160 flipc_simple_lock_release(lock1); \
161 \
162 while (flipc_simple_lock_locked(lock2) \
163 || !flipc_simple_lock_try(lock2)) \
164 if (++__spin_count > LOCK_SPIN_LIMIT) { \
165 (*flipc_simple_lock_yield_fn)(); \
166 __spin_count = 0; \
167 } \
168 \
169 if (flipc_simple_lock_try(lock1)) \
170 break; \
171 flipc_simple_lock_release(lock2); \
172 } \
173 } while (0)
174
175 #endif /* _MACH_FLIPC_LOCKS_H_ */