Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/lib/acid/thread – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
include("/sys/src/libthread/sched.acid");
2
 
3
defn labpc(l)
4
{
5
	if objtype == "386" then
6
		return longjmp;
7
	return *(l+4);
8
}
9
 
10
defn labsp(l)
11
{
12
	return *l;
13
}
14
 
15
defn labstk(l)
16
{
17
	_stk(labpc(l), labsp(l), 0, 0);
18
}
19
 
20
defn lablstk(l)
21
{
22
	_stk(labpc(l), labsp(l), 0, 1);
23
}
24
 
25
defn altfmt(A){
26
	local i, s, yes;
27
	complex Alt A;
28
 
29
	s = "alt(";
30
	s = s + "tag(*" + itoa(A.tag, "%x") + "=" + itoa(*A.tag, "%x") + ") ";
31
	i = 0;
32
	yes = 0;
33
	while A.op != CHANEND && A.op != CHANNOBLK do{
34
		if A.op != CHANNOP then{
35
			if yes then s = s + " ";
36
			s = s + itoa(i, "%d");
37
			s = s + ":";
38
			if A.op == CHANSND then s = s + "send";
39
			if A.op == CHANRCV then s = s + "recv";
40
			s = s + "(channel(";
41
			s = s + itoa(A.c, "%x");
42
			s = s + "))";
43
			yes = 1;
44
		}
45
		i = i + 1;
46
		A = (Alt)(A + sizeofAlt);
47
	}
48
	if A.op==CHANNOBLK then{
49
		if yes then s = s + " ";
50
		s = s + "noblock";
51
	}
52
	s = s + ")";
53
	return s;
54
}
55
 
56
defn alt(A){
57
	print(altfmt(A), "\n");
58
}
59
 
60
threadignsrc = {
61
	"^/sys/src/libc",
62
	"^/sys/src/libthread",
63
};
64
 
65
defn fnname(a){
66
	local sym, s;
67
 
68
	s = symbols;
69
	while s do {
70
		sym = head s;
71
		if sym[2] == a then
72
			return sym[0];
73
		s = tail s;
74
	}
75
	if a == {} then
76
		return "{}";
77
	return itoa(a\X, "%x");
78
}
79
 
80
stkignorelist = {};
81
 
82
defn stkignore(s){
83
	append stkignorelist, s;
84
}
85
 
86
defn threadstkline(T){
87
	local ostk, stk, frame, pc, pc0, file, lastpc0, s, sym, i, stop;
88
 
89
	if T.state == Running then{
90
		pc = *PC;
91
		stk = strace(*PC, *SP, linkreg(0));
92
	}else{
93
		pc = labpc(T.sched);
94
		stk = strace(labpc(T.sched), labsp(T.sched), 0);
95
	}
96
	firstpc = pc;
97
	lastpc0 = 0;
98
	pc0 = 0;
99
	stop = 0;
100
	ostk = stk;
101
	while stk && !stop do {
102
		file = pcfile(pc);
103
		if !regexp("^/sys/src/libc/", file)
104
		&& !regexp("^/sys/src/libthread/", file) 
105
		&& match(file, stkignore)==-1 then
106
			stop = 1;
107
		else if stk[0][1] == 0xfefefefe then {
108
			pc = ostk[0][1];
109
			pc0 = ostk[1][0];
110
			stop = 1;
111
		}else{
112
			lastpc0 = pc0;
113
			frame = head stk;
114
			stk = tail stk;
115
			nextframe = head stk;
116
			pc = frame[1];
117
			pc0 = nextframe[0];
118
		}
119
	}
120
	file = pcfile(pc);
121
	s = file+":"+itoa(pcline(pc), "%d");
122
	if pc0 != 0 then 
123
		s = s + " "+fnname(pc0);
124
	return s;
125
}
126
 
127
defn threadfmt(T){
128
	complex Thread T;
129
	local A, yes, i, P, s;
130
 
131
	P = (Proc)T.proc;
132
	s = "t=(Thread)"+itoa(T, "%-10x")+" ";
133
 
134
	if T.state == Running then
135
		s = s + "Running    ";
136
	else if T.state == Ready then
137
		s = s + "Ready      ";
138
	else if T.state == Rendezvous then
139
		s = s + "Rendez     ";
140
	else
141
		s = s + "Bad state "+itoa(T.state, "%x")+" ";
142
 
143
	A = (Alt)T.alt;
144
	if 1 then
145
		s = s + threadstkline(T);
146
	else if T.chan == Chanalt then
147
		s = s + altfmt(T.alt);
148
	else if T.chan == Chansend then
149
		s = s + "send(Channel("+itoa(A.c, "%x")+"))";
150
	else if T.chan == Chanrecv then
151
		s = s + "recv(Channel("+itoa(A.c, "%x")+"))";
152
	else
153
		s = s + threadstkline(T);
154
 
155
	if T.moribund == 1 then
156
		s = s + " Moribund";
157
	if T.cmdname != 0 then
158
		s = s + " ["+*(T.cmdname\s)+"]";
159
	return s;
160
}
161
 
162
defn thread(T){
163
	print(threadfmt(T), "\n");
164
}
165
 
166
defn pthreads(P){
167
	complex Proc P;
168
	local T, Tq, mainpid;
169
 
170
	mainpid = pid;
171
	setproc(P.pid);
172
	Tq = (Tqueue)P.threads;
173
	T = (Thread)Tq.$head;
174
	while T != 0 do{
175
		print("\t");
176
		thread(T);
177
		T = T.nextt;
178
	}
179
	setproc(mainpid);
180
}
181
 
