Changes in kernel/generic/src/synch/spinlock.c [90c8b8d:7e752b2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/spinlock.c
r90c8b8d r7e752b2 52 52 * 53 53 */ 54 void spinlock_initialize(spinlock_t *lock, c har *name)54 void spinlock_initialize(spinlock_t *lock, const char *name) 55 55 { 56 56 atomic_set(&lock->val, 0); … … 102 102 103 103 if (i++ > DEADLOCK_THRESHOLD) { 104 printf("cpu%u: looping on spinlock % " PRIp ":%s, "105 "caller=% " PRIp "(%s)\n", CPU->id, lock, lock->name,106 CALLER, symtab_fmt_name_lookup(CALLER));104 printf("cpu%u: looping on spinlock %p:%s, " 105 "caller=%p (%s)\n", CPU->id, lock, lock->name, 106 (void *) CALLER, symtab_fmt_name_lookup(CALLER)); 107 107 108 108 i = 0; … … 120 120 } 121 121 122 /** Unlock spinlock 123 * 124 * Unlock spinlock. 125 * 126 * @param sl Pointer to spinlock_t structure. 127 */ 128 void spinlock_unlock_debug(spinlock_t *lock) 129 { 130 ASSERT_SPINLOCK(spinlock_locked(lock), lock); 131 132 /* 133 * Prevent critical section code from bleeding out this way down. 134 */ 135 CS_LEAVE_BARRIER(); 136 137 atomic_set(&lock->val, 0); 138 preemption_enable(); 139 } 140 122 141 #endif 123 142 124 143 /** Lock spinlock conditionally 125 144 * 126 * Lock spinlock conditionally. 127 * If the spinlock is not available at the moment, 128 * signal failure. 145 * Lock spinlock conditionally. If the spinlock is not available 146 * at the moment, signal failure. 129 147 * 130 148 * @param lock Pointer to spinlock_t structure. … … 149 167 } 150 168 169 /** Find out whether the spinlock is currently locked. 170 * 171 * @param lock Spinlock. 172 * @return True if the spinlock is locked, false otherwise. 173 */ 174 bool spinlock_locked(spinlock_t *lock) 175 { 176 return atomic_get(&lock->val) != 0; 177 } 178 151 179 #endif 152 180 181 /** Initialize interrupts-disabled spinlock 182 * 183 * @param lock IRQ spinlock to be initialized. 184 * @param name IRQ spinlock name. 185 * 186 */ 187 void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name) 188 { 189 spinlock_initialize(&(lock->lock), name); 190 lock->guard = false; 191 lock->ipl = 0; 192 } 193 194 /** Lock interrupts-disabled spinlock 195 * 196 * Lock a spinlock which requires disabled interrupts. 197 * 198 * @param lock IRQ spinlock to be locked. 199 * @param irq_dis If true, interrupts are actually disabled 200 * prior locking the spinlock. If false, interrupts 201 * are expected to be already disabled. 202 * 203 */ 204 void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis) 205 { 206 if (irq_dis) { 207 ipl_t ipl = interrupts_disable(); 208 spinlock_lock(&(lock->lock)); 209 210 lock->guard = true; 211 lock->ipl = ipl; 212 } else { 213 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 214 215 spinlock_lock(&(lock->lock)); 216 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 217 } 218 } 219 220 /** Unlock interrupts-disabled spinlock 221 * 222 * Unlock a spinlock which requires disabled interrupts. 223 * 224 * @param lock IRQ spinlock to be unlocked. 225 * @param irq_res If true, interrupts are restored to previously 226 * saved interrupt level. 227 * 228 */ 229 void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res) 230 { 231 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 232 233 if (irq_res) { 234 ASSERT_IRQ_SPINLOCK(lock->guard, lock); 235 236 lock->guard = false; 237 ipl_t ipl = lock->ipl; 238 239 spinlock_unlock(&(lock->lock)); 240 interrupts_restore(ipl); 241 } else { 242 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 243 spinlock_unlock(&(lock->lock)); 244 } 245 } 246 247 /** Lock interrupts-disabled spinlock 248 * 249 * Lock an interrupts-disabled spinlock conditionally. If the 250 * spinlock is not available at the moment, signal failure. 251 * Interrupts are expected to be already disabled. 252 * 253 * @param lock IRQ spinlock to be locked conditionally. 254 * 255 * @return Zero on failure, non-zero otherwise. 256 * 257 */ 258 int irq_spinlock_trylock(irq_spinlock_t *lock) 259 { 260 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 261 int rc = spinlock_trylock(&(lock->lock)); 262 263 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 264 return rc; 265 } 266 267 /** Pass lock from one interrupts-disabled spinlock to another 268 * 269 * Pass lock from one IRQ spinlock to another IRQ spinlock 270 * without enabling interrupts during the process. 271 * 272 * The first IRQ spinlock is supposed to be locked. 273 * 274 * @param unlock IRQ spinlock to be unlocked. 275 * @param lock IRQ spinlock to be locked. 276 * 277 */ 278 void irq_spinlock_pass(irq_spinlock_t *unlock, irq_spinlock_t *lock) 279 { 280 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 281 282 /* Pass guard from unlock to lock */ 283 bool guard = unlock->guard; 284 ipl_t ipl = unlock->ipl; 285 unlock->guard = false; 286 287 spinlock_unlock(&(unlock->lock)); 288 spinlock_lock(&(lock->lock)); 289 290 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 291 292 if (guard) { 293 lock->guard = true; 294 lock->ipl = ipl; 295 } 296 } 297 298 /** Hand-over-hand locking of interrupts-disabled spinlocks 299 * 300 * Implement hand-over-hand locking between two interrupts-disabled 301 * spinlocks without enabling interrupts during the process. 302 * 303 * The first IRQ spinlock is supposed to be locked. 304 * 305 * @param unlock IRQ spinlock to be unlocked. 306 * @param lock IRQ spinlock to be locked. 307 * 308 */ 309 void irq_spinlock_exchange(irq_spinlock_t *unlock, irq_spinlock_t *lock) 310 { 311 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 312 313 spinlock_lock(&(lock->lock)); 314 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 315 316 /* Pass guard from unlock to lock */ 317 if (unlock->guard) { 318 lock->guard = true; 319 lock->ipl = unlock->ipl; 320 unlock->guard = false; 321 } 322 323 spinlock_unlock(&(unlock->lock)); 324 } 325 326 /** Find out whether the IRQ spinlock is currently locked. 327 * 328 * @param lock IRQ spinlock. 329 * @return True if the IRQ spinlock is locked, false otherwise. 330 */ 331 bool irq_spinlock_locked(irq_spinlock_t *ilock) 332 { 333 return spinlock_locked(&ilock->lock); 334 } 335 153 336 /** @} 154 337 */
Note:
See TracChangeset
for help on using the changeset viewer.