diff options
author | jhb <jhb@FreeBSD.org> | 2001-08-23 22:47:05 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-08-23 22:47:05 +0000 |
commit | 93fe8f866da9c2d2485f2d226feec9259756ba1c (patch) | |
tree | 97fce3663f339733cd33bb6f57b543754ea1a5ef /sys/kern/subr_witness.c | |
parent | 4c37bfb8ee93101b59e967c6303d9cdabe5b7819 (diff) | |
download | FreeBSD-src-93fe8f866da9c2d2485f2d226feec9259756ba1c.zip FreeBSD-src-93fe8f866da9c2d2485f2d226feec9259756ba1c.tar.gz |
Add witness_upgrade() and witness_downgrade() for handling upgrades and
downgrades of shared/exclusive locks.
Diffstat (limited to 'sys/kern/subr_witness.c')
-rw-r--r-- | sys/kern/subr_witness.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 6e6dd5a..9ffb31a 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -348,6 +348,11 @@ witness_init(struct lock_object *lock) panic("%s: lock (%s) %s can not be sleepable!\n", __func__, class->lc_name, lock->lo_name); + if ((lock->lo_flags & LO_UPGRADABLE) != 0 && + (class->lc_flags & LC_UPGRADABLE) == 0) + panic("%s: lock (%s) %s can not be upgradable!\n", __func__, + class->lc_name, lock->lo_name); + mtx_lock(&all_mtx); STAILQ_INSERT_TAIL(&all_locks, lock, lo_list); lock->lo_flags |= LO_INITIALIZED; @@ -713,6 +718,72 @@ out: } void +witness_upgrade(struct lock_object *lock, int flags, const char *file, int line) +{ + struct lock_instance *instance; + struct lock_class *class; + + KASSERT(!witness_cold, ("%s: witness_cold\n", __func__)); + if (lock->lo_witness == NULL || witness_dead || panicstr != NULL) + return; + + class = lock->lo_class; + if ((lock->lo_flags & LO_UPGRADABLE) == 0) + panic("upgrade of non-upgradable lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + if ((flags & LOP_TRYLOCK) == 0) + panic("non-try upgrade of lock (%s) %s @ %s:%d", class->lc_name, + lock->lo_name, file, line); + if ((lock->lo_class->lc_flags & LC_SLEEPLOCK) == 0) + panic("upgrade of non-sleep lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + instance = find_instance(curproc->p_sleeplocks, lock); + if (instance == NULL) + panic("upgrade of unlocked lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + if ((instance->li_flags & LI_EXCLUSIVE) != 0) + panic("upgrade of exclusive lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + if ((instance->li_flags & LI_RECURSEMASK) != 0) + panic("upgrade of recursed lock (%s) %s r=%d @ %s:%d", + class->lc_name, lock->lo_name, + instance->li_flags & LI_RECURSEMASK, file, line); + instance->li_flags |= LI_EXCLUSIVE; +} + +void +witness_downgrade(struct lock_object *lock, int flags, const char *file, + int line) +{ + struct lock_instance *instance; + struct lock_class *class; + + KASSERT(!witness_cold, ("%s: witness_cold\n", __func__)); + if (lock->lo_witness == NULL || witness_dead || panicstr != NULL) + return; + + class = lock->lo_class; + if ((lock->lo_flags & LO_UPGRADABLE) == 0) + panic("downgrade of non-upgradable lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + if ((lock->lo_class->lc_flags & LC_SLEEPLOCK) == 0) + panic("downgrade of non-sleep lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + instance = find_instance(curproc->p_sleeplocks, lock); + if (instance == NULL) + panic("downgrade of unlocked lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + if ((instance->li_flags & LI_EXCLUSIVE) == 0) + panic("downgrade of shared lock (%s) %s @ %s:%d", + class->lc_name, lock->lo_name, file, line); + if ((instance->li_flags & LI_RECURSEMASK) != 0) + panic("downgrade of recursed lock (%s) %s r=%d @ %s:%d", + class->lc_name, lock->lo_name, + instance->li_flags & LI_RECURSEMASK, file, line); + instance->li_flags &= ~LI_EXCLUSIVE; +} + +void witness_unlock(struct lock_object *lock, int flags, const char *file, int line) { struct lock_list_entry **lock_list, *lle; |