summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_rwlock.c
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2019-11-16 16:21:10 +0000
committervisa <visa@openbsd.org>2019-11-16 16:21:10 +0000
commitd8449269f3d4b2b48d2eb3b3e789cae1e149f79f (patch)
tree414f5d46081c646ce9cb97f223ef1538f37141d4 /sys/kern/kern_rwlock.c
parentRevert previous deduplication diff, I broke portable in a strange way. (diff)
downloadwireguard-openbsd-d8449269f3d4b2b48d2eb3b3e789cae1e149f79f.tar.xz
wireguard-openbsd-d8449269f3d4b2b48d2eb3b3e789cae1e149f79f.zip
Provide exact lock assertions for rwlocks when witness(4) is enabled.
The checker keeps track of all held rwlocks, so it is able to tell if a given thread holds a specific lock even when the lock is shared. OK anton@ mpi@
Diffstat (limited to 'sys/kern/kern_rwlock.c')
-rw-r--r--sys/kern/kern_rwlock.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index 54c3ad80529..d52349c100d 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_rwlock.c,v 1.41 2019/11/12 07:51:46 mpi Exp $ */
+/* $OpenBSD: kern_rwlock.c,v 1.42 2019/11/16 16:21:10 visa Exp $ */
/*
* Copyright (c) 2002, 2003 Artur Grabowski <art@openbsd.org>
@@ -363,11 +363,15 @@ rw_assert_wrlock(struct rwlock *rwl)
if (panicstr || db_active)
return;
+#ifdef WITNESS
+ witness_assert(&rwl->rwl_lock_obj, LA_XLOCKED);
+#else
if (!(rwl->rwl_owner & RWLOCK_WRLOCK))
panic("%s: lock not held", rwl->rwl_name);
if (RWLOCK_OWNER(rwl) != (struct proc *)RW_PROC(curproc))
panic("%s: lock not held by this process", rwl->rwl_name);
+#endif
}
void
@@ -376,8 +380,12 @@ rw_assert_rdlock(struct rwlock *rwl)
if (panicstr || db_active)
return;
+#ifdef WITNESS
+ witness_assert(&rwl->rwl_lock_obj, LA_SLOCKED);
+#else
if (!RWLOCK_OWNER(rwl) || (rwl->rwl_owner & RWLOCK_WRLOCK))
panic("%s: lock not shared", rwl->rwl_name);
+#endif
}
void
@@ -386,12 +394,16 @@ rw_assert_anylock(struct rwlock *rwl)
if (panicstr || db_active)
return;
+#ifdef WITNESS
+ witness_assert(&rwl->rwl_lock_obj, LA_LOCKED);
+#else
switch (rw_status(rwl)) {
case RW_WRITE_OTHER:
panic("%s: lock held by different process", rwl->rwl_name);
case 0:
panic("%s: lock not held", rwl->rwl_name);
}
+#endif
}
void
@@ -400,8 +412,12 @@ rw_assert_unlocked(struct rwlock *rwl)
if (panicstr || db_active)
return;
+#ifdef WITNESS
+ witness_assert(&rwl->rwl_lock_obj, LA_UNLOCKED);
+#else
if (RW_PROC(curproc) == RW_PROC(rwl->rwl_owner))
panic("%s: lock held", rwl->rwl_name);
+#endif
}
#endif