diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-08-15 18:30:28 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-08-17 15:57:15 +0200 |
commit | e6c6e15b03639e98df68df35ba0f639bdbc1dc51 (patch) | |
tree | 7a8a3c3d253e8d6e38390f17581e0dd2dcb295dc /kern/lock.c | |
parent | 347cb29151859a56a6c5f0f355a43033e5e035a5 (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.c | 28 |
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"); } |