summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-15 17:04:08 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-17 15:44:04 +0200
commit347cb29151859a56a6c5f0f355a43033e5e035a5 (patch)
tree9800e817d7712ad3d2a8e36c309466fefe2efeb1
parentbdc9b8583e6336bb3a44a80f10bac8b7b369719c (diff)
kern: improve simple lock debugging
Do not bother saving the return address when acquire a simple lock. Save the location as provided by the compiler as string instead. Also save the lock parameter. * kern/lock.c (struct simple_locks_info): Drop `ra', add `expr', `loc'. (simple_lock): Rename to `_simple_lock', add expression and location parameters and save them. (simple_lock_try): Likewise. (simple_unlock): Zero-out the now unused slot in the list of taken locks. (db_show_all_slocks): Use the new information. * kern/lock.h (simple_lock, simple_lock_try): Provide macro versions passing the location and expression as string.
-rw-r--r--kern/lock.c32
-rw-r--r--kern/lock.h15
2 files changed, 30 insertions, 17 deletions
diff --git a/kern/lock.c b/kern/lock.c
index d894b06c..de227950 100644
--- a/kern/lock.c
+++ b/kern/lock.c
@@ -133,7 +133,8 @@ unsigned int simple_locks_taken = 0;
struct simple_locks_info {
simple_lock_t l;
- void *ra;
+ const char *expr;
+ const char *loc;
} simple_locks_info[NSLINFO];
int do_check_simple_locks = 1;
@@ -162,8 +163,10 @@ void simple_lock_init(
l->lock_data = 0;
}
-void simple_lock(
- simple_lock_t l)
+void _simple_lock(
+ simple_lock_t l,
+ const char *expression,
+ const char *location)
{
struct simple_locks_info *info;
@@ -173,12 +176,14 @@ void simple_lock(
info = &simple_locks_info[simple_locks_taken++];
info->l = l;
- info->ra =
- __builtin_extract_return_addr (__builtin_return_address (0));
+ info->expr = expression;
+ info->loc = location;
}
-boolean_t simple_lock_try(
- simple_lock_t l)
+boolean_t _simple_lock_try(
+ simple_lock_t l,
+ const char *expression,
+ const char *location)
{
struct simple_locks_info *info;
@@ -189,8 +194,8 @@ boolean_t simple_lock_try(
info = &simple_locks_info[simple_locks_taken++];
info->l = l;
- info->ra =
- __builtin_extract_return_addr (__builtin_return_address (0));
+ info->expr = expression;
+ info->loc = location;
return TRUE;
}
@@ -214,6 +219,7 @@ void simple_unlock(
simple_locks_info[i] = simple_locks_info[simple_locks_taken-1];
}
+ simple_locks_info[simple_locks_taken] = (struct simple_locks_info) {0};
simple_locks_taken--;
}
@@ -628,13 +634,9 @@ void db_show_all_slocks(void)
for (i = 0; i < simple_locks_taken; i++) {
info = &simple_locks_info[i];
- db_printf("%d: ", i);
+ db_printf("%d: %s (", i, info->expr);
db_printsym(info->l, DB_STGY_ANY);
-#if defined(__i386__)
- db_printf(" locked by ");
- db_printsym(info->ra, DB_STGY_PROC);
-#endif
- db_printf("\n");
+ db_printf(") locked by %s\n", info->loc);
}
}
#else /* MACH_SLOCKS && NCPUS == 1 */
diff --git a/kern/lock.h b/kern/lock.h
index 0eba0ad1..e88e1824 100644
--- a/kern/lock.h
+++ b/kern/lock.h
@@ -90,9 +90,20 @@ class simple_lock_data_t name;
*/
extern void simple_lock_init(simple_lock_t);
-extern void simple_lock(simple_lock_t);
+extern void _simple_lock(simple_lock_t,
+ const char *, const char *);
extern void simple_unlock(simple_lock_t);
-extern boolean_t simple_lock_try(simple_lock_t);
+extern boolean_t _simple_lock_try(simple_lock_t,
+ const char *, const char *);
+
+/* We provide simple_lock and simple_lock_try so that we can save the
+ location. */
+#define XSTR(x) #x
+#define STR(x) XSTR(x)
+#define LOCATION __FILE__ ":" STR(__LINE__)
+
+#define simple_lock(lock) _simple_lock((lock), #lock, LOCATION)
+#define simple_lock_try(lock) _simple_lock_try((lock), #lock, LOCATION)
#define simple_lock_pause()
#define simple_lock_taken(lock) (simple_lock_assert(lock), \