Lines Matching full:lock
36 #include <sys/lock.h>
64 * Lock is in cheat mode when RL_CHEAT_CHEATING bit is set in the
65 * lock->head. Special cookies are returned in this mode, and
86 rangelock_cheat_drain(struct rangelock *lock)
92 v = atomic_load_ptr(&lock->head);
95 sleepq_add(&lock->head, NULL, "ranged1", 0, 0);
96 sleepq_wait(&lock->head, PRI_USER);
97 sleepq_lock(&lock->head);
99 sleepq_release(&lock->head);
104 rangelock_cheat_lock(struct rangelock *lock, int locktype, bool trylock,
109 v = atomic_load_ptr(&lock->head);
118 sleepq_lock(&lock->head);
120 rangelock_cheat_drain(lock);
133 sleepq_lock(&lock->head);
134 if (atomic_fcmpset_rel_ptr(&lock->head, &v,
137 sleepq_release(&lock->head);
142 if (atomic_fcmpset_acq_ptr(&lock->head, &v,
162 sleepq_lock(&lock->head);
163 if (atomic_fcmpset_rel_ptr(&lock->head, &v,
166 sleepq_release(&lock->head);
170 if (atomic_fcmpset_acq_ptr(&lock->head, &v,
189 rangelock_cheat_unlock(struct rangelock *lock, void *cookie)
193 v = atomic_load_ptr(&lock->head);
210 if (atomic_fcmpset_rel_ptr(&lock->head,
214 sleepq_lock(&lock->head);
215 if (atomic_fcmpset_rel_ptr(&lock->head,
218 &lock->head,
220 sleepq_release(&lock->head);
223 sleepq_release(&lock->head);
227 if (atomic_fcmpset_rel_ptr(&lock->head, &v,
237 sleepq_lock(&lock->head);
238 atomic_store_ptr(&lock->head, 0);
239 sleepq_broadcast(&lock->head,
241 sleepq_release(&lock->head);
244 if (atomic_fcmpset_ptr(&lock->head, &v,
258 rangelock_cheat_destroy(struct rangelock *lock)
262 v = atomic_load_ptr(&lock->head);
280 * rl_q_next links all granted ranges in the lock. We cannot free an
300 static void rangelock_noncheating_destroy(struct rangelock *lock);
330 rangelock_init(struct rangelock *lock)
332 lock->sleepers = false;
333 atomic_store_ptr(&lock->head, rangelock_cheat ? RL_CHEAT_CHEATING : 0);
337 rangelock_destroy(struct rangelock *lock)
339 MPASS(!lock->sleepers);
340 if (!rangelock_cheat_destroy(lock))
341 rangelock_noncheating_destroy(lock);
342 DEBUG_POISON_POINTER(*(void **)&lock->head);
401 rangelock_unlock_int(struct rangelock *lock, struct rl_q_entry *e)
405 MPASS(lock != NULL && e != NULL);
410 sleepers = lock->sleepers;
411 lock->sleepers = false;
413 sleepq_broadcast(&lock->sleepers, SLEEPQ_SLEEP, 0, 0);
417 rangelock_unlock(struct rangelock *lock, void *cookie)
419 if (rangelock_cheat_unlock(lock, cookie))
422 sleepq_lock(&lock->sleepers);
423 rangelock_unlock_int(lock, cookie);
424 sleepq_release(&lock->sleepers);
432 * 0 if e1 and e2 overlap and at least one lock is writer
454 rl_insert_sleep(struct rangelock *lock)
458 lock->sleepers = true;
459 sleepq_add(&lock->sleepers, NULL, "rangelk", 0, 0);
460 sleepq_wait(&lock->sleepers, PRI_USER);
475 rangelock_noncheating_destroy(struct rangelock *lock)
482 prev = (struct rl_q_entry **)&lock->head;
508 sleepq_lock(&lock->sleepers);
510 rl_insert_sleep(lock);
525 rl_r_validate(struct rangelock *lock, struct rl_q_entry *e, bool trylock,
554 sleepq_lock(&lock->sleepers);
556 sleepq_release(&lock->sleepers);
559 rangelock_unlock_int(lock, e);
561 sleepq_release(&lock->sleepers);
564 rl_insert_sleep(lock);
571 rl_w_validate(struct rangelock *lock, struct rl_q_entry *e,
577 prev = (struct rl_q_entry **)&lock->head;
599 sleepq_lock(&lock->sleepers);
603 sleepq_release(&lock->sleepers);
606 rangelock_unlock_int(lock, e);
608 sleepq_release(&lock->sleepers);
611 rl_insert_sleep(lock);
617 rl_insert(struct rangelock *lock, struct rl_q_entry *e, bool trylock,
624 prev = (struct rl_q_entry **)&lock->head;
656 sleepq_lock(&lock->sleepers);
659 sleepq_release(&lock->sleepers);
663 sleepq_release(&lock->sleepers);
666 rl_insert_sleep(lock);
674 rl_r_validate(lock, e, trylock, free) :
675 rl_w_validate(lock, e, trylock, free));
685 rangelock_lock_int(struct rangelock *lock, bool trylock, vm_ooffset_t start,
692 if (rangelock_cheat_lock(lock, locktype, trylock, &cookie))
698 res = rl_insert(lock, e, trylock, &free);
712 rangelock_rlock(struct rangelock *lock, vm_ooffset_t start, vm_ooffset_t end)
714 return (rangelock_lock_int(lock, false, start, end, RL_LOCK_READ));
718 rangelock_tryrlock(struct rangelock *lock, vm_ooffset_t start, vm_ooffset_t end)
720 return (rangelock_lock_int(lock, true, start, end, RL_LOCK_READ));
724 rangelock_wlock(struct rangelock *lock, vm_ooffset_t start, vm_ooffset_t end)
726 return (rangelock_lock_int(lock, false, start, end, RL_LOCK_WRITE));
730 rangelock_trywlock(struct rangelock *lock, vm_ooffset_t start, vm_ooffset_t end)
732 return (rangelock_lock_int(lock, true, start, end, RL_LOCK_WRITE));
737 * same lock simultaneously, switch to the non-cheat mode. Cheat mode
741 rangelock_may_recurse(struct rangelock *lock)
745 v = atomic_load_ptr(&lock->head);
749 sleepq_lock(&lock->head);
752 sleepq_release(&lock->head);
760 if (atomic_fcmpset_ptr(&lock->head, &v, x) != 0) {
761 rangelock_cheat_drain(lock);
769 if (atomic_fcmpset_ptr(&lock->head, &v, x) != 0) {
770 sleepq_release(&lock->head);
789 struct rangelock *lock;
798 lock = (struct rangelock *)addr;
799 db_printf("rangelock %p sleepers %d\n", lock, lock->sleepers);
800 v = lock->head;
805 for (e = (struct rl_q_entry *)(lock->head);;) {