xref: /xnu-12377.41.6/iokit/IOKit/IOLocks.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1*bbb1b6f9SApple OSS Distributions /*
2*bbb1b6f9SApple OSS Distributions  * Copyright (c) 1998-2012 Apple Inc. All rights reserved.
3*bbb1b6f9SApple OSS Distributions  *
4*bbb1b6f9SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*bbb1b6f9SApple OSS Distributions  *
6*bbb1b6f9SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*bbb1b6f9SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*bbb1b6f9SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*bbb1b6f9SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*bbb1b6f9SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*bbb1b6f9SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*bbb1b6f9SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*bbb1b6f9SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*bbb1b6f9SApple OSS Distributions  *
15*bbb1b6f9SApple OSS Distributions  * Please obtain a copy of the License at
16*bbb1b6f9SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*bbb1b6f9SApple OSS Distributions  *
18*bbb1b6f9SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*bbb1b6f9SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*bbb1b6f9SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*bbb1b6f9SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*bbb1b6f9SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*bbb1b6f9SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*bbb1b6f9SApple OSS Distributions  * limitations under the License.
25*bbb1b6f9SApple OSS Distributions  *
26*bbb1b6f9SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*bbb1b6f9SApple OSS Distributions  */
28*bbb1b6f9SApple OSS Distributions /*
29*bbb1b6f9SApple OSS Distributions  *
30*bbb1b6f9SApple OSS Distributions  */
31*bbb1b6f9SApple OSS Distributions 
32*bbb1b6f9SApple OSS Distributions #ifndef __IOKIT_IOLOCKS_H
33*bbb1b6f9SApple OSS Distributions #define __IOKIT_IOLOCKS_H
34*bbb1b6f9SApple OSS Distributions 
35*bbb1b6f9SApple OSS Distributions #ifndef KERNEL
36*bbb1b6f9SApple OSS Distributions #error IOLocks.h is for kernel use only
37*bbb1b6f9SApple OSS Distributions #endif
38*bbb1b6f9SApple OSS Distributions 
39*bbb1b6f9SApple OSS Distributions #include <sys/appleapiopts.h>
40*bbb1b6f9SApple OSS Distributions #include <sys/cdefs.h>
41*bbb1b6f9SApple OSS Distributions 
42*bbb1b6f9SApple OSS Distributions #include <IOKit/system.h>
43*bbb1b6f9SApple OSS Distributions 
44*bbb1b6f9SApple OSS Distributions #include <IOKit/IOReturn.h>
45*bbb1b6f9SApple OSS Distributions #include <IOKit/IOTypes.h>
46*bbb1b6f9SApple OSS Distributions #include <machine/machine_routines.h>
47*bbb1b6f9SApple OSS Distributions #include <libkern/locks.h>
48*bbb1b6f9SApple OSS Distributions 
49*bbb1b6f9SApple OSS Distributions #ifdef __cplusplus
50*bbb1b6f9SApple OSS Distributions extern "C" {
51*bbb1b6f9SApple OSS Distributions #endif
52*bbb1b6f9SApple OSS Distributions 
53*bbb1b6f9SApple OSS Distributions /*! @var IOLockGroup
54*bbb1b6f9SApple OSS Distributions  *   Global lock group used by all IOKit locks.  To simplify kext debugging and lock-heat analysis, consider using lck_* locks with a per-driver lock group, as defined in kern/locks.h.
55*bbb1b6f9SApple OSS Distributions  */
56*bbb1b6f9SApple OSS Distributions extern lck_grp_t        *IOLockGroup;
57*bbb1b6f9SApple OSS Distributions 
58*bbb1b6f9SApple OSS Distributions #if defined(XNU_KERNEL_PRIVATE)
59*bbb1b6f9SApple OSS Distributions #define IOLOCKS_INLINE  1
60*bbb1b6f9SApple OSS Distributions #endif
61*bbb1b6f9SApple OSS Distributions 
62*bbb1b6f9SApple OSS Distributions /*
63*bbb1b6f9SApple OSS Distributions  * Mutex lock operations
64*bbb1b6f9SApple OSS Distributions  */
65*bbb1b6f9SApple OSS Distributions 
66*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
67*bbb1b6f9SApple OSS Distributions typedef lck_mtx_t       IOLock;
68*bbb1b6f9SApple OSS Distributions #else
69*bbb1b6f9SApple OSS Distributions typedef struct _IOLock  IOLock;
70*bbb1b6f9SApple OSS Distributions #endif  /* IOLOCKS_INLINE */
71*bbb1b6f9SApple OSS Distributions 
72*bbb1b6f9SApple OSS Distributions 
73*bbb1b6f9SApple OSS Distributions /*! @function IOLockAlloc
74*bbb1b6f9SApple OSS Distributions  *   @abstract Allocates and initializes a mutex.
75*bbb1b6f9SApple OSS Distributions  *   @discussion Allocates a mutex in general purpose memory, and initializes it. Mutexes are general purpose blocking mutual exclusion locks, supplied by libkern/locks.h. This function may block and so should not be called from interrupt level or while a spin lock is held.  IOLocks use the global IOKit lock group, IOLockGroup.  To simplify kext debugging and lock-heat analysis, consider using lck_* locks with a per-driver lock group, as defined in kern/locks.h.
76*bbb1b6f9SApple OSS Distributions  *   @result Pointer to the allocated lock, or zero on failure. */
77*bbb1b6f9SApple OSS Distributions 
78*bbb1b6f9SApple OSS Distributions IOLock * IOLockAlloc( void );
79*bbb1b6f9SApple OSS Distributions 
80*bbb1b6f9SApple OSS Distributions /*! @function IOLockFree
81*bbb1b6f9SApple OSS Distributions  *   @abstract Frees a mutex.
82*bbb1b6f9SApple OSS Distributions  *   @discussion Frees a lock allocated with IOLockAlloc. Mutex should be unlocked with no waiters.
83*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
84*bbb1b6f9SApple OSS Distributions 
85*bbb1b6f9SApple OSS Distributions void    IOLockFree( IOLock * lock);
86*bbb1b6f9SApple OSS Distributions 
87*bbb1b6f9SApple OSS Distributions /*! @function IOLockGetMachLock
88*bbb1b6f9SApple OSS Distributions  *   @abstract Accessor to a Mach mutex.
89*bbb1b6f9SApple OSS Distributions  *   @discussion Accessor to the Mach mutex.
90*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
91*bbb1b6f9SApple OSS Distributions 
92*bbb1b6f9SApple OSS Distributions lck_mtx_t * IOLockGetMachLock( IOLock * lock);
93*bbb1b6f9SApple OSS Distributions 
94*bbb1b6f9SApple OSS Distributions /*! @function IOLockLock
95*bbb1b6f9SApple OSS Distributions  *   @abstract Lock a mutex.
96*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the mutex. If the lock is held by any thread, block waiting for its unlock. This function may block and so should not be called from interrupt level or while a spin lock is held. Locking the mutex recursively from one thread will result in deadlock.
97*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
98*bbb1b6f9SApple OSS Distributions 
99*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
100*bbb1b6f9SApple OSS Distributions #define IOLockLock(l)   lck_mtx_lock(l)
101*bbb1b6f9SApple OSS Distributions #else
102*bbb1b6f9SApple OSS Distributions void    IOLockLock( IOLock * lock);
103*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
104*bbb1b6f9SApple OSS Distributions 
105*bbb1b6f9SApple OSS Distributions /*! @function IOLockTryLock
106*bbb1b6f9SApple OSS Distributions  *   @abstract Attempt to lock a mutex.
107*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the mutex if it is currently unlocked, and return true. If the lock is held by any thread, return false.
108*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock.
109*bbb1b6f9SApple OSS Distributions  *   @result True if the mutex was unlocked and is now locked by the caller, otherwise false. */
110*bbb1b6f9SApple OSS Distributions 
111*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
112*bbb1b6f9SApple OSS Distributions #define IOLockTryLock(l)        lck_mtx_try_lock(l)
113*bbb1b6f9SApple OSS Distributions #else
114*bbb1b6f9SApple OSS Distributions boolean_t IOLockTryLock( IOLock * lock);
115*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
116*bbb1b6f9SApple OSS Distributions 
117*bbb1b6f9SApple OSS Distributions /*! @function IOLockUnlock
118*bbb1b6f9SApple OSS Distributions  *   @abstract Unlock a mutex.
119*bbb1b6f9SApple OSS Distributions  *  @discussion Unlock the mutex and wake any blocked waiters. Results are undefined if the caller has not locked the mutex. This function may block and so should not be called from interrupt level or while a spin lock is held.
120*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
121*bbb1b6f9SApple OSS Distributions 
122*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
123*bbb1b6f9SApple OSS Distributions #define IOLockUnlock(l) lck_mtx_unlock(l)
124*bbb1b6f9SApple OSS Distributions #else
125*bbb1b6f9SApple OSS Distributions void    IOLockUnlock( IOLock * lock);
126*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
127*bbb1b6f9SApple OSS Distributions 
128*bbb1b6f9SApple OSS Distributions /*! @function IOLockSleep
129*bbb1b6f9SApple OSS Distributions  *   @abstract Sleep with mutex unlock and relock
130*bbb1b6f9SApple OSS Distributions  *  @discussion Prepare to sleep,unlock the mutex, and re-acquire it on wakeup. Results are undefined if the caller has not locked the mutex. This function may block and so should not be called from interrupt level or while a spin lock is held.
131*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the locked lock.
132*bbb1b6f9SApple OSS Distributions  *   @param event The event to sleep on. Must be non-NULL.
133*bbb1b6f9SApple OSS Distributions  *   @param interType How can the sleep be interrupted.
134*bbb1b6f9SApple OSS Distributions  *       @result The wait-result value indicating how the thread was awakened.*/
135*bbb1b6f9SApple OSS Distributions int     IOLockSleep( IOLock * lock, void *event, UInt32 interType) __DARWIN14_ALIAS(IOLockSleep);
136*bbb1b6f9SApple OSS Distributions 
137*bbb1b6f9SApple OSS Distributions int     IOLockSleepDeadline( IOLock * lock, void *event,
138*bbb1b6f9SApple OSS Distributions     AbsoluteTime deadline, UInt32 interType) __DARWIN14_ALIAS(IOLockSleepDeadline);
139*bbb1b6f9SApple OSS Distributions 
140*bbb1b6f9SApple OSS Distributions void    IOLockWakeup(IOLock * lock, void *event, bool oneThread) __DARWIN14_ALIAS(IOLockWakeup);
141*bbb1b6f9SApple OSS Distributions 
142*bbb1b6f9SApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE
143*bbb1b6f9SApple OSS Distributions /*! @enum     IOLockAssertState
144*bbb1b6f9SApple OSS Distributions  *  @abstract Used with IOLockAssert to assert the state of a lock.
145*bbb1b6f9SApple OSS Distributions  */
146*bbb1b6f9SApple OSS Distributions typedef enum {
147*bbb1b6f9SApple OSS Distributions 	kIOLockAssertOwned    = LCK_ASSERT_OWNED,
148*bbb1b6f9SApple OSS Distributions 	kIOLockAssertNotOwned = LCK_ASSERT_NOTOWNED
149*bbb1b6f9SApple OSS Distributions } IOLockAssertState;
150*bbb1b6f9SApple OSS Distributions 
151*bbb1b6f9SApple OSS Distributions int     IOLockSleepWithInheritor( IOLock * lock, UInt32 lck_sleep_action,
152*bbb1b6f9SApple OSS Distributions     void *event, thread_t inheritor, UInt32 interType, uint64_t deadline);
153*bbb1b6f9SApple OSS Distributions 
154*bbb1b6f9SApple OSS Distributions void    IOLockWakeupAllWithInheritor(IOLock * lock, void *event);
155*bbb1b6f9SApple OSS Distributions 
156*bbb1b6f9SApple OSS Distributions #ifdef IOLOCKS_INLINE
157*bbb1b6f9SApple OSS Distributions #define IOLockAssert(l, type) LCK_MTX_ASSERT(l, type)
158*bbb1b6f9SApple OSS Distributions 
159*bbb1b6f9SApple OSS Distributions /*! @function   IOLockInlineInit()
160*bbb1b6f9SApple OSS Distributions  * @abstract    Initializes an inline lock.
161*bbb1b6f9SApple OSS Distributions  */
162*bbb1b6f9SApple OSS Distributions void    IOLockInlineInit(IOLock *);
163*bbb1b6f9SApple OSS Distributions 
164*bbb1b6f9SApple OSS Distributions /*! @function   IOLockInlineDestroy()
165*bbb1b6f9SApple OSS Distributions  * @abstract    Destroys an inline lock.
166*bbb1b6f9SApple OSS Distributions  */
167*bbb1b6f9SApple OSS Distributions void    IOLockInlineDestroy(IOLock *);
168*bbb1b6f9SApple OSS Distributions 
169*bbb1b6f9SApple OSS Distributions #else
170*bbb1b6f9SApple OSS Distributions /*! @function   IOLockAssert
171*bbb1b6f9SApple OSS Distributions  *  @abstract   Assert that lock is either held or not held by current thread.
172*bbb1b6f9SApple OSS Distributions  *  @discussion Call with either kIOLockAssertOwned or kIOLockAssertNotOwned.
173*bbb1b6f9SApple OSS Distributions  *  Panics the kernel if the lock is not owned if called with kIOLockAssertOwned,
174*bbb1b6f9SApple OSS Distributions  *  and vice-versa.
175*bbb1b6f9SApple OSS Distributions  */
176*bbb1b6f9SApple OSS Distributions void    IOLockAssert(IOLock * lock, IOLockAssertState type);
177*bbb1b6f9SApple OSS Distributions #endif /* !IOLOCKS_INLINE */
178*bbb1b6f9SApple OSS Distributions #endif /* !XNU_KERNEL_PRIVATE */
179*bbb1b6f9SApple OSS Distributions 
180*bbb1b6f9SApple OSS Distributions #ifdef __APPLE_API_OBSOLETE
181*bbb1b6f9SApple OSS Distributions 
182*bbb1b6f9SApple OSS Distributions /* The following API is deprecated */
183*bbb1b6f9SApple OSS Distributions 
184*bbb1b6f9SApple OSS Distributions typedef enum {
185*bbb1b6f9SApple OSS Distributions 	kIOLockStateUnlocked        = 0,
186*bbb1b6f9SApple OSS Distributions 	kIOLockStateLocked          = 1
187*bbb1b6f9SApple OSS Distributions } IOLockState;
188*bbb1b6f9SApple OSS Distributions 
189*bbb1b6f9SApple OSS Distributions void    IOLockInitWithState( IOLock * lock, IOLockState state);
190*bbb1b6f9SApple OSS Distributions #define IOLockInit( l ) IOLockInitWithState( l, kIOLockStateUnlocked);
191*bbb1b6f9SApple OSS Distributions 
192*bbb1b6f9SApple OSS Distributions static __inline__ void
IOTakeLock(IOLock * lock)193*bbb1b6f9SApple OSS Distributions IOTakeLock( IOLock * lock)
194*bbb1b6f9SApple OSS Distributions {
195*bbb1b6f9SApple OSS Distributions 	IOLockLock(lock);
196*bbb1b6f9SApple OSS Distributions }
197*bbb1b6f9SApple OSS Distributions static __inline__ boolean_t
IOTryLock(IOLock * lock)198*bbb1b6f9SApple OSS Distributions IOTryLock(  IOLock * lock)
199*bbb1b6f9SApple OSS Distributions {
200*bbb1b6f9SApple OSS Distributions 	return IOLockTryLock(lock);
201*bbb1b6f9SApple OSS Distributions }
202*bbb1b6f9SApple OSS Distributions static __inline__ void
IOUnlock(IOLock * lock)203*bbb1b6f9SApple OSS Distributions IOUnlock(   IOLock * lock)
204*bbb1b6f9SApple OSS Distributions {
205*bbb1b6f9SApple OSS Distributions 	IOLockUnlock(lock);
206*bbb1b6f9SApple OSS Distributions }
207*bbb1b6f9SApple OSS Distributions 
208*bbb1b6f9SApple OSS Distributions #endif /* __APPLE_API_OBSOLETE */
209*bbb1b6f9SApple OSS Distributions 
210*bbb1b6f9SApple OSS Distributions /*
211*bbb1b6f9SApple OSS Distributions  * Recursive lock operations
212*bbb1b6f9SApple OSS Distributions  */
213*bbb1b6f9SApple OSS Distributions 
214*bbb1b6f9SApple OSS Distributions typedef struct _IORecursiveLock IORecursiveLock;
215*bbb1b6f9SApple OSS Distributions 
216*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockAlloc
217*bbb1b6f9SApple OSS Distributions  *   @abstract Allocates and initializes an recursive lock.
218*bbb1b6f9SApple OSS Distributions  *   @discussion Allocates a recursive lock in general purpose memory, and initializes it. Recursive locks function identically to mutexes but allow one thread to lock more than once, with balanced unlocks.  IORecursiveLocks use the global IOKit lock group, IOLockGroup.  To simplify kext debugging and lock-heat analysis, consider using lck_* locks with a per-driver lock group, as defined in kern/locks.h.
219*bbb1b6f9SApple OSS Distributions  *   @result Pointer to the allocated lock, or zero on failure. */
220*bbb1b6f9SApple OSS Distributions 
221*bbb1b6f9SApple OSS Distributions IORecursiveLock * IORecursiveLockAlloc( void );
222*bbb1b6f9SApple OSS Distributions 
223*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockFree
224*bbb1b6f9SApple OSS Distributions  *   @abstract Frees a recursive lock.
225*bbb1b6f9SApple OSS Distributions  *   @discussion Frees a lock allocated with IORecursiveLockAlloc. Lock should be unlocked with no waiters.
226*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
227*bbb1b6f9SApple OSS Distributions 
228*bbb1b6f9SApple OSS Distributions void            IORecursiveLockFree( IORecursiveLock * lock);
229*bbb1b6f9SApple OSS Distributions 
230*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockGetMachLock
231*bbb1b6f9SApple OSS Distributions  *   @abstract Accessor to a Mach mutex.
232*bbb1b6f9SApple OSS Distributions  *   @discussion Accessor to the Mach mutex.
233*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
234*bbb1b6f9SApple OSS Distributions 
235*bbb1b6f9SApple OSS Distributions lck_mtx_t * IORecursiveLockGetMachLock( IORecursiveLock * lock);
236*bbb1b6f9SApple OSS Distributions 
237*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockLock
238*bbb1b6f9SApple OSS Distributions  *   @abstract Lock a recursive lock.
239*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the recursive lock. If the lock is held by another thread, block waiting for its unlock. This function may block and so should not be called from interrupt level or while a spin lock is held. The lock may be taken recursively by the same thread, with a balanced number of calls to IORecursiveLockUnlock.
240*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
241*bbb1b6f9SApple OSS Distributions 
242*bbb1b6f9SApple OSS Distributions void            IORecursiveLockLock( IORecursiveLock * lock);
243*bbb1b6f9SApple OSS Distributions 
244*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockTryLock
245*bbb1b6f9SApple OSS Distributions  *   @abstract Attempt to lock a recursive lock.
246*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the lock if it is currently unlocked, or held by the calling thread, and return true. If the lock is held by another thread, return false. Successful calls to IORecursiveLockTryLock should be balanced with calls to IORecursiveLockUnlock.
247*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock.
248*bbb1b6f9SApple OSS Distributions  *   @result True if the lock is now locked by the caller, otherwise false. */
249*bbb1b6f9SApple OSS Distributions 
250*bbb1b6f9SApple OSS Distributions boolean_t       IORecursiveLockTryLock( IORecursiveLock * lock);
251*bbb1b6f9SApple OSS Distributions 
252*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockUnlock
253*bbb1b6f9SApple OSS Distributions  *   @abstract Unlock a recursive lock.
254*bbb1b6f9SApple OSS Distributions  *  @discussion Undo one call to IORecursiveLockLock, if the lock is now unlocked wake any blocked waiters. Results are undefined if the caller does not balance calls to IORecursiveLockLock with IORecursiveLockUnlock. This function may block and so should not be called from interrupt level or while a spin lock is held.
255*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
256*bbb1b6f9SApple OSS Distributions 
257*bbb1b6f9SApple OSS Distributions void            IORecursiveLockUnlock( IORecursiveLock * lock);
258*bbb1b6f9SApple OSS Distributions 
259*bbb1b6f9SApple OSS Distributions /*! @function IORecursiveLockHaveLock
260*bbb1b6f9SApple OSS Distributions  *   @abstract Check if a recursive lock is held by the calling thread.
261*bbb1b6f9SApple OSS Distributions  *   @discussion If the lock is held by the calling thread, return true, otherwise the lock is unlocked, or held by another thread and false is returned.
262*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock.
263*bbb1b6f9SApple OSS Distributions  *   @result True if the calling thread holds the lock otherwise false. */
264*bbb1b6f9SApple OSS Distributions 
265*bbb1b6f9SApple OSS Distributions boolean_t       IORecursiveLockHaveLock( const IORecursiveLock * lock);
266*bbb1b6f9SApple OSS Distributions 
267*bbb1b6f9SApple OSS Distributions extern int      IORecursiveLockSleep( IORecursiveLock *_lock,
268*bbb1b6f9SApple OSS Distributions     void *event, UInt32 interType);
269*bbb1b6f9SApple OSS Distributions extern int      IORecursiveLockSleepDeadline( IORecursiveLock * _lock, void *event,
270*bbb1b6f9SApple OSS Distributions     AbsoluteTime deadline, UInt32 interType);
271*bbb1b6f9SApple OSS Distributions extern void     IORecursiveLockWakeup( IORecursiveLock *_lock,
272*bbb1b6f9SApple OSS Distributions     void *event, bool oneThread);
273*bbb1b6f9SApple OSS Distributions 
274*bbb1b6f9SApple OSS Distributions /*
275*bbb1b6f9SApple OSS Distributions  * Complex (read/write) lock operations
276*bbb1b6f9SApple OSS Distributions  */
277*bbb1b6f9SApple OSS Distributions 
278*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
279*bbb1b6f9SApple OSS Distributions typedef lck_rw_t                IORWLock;
280*bbb1b6f9SApple OSS Distributions #else
281*bbb1b6f9SApple OSS Distributions typedef struct _IORWLock        IORWLock;
282*bbb1b6f9SApple OSS Distributions #endif  /* IOLOCKS_INLINE */
283*bbb1b6f9SApple OSS Distributions 
284*bbb1b6f9SApple OSS Distributions /*! @function IORWLockAlloc
285*bbb1b6f9SApple OSS Distributions  *   @abstract Allocates and initializes a read/write lock.
286*bbb1b6f9SApple OSS Distributions  *   @discussion Allocates and initializes a read/write lock in general purpose memory. Read/write locks provide for multiple readers, one exclusive writer, and are supplied by libkern/locks.h. This function may block and so should not be called from interrupt level or while a spin lock is held.  IORWLocks use the global IOKit lock group, IOLockGroup.  To simplify kext debugging and lock-heat analysis, consider using lck_* locks with a per-driver lock group, as defined in kern/locks.h.
287*bbb1b6f9SApple OSS Distributions  *   @result Pointer to the allocated lock, or zero on failure. */
288*bbb1b6f9SApple OSS Distributions 
289*bbb1b6f9SApple OSS Distributions IORWLock * IORWLockAlloc( void );
290*bbb1b6f9SApple OSS Distributions 
291*bbb1b6f9SApple OSS Distributions /*! @function IORWLockFree
292*bbb1b6f9SApple OSS Distributions  *  @abstract Frees a read/write lock.
293*bbb1b6f9SApple OSS Distributions  *  @discussion Frees a lock allocated with IORWLockAlloc. Lock should be unlocked with no waiters.
294*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
295*bbb1b6f9SApple OSS Distributions 
296*bbb1b6f9SApple OSS Distributions void    IORWLockFree( IORWLock * lock);
297*bbb1b6f9SApple OSS Distributions 
298*bbb1b6f9SApple OSS Distributions /*! @function IORWLockGetMachLock
299*bbb1b6f9SApple OSS Distributions  *   @abstract Accessor to a Mach read/write lock.
300*bbb1b6f9SApple OSS Distributions  *   @discussion Accessor to the Mach read/write lock.
301*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
302*bbb1b6f9SApple OSS Distributions 
303*bbb1b6f9SApple OSS Distributions lck_rw_t * IORWLockGetMachLock( IORWLock * lock);
304*bbb1b6f9SApple OSS Distributions 
305*bbb1b6f9SApple OSS Distributions /*! @function IORWLockRead
306*bbb1b6f9SApple OSS Distributions  *   @abstract Lock a read/write lock for read.
307*bbb1b6f9SApple OSS Distributions  *  @discussion Lock the lock for read, allowing multiple readers when there are no writers. If the lock is held for write, block waiting for its unlock. This function may block and so should not be called from interrupt level or while a spin lock is held. Locking the lock recursively from one thread, for read or write, can result in deadlock.
308*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
309*bbb1b6f9SApple OSS Distributions 
310*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
311*bbb1b6f9SApple OSS Distributions #define IORWLockRead(l) lck_rw_lock_shared(l)
312*bbb1b6f9SApple OSS Distributions #else
313*bbb1b6f9SApple OSS Distributions void    IORWLockRead(IORWLock * lock);
314*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
315*bbb1b6f9SApple OSS Distributions 
316*bbb1b6f9SApple OSS Distributions /*! @function IORWLockTryRead
317*bbb1b6f9SApple OSS Distributions  *   @abstract Attempt to lock a read/write lock for read.
318*bbb1b6f9SApple OSS Distributions  *  @discussion Lock the lock for read, allowing multiple readers when there are no writers. If the lock is held for write, return false. Return true otherwise.
319*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
320*bbb1b6f9SApple OSS Distributions 
321*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
322*bbb1b6f9SApple OSS Distributions #define IORWLockTryRead(l)        lck_rw_try_lock_shared(l)
323*bbb1b6f9SApple OSS Distributions #else
324*bbb1b6f9SApple OSS Distributions void    IORWLockTryRead( IORWLock * lock);
325*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
326*bbb1b6f9SApple OSS Distributions 
327*bbb1b6f9SApple OSS Distributions /*! @function IORWLockWrite
328*bbb1b6f9SApple OSS Distributions  *   @abstract Lock a read/write lock for write.
329*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the lock for write, allowing one writer exlusive access. If the lock is held for read or write, block waiting for its unlock. This function may block and so should not be called from interrupt level or while a spin lock is held. Locking the lock recursively from one thread, for read or write, can result in deadlock.
330*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
331*bbb1b6f9SApple OSS Distributions 
332*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
333*bbb1b6f9SApple OSS Distributions #define IORWLockWrite(l)        lck_rw_lock_exclusive(l)
334*bbb1b6f9SApple OSS Distributions #else
335*bbb1b6f9SApple OSS Distributions void    IORWLockWrite( IORWLock * lock);
336*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
337*bbb1b6f9SApple OSS Distributions 
338*bbb1b6f9SApple OSS Distributions /*! @function IORWLockTryWrite
339*bbb1b6f9SApple OSS Distributions  *   @abstract Attempt to lock a read/write lock for write.
340*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the lock for write, allowing one writer exlusive access. If the lock is held for read or write, return false. Return true otherwise.
341*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
342*bbb1b6f9SApple OSS Distributions 
343*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
344*bbb1b6f9SApple OSS Distributions #define IORWLockTryWrite(l)        lck_rw_try_lock_exclusive(l)
345*bbb1b6f9SApple OSS Distributions #else
346*bbb1b6f9SApple OSS Distributions void    IORWLockTryWrite( IORWLock * lock);
347*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
348*bbb1b6f9SApple OSS Distributions 
349*bbb1b6f9SApple OSS Distributions /*! @function IORWLockUnlock
350*bbb1b6f9SApple OSS Distributions  *   @abstract Unlock a read/write lock.
351*bbb1b6f9SApple OSS Distributions  *   @discussion Undo one call to IORWLockRead or IORWLockWrite. Results are undefined if the caller has not locked the lock. This function may block and so should not be called from interrupt level or while a spin lock is held.
352*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
353*bbb1b6f9SApple OSS Distributions 
354*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
355*bbb1b6f9SApple OSS Distributions #define IORWLockUnlock(l)       lck_rw_done(l)
356*bbb1b6f9SApple OSS Distributions #else
357*bbb1b6f9SApple OSS Distributions void    IORWLockUnlock( IORWLock * lock);
358*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
359*bbb1b6f9SApple OSS Distributions 
360*bbb1b6f9SApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE
361*bbb1b6f9SApple OSS Distributions /*! @enum     IORWLockAssertState
362*bbb1b6f9SApple OSS Distributions  *  @abstract Used with IORWLockAssert to assert the state of a lock.
363*bbb1b6f9SApple OSS Distributions  */
364*bbb1b6f9SApple OSS Distributions typedef enum {
365*bbb1b6f9SApple OSS Distributions 	kIORWLockAssertRead    = LCK_RW_ASSERT_SHARED,
366*bbb1b6f9SApple OSS Distributions 	kIORWLockAssertWrite   = LCK_RW_ASSERT_EXCLUSIVE,
367*bbb1b6f9SApple OSS Distributions 	kIORWLockAssertHeld    = LCK_RW_ASSERT_HELD,
368*bbb1b6f9SApple OSS Distributions 	kIORWLockAssertNotHeld = LCK_RW_ASSERT_NOTHELD
369*bbb1b6f9SApple OSS Distributions } IORWLockAssertState;
370*bbb1b6f9SApple OSS Distributions 
371*bbb1b6f9SApple OSS Distributions #ifdef IOLOCKS_INLINE
372*bbb1b6f9SApple OSS Distributions #define IORWLockAssert(l, type) LCK_RW_ASSERT(l, type)
373*bbb1b6f9SApple OSS Distributions 
374*bbb1b6f9SApple OSS Distributions /*! @function   IORWLockInlineInit()
375*bbb1b6f9SApple OSS Distributions  * @abstract    Initializes an inline lock.
376*bbb1b6f9SApple OSS Distributions  */
377*bbb1b6f9SApple OSS Distributions void    IORWLockInlineInit(IORWLock *);
378*bbb1b6f9SApple OSS Distributions 
379*bbb1b6f9SApple OSS Distributions /*! @function   IORWLockInlineDestroy()
380*bbb1b6f9SApple OSS Distributions  * @abstract    Destroys an inline lock.
381*bbb1b6f9SApple OSS Distributions  */
382*bbb1b6f9SApple OSS Distributions void    IORWLockInlineDestroy(IORWLock *);
383*bbb1b6f9SApple OSS Distributions 
384*bbb1b6f9SApple OSS Distributions #else
385*bbb1b6f9SApple OSS Distributions /*! @function   IORWLockAssert
386*bbb1b6f9SApple OSS Distributions  *  @abstract   Assert that a reader-writer lock is either held or not held
387*bbb1b6f9SApple OSS Distributions  *  by the current thread.
388*bbb1b6f9SApple OSS Distributions  *  @discussion Call with a value defined by the IORWLockAssertState type.
389*bbb1b6f9SApple OSS Distributions  *  If the specified lock is not in the state specified by the type argument,
390*bbb1b6f9SApple OSS Distributions  *  then the kernel will panic.
391*bbb1b6f9SApple OSS Distributions  */
392*bbb1b6f9SApple OSS Distributions void    IORWLockAssert(IORWLock * lock, IORWLockAssertState type);
393*bbb1b6f9SApple OSS Distributions #endif /* !IOLOCKS_INLINE */
394*bbb1b6f9SApple OSS Distributions #endif /* !XNU_KERNEL_PRIVATE */
395*bbb1b6f9SApple OSS Distributions 
396*bbb1b6f9SApple OSS Distributions #ifdef __APPLE_API_OBSOLETE
397*bbb1b6f9SApple OSS Distributions 
398*bbb1b6f9SApple OSS Distributions /* The following API is deprecated */
399*bbb1b6f9SApple OSS Distributions 
400*bbb1b6f9SApple OSS Distributions static __inline__ void
IOReadLock(IORWLock * lock)401*bbb1b6f9SApple OSS Distributions IOReadLock( IORWLock * lock)
402*bbb1b6f9SApple OSS Distributions {
403*bbb1b6f9SApple OSS Distributions 	IORWLockRead(lock);
404*bbb1b6f9SApple OSS Distributions }
405*bbb1b6f9SApple OSS Distributions static __inline__ void
IOWriteLock(IORWLock * lock)406*bbb1b6f9SApple OSS Distributions IOWriteLock(  IORWLock * lock)
407*bbb1b6f9SApple OSS Distributions {
408*bbb1b6f9SApple OSS Distributions 	IORWLockWrite(lock);
409*bbb1b6f9SApple OSS Distributions }
410*bbb1b6f9SApple OSS Distributions static __inline__ void
IORWUnlock(IORWLock * lock)411*bbb1b6f9SApple OSS Distributions IORWUnlock(   IORWLock * lock)
412*bbb1b6f9SApple OSS Distributions {
413*bbb1b6f9SApple OSS Distributions 	IORWLockUnlock(lock);
414*bbb1b6f9SApple OSS Distributions }
415*bbb1b6f9SApple OSS Distributions 
416*bbb1b6f9SApple OSS Distributions #endif /* __APPLE_API_OBSOLETE */
417*bbb1b6f9SApple OSS Distributions 
418*bbb1b6f9SApple OSS Distributions 
419*bbb1b6f9SApple OSS Distributions /*
420*bbb1b6f9SApple OSS Distributions  * Simple locks. Cannot block while holding a simple lock.
421*bbb1b6f9SApple OSS Distributions  */
422*bbb1b6f9SApple OSS Distributions 
423*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
424*bbb1b6f9SApple OSS Distributions typedef lck_spin_t              IOSimpleLock;
425*bbb1b6f9SApple OSS Distributions #else
426*bbb1b6f9SApple OSS Distributions typedef struct _IOSimpleLock    IOSimpleLock;
427*bbb1b6f9SApple OSS Distributions #endif  /* IOLOCKS_INLINE */
428*bbb1b6f9SApple OSS Distributions 
429*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockAlloc
430*bbb1b6f9SApple OSS Distributions  *   @abstract Allocates and initializes a spin lock.
431*bbb1b6f9SApple OSS Distributions  *   @discussion Allocates and initializes a spin lock in general purpose memory. Spin locks provide non-blocking mutual exclusion for synchronization between thread context and interrupt context, or for multiprocessor synchronization, and are supplied by libkern/locks.h. This function may block and so should not be called from interrupt level or while a spin lock is held.  IOSimpleLocks use the global IOKit lock group, IOLockGroup.  To simplify kext debugging and lock-heat analysis, consider using lck_* locks with a per-driver lock group, as defined in kern/locks.h.
432*bbb1b6f9SApple OSS Distributions  *   @result Pointer to the allocated lock, or zero on failure. */
433*bbb1b6f9SApple OSS Distributions 
434*bbb1b6f9SApple OSS Distributions IOSimpleLock * IOSimpleLockAlloc( void );
435*bbb1b6f9SApple OSS Distributions 
436*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockFree
437*bbb1b6f9SApple OSS Distributions  *   @abstract Frees a spin lock.
438*bbb1b6f9SApple OSS Distributions  *   @discussion Frees a lock allocated with IOSimpleLockAlloc.
439*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock. */
440*bbb1b6f9SApple OSS Distributions 
441*bbb1b6f9SApple OSS Distributions void IOSimpleLockFree( IOSimpleLock * lock );
442*bbb1b6f9SApple OSS Distributions 
443*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockGetMachLock
444*bbb1b6f9SApple OSS Distributions  *   @abstract Accessor to a Mach spin lock.
445*bbb1b6f9SApple OSS Distributions  *   @discussion Accessor to the Mach spin lock.
446*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the allocated lock. */
447*bbb1b6f9SApple OSS Distributions 
448*bbb1b6f9SApple OSS Distributions lck_spin_t * IOSimpleLockGetMachLock( IOSimpleLock * lock);
449*bbb1b6f9SApple OSS Distributions 
450*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockInit
451*bbb1b6f9SApple OSS Distributions  *   @abstract Initialize a spin lock.
452*bbb1b6f9SApple OSS Distributions  *   @discussion Initialize a non heap allocated spin lock to the unlocked state. Use this function when your lock is, for example, a member variable. You will need to call IOSimpleLockDestroy when you are finished with the lock to avoid lock group refcount leaks.
453*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock. */
454*bbb1b6f9SApple OSS Distributions 
455*bbb1b6f9SApple OSS Distributions void IOSimpleLockInit( IOSimpleLock * lock );
456*bbb1b6f9SApple OSS Distributions 
457*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockDestroy
458*bbb1b6f9SApple OSS Distributions  *   @abstract De-initializes (destroys) a spin lock initialized with IOSimpleLockInit
459*bbb1b6f9SApple OSS Distributions  *   @discussion Destroy / De-initialize a non heap allocated spin lock, releasing any system resources such as lock group refcounts.
460*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock. */
461*bbb1b6f9SApple OSS Distributions 
462*bbb1b6f9SApple OSS Distributions void IOSimpleLockDestroy( IOSimpleLock * lock );
463*bbb1b6f9SApple OSS Distributions 
464*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockLock
465*bbb1b6f9SApple OSS Distributions  *   @abstract Lock a spin lock.
466*bbb1b6f9SApple OSS Distributions  *  @discussion Lock the spin lock. If the lock is held, spin waiting for its unlock. Spin locks disable preemption, cannot be held across any blocking operation, and should be held for very short periods. When used to synchronize between interrupt context and thread context they should be locked with interrupts disabled - IOSimpleLockLockDisableInterrupt() will do both. Locking the lock recursively from one thread will result in deadlock.
467*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock. */
468*bbb1b6f9SApple OSS Distributions 
469*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
470*bbb1b6f9SApple OSS Distributions #define IOSimpleLockLock(l)     lck_spin_lock(l)
471*bbb1b6f9SApple OSS Distributions #else
472*bbb1b6f9SApple OSS Distributions void IOSimpleLockLock( IOSimpleLock * lock );
473*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
474*bbb1b6f9SApple OSS Distributions 
475*bbb1b6f9SApple OSS Distributions 
476*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockTryLock
477*bbb1b6f9SApple OSS Distributions  *   @abstract Attempt to lock a spin lock.
478*bbb1b6f9SApple OSS Distributions  *  @discussion Lock the spin lock if it is currently unlocked, and return true. If the lock is held, return false. Successful calls to IOSimpleLockTryLock should be balanced with calls to IOSimpleLockUnlock.
479*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock.
480*bbb1b6f9SApple OSS Distributions  *   @result True if the lock was unlocked and is now locked by the caller, otherwise false. */
481*bbb1b6f9SApple OSS Distributions 
482*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
483*bbb1b6f9SApple OSS Distributions #define IOSimpleLockTryLock(l)  lck_spin_try_lock(l)
484*bbb1b6f9SApple OSS Distributions #else
485*bbb1b6f9SApple OSS Distributions boolean_t IOSimpleLockTryLock( IOSimpleLock * lock );
486*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
487*bbb1b6f9SApple OSS Distributions 
488*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockUnlock
489*bbb1b6f9SApple OSS Distributions  *   @abstract Unlock a spin lock.
490*bbb1b6f9SApple OSS Distributions  *   @discussion Unlock the lock, and restore preemption. Results are undefined if the caller has not locked the lock.
491*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock. */
492*bbb1b6f9SApple OSS Distributions 
493*bbb1b6f9SApple OSS Distributions #ifdef  IOLOCKS_INLINE
494*bbb1b6f9SApple OSS Distributions #define IOSimpleLockUnlock(l)   lck_spin_unlock(l)
495*bbb1b6f9SApple OSS Distributions #else
496*bbb1b6f9SApple OSS Distributions void IOSimpleLockUnlock( IOSimpleLock * lock );
497*bbb1b6f9SApple OSS Distributions #endif  /* !IOLOCKS_INLINE */
498*bbb1b6f9SApple OSS Distributions 
499*bbb1b6f9SApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE
500*bbb1b6f9SApple OSS Distributions /*! @enum     IOSimpleLockAssertState
501*bbb1b6f9SApple OSS Distributions  *  @abstract Used with IOSimpleLockAssert to assert the state of a lock.
502*bbb1b6f9SApple OSS Distributions  */
503*bbb1b6f9SApple OSS Distributions typedef enum {
504*bbb1b6f9SApple OSS Distributions 	kIOSimpleLockAssertOwned    = LCK_ASSERT_OWNED,
505*bbb1b6f9SApple OSS Distributions 	kIOSimpleLockAssertNotOwned = LCK_ASSERT_NOTOWNED
506*bbb1b6f9SApple OSS Distributions } IOSimpleLockAssertState;
507*bbb1b6f9SApple OSS Distributions 
508*bbb1b6f9SApple OSS Distributions #ifdef IOLOCKS_INLINE
509*bbb1b6f9SApple OSS Distributions #define IOSimpleLockAssert(l, type) LCK_SPIN_ASSERT(l, type)
510*bbb1b6f9SApple OSS Distributions #else
511*bbb1b6f9SApple OSS Distributions /*! @function   IOSimpleLockAssert
512*bbb1b6f9SApple OSS Distributions  *  @abstract   Assert that spinlock is either held or not held by current thread.
513*bbb1b6f9SApple OSS Distributions  *  @discussion Call with either kIOSimpleLockAssertOwned or kIOSimpleLockAssertNotOwned.
514*bbb1b6f9SApple OSS Distributions  *  Panics the kernel if the lock is not owned if called with
515*bbb1b6f9SApple OSS Distributions  *  kIOSimpleLockAssertOwned and vice-versa.
516*bbb1b6f9SApple OSS Distributions  */
517*bbb1b6f9SApple OSS Distributions void    IOSimpleLockAssert(IOSimpleLock *lock, IOSimpleLockAssertState type);
518*bbb1b6f9SApple OSS Distributions #endif /* !IOLOCKS_INLINE */
519*bbb1b6f9SApple OSS Distributions #endif /* !XNU_KERNEL_PRIVATE */
520*bbb1b6f9SApple OSS Distributions 
521*bbb1b6f9SApple OSS Distributions #if __LP64__
522*bbb1b6f9SApple OSS Distributions typedef boolean_t IOInterruptState;
523*bbb1b6f9SApple OSS Distributions #else
524*bbb1b6f9SApple OSS Distributions typedef long int IOInterruptState;
525*bbb1b6f9SApple OSS Distributions #endif
526*bbb1b6f9SApple OSS Distributions 
527*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockLockDisableInterrupt
528*bbb1b6f9SApple OSS Distributions  *   @abstract Lock a spin lock.
529*bbb1b6f9SApple OSS Distributions  *   @discussion Lock the spin lock. If the lock is held, spin waiting for its unlock. Simple locks disable preemption, cannot be held across any blocking operation, and should be held for very short periods. When used to synchronize between interrupt context and thread context they should be locked with interrupts disabled - IOSimpleLockLockDisableInterrupt() will do both. Locking the lock recursively from one thread will result in deadlock.
530*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock. */
531*bbb1b6f9SApple OSS Distributions 
532*bbb1b6f9SApple OSS Distributions static __inline__
533*bbb1b6f9SApple OSS Distributions IOInterruptState
IOSimpleLockLockDisableInterrupt(IOSimpleLock * lock)534*bbb1b6f9SApple OSS Distributions IOSimpleLockLockDisableInterrupt( IOSimpleLock * lock )
535*bbb1b6f9SApple OSS Distributions {
536*bbb1b6f9SApple OSS Distributions 	IOInterruptState    state = ml_set_interrupts_enabled( false );
537*bbb1b6f9SApple OSS Distributions 	IOSimpleLockLock( lock );
538*bbb1b6f9SApple OSS Distributions 	return state;
539*bbb1b6f9SApple OSS Distributions }
540*bbb1b6f9SApple OSS Distributions 
541*bbb1b6f9SApple OSS Distributions /*! @function IOSimpleLockUnlockEnableInterrupt
542*bbb1b6f9SApple OSS Distributions  *   @abstract Unlock a spin lock, and restore interrupt state.
543*bbb1b6f9SApple OSS Distributions  *   @discussion Unlock the lock, and restore preemption and interrupts to the state as they were when the lock was taken. Results are undefined if the caller has not locked the lock.
544*bbb1b6f9SApple OSS Distributions  *   @param lock Pointer to the lock.
545*bbb1b6f9SApple OSS Distributions  *   @param state The interrupt state returned by IOSimpleLockLockDisableInterrupt() */
546*bbb1b6f9SApple OSS Distributions 
547*bbb1b6f9SApple OSS Distributions static __inline__
548*bbb1b6f9SApple OSS Distributions void
IOSimpleLockUnlockEnableInterrupt(IOSimpleLock * lock,IOInterruptState state)549*bbb1b6f9SApple OSS Distributions IOSimpleLockUnlockEnableInterrupt( IOSimpleLock * lock,
550*bbb1b6f9SApple OSS Distributions     IOInterruptState state )
551*bbb1b6f9SApple OSS Distributions {
552*bbb1b6f9SApple OSS Distributions 	IOSimpleLockUnlock( lock );
553*bbb1b6f9SApple OSS Distributions 	ml_set_interrupts_enabled( state );
554*bbb1b6f9SApple OSS Distributions }
555*bbb1b6f9SApple OSS Distributions 
556*bbb1b6f9SApple OSS Distributions #ifdef __cplusplus
557*bbb1b6f9SApple OSS Distributions } /* extern "C" */
558*bbb1b6f9SApple OSS Distributions #endif
559*bbb1b6f9SApple OSS Distributions 
560*bbb1b6f9SApple OSS Distributions #endif /* !__IOKIT_IOLOCKS_H */
561