1 /* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 /* 23 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. 24 * 25 * HISTORY 26 * 27 */ 28 29 30 #include <IOKit/system.h> 31 32 #include <IOKit/IOReturn.h> 33 #include <IOKit/IOLib.h> 34 #include <IOKit/assert.h> 35 36 extern "C" { 37 #include <kern/simple_lock.h> 38 #include <machine/machine_routines.h> 39 40 IOLock * IOLockAlloc( void ) 41 { 42 return( mutex_alloc(ETAP_IO_AHA) ); 43 } 44 45 void IOLockFree( IOLock * lock) 46 { 47 mutex_free( lock ); 48 } 49 50 void IOLockInitWithState( IOLock * lock, IOLockState state) 51 { 52 if( state == kIOLockStateLocked) 53 IOLockLock( lock); 54 } 55 56 struct _IORecursiveLock { 57 mutex_t * mutex; 58 thread_t thread; 59 UInt32 count; 60 }; 61 62 IORecursiveLock * IORecursiveLockAlloc( void ) 63 { 64 _IORecursiveLock * lock; 65 66 lock = IONew( _IORecursiveLock, 1); 67 if( !lock) 68 return( 0 ); 69 70 lock->mutex = mutex_alloc(ETAP_IO_AHA); 71 if( lock->mutex) { 72 lock->thread = 0; 73 lock->count = 0; 74 } else { 75 IODelete( lock, _IORecursiveLock, 1); 76 lock = 0; 77 } 78 79 return( (IORecursiveLock *) lock ); 80 } 81 82 void IORecursiveLockFree( IORecursiveLock * _lock ) 83 { 84 _IORecursiveLock * lock = (_IORecursiveLock *)_lock; 85 86 mutex_free( lock->mutex ); 87 IODelete( lock, _IORecursiveLock, 1); 88 } 89 90 void IORecursiveLockLock( IORecursiveLock * _lock) 91 { 92 _IORecursiveLock * lock = (_IORecursiveLock *)_lock; 93 94 if( lock->thread == IOThreadSelf()) 95 lock->count++; 96 else { 97 mutex_lock( lock->mutex ); 98 assert( lock->thread == 0 ); 99 assert( lock->count == 0 ); 100 lock->thread = IOThreadSelf(); 101 lock->count = 1; 102 } 103 } 104 105 boolean_t IORecursiveLockTryLock( IORecursiveLock * _lock) 106 { 107 _IORecursiveLock * lock = (_IORecursiveLock *)_lock; 108 109 if( lock->thread == IOThreadSelf()) { 110 lock->count++; 111 return( true ); 112 } else { 113 if( mutex_try( lock->mutex )) { 114 assert( lock->thread == 0 ); 115 assert( lock->count == 0 ); 116 lock->thread = IOThreadSelf(); 117 lock->count = 1; 118 return( true ); 119 } 120 } 121 return( false ); 122 } 123 124 void IORecursiveLockUnlock( IORecursiveLock * _lock) 125 { 126 _IORecursiveLock * lock = (_IORecursiveLock *)_lock; 127 128 assert( lock->thread == IOThreadSelf() ); 129 130 if( 0 == (--lock->count)) { 131 lock->thread = 0; 132 mutex_unlock( lock->mutex ); 133 } 134 } 135 136 boolean_t IORecursiveLockHaveLock( const IORecursiveLock * _lock) 137 { 138 _IORecursiveLock * lock = (_IORecursiveLock *)_lock; 139 140 return( lock->thread == IOThreadSelf()); 141 } 142 143 int IORecursiveLockSleep(IORecursiveLock *_lock, void *event, UInt32 interType) 144 { 145 _IORecursiveLock * lock = (_IORecursiveLock *)_lock; 146 UInt32 count = lock->count; 147 int res; 148 149 assert(lock->thread == IOThreadSelf()); 150 assert(lock->count == 1 || interType == THREAD_UNINT); 151 152 assert_wait((event_t) event, (int) interType); 153 lock->count = 0; 154 lock->thread = 0; 155 mutex_unlock(lock->mutex); 156 157 res = thread_block(0); 158 159 if (THREAD_AWAKENED == res) { 160 mutex_lock(lock->mutex); 161 assert(lock->thread == 0); 162 assert(lock->count == 0); 163 lock->thread = IOThreadSelf(); 164 lock->count = count; 165 } 166 167 return res; 168 } 169 170 void IORecursiveLockWakeup(IORecursiveLock *, void *event, bool oneThread) 171 { 172 thread_wakeup_prim((event_t) event, oneThread, THREAD_AWAKENED); 173 } 174 175 /* 176 * Complex (read/write) lock operations 177 */ 178 179 IORWLock * IORWLockAlloc( void ) 180 { 181 IORWLock * lock; 182 183 lock = lock_alloc( true, ETAP_IO_AHA, ETAP_IO_AHA); 184 185 return( lock); 186 } 187 188 void IORWLockFree( IORWLock * lock) 189 { 190 lock_free( lock ); 191 } 192 193 194 /* 195 * Spin locks 196 */ 197 198 IOSimpleLock * IOSimpleLockAlloc( void ) 199 { 200 IOSimpleLock * lock; 201 202 lock = (IOSimpleLock *) IOMalloc( sizeof(IOSimpleLock)); 203 if( lock) 204 IOSimpleLockInit( lock ); 205 206 return( lock ); 207 } 208 209 void IOSimpleLockInit( IOSimpleLock * lock) 210 { 211 simple_lock_init( (simple_lock_t) lock, ETAP_IO_AHA ); 212 } 213 214 void IOSimpleLockFree( IOSimpleLock * lock ) 215 { 216 IOFree( lock, sizeof(IOSimpleLock)); 217 } 218 219 } /* extern "C" */ 220 221 222