Changeset a9f1372 in mainline
- Timestamp:
- 2010-05-25T18:35:36Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b7398c0
- Parents:
- 0095368
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/synch/spinlock.h
r0095368 ra9f1372 277 277 IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name) 278 278 279 /** Initialize interrupts-disabled spinlock 280 * 281 * @param lock IRQ spinlock to be initialized. 282 * @param name IRQ spinlock name. 283 * 284 */ 285 static inline void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name) 286 { 287 spinlock_initialize(&(lock->lock), name); 288 lock->guard = false; 289 lock->ipl = 0; 290 } 291 292 /** Lock interrupts-disabled spinlock 293 * 294 * Lock a spinlock which requires disabled interrupts. 295 * 296 * @param lock IRQ spinlock to be locked. 297 * @param irq_dis If true, interrupts are actually disabled 298 * prior locking the spinlock. If false, interrupts 299 * are expected to be already disabled. 300 * 301 */ 302 static inline void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis) 303 { 304 if (irq_dis) { 305 ipl_t ipl = interrupts_disable(); 306 spinlock_lock(&(lock->lock)); 307 308 lock->guard = true; 309 lock->ipl = ipl; 310 } else { 311 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 312 313 spinlock_lock(&(lock->lock)); 314 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 315 } 316 } 317 318 /** Unlock interrupts-disabled spinlock 319 * 320 * Unlock a spinlock which requires disabled interrupts. 321 * 322 * @param lock IRQ spinlock to be unlocked. 323 * @param irq_res If true, interrupts are restored to previously 324 * saved interrupt level. 325 * 326 */ 327 static inline void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res) 328 { 329 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 330 331 if (irq_res) { 332 ASSERT_IRQ_SPINLOCK(lock->guard, lock); 333 334 lock->guard = false; 335 ipl_t ipl = lock->ipl; 336 337 spinlock_unlock(&(lock->lock)); 338 interrupts_restore(ipl); 339 } else { 340 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 341 spinlock_unlock(&(lock->lock)); 342 } 343 } 344 345 /** Lock interrupts-disabled spinlock 346 * 347 * Lock an interrupts-disabled spinlock conditionally. If the 348 * spinlock is not available at the moment, signal failure. 349 * Interrupts are expected to be already disabled. 350 * 351 * @param lock IRQ spinlock to be locked conditionally. 352 * 353 * @return Zero on failure, non-zero otherwise. 354 * 355 */ 356 static inline int irq_spinlock_trylock(irq_spinlock_t *lock) 357 { 358 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 359 int rc = spinlock_trylock(&(lock->lock)); 360 361 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 362 return rc; 363 } 364 365 /** Pass lock from one interrupts-disabled spinlock to another 366 * 367 * Pass lock from one IRQ spinlock to another IRQ spinlock 368 * without enabling interrupts during the process. 369 * 370 * The first IRQ spinlock is supposed to be locked. 371 * 372 * @param unlock IRQ spinlock to be unlocked. 373 * @param lock IRQ spinlock to be locked. 374 * 375 */ 376 static inline void irq_spinlock_pass(irq_spinlock_t *unlock, 377 irq_spinlock_t *lock) 378 { 379 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 380 381 /* Pass guard from unlock to lock */ 382 bool guard = unlock->guard; 383 ipl_t ipl = unlock->ipl; 384 unlock->guard = false; 385 386 spinlock_unlock(&(unlock->lock)); 387 spinlock_lock(&(lock->lock)); 388 389 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 390 391 if (guard) { 392 lock->guard = true; 393 lock->ipl = ipl; 394 } 395 } 396 397 /** Hand-over-hand locking of interrupts-disabled spinlocks 398 * 399 * Implement hand-over-hand locking between two interrupts-disabled 400 * spinlocks without enabling interrupts during the process. 401 * 402 * The first IRQ spinlock is supposed to be locked. 403 * 404 * @param unlock IRQ spinlock to be unlocked. 405 * @param lock IRQ spinlock to be locked. 406 * 407 */ 408 static inline void irq_spinlock_exchange(irq_spinlock_t *unlock, 409 irq_spinlock_t *lock) 410 { 411 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 412 413 spinlock_lock(&(lock->lock)); 414 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 415 416 /* Pass guard from unlock to lock */ 417 if (unlock->guard) { 418 lock->guard = true; 419 lock->ipl = unlock->ipl; 420 unlock->guard = false; 421 } 422 423 spinlock_unlock(&(unlock->lock)); 424 } 279 extern void irq_spinlock_initialize(irq_spinlock_t *, const char *); 280 extern void irq_spinlock_lock(irq_spinlock_t *, bool); 281 extern void irq_spinlock_unlock(irq_spinlock_t *, bool); 282 extern int irq_spinlock_trylock(irq_spinlock_t *); 283 extern void irq_spinlock_pass(irq_spinlock_t *, irq_spinlock_t *); 284 extern void irq_spinlock_exchange(irq_spinlock_t *, irq_spinlock_t *); 425 285 426 286 #endif -
kernel/generic/src/synch/spinlock.c
r0095368 ra9f1372 169 169 #endif 170 170 171 /** Initialize interrupts-disabled spinlock 172 * 173 * @param lock IRQ spinlock to be initialized. 174 * @param name IRQ spinlock name. 175 * 176 */ 177 void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name) 178 { 179 spinlock_initialize(&(lock->lock), name); 180 lock->guard = false; 181 lock->ipl = 0; 182 } 183 184 /** Lock interrupts-disabled spinlock 185 * 186 * Lock a spinlock which requires disabled interrupts. 187 * 188 * @param lock IRQ spinlock to be locked. 189 * @param irq_dis If true, interrupts are actually disabled 190 * prior locking the spinlock. If false, interrupts 191 * are expected to be already disabled. 192 * 193 */ 194 void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis) 195 { 196 if (irq_dis) { 197 ipl_t ipl = interrupts_disable(); 198 spinlock_lock(&(lock->lock)); 199 200 lock->guard = true; 201 lock->ipl = ipl; 202 } else { 203 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 204 205 spinlock_lock(&(lock->lock)); 206 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 207 } 208 } 209 210 /** Unlock interrupts-disabled spinlock 211 * 212 * Unlock a spinlock which requires disabled interrupts. 213 * 214 * @param lock IRQ spinlock to be unlocked. 215 * @param irq_res If true, interrupts are restored to previously 216 * saved interrupt level. 217 * 218 */ 219 void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res) 220 { 221 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 222 223 if (irq_res) { 224 ASSERT_IRQ_SPINLOCK(lock->guard, lock); 225 226 lock->guard = false; 227 ipl_t ipl = lock->ipl; 228 229 spinlock_unlock(&(lock->lock)); 230 interrupts_restore(ipl); 231 } else { 232 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 233 spinlock_unlock(&(lock->lock)); 234 } 235 } 236 237 /** Lock interrupts-disabled spinlock 238 * 239 * Lock an interrupts-disabled spinlock conditionally. If the 240 * spinlock is not available at the moment, signal failure. 241 * Interrupts are expected to be already disabled. 242 * 243 * @param lock IRQ spinlock to be locked conditionally. 244 * 245 * @return Zero on failure, non-zero otherwise. 246 * 247 */ 248 int irq_spinlock_trylock(irq_spinlock_t *lock) 249 { 250 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 251 int rc = spinlock_trylock(&(lock->lock)); 252 253 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 254 return rc; 255 } 256 257 /** Pass lock from one interrupts-disabled spinlock to another 258 * 259 * Pass lock from one IRQ spinlock to another IRQ spinlock 260 * without enabling interrupts during the process. 261 * 262 * The first IRQ spinlock is supposed to be locked. 263 * 264 * @param unlock IRQ spinlock to be unlocked. 265 * @param lock IRQ spinlock to be locked. 266 * 267 */ 268 void irq_spinlock_pass(irq_spinlock_t *unlock, irq_spinlock_t *lock) 269 { 270 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 271 272 /* Pass guard from unlock to lock */ 273 bool guard = unlock->guard; 274 ipl_t ipl = unlock->ipl; 275 unlock->guard = false; 276 277 spinlock_unlock(&(unlock->lock)); 278 spinlock_lock(&(lock->lock)); 279 280 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 281 282 if (guard) { 283 lock->guard = true; 284 lock->ipl = ipl; 285 } 286 } 287 288 /** Hand-over-hand locking of interrupts-disabled spinlocks 289 * 290 * Implement hand-over-hand locking between two interrupts-disabled 291 * spinlocks without enabling interrupts during the process. 292 * 293 * The first IRQ spinlock is supposed to be locked. 294 * 295 * @param unlock IRQ spinlock to be unlocked. 296 * @param lock IRQ spinlock to be locked. 297 * 298 */ 299 void irq_spinlock_exchange(irq_spinlock_t *unlock, irq_spinlock_t *lock) 300 { 301 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 302 303 spinlock_lock(&(lock->lock)); 304 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 305 306 /* Pass guard from unlock to lock */ 307 if (unlock->guard) { 308 lock->guard = true; 309 lock->ipl = unlock->ipl; 310 unlock->guard = false; 311 } 312 313 spinlock_unlock(&(unlock->lock)); 314 } 315 171 316 /** @} 172 317 */
Note:
See TracChangeset
for help on using the changeset viewer.