182
defn threads(){
183
	local P;
184
 
185
	P = (Proc)_threadpq.$head;
186
	while P != 0 do{
187
		if P != (Proc)_threadpq.$head then print("\n");
188
		lproc(P);
189
		P = P.next;
190
	}
191
}
192
 
193
defn stacks(){
194
	local P, mainpid;
195
 
196
	mainpid = pid;
197
	P = (Proc)_threadpq.$head;
198
	while P != 0 do{
199
		proc(P);
200
	//	setproc(P.pid);
201
	//	if P.thread==0 then{
202
	//		print("=== thread scheduler stack\n");
203
	//		stk();
204
	//	}
205
	//	print("threadstks(", P\X, ")\n");
206
		threadstks(P);
207
		P = P.next;
208
		print("\n");
209
	}
210
	setproc(mainpid);
211
}
212
 
213
defn stacksizes(){
214
	local P, T, Tq, top, sp, mainpid;
215
 
216
	mainpid = pid;
217
	P = (Proc)_threadpq.$head;
218
	while P != 0 do{
219
		P = (Proc)P;
220
		Tq = (Tqueue)P.threads;
221
		T = (Thread)Tq.$head;
222
		while T != 0 do{
223
			top = T.stk+T.stksize;
224
			if T.state==Running then {
225
				sp = *SP;
226
			}else{
227
				sp = *(T.sched);
228
			}
229
			sp = *(T.sched);
230
			print(top-sp\D, " / ", T.stksize\D, "\n");
231
			T = T.nextt;
232
		}
233
		P = P.next;
234
	}
235
	setproc(mainpid);
236
}
237
 
238
defn lproc(P){
239
	proc(P);
240
	pthreads(P);
241
}
242
 
243
defn threadstks(P){
244
	complex Proc P;
245
	local T, Tq, mainpid, pref, ign;
246
 
247
	mainpid = pid;
248
	pref = stkprefix;
249
	stkprefix = pref+"\t\t";
250
	ign = stkignore;
251
	stkignore = {
252
		"^/sys/src/libthread/",
253
		"^/sys/src/libc/(386|arm|alpha|sparc|power|mips)/"
254
	};
255
	setproc(P.pid);
256
	Tq = (Tqueue)P.threads;
257
	T = (Thread)Tq.$head;
258
	while T != 0 do{
259
	//	print("=============================\n");
260
	//	print("  thread(", T\X, ")\n");
261
		print("\t");
262
		thread(T);
263
		threadstk(T);
264
		T = T.nextt;
265
		print("\n");
266
	}
267
	setproc(mainpid);
268
	stkprefix = pref;
269
	stkignore = ign;
270
}
271
 
272
defn proc(P){
273
	complex Proc P;
274
 
275
	print("p=(Proc)", itoa(P, "%-10x"), " pid ", P.pid\D, " ");
276
	if P.thread==0 then
277
		print(" Sched");
278
	else
279
		print(" Running");
280
	print("\n");
281
}
282
 
283
defn procs(){
284
	local P;
285
 
286
	P = (Proc)_threadpq.$head;
287
	while P != 0 do{
288
		proc(P);
289
		P = P.next;
290
	}
291
}
292
 
293
defn threadlstk(T){
294
	complex Thread T;
295
	local P, mainpid;
296
 
297
	P = (Proc)T.proc;
298
	mainpid = pid;
299
	setproc(P.pid);
300
 
301
	if T.state == Running then{
302
		lstk();
303
	} else {
304
		lablstk(T.sched);
305
	}
306
	setproc(mainpid);
307
}
308
 
309
defn threadstk(T){
310
	complex Thread T;
311
	local P, mainpid;
312
 
313
	P = (Proc)T.proc;
314
	mainpid = pid;
315
	setproc(P.pid);
316
 
317
	if T.state == Running then{
318
		stk();
319
	} else {
320
		labstk(T.sched);
321
	}
322
	setproc(mainpid);
323
}
324
 
325
defn tqueue(Q) {
326
	complex Tqueue Q;
327
 
328
	while Q != 0 do {
329
		print(Q.$head\X, " ");
330
		Q = *(Q.$tail);
331
 
332
	}
333
	print("#\n");
334
}
335
 
336
defn channel(C) {
337
	complex Channel C;
338
	local i, p;
339
 
340
	print("channel ", C\X);
341
	if C.freed then {
342
		print(" (moribund)");
343
	}
344
	print("\n");
345
	print("\telementsize=", C.e\D, " buffersize=", C.s, "\n");
346
	if C.s then {
347
		print("\t", C.n\D, " values in channel:\n");
348
		print("\t");
349
		p = C.v+C.e*(C.f%C.s);
350
		loop 1,C.n do {
351
			if C.e==4 then {
352
				print((*p)\X, " ");
353
			}else {
354
				print("data(", (*p)\X, ") ");
355
			}
356
			p = p+C.e;
357
			if p == C.v+C.s*C.e then {
358
				p = C.v;
359
			}
360
		}
361
	}
362
	print("\n");
363
	print(C.nentry\D, " queue slots:\n");
364
	i=0;
365
	loop 1,C.nentry do {
366
		if C.qentry[i] then
367
			print("\t", altfmt(C.qentry[i]), "\n");
368
		else
369
			print("\t<empty>\n");
370
		i=i+1;
371
	}
372
}
373
 
374
print("/sys/lib/acid/thread");