1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
From 527997b2efdb6bd14cc051dd85a0d4940bc453dc 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: [PATCH gnumach 04/12] yyy kern: keep track of the writer when
debugging locks
* kern/lock.c
* kern/lock.h
---
kern/lock.c | 28 +++++++++++++++++++++++++++-
kern/lock.h | 13 +++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
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 e88e182..b237a94 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
@@ -203,6 +206,16 @@ extern boolean_t lock_try_read_to_write(lock_t);
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_ */
--
2.1.4
|