| 399 | } |
| 400 | |
| 401 | static bool __always_inline |
| 402 | __rw_rlock_try(struct rwlock *rw, struct thread *td, uintptr_t *vp, bool fp |
| 403 | LOCK_FILE_LINE_ARG_DEF) |
| 404 | { |
| 405 | |
| 406 | /* |
| 407 | * Handle the easy case. If no other thread has a write |
| 408 | * lock, then try to bump up the count of read locks. Note |
| 409 | * that we have to preserve the current state of the |
| 410 | * RW_LOCK_WRITE_WAITERS flag. If we fail to acquire a |
| 411 | * read lock, then rw_lock must have changed, so restart |
| 412 | * the loop. Note that this handles the case of a |
| 413 | * completely unlocked rwlock since such a lock is encoded |
| 414 | * as a read lock with no waiters. |
| 415 | */ |
| 416 | while (__rw_can_read(td, *vp, fp)) { |
| 417 | if (atomic_fcmpset_acq_ptr(&rw->rw_lock, vp, |
| 418 | *vp + RW_ONE_READER)) { |
| 419 | if (LOCK_LOG_TEST(&rw->lock_object, 0)) |
| 420 | CTR4(KTR_LOCK, |
| 421 | "%s: %p succeed %p -> %p", __func__, |
| 422 | rw, (void *)*vp, |
| 423 | (void *)(*vp + RW_ONE_READER)); |
| 424 | td->td_rw_rlocks++; |
| 425 | return (true); |
| 426 | } |
| 427 | } |
| 428 | return (false); |
| 429 | } |
| 430 | |
| 431 | static void __noinline |
| 432 | __rw_rlock_hard(struct rwlock *rw, struct thread *td, uintptr_t v |
no test coverage detected