Blame


1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
2 6f4d00ee 2013-09-23 0intro #include "dat.h"
3 6f4d00ee 2013-09-23 0intro #include "fns.h"
4 6f4d00ee 2013-09-23 0intro #include "error.h"
5 6f4d00ee 2013-09-23 0intro
6 6f4d00ee 2013-09-23 0intro /*
7 6f4d00ee 2013-09-23 0intro * Lock watcher. Check that locking of blocks is always down.
8 6f4d00ee 2013-09-23 0intro *
9 6f4d00ee 2013-09-23 0intro * This is REALLY slow, and it won't work when the blocks aren't
10 6f4d00ee 2013-09-23 0intro * arranged in a tree (e.g., after the first snapshot). But it's great
11 6f4d00ee 2013-09-23 0intro * for debugging.
12 6f4d00ee 2013-09-23 0intro */
13 6f4d00ee 2013-09-23 0intro enum
14 6f4d00ee 2013-09-23 0intro {
15 6f4d00ee 2013-09-23 0intro MaxLock = 16,
16 6f4d00ee 2013-09-23 0intro HashSize = 1009,
17 6f4d00ee 2013-09-23 0intro };
18 6f4d00ee 2013-09-23 0intro
19 6f4d00ee 2013-09-23 0intro /*
20 6f4d00ee 2013-09-23 0intro * Thread-specific watch state.
21 6f4d00ee 2013-09-23 0intro */
22 6f4d00ee 2013-09-23 0intro typedef struct WThread WThread;
23 6f4d00ee 2013-09-23 0intro struct WThread
24 6f4d00ee 2013-09-23 0intro {
25 6f4d00ee 2013-09-23 0intro Block *b[MaxLock]; /* blocks currently held */
26 6f4d00ee 2013-09-23 0intro uint nb;
27 6f4d00ee 2013-09-23 0intro uint pid;
28 6f4d00ee 2013-09-23 0intro };
29 6f4d00ee 2013-09-23 0intro
30 6f4d00ee 2013-09-23 0intro typedef struct WMap WMap;
31 6f4d00ee 2013-09-23 0intro typedef struct WEntry WEntry;
32 6f4d00ee 2013-09-23 0intro
33 6f4d00ee 2013-09-23 0intro struct WEntry
34 6f4d00ee 2013-09-23 0intro {
35 6f4d00ee 2013-09-23 0intro uchar c[VtScoreSize];
36 6f4d00ee 2013-09-23 0intro uchar p[VtScoreSize];
37 6f4d00ee 2013-09-23 0intro int off;
38 6f4d00ee 2013-09-23 0intro
39 6f4d00ee 2013-09-23 0intro WEntry *cprev;
40 6f4d00ee 2013-09-23 0intro WEntry *cnext;
41 6f4d00ee 2013-09-23 0intro WEntry *pprev;
42 6f4d00ee 2013-09-23 0intro WEntry *pnext;
43 6f4d00ee 2013-09-23 0intro };
44 6f4d00ee 2013-09-23 0intro
45 6f4d00ee 2013-09-23 0intro struct WMap
46 6f4d00ee 2013-09-23 0intro {
47 4b576658 2013-09-23 0intro QLock lk;
48 6f4d00ee 2013-09-23 0intro
49 6f4d00ee 2013-09-23 0intro WEntry *hchild[HashSize];
50 6f4d00ee 2013-09-23 0intro WEntry *hparent[HashSize];
51 6f4d00ee 2013-09-23 0intro };
52 6f4d00ee 2013-09-23 0intro
53 6f4d00ee 2013-09-23 0intro static WMap map;
54 6f4d00ee 2013-09-23 0intro static void **wp;
55 6f4d00ee 2013-09-23 0intro static uint blockSize;
56 6f4d00ee 2013-09-23 0intro static WEntry *pool;
57 6f4d00ee 2013-09-23 0intro uint bwatchDisabled;
58 6f4d00ee 2013-09-23 0intro
59 6f4d00ee 2013-09-23 0intro static uint
60 6f4d00ee 2013-09-23 0intro hash(uchar score[VtScoreSize])
61 6f4d00ee 2013-09-23 0intro {
62 6f4d00ee 2013-09-23 0intro uint i, h;
63 6f4d00ee 2013-09-23 0intro
64 6f4d00ee 2013-09-23 0intro h = 0;
65 6f4d00ee 2013-09-23 0intro for(i=0; i<VtScoreSize; i++)
66 6f4d00ee 2013-09-23 0intro h = h*37 + score[i];
67 6f4d00ee 2013-09-23 0intro return h%HashSize;
68 6f4d00ee 2013-09-23 0intro }
69 6f4d00ee 2013-09-23 0intro
70 6f4d00ee 2013-09-23 0intro #include <pool.h>
71 6f4d00ee 2013-09-23 0intro static void
72 6f4d00ee 2013-09-23 0intro freeWEntry(WEntry *e)
73 6f4d00ee 2013-09-23 0intro {
74 6f4d00ee 2013-09-23 0intro memset(e, 0, sizeof(WEntry));
75 6f4d00ee 2013-09-23 0intro e->pnext = pool;
76 6f4d00ee 2013-09-23 0intro pool = e;
77 6f4d00ee 2013-09-23 0intro }
78 6f4d00ee 2013-09-23 0intro
79 6f4d00ee 2013-09-23 0intro static WEntry*
80 6f4d00ee 2013-09-23 0intro allocWEntry(void)
81 6f4d00ee 2013-09-23 0intro {
82 6f4d00ee 2013-09-23 0intro int i;
83 6f4d00ee 2013-09-23 0intro WEntry *w;
84 6f4d00ee 2013-09-23 0intro
85 6f4d00ee 2013-09-23 0intro w = pool;
86 6f4d00ee 2013-09-23 0intro if(w == nil){
87 4b576658 2013-09-23 0intro w = vtmallocz(1024*sizeof(WEntry));
88 6f4d00ee 2013-09-23 0intro for(i=0; i<1024; i++)
89 6f4d00ee 2013-09-23 0intro freeWEntry(&w[i]);
90 6f4d00ee 2013-09-23 0intro w = pool;
91 6f4d00ee 2013-09-23 0intro }
92 6f4d00ee 2013-09-23 0intro pool = w->pnext;
93 6f4d00ee 2013-09-23 0intro memset(w, 0, sizeof(WEntry));
94 6f4d00ee 2013-09-23 0intro return w;
95 6f4d00ee 2013-09-23 0intro }
96 6f4d00ee 2013-09-23 0intro
97 6f4d00ee 2013-09-23 0intro /*
98 6f4d00ee 2013-09-23 0intro * remove all dependencies with score as a parent
99 6f4d00ee 2013-09-23 0intro */
100 6f4d00ee 2013-09-23 0intro static void
101 6f4d00ee 2013-09-23 0intro _bwatchResetParent(uchar *score)
102 6f4d00ee 2013-09-23 0intro {
103 6f4d00ee 2013-09-23 0intro WEntry *w, *next;
104 6f4d00ee 2013-09-23 0intro uint h;
105 6f4d00ee 2013-09-23 0intro
106 6f4d00ee 2013-09-23 0intro h = hash(score);
107 6f4d00ee 2013-09-23 0intro for(w=map.hparent[h]; w; w=next){
108 6f4d00ee 2013-09-23 0intro next = w->pnext;
109 6f4d00ee 2013-09-23 0intro if(memcmp(w->p, score, VtScoreSize) == 0){
110 6f4d00ee 2013-09-23 0intro if(w->pnext)
111 6f4d00ee 2013-09-23 0intro w->pnext->pprev = w->pprev;
112 6f4d00ee 2013-09-23 0intro if(w->pprev)
113 6f4d00ee 2013-09-23 0intro w->pprev->pnext = w->pnext;
114 6f4d00ee 2013-09-23 0intro else
115 6f4d00ee 2013-09-23 0intro map.hparent[h] = w->pnext;
116 6f4d00ee 2013-09-23 0intro if(w->cnext)
117 6f4d00ee 2013-09-23 0intro w->cnext->cprev = w->cprev;
118 6f4d00ee 2013-09-23 0intro if(w->cprev)
119 6f4d00ee 2013-09-23 0intro w->cprev->cnext = w->cnext;
120 6f4d00ee 2013-09-23 0intro else
121 6f4d00ee 2013-09-23 0intro map.hchild[hash(w->c)] = w->cnext;
122 6f4d00ee 2013-09-23 0intro freeWEntry(w);
123 6f4d00ee 2013-09-23 0intro }
124 6f4d00ee 2013-09-23 0intro }
125 6f4d00ee 2013-09-23 0intro }
126 6f4d00ee 2013-09-23 0intro /*
127 fa325e9b 2020-01-10 cross * and child
128 6f4d00ee 2013-09-23 0intro */
129 6f4d00ee 2013-09-23 0intro static void
130 6f4d00ee 2013-09-23 0intro _bwatchResetChild(uchar *score)
131 6f4d00ee 2013-09-23 0intro {
132 6f4d00ee 2013-09-23 0intro WEntry *w, *next;
133 6f4d00ee 2013-09-23 0intro uint h;
134 6f4d00ee 2013-09-23 0intro
135 6f4d00ee 2013-09-23 0intro h = hash(score);
136 6f4d00ee 2013-09-23 0intro for(w=map.hchild[h]; w; w=next){
137 6f4d00ee 2013-09-23 0intro next = w->cnext;
138 6f4d00ee 2013-09-23 0intro if(memcmp(w->c, score, VtScoreSize) == 0){
139 6f4d00ee 2013-09-23 0intro if(w->pnext)
140 6f4d00ee 2013-09-23 0intro w->pnext->pprev = w->pprev;
141 6f4d00ee 2013-09-23 0intro if(w->pprev)
142 6f4d00ee 2013-09-23 0intro w->pprev->pnext = w->pnext;
143 6f4d00ee 2013-09-23 0intro else
144 6f4d00ee 2013-09-23 0intro map.hparent[hash(w->p)] = w->pnext;
145 6f4d00ee 2013-09-23 0intro if(w->cnext)
146 6f4d00ee 2013-09-23 0intro w->cnext->cprev = w->cprev;
147 6f4d00ee 2013-09-23 0intro if(w->cprev)
148 6f4d00ee 2013-09-23 0intro w->cprev->cnext = w->cnext;
149 6f4d00ee 2013-09-23 0intro else
150 6f4d00ee 2013-09-23 0intro map.hchild[h] = w->cnext;
151 6f4d00ee 2013-09-23 0intro freeWEntry(w);
152 6f4d00ee 2013-09-23 0intro }
153 6f4d00ee 2013-09-23 0intro }
154 6f4d00ee 2013-09-23 0intro }
155 6f4d00ee 2013-09-23 0intro
156 6f4d00ee 2013-09-23 0intro static uchar*
157 6f4d00ee 2013-09-23 0intro parent(uchar c[VtScoreSize], int *off)
158 6f4d00ee 2013-09-23 0intro {
159 6f4d00ee 2013-09-23 0intro WEntry *w;
160 6f4d00ee 2013-09-23 0intro uint h;
161 6f4d00ee 2013-09-23 0intro
162 6f4d00ee 2013-09-23 0intro h = hash(c);
163 6f4d00ee 2013-09-23 0intro for(w=map.hchild[h]; w; w=w->cnext)
164 6f4d00ee 2013-09-23 0intro if(memcmp(w->c, c, VtScoreSize) == 0){
165 6f4d00ee 2013-09-23 0intro *off = w->off;
166 6f4d00ee 2013-09-23 0intro return w->p;
167 6f4d00ee 2013-09-23 0intro }
168 6f4d00ee 2013-09-23 0intro return nil;
169 6f4d00ee 2013-09-23 0intro }
170 6f4d00ee 2013-09-23 0intro
171 6f4d00ee 2013-09-23 0intro static void
172 6f4d00ee 2013-09-23 0intro addChild(uchar p[VtEntrySize], uchar c[VtEntrySize], int off)
173 6f4d00ee 2013-09-23 0intro {
174 6f4d00ee 2013-09-23 0intro uint h;
175 6f4d00ee 2013-09-23 0intro WEntry *w;
176 6f4d00ee 2013-09-23 0intro
177 6f4d00ee 2013-09-23 0intro w = allocWEntry();
178 6f4d00ee 2013-09-23 0intro memmove(w->p, p, VtScoreSize);
179 6f4d00ee 2013-09-23 0intro memmove(w->c, c, VtScoreSize);
180 6f4d00ee 2013-09-23 0intro w->off = off;
181 6f4d00ee 2013-09-23 0intro
182 6f4d00ee 2013-09-23 0intro h = hash(p);
183 6f4d00ee 2013-09-23 0intro w->pnext = map.hparent[h];
184 6f4d00ee 2013-09-23 0intro if(w->pnext)
185 6f4d00ee 2013-09-23 0intro w->pnext->pprev = w;
186 6f4d00ee 2013-09-23 0intro map.hparent[h] = w;
187 6f4d00ee 2013-09-23 0intro
188 6f4d00ee 2013-09-23 0intro h = hash(c);
189 6f4d00ee 2013-09-23 0intro w->cnext = map.hchild[h];
190 6f4d00ee 2013-09-23 0intro if(w->cnext)
191 6f4d00ee 2013-09-23 0intro w->cnext->cprev = w;
192 6f4d00ee 2013-09-23 0intro map.hchild[h] = w;
193 6f4d00ee 2013-09-23 0intro }
194 6f4d00ee 2013-09-23 0intro
195 6f4d00ee 2013-09-23 0intro void
196 6f4d00ee 2013-09-23 0intro bwatchReset(uchar score[VtScoreSize])
197 6f4d00ee 2013-09-23 0intro {
198 4b576658 2013-09-23 0intro qlock(&map.lk);
199 6f4d00ee 2013-09-23 0intro _bwatchResetParent(score);
200 6f4d00ee 2013-09-23 0intro _bwatchResetChild(score);
201 4b576658 2013-09-23 0intro qunlock(&map.lk);
202 6f4d00ee 2013-09-23 0intro }
203 6f4d00ee 2013-09-23 0intro
204 6f4d00ee 2013-09-23 0intro void
205 6f4d00ee 2013-09-23 0intro bwatchInit(void)
206 6f4d00ee 2013-09-23 0intro {
207 6f4d00ee 2013-09-23 0intro wp = privalloc();
208 6f4d00ee 2013-09-23 0intro *wp = nil;
209 6f4d00ee 2013-09-23 0intro }
210 6f4d00ee 2013-09-23 0intro
211 6f4d00ee 2013-09-23 0intro void
212 6f4d00ee 2013-09-23 0intro bwatchSetBlockSize(uint bs)
213 6f4d00ee 2013-09-23 0intro {
214 6f4d00ee 2013-09-23 0intro blockSize = bs;
215 6f4d00ee 2013-09-23 0intro }
216 6f4d00ee 2013-09-23 0intro
217 6f4d00ee 2013-09-23 0intro static WThread*
218 6f4d00ee 2013-09-23 0intro getWThread(void)
219 6f4d00ee 2013-09-23 0intro {
220 6f4d00ee 2013-09-23 0intro WThread *w;
221 6f4d00ee 2013-09-23 0intro
222 6f4d00ee 2013-09-23 0intro w = *wp;
223 6f4d00ee 2013-09-23 0intro if(w == nil || w->pid != getpid()){
224 4b576658 2013-09-23 0intro w = vtmallocz(sizeof(WThread));
225 6f4d00ee 2013-09-23 0intro *wp = w;
226 6f4d00ee 2013-09-23 0intro w->pid = getpid();
227 6f4d00ee 2013-09-23 0intro }
228 6f4d00ee 2013-09-23 0intro return w;
229 6f4d00ee 2013-09-23 0intro }
230 6f4d00ee 2013-09-23 0intro
231 6f4d00ee 2013-09-23 0intro /*
232 6f4d00ee 2013-09-23 0intro * Derive dependencies from the contents of b.
233 6f4d00ee 2013-09-23 0intro */
234 6f4d00ee 2013-09-23 0intro void
235 6f4d00ee 2013-09-23 0intro bwatchDependency(Block *b)
236 6f4d00ee 2013-09-23 0intro {
237 6f4d00ee 2013-09-23 0intro int i, epb, ppb;
238 6f4d00ee 2013-09-23 0intro Entry e;
239 6f4d00ee 2013-09-23 0intro
240 6f4d00ee 2013-09-23 0intro if(bwatchDisabled)
241 6f4d00ee 2013-09-23 0intro return;
242 6f4d00ee 2013-09-23 0intro
243 4b576658 2013-09-23 0intro qlock(&map.lk);
244 6f4d00ee 2013-09-23 0intro _bwatchResetParent(b->score);
245 6f4d00ee 2013-09-23 0intro
246 6f4d00ee 2013-09-23 0intro switch(b->l.type){
247 6f4d00ee 2013-09-23 0intro case BtData:
248 6f4d00ee 2013-09-23 0intro break;
249 6f4d00ee 2013-09-23 0intro
250 6f4d00ee 2013-09-23 0intro case BtDir:
251 6f4d00ee 2013-09-23 0intro epb = blockSize / VtEntrySize;
252 6f4d00ee 2013-09-23 0intro for(i=0; i<epb; i++){
253 6f4d00ee 2013-09-23 0intro entryUnpack(&e, b->data, i);
254 6f4d00ee 2013-09-23 0intro if(!(e.flags & VtEntryActive))
255 6f4d00ee 2013-09-23 0intro continue;
256 6f4d00ee 2013-09-23 0intro addChild(b->score, e.score, i);
257 6f4d00ee 2013-09-23 0intro }
258 6f4d00ee 2013-09-23 0intro break;
259 6f4d00ee 2013-09-23 0intro
260 6f4d00ee 2013-09-23 0intro default:
261 6f4d00ee 2013-09-23 0intro ppb = blockSize / VtScoreSize;
262 6f4d00ee 2013-09-23 0intro for(i=0; i<ppb; i++)
263 6f4d00ee 2013-09-23 0intro addChild(b->score, b->data+i*VtScoreSize, i);
264 6f4d00ee 2013-09-23 0intro break;
265 6f4d00ee 2013-09-23 0intro }
266 4b576658 2013-09-23 0intro qunlock(&map.lk);
267 6f4d00ee 2013-09-23 0intro }
268 6f4d00ee 2013-09-23 0intro
269 6f4d00ee 2013-09-23 0intro static int
270 6f4d00ee 2013-09-23 0intro depth(uchar *s)
271 6f4d00ee 2013-09-23 0intro {
272 6f4d00ee 2013-09-23 0intro int d, x;
273 6f4d00ee 2013-09-23 0intro
274 6f4d00ee 2013-09-23 0intro d = -1;
275 6f4d00ee 2013-09-23 0intro while(s){
276 6f4d00ee 2013-09-23 0intro d++;
277 6f4d00ee 2013-09-23 0intro s = parent(s, &x);
278 6f4d00ee 2013-09-23 0intro }
279 6f4d00ee 2013-09-23 0intro return d;
280 6f4d00ee 2013-09-23 0intro }
281 6f4d00ee 2013-09-23 0intro
282 6f4d00ee 2013-09-23 0intro static int
283 6f4d00ee 2013-09-23 0intro lockConflicts(uchar xhave[VtScoreSize], uchar xwant[VtScoreSize])
284 6f4d00ee 2013-09-23 0intro {
285 6f4d00ee 2013-09-23 0intro uchar *have, *want;
286 6f4d00ee 2013-09-23 0intro int havedepth, wantdepth, havepos, wantpos;
287 6f4d00ee 2013-09-23 0intro
288 6f4d00ee 2013-09-23 0intro have = xhave;
289 6f4d00ee 2013-09-23 0intro want = xwant;
290 6f4d00ee 2013-09-23 0intro
291 6f4d00ee 2013-09-23 0intro havedepth = depth(have);
292 6f4d00ee 2013-09-23 0intro wantdepth = depth(want);
293 6f4d00ee 2013-09-23 0intro
294 6f4d00ee 2013-09-23 0intro /*
295 6f4d00ee 2013-09-23 0intro * walk one or the other up until they're both
296 6f4d00ee 2013-09-23 0intro * at the same level.
297 6f4d00ee 2013-09-23 0intro */
298 6f4d00ee 2013-09-23 0intro havepos = -1;
299 6f4d00ee 2013-09-23 0intro wantpos = -1;
300 6f4d00ee 2013-09-23 0intro have = xhave;
301 6f4d00ee 2013-09-23 0intro want = xwant;
302 6f4d00ee 2013-09-23 0intro while(wantdepth > havedepth){
303 6f4d00ee 2013-09-23 0intro wantdepth--;
304 6f4d00ee 2013-09-23 0intro want = parent(want, &wantpos);
305 6f4d00ee 2013-09-23 0intro }
306 6f4d00ee 2013-09-23 0intro while(havedepth > wantdepth){
307 6f4d00ee 2013-09-23 0intro havedepth--;
308 6f4d00ee 2013-09-23 0intro have = parent(have, &havepos);
309 6f4d00ee 2013-09-23 0intro }
310 6f4d00ee 2013-09-23 0intro
311 6f4d00ee 2013-09-23 0intro /*
312 6f4d00ee 2013-09-23 0intro * walk them up simultaneously until we reach
313 6f4d00ee 2013-09-23 0intro * a common ancestor.
314 6f4d00ee 2013-09-23 0intro */
315 6f4d00ee 2013-09-23 0intro while(have && want && memcmp(have, want, VtScoreSize) != 0){
316 6f4d00ee 2013-09-23 0intro have = parent(have, &havepos);
317 6f4d00ee 2013-09-23 0intro want = parent(want, &wantpos);
318 6f4d00ee 2013-09-23 0intro }
319 6f4d00ee 2013-09-23 0intro
320 6f4d00ee 2013-09-23 0intro /*
321 6f4d00ee 2013-09-23 0intro * not part of same tree. happens mainly with
322 6f4d00ee 2013-09-23 0intro * newly allocated blocks.
323 6f4d00ee 2013-09-23 0intro */
324 6f4d00ee 2013-09-23 0intro if(!have || !want)
325 6f4d00ee 2013-09-23 0intro return 0;
326 6f4d00ee 2013-09-23 0intro
327 6f4d00ee 2013-09-23 0intro /*
328 6f4d00ee 2013-09-23 0intro * never walked want: means we want to lock
329 6f4d00ee 2013-09-23 0intro * an ancestor of have. no no.
330 6f4d00ee 2013-09-23 0intro */
331 6f4d00ee 2013-09-23 0intro if(wantpos == -1)
332 6f4d00ee 2013-09-23 0intro return 1;
333 6f4d00ee 2013-09-23 0intro
334 6f4d00ee 2013-09-23 0intro /*
335 6f4d00ee 2013-09-23 0intro * never walked have: means we want to lock a
336 6f4d00ee 2013-09-23 0intro * child of have. that's okay.
337 6f4d00ee 2013-09-23 0intro */
338 6f4d00ee 2013-09-23 0intro if(havepos == -1)
339 6f4d00ee 2013-09-23 0intro return 0;
340 6f4d00ee 2013-09-23 0intro
341 6f4d00ee 2013-09-23 0intro /*
342 6f4d00ee 2013-09-23 0intro * walked both: they're from different places in the tree.
343 6f4d00ee 2013-09-23 0intro * require that the left one be locked before the right one.
344 6f4d00ee 2013-09-23 0intro * (this is questionable, but it puts a total order on the block tree).
345 6f4d00ee 2013-09-23 0intro */
346 6f4d00ee 2013-09-23 0intro return havepos < wantpos;
347 6f4d00ee 2013-09-23 0intro }
348 6f4d00ee 2013-09-23 0intro
349 6f4d00ee 2013-09-23 0intro static void
350 6f4d00ee 2013-09-23 0intro stop(void)
351 6f4d00ee 2013-09-23 0intro {
352 6f4d00ee 2013-09-23 0intro int fd;
353 6f4d00ee 2013-09-23 0intro char buf[32];
354 6f4d00ee 2013-09-23 0intro
355 6f4d00ee 2013-09-23 0intro snprint(buf, sizeof buf, "#p/%d/ctl", getpid());
356 6f4d00ee 2013-09-23 0intro fd = open(buf, OWRITE);
357 6f4d00ee 2013-09-23 0intro write(fd, "stop", 4);
358 6f4d00ee 2013-09-23 0intro close(fd);
359 6f4d00ee 2013-09-23 0intro }
360 6f4d00ee 2013-09-23 0intro
361 6f4d00ee 2013-09-23 0intro /*
362 6f4d00ee 2013-09-23 0intro * Check whether the calling thread can validly lock b.
363 6f4d00ee 2013-09-23 0intro * That is, check that the calling thread doesn't hold
364 6f4d00ee 2013-09-23 0intro * locks for any of b's children.
365 6f4d00ee 2013-09-23 0intro */
366 6f4d00ee 2013-09-23 0intro void
367 6f4d00ee 2013-09-23 0intro bwatchLock(Block *b)
368 6f4d00ee 2013-09-23 0intro {
369 6f4d00ee 2013-09-23 0intro int i;
370 6f4d00ee 2013-09-23 0intro WThread *w;
371 6f4d00ee 2013-09-23 0intro
372 6f4d00ee 2013-09-23 0intro if(bwatchDisabled)
373 6f4d00ee 2013-09-23 0intro return;
374 6f4d00ee 2013-09-23 0intro
375 6f4d00ee 2013-09-23 0intro if(b->part != PartData)
376 6f4d00ee 2013-09-23 0intro return;
377 6f4d00ee 2013-09-23 0intro
378 4b576658 2013-09-23 0intro qlock(&map.lk);
379 6f4d00ee 2013-09-23 0intro w = getWThread();
380 6f4d00ee 2013-09-23 0intro for(i=0; i<w->nb; i++){
381 6f4d00ee 2013-09-23 0intro if(lockConflicts(w->b[i]->score, b->score)){
382 6f4d00ee 2013-09-23 0intro fprint(2, "%d: have block %V; shouldn't lock %V\n",
383 6f4d00ee 2013-09-23 0intro w->pid, w->b[i]->score, b->score);
384 6f4d00ee 2013-09-23 0intro stop();
385 6f4d00ee 2013-09-23 0intro }
386 6f4d00ee 2013-09-23 0intro }
387 4b576658 2013-09-23 0intro qunlock(&map.lk);
388 6f4d00ee 2013-09-23 0intro if(w->nb >= MaxLock){
389 6f4d00ee 2013-09-23 0intro fprint(2, "%d: too many blocks held\n", w->pid);
390 6f4d00ee 2013-09-23 0intro stop();
391 6f4d00ee 2013-09-23 0intro }else
392 6f4d00ee 2013-09-23 0intro w->b[w->nb++] = b;
393 6f4d00ee 2013-09-23 0intro }
394 6f4d00ee 2013-09-23 0intro
395 6f4d00ee 2013-09-23 0intro /*
396 6f4d00ee 2013-09-23 0intro * Note that the calling thread is about to unlock b.
397 6f4d00ee 2013-09-23 0intro */
398 6f4d00ee 2013-09-23 0intro void
399 6f4d00ee 2013-09-23 0intro bwatchUnlock(Block *b)
400 6f4d00ee 2013-09-23 0intro {
401 6f4d00ee 2013-09-23 0intro int i;
402 6f4d00ee 2013-09-23 0intro WThread *w;
403 6f4d00ee 2013-09-23 0intro
404 6f4d00ee 2013-09-23 0intro if(bwatchDisabled)
405 6f4d00ee 2013-09-23 0intro return;
406 6f4d00ee 2013-09-23 0intro
407 6f4d00ee 2013-09-23 0intro if(b->part != PartData)
408 6f4d00ee 2013-09-23 0intro return;
409 6f4d00ee 2013-09-23 0intro
410 6f4d00ee 2013-09-23 0intro w = getWThread();
411 6f4d00ee 2013-09-23 0intro for(i=0; i<w->nb; i++)
412 6f4d00ee 2013-09-23 0intro if(w->b[i] == b)
413 6f4d00ee 2013-09-23 0intro break;
414 6f4d00ee 2013-09-23 0intro if(i>=w->nb){
415 6f4d00ee 2013-09-23 0intro fprint(2, "%d: unlock of unlocked block %V\n", w->pid, b->score);
416 6f4d00ee 2013-09-23 0intro stop();
417 6f4d00ee 2013-09-23 0intro }else
418 6f4d00ee 2013-09-23 0intro w->b[i] = w->b[--w->nb];
419 6f4d00ee 2013-09-23 0intro }