From 75e34439527edaf9299da07b54c305a5068b3a1a Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 15 Aug 2015 18:30:28 +0200 Subject: yyy kern: keep track of the writer when debugging locks * kern/lock.c * kern/lock.h --- kern/lock.c | 28 +++++++++++++++++++++++++++- kern/lock.h | 19 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 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"); } diff --git a/kern/lock.h b/kern/lock.h index 85f03a4..ea7a977 100644 --- a/kern/lock.h +++ b/kern/lock.h @@ -174,6 +174,9 @@ struct lock { /* boolean_t */ can_sleep:1, /* Can attempts to lock go to sleep? */ recursion_depth:12, /* Depth of recursion */ :0; +#if MACH_LDEBUG + struct thread *writer; +#endif /* MACH_LDEBUG */ decl_simple_lock_data(,interlock) /* Hardware interlock field. Last in the structure so that @@ -199,11 +202,25 @@ extern boolean_t lock_try_read_to_write(lock_t); #define lock_read_done(l) lock_done(l) #define lock_write_done(l) lock_done(l) +#if ! MACH_LDEBUG #define lock_taken(l) ((l)->want_write || (l)->read_count) - +#else /* MACH_LDEBUG */ +#define lock_taken(l) ((l)->writer == current_thread() \ + || (l)->read_count) +#endif /* MACH_LDEBUG */ extern void lock_set_recursive(lock_t); extern void lock_clear_recursive(lock_t); +/* Lock debugging support. */ +#if ! MACH_LDEBUG +#define have_read_lock(l) 1 +#define have_write_lock(l) 1 +#else /* MACH_LDEBUG */ +#define have_read_lock(l) ((l)->read_count > 0) +#define have_write_lock(l) ((l)->writer == current_thread()) +#endif /* MACH_LDEBUG */ +#define have_lock(l) (have_read_lock(l) || have_write_lock(l)) + void db_show_all_slocks(void); #endif /* _KERN_LOCK_H_ */ -- cgit v1.2.3