summaryrefslogtreecommitdiff
path: root/kern/lock.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-15 18:30:28 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-17 15:57:15 +0200
commite6c6e15b03639e98df68df35ba0f639bdbc1dc51 (patch)
tree7a8a3c3d253e8d6e38390f17581e0dd2dcb295dc /kern/lock.c
parent347cb29151859a56a6c5f0f355a43033e5e035a5 (diff)
kern: keep track of the writer when debugging locks
* configfrag.ac (MACH_LDEBUG): Adjust comment, we use it to sanity check all locks now. * kern/lock.c (lock_write): Keep track of the writer thread. (lock_done): Clear writer. (lock_read_to_write): Keep track of the writer thread. (lock_write_to_read): Assert that the current thread holds the lock. Clear writer. (lock_try_write): Keep track of the writer thread. (lock_try_read_to_write): Likewise. (lock_set_recursive): Assert that the current thread holds the lock. * kern/lock.h (struct lock): New field `writer'. (have_read_lock, have_write_lock, have_lock): New macros that can be used to assert that the current thread holds the given lock. If MACH_LDEBUG is not set, they evaluate to true.
Diffstat (limited to 'kern/lock.c')
-rw-r--r--kern/lock.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/kern/lock.c b/kern/lock.c
index de22795..46c78da 100644
--- a/kern/lock.c
+++ b/kern/lock.c
@@ -318,6 +318,9 @@ void lock_write(
simple_lock(&l->interlock);
}
}
+#if MACH_LDEBUG
+ l->writer = current_thread();
+#endif /* MACH_LDEBUG */
simple_unlock(&l->interlock);
}
@@ -334,8 +337,12 @@ void lock_done(
else
if (l->want_upgrade)
l->want_upgrade = FALSE;
- else
+ else {
l->want_write = FALSE;
+#if MACH_LDEBUG
+ l->writer = THREAD_NULL;
+#endif /* MACH_LDEBUG */
+ }
/*
* There is no reason to wakeup a waiting thread
@@ -452,6 +459,9 @@ boolean_t lock_read_to_write(
}
}
+#if MACH_LDEBUG
+ l->writer = current_thread();
+#endif /* MACH_LDEBUG */
simple_unlock(&l->interlock);
return FALSE;
}
@@ -460,6 +470,9 @@ void lock_write_to_read(
lock_t l)
{
simple_lock(&l->interlock);
+#if MACH_LDEBUG
+ assert(l->writer == current_thread());
+#endif /* MACH_LDEBUG */
l->read_count++;
if (l->recursion_depth != 0)
@@ -475,6 +488,9 @@ void lock_write_to_read(
thread_wakeup(l);
}
+#if MACH_LDEBUG
+ l->writer = THREAD_NULL;
+#endif /* MACH_LDEBUG */
simple_unlock(&l->interlock);
}
@@ -514,6 +530,9 @@ boolean_t lock_try_write(
*/
l->want_write = TRUE;
+#if MACH_LDEBUG
+ l->writer = current_thread();
+#endif /* MACH_LDEBUG */
simple_unlock(&l->interlock);
return TRUE;
}
@@ -590,6 +609,9 @@ boolean_t lock_try_read_to_write(
simple_lock(&l->interlock);
}
+#if MACH_LDEBUG
+ l->writer = current_thread();
+#endif /* MACH_LDEBUG */
simple_unlock(&l->interlock);
return TRUE;
}
@@ -602,6 +624,10 @@ void lock_set_recursive(
lock_t l)
{
simple_lock(&l->interlock);
+#if MACH_LDEBUG
+ assert(l->writer == current_thread());
+#endif /* MACH_LDEBUG */
+
if (!l->want_write) {
panic("lock_set_recursive: don't have write lock");
}