summaryrefslogtreecommitdiffstats
path: root/sys/sys/rmlock.h
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2013-06-25 18:44:15 +0000
committerjhb <jhb@FreeBSD.org>2013-06-25 18:44:15 +0000
commit0807c44cdd0226cdd2553f723a00de3d13882321 (patch)
tree7b07a13eb6ad28065286a3f60650edd2a6a0dc1c /sys/sys/rmlock.h
parent43efcb27b6a0f52dec7b605055f5aae35f6d41de (diff)
downloadFreeBSD-src-0807c44cdd0226cdd2553f723a00de3d13882321.zip
FreeBSD-src-0807c44cdd0226cdd2553f723a00de3d13882321.tar.gz
Several improvements to rmlock(9). Many of these are based on patches
provided by Isilon. - Add an rm_assert() supporting various lock assertions similar to other locking primitives. Because rmlocks track readers the assertions are always fully accurate unlike rw_assert() and sx_assert(). - Flesh out the lock class methods for rmlocks to support sleeping via condvars and rm_sleep() (but only while holding write locks), rmlock details in 'show lock' in DDB, and the lc_owner method used by dtrace. - Add an internal destroyed cookie so that API functions can assert that an rmlock is not destroyed. - Make use of rm_assert() to add various assertions to the API (e.g. to assert locks are held when an unlock routine is called). - Give RM_SLEEPABLE locks their own lock class and always use the rmlock's own lock_object with WITNESS. - Use THREAD_NO_SLEEPING() / THREAD_SLEEPING_OK() to disallow sleeping while holding a read lock on an rmlock. Submitted by: andre Obtained from: EMC/Isilon
Diffstat (limited to 'sys/sys/rmlock.h')
-rw-r--r--sys/sys/rmlock.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/sys/sys/rmlock.h b/sys/sys/rmlock.h
index 5a0fa8a..ed6110a 100644
--- a/sys/sys/rmlock.h
+++ b/sys/sys/rmlock.h
@@ -65,6 +65,10 @@ void _rm_wunlock(struct rmlock *rm);
int _rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker,
int trylock);
void _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker);
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+void _rm_assert(const struct rmlock *rm, int what, const char *file,
+ int line);
+#endif
/*
* Public interface for lock operations.
@@ -89,6 +93,9 @@ void _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker);
#define rm_try_rlock(rm,tracker) _rm_rlock((rm),(tracker), 1)
#define rm_runlock(rm,tracker) _rm_runlock((rm), (tracker))
#endif
+#define rm_sleep(chan, rm, pri, wmesg, timo) \
+ _sleep((chan), &(rm)->lock_object, (pri), (wmesg), \
+ tick_sbt * (timo), 0, C_HARDCLOCK)
struct rm_args {
struct rmlock *ra_rm;
@@ -123,5 +130,20 @@ struct rm_args_flags {
SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
rm_destroy, (rm))
+#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+#define RA_LOCKED LA_LOCKED
+#define RA_RLOCKED LA_SLOCKED
+#define RA_WLOCKED LA_XLOCKED
+#define RA_UNLOCKED LA_UNLOCKED
+#define RA_RECURSED LA_RECURSED
+#define RA_NOTRECURSED LA_NOTRECURSED
+#endif
+
+#ifdef INVARIANTS
+#define rm_assert(rm, what) _rm_assert((rm), (what), LOCK_FILE, LOCK_LINE)
+#else
+#define rm_assert(rm, what)
+#endif
+
#endif /* _KERNEL */
#endif /* !_SYS_RMLOCK_H_ */
OpenPOWER on IntegriCloud