Blame


1 d89ce51a 2005-02-11 devnull //
2 d89ce51a 2005-02-11 devnull // pthread-specific access functions
3 d89ce51a 2005-02-11 devnull // avoid complicated libthread_db interface
4 d89ce51a 2005-02-11 devnull //
5 0a61c07d 2004-04-19 devnull
6 d89ce51a 2005-02-11 devnull // Linux NPTL 2.3.2
7 d89ce51a 2005-02-11 devnull complex list_head {
8 d89ce51a 2005-02-11 devnull 'X' 0 next;
9 d89ce51a 2005-02-11 devnull 'X' 4 prev;
10 d89ce51a 2005-02-11 devnull };
11 d89ce51a 2005-02-11 devnull complex nptl_pthread {
12 d89ce51a 2005-02-11 devnull 'X' 0 loopback;
13 d89ce51a 2005-02-11 devnull 'X' 0x48 tid;
14 d89ce51a 2005-02-11 devnull };
15 d89ce51a 2005-02-11 devnull defn isnptl() {
16 d89ce51a 2005-02-11 devnull return var("nptl_version") != {};
17 d89ce51a 2005-02-11 devnull }
18 d89ce51a 2005-02-11 devnull defn nptl2tid(p) {
19 d89ce51a 2005-02-11 devnull complex nptl_pthread p;
20 d89ce51a 2005-02-11 devnull if p.loopback != p then
21 d89ce51a 2005-02-11 devnull error("bad pthread "+itoa(p, "%x"));
22 d89ce51a 2005-02-11 devnull return p.tid;
23 d89ce51a 2005-02-11 devnull }
24 d89ce51a 2005-02-11 devnull defn nptlpthreadlist() {
25 d89ce51a 2005-02-11 devnull local all, p, n, l;
26 7284df18 2004-04-19 devnull
27 d89ce51a 2005-02-11 devnull all = {};
28 d89ce51a 2005-02-11 devnull l = (list_head)stack_used;
29 d89ce51a 2005-02-11 devnull l = (list_head)l.next;
30 d89ce51a 2005-02-11 devnull while l != stack_used do {
31 d89ce51a 2005-02-11 devnull p = l - *_thread_db_pthread_list;
32 d89ce51a 2005-02-11 devnull all = append all, p;
33 d89ce51a 2005-02-11 devnull l = (list_head)l.next;
34 d89ce51a 2005-02-11 devnull }
35 d89ce51a 2005-02-11 devnull return all;
36 0a61c07d 2004-04-19 devnull }
37 0a61c07d 2004-04-19 devnull
38 d89ce51a 2005-02-11 devnull //
39 d89ce51a 2005-02-11 devnull // Generic dispatch
40 d89ce51a 2005-02-11 devnull //
41 d89ce51a 2005-02-11 devnull defn pthreadlibrary() {
42 d89ce51a 2005-02-11 devnull if var("_pthreadlibrary") == {} then {
43 d89ce51a 2005-02-11 devnull if isnptl() then
44 d89ce51a 2005-02-11 devnull _pthreadlibrary = "nptl";
45 d89ce51a 2005-02-11 devnull else
46 d89ce51a 2005-02-11 devnull _pthreadlibrary = "unknown";
47 d89ce51a 2005-02-11 devnull }
48 d89ce51a 2005-02-11 devnull return _pthreadlibrary;
49 d89ce51a 2005-02-11 devnull }
50 d89ce51a 2005-02-11 devnull
51 d89ce51a 2005-02-11 devnull defn id2tid(id) {
52 d89ce51a 2005-02-11 devnull if pthreadlibrary() == "nptl" then
53 d89ce51a 2005-02-11 devnull return nptl2tid(id);
54 d89ce51a 2005-02-11 devnull error("unknown pthread library: "+pthreadlibrary);
55 d89ce51a 2005-02-11 devnull }
56 d89ce51a 2005-02-11 devnull
57 d89ce51a 2005-02-11 devnull defn pthreadlist() {
58 d89ce51a 2005-02-11 devnull if pthreadlibrary() == "nptl" then
59 d89ce51a 2005-02-11 devnull return nptlpthreadlist(id);
60 d89ce51a 2005-02-11 devnull error("unknown pthread library: "+pthreadlibrary);
61 d89ce51a 2005-02-11 devnull }
62 d89ce51a 2005-02-11 devnull
63 d89ce51a 2005-02-11 devnull // pick apart system mcontext_t structures
64 d89ce51a 2005-02-11 devnull defn mcontext(m)
65 0a61c07d 2004-04-19 devnull {
66 d89ce51a 2005-02-11 devnull complex mcontext_t m;
67 7284df18 2004-04-19 devnull
68 d89ce51a 2005-02-11 devnull if systype == "linux" then {
69 d89ce51a 2005-02-11 devnull m = m\X;
70 d89ce51a 2005-02-11 devnull return {"PC", m[14], "SP", m[7], "BP", m[6]};
71 d89ce51a 2005-02-11 devnull } else if systype == "freebsd" then {
72 d89ce51a 2005-02-11 devnull return {"PC", m.mc_eip, "SP", m.mc_esp, "BP", m.mc_ebp};
73 d89ce51a 2005-02-11 devnull } else
74 d89ce51a 2005-02-11 devnull error("do not know how to read mcontext_t on system "+systype);
75 0a61c07d 2004-04-19 devnull }
76 0a61c07d 2004-04-19 devnull
77 d89ce51a 2005-02-11 devnull //
78 d89ce51a 2005-02-11 devnull // plan 9 thread library support
79 d89ce51a 2005-02-11 devnull //
80 d89ce51a 2005-02-11 devnull defn context(c)
81 d89ce51a 2005-02-11 devnull {
82 d89ce51a 2005-02-11 devnull c = (Context)c;
83 d89ce51a 2005-02-11 devnull return mcontext(c.uc.uc_mcontext);
84 d89ce51a 2005-02-11 devnull }
85 7284df18 2004-04-19 devnull
86 d89ce51a 2005-02-11 devnull defn contextstk(c)
87 0a61c07d 2004-04-19 devnull {
88 d89ce51a 2005-02-11 devnull _stk(context(c), 0);
89 0a61c07d 2004-04-19 devnull }
90 0a61c07d 2004-04-19 devnull
91 d89ce51a 2005-02-11 devnull defn contextlstk(c)
92 0a61c07d 2004-04-19 devnull {
93 d89ce51a 2005-02-11 devnull _stk(context(c), 1);
94 0a61c07d 2004-04-19 devnull }
95 0a61c07d 2004-04-19 devnull
96 0a61c07d 2004-04-19 devnull defn altfmt(A){
97 0a61c07d 2004-04-19 devnull local i, s, yes;
98 0a61c07d 2004-04-19 devnull complex Alt A;
99 0a61c07d 2004-04-19 devnull
100 0a61c07d 2004-04-19 devnull s = "alt(";
101 0a61c07d 2004-04-19 devnull s = s + "tag(*" + itoa(A.tag, "%x") + "=" + itoa(*A.tag, "%x") + ") ";
102 0a61c07d 2004-04-19 devnull i = 0;
103 0a61c07d 2004-04-19 devnull yes = 0;
104 0a61c07d 2004-04-19 devnull while A.op != CHANEND && A.op != CHANNOBLK do{
105 0a61c07d 2004-04-19 devnull if A.op != CHANNOP then{
106 0a61c07d 2004-04-19 devnull if yes then s = s + " ";
107 0a61c07d 2004-04-19 devnull s = s + itoa(i, "%d");
108 0a61c07d 2004-04-19 devnull s = s + ":";
109 0a61c07d 2004-04-19 devnull if A.op == CHANSND then s = s + "send";
110 0a61c07d 2004-04-19 devnull if A.op == CHANRCV then s = s + "recv";
111 0a61c07d 2004-04-19 devnull s = s + "(channel(";
112 0a61c07d 2004-04-19 devnull s = s + itoa(A.c, "%x");
113 0a61c07d 2004-04-19 devnull s = s + "))";
114 0a61c07d 2004-04-19 devnull yes = 1;
115 0a61c07d 2004-04-19 devnull }
116 0a61c07d 2004-04-19 devnull i = i + 1;
117 0a61c07d 2004-04-19 devnull A = (Alt)(A + sizeofAlt);
118 0a61c07d 2004-04-19 devnull }
119 0a61c07d 2004-04-19 devnull if A.op==CHANNOBLK then{
120 0a61c07d 2004-04-19 devnull if yes then s = s + " ";
121 0a61c07d 2004-04-19 devnull s = s + "noblock";
122 0a61c07d 2004-04-19 devnull }
123 0a61c07d 2004-04-19 devnull s = s + ")";
124 0a61c07d 2004-04-19 devnull return s;
125 0a61c07d 2004-04-19 devnull }
126 0a61c07d 2004-04-19 devnull
127 0a61c07d 2004-04-19 devnull defn alt(A){
128 0a61c07d 2004-04-19 devnull print(altfmt(A), "\n");
129 0a61c07d 2004-04-19 devnull }
130 0a61c07d 2004-04-19 devnull
131 d89ce51a 2005-02-11 devnull defn channel(C) {
132 d89ce51a 2005-02-11 devnull complex Channel C;
133 d89ce51a 2005-02-11 devnull local i, p;
134 d89ce51a 2005-02-11 devnull
135 d89ce51a 2005-02-11 devnull print("channel ", C\X, " // ", *(C.name\s));
136 d89ce51a 2005-02-11 devnull if C.freed then {
137 d89ce51a 2005-02-11 devnull print(" (moribund)");
138 d89ce51a 2005-02-11 devnull }
139 d89ce51a 2005-02-11 devnull print("\n");
140 d89ce51a 2005-02-11 devnull print("\telemsize=", C.elemsize\D, " bufsize=", C.bufsize, "\n");
141 d89ce51a 2005-02-11 devnull if C.bufsize then {
142 d89ce51a 2005-02-11 devnull print("\t", C.nbuf\D, " values in channel:\n");
143 d89ce51a 2005-02-11 devnull print("\t");
144 d89ce51a 2005-02-11 devnull p = C.buf+C.off*C.elemsize;
145 d89ce51a 2005-02-11 devnull loop 1,C.nbuf do {
146 d89ce51a 2005-02-11 devnull if C.elemsize==4 then {
147 d89ce51a 2005-02-11 devnull print(*p\X, " ");
148 d89ce51a 2005-02-11 devnull }else {
149 d89ce51a 2005-02-11 devnull print("data(", p\X, ") ");
150 d89ce51a 2005-02-11 devnull }
151 d89ce51a 2005-02-11 devnull p = p+C.elemsize;
152 d89ce51a 2005-02-11 devnull if p == C.buf+C.bufsize*C.elemsize then {
153 d89ce51a 2005-02-11 devnull p = C.buf;
154 d89ce51a 2005-02-11 devnull }
155 d89ce51a 2005-02-11 devnull }
156 d89ce51a 2005-02-11 devnull }
157 d89ce51a 2005-02-11 devnull print("\n");
158 d89ce51a 2005-02-11 devnull print(" senders:\n");
159 d89ce51a 2005-02-11 devnull _altarray(C.asend);
160 d89ce51a 2005-02-11 devnull print(" recvers:\n");
161 d89ce51a 2005-02-11 devnull _altarray(C.arecv);
162 d89ce51a 2005-02-11 devnull }
163 d89ce51a 2005-02-11 devnull
164 d89ce51a 2005-02-11 devnull defn _altarray(aa)
165 d89ce51a 2005-02-11 devnull {
166 d89ce51a 2005-02-11 devnull local i, a, t;
167 d89ce51a 2005-02-11 devnull
168 d89ce51a 2005-02-11 devnull i = 0;
169 d89ce51a 2005-02-11 devnull aa = (_Altarray)aa;
170 d89ce51a 2005-02-11 devnull while i < aa.n do {
171 d89ce51a 2005-02-11 devnull a = (Alt)aa.a[i];
172 d89ce51a 2005-02-11 devnull print("\t"+threadstkline(a.thread)+"\n");
173 d89ce51a 2005-02-11 devnull i++;
174 d89ce51a 2005-02-11 devnull }
175 d89ce51a 2005-02-11 devnull }
176 d89ce51a 2005-02-11 devnull
177 0a61c07d 2004-04-19 devnull defn fnname(a){
178 0a61c07d 2004-04-19 devnull local sym, s;
179 0a61c07d 2004-04-19 devnull
180 0a61c07d 2004-04-19 devnull s = symbols;
181 0a61c07d 2004-04-19 devnull while s do {
182 0a61c07d 2004-04-19 devnull sym = head s;
183 0a61c07d 2004-04-19 devnull if sym[2] == a then
184 0a61c07d 2004-04-19 devnull return sym[0];
185 0a61c07d 2004-04-19 devnull s = tail s;
186 0a61c07d 2004-04-19 devnull }
187 0a61c07d 2004-04-19 devnull return itoa(a, "%x");
188 0a61c07d 2004-04-19 devnull }
189 0a61c07d 2004-04-19 devnull
190 0a61c07d 2004-04-19 devnull stkignorelist = {};
191 0a61c07d 2004-04-19 devnull defn stkignore(s){
192 0a61c07d 2004-04-19 devnull append stkignorelist, s;
193 0a61c07d 2004-04-19 devnull }
194 0a61c07d 2004-04-19 devnull
195 0a61c07d 2004-04-19 devnull defn threadstkline(T){
196 c9896e2e 2004-05-23 devnull local stk, frame, pc, pc0, file, s, sym, i, stop, P, mainpid;
197 0a61c07d 2004-04-19 devnull
198 d89ce51a 2005-02-11 devnull T = (_Thread)T;
199 d89ce51a 2005-02-11 devnull P = (Proc)T.proc;
200 d89ce51a 2005-02-11 devnull if P.thread == T then {
201 c9896e2e 2004-05-23 devnull mainpid = pid;
202 d89ce51a 2005-02-11 devnull setproc(id2tid(P.osprocid));
203 7284df18 2004-04-19 devnull stk = strace({});
204 d89ce51a 2005-02-11 devnull setproc(mainpid);
205 c9896e2e 2004-05-23 devnull } else
206 d89ce51a 2005-02-11 devnull stk = strace(context(T.context));
207 7284df18 2004-04-19 devnull
208 0a61c07d 2004-04-19 devnull stop = 0;
209 0a61c07d 2004-04-19 devnull while stk && !stop do {
210 7284df18 2004-04-19 devnull frame = head stk;
211 7284df18 2004-04-19 devnull stk = tail stk;
212 7284df18 2004-04-19 devnull pc = frame[2];
213 7284df18 2004-04-19 devnull pc0 = frame[0];
214 0a61c07d 2004-04-19 devnull file = pcfile(pc);
215 2e965b33 2004-05-05 devnull if !regexp("plan9/src/lib9/", file)
216 7284df18 2004-04-19 devnull && !regexp("plan9/src/libthread/", file)
217 d89ce51a 2005-02-11 devnull && file != "?file?"
218 0a61c07d 2004-04-19 devnull && match(file, stkignore)==-1 then
219 0a61c07d 2004-04-19 devnull stop = 1;
220 0a61c07d 2004-04-19 devnull }
221 0a61c07d 2004-04-19 devnull file = pcfile(pc);
222 0a61c07d 2004-04-19 devnull s = file+":"+itoa(pcline(pc), "%d");
223 0a61c07d 2004-04-19 devnull if pc0 != 0 then
224 0a61c07d 2004-04-19 devnull s = s + " "+fnname(pc0);
225 0a61c07d 2004-04-19 devnull return s;
226 0a61c07d 2004-04-19 devnull }
227 0a61c07d 2004-04-19 devnull
228 0a61c07d 2004-04-19 devnull defn threadfmt(T){
229 d89ce51a 2005-02-11 devnull complex _Thread T;
230 d89ce51a 2005-02-11 devnull local P, s, name;
231 0a61c07d 2004-04-19 devnull
232 0a61c07d 2004-04-19 devnull P = (Proc)T.proc;
233 d89ce51a 2005-02-11 devnull s = "t=(_Thread)"+itoa(T, "%-10x")+" // ";
234 0a61c07d 2004-04-19 devnull
235 d89ce51a 2005-02-11 devnull if P.thread == T then
236 0a61c07d 2004-04-19 devnull s = s + "Running ";
237 0a61c07d 2004-04-19 devnull else
238 d89ce51a 2005-02-11 devnull s = s + "Sleeping ";
239 d89ce51a 2005-02-11 devnull s = s + threadstkline(T);
240 0a61c07d 2004-04-19 devnull
241 d89ce51a 2005-02-11 devnull name = T+392; // T+offsetof(_Thread, name);
242 d89ce51a 2005-02-11 devnull if *(name\b) != 0 then
243 d89ce51a 2005-02-11 devnull s = s + " ["+*(name\s)+"]";
244 0a61c07d 2004-04-19 devnull return s;
245 0a61c07d 2004-04-19 devnull }
246 0a61c07d 2004-04-19 devnull
247 0a61c07d 2004-04-19 devnull defn thread(T){
248 0a61c07d 2004-04-19 devnull print(threadfmt(T), "\n");
249 0a61c07d 2004-04-19 devnull }
250 0a61c07d 2004-04-19 devnull
251 d89ce51a 2005-02-11 devnull defn procthreads(P){
252 0a61c07d 2004-04-19 devnull complex Proc P;
253 d89ce51a 2005-02-11 devnull local T;
254 0a61c07d 2004-04-19 devnull
255 d89ce51a 2005-02-11 devnull T = (_Thread)P.allthreads.$head;
256 0a61c07d 2004-04-19 devnull while T != 0 do{
257 0a61c07d 2004-04-19 devnull print("\t");
258 0a61c07d 2004-04-19 devnull thread(T);
259 d89ce51a 2005-02-11 devnull T = (_Thread)T.allnext;
260 0a61c07d 2004-04-19 devnull }
261 0a61c07d 2004-04-19 devnull }
262 0a61c07d 2004-04-19 devnull
263 d89ce51a 2005-02-11 devnull defn prociter(x) {
264 0a61c07d 2004-04-19 devnull local P;
265 c73e7cf5 2004-04-20 devnull
266 d89ce51a 2005-02-11 devnull P = (Proc)*_threadprocs;
267 0a61c07d 2004-04-19 devnull while P != 0 do{
268 d89ce51a 2005-02-11 devnull if P != (Proc)*_threadprocs then print("\n");
269 d89ce51a 2005-02-11 devnull proc(P);
270 d89ce51a 2005-02-11 devnull if x == 1 then
271 d89ce51a 2005-02-11 devnull procthreads(P);
272 d89ce51a 2005-02-11 devnull if x == 2 then
273 d89ce51a 2005-02-11 devnull threadstks(P);
274 c73e7cf5 2004-04-20 devnull P = (Proc)P.next;
275 0a61c07d 2004-04-19 devnull }
276 0a61c07d 2004-04-19 devnull }
277 0a61c07d 2004-04-19 devnull
278 d89ce51a 2005-02-11 devnull defn procs() {
279 d89ce51a 2005-02-11 devnull prociter(0);
280 0a61c07d 2004-04-19 devnull }
281 0a61c07d 2004-04-19 devnull
282 d89ce51a 2005-02-11 devnull defn threads() {
283 d89ce51a 2005-02-11 devnull prociter(1);
284 0a61c07d 2004-04-19 devnull }
285 0a61c07d 2004-04-19 devnull
286 d89ce51a 2005-02-11 devnull defn stacks() {
287 d89ce51a 2005-02-11 devnull prociter(2);
288 0a61c07d 2004-04-19 devnull }
289 0a61c07d 2004-04-19 devnull
290 c73e7cf5 2004-04-20 devnull threadstkignore = {
291 c73e7cf5 2004-04-20 devnull "plan9/src/libthread/",
292 2e965b33 2004-05-05 devnull "plan9/src/lib9/",
293 2e965b33 2004-05-05 devnull "plan9/src/lib9/(fmt|utf)/",
294 c73e7cf5 2004-04-20 devnull };
295 0a61c07d 2004-04-19 devnull defn threadstks(P){
296 0a61c07d 2004-04-19 devnull complex Proc P;
297 d89ce51a 2005-02-11 devnull local T, mainpid, pref, ign;
298 0a61c07d 2004-04-19 devnull
299 d89ce51a 2005-02-11 devnull // mainpid = pid;
300 0a61c07d 2004-04-19 devnull pref = stkprefix;
301 0a61c07d 2004-04-19 devnull stkprefix = pref+"\t\t";
302 0a61c07d 2004-04-19 devnull ign = stkignore;
303 c73e7cf5 2004-04-20 devnull stkignore = threadstkignore;
304 a796abef 2004-05-12 devnull // setproc(P.pid);
305 d89ce51a 2005-02-11 devnull T = (_Thread)P.allthreads.$head;
306 0a61c07d 2004-04-19 devnull while T != 0 do{
307 0a61c07d 2004-04-19 devnull print("\t");
308 0a61c07d 2004-04-19 devnull thread(T);
309 0a61c07d 2004-04-19 devnull threadstk(T);
310 d89ce51a 2005-02-11 devnull T = (_Thread)T.allnext;
311 0a61c07d 2004-04-19 devnull print("\n");
312 0a61c07d 2004-04-19 devnull }
313 a796abef 2004-05-12 devnull // setproc(mainpid);
314 0a61c07d 2004-04-19 devnull stkprefix = pref;
315 0a61c07d 2004-04-19 devnull stkignore = ign;
316 0a61c07d 2004-04-19 devnull }
317 0a61c07d 2004-04-19 devnull
318 0a61c07d 2004-04-19 devnull defn proc(P){
319 0a61c07d 2004-04-19 devnull complex Proc P;
320 0a61c07d 2004-04-19 devnull
321 d89ce51a 2005-02-11 devnull print("p=(Proc)", itoa(P, "%-10x"), " // pthread ", P.osprocid\X, " pid ", id2tid(P.osprocid)\D, " ");
322 0a61c07d 2004-04-19 devnull if P.thread==0 then
323 0a61c07d 2004-04-19 devnull print(" Sched");
324 0a61c07d 2004-04-19 devnull else
325 0a61c07d 2004-04-19 devnull print(" Running");
326 0a61c07d 2004-04-19 devnull print("\n");
327 0a61c07d 2004-04-19 devnull }
328 0a61c07d 2004-04-19 devnull
329 0a61c07d 2004-04-19 devnull defn threadlstk(T){
330 d89ce51a 2005-02-11 devnull complex _Thread T;
331 0a61c07d 2004-04-19 devnull local P, mainpid;
332 0a61c07d 2004-04-19 devnull
333 0a61c07d 2004-04-19 devnull P = (Proc)T.proc;
334 d89ce51a 2005-02-11 devnull mainpid = pid;
335 d89ce51a 2005-02-11 devnull setproc(id2tid(P.osprocid));
336 0a61c07d 2004-04-19 devnull
337 d89ce51a 2005-02-11 devnull if P.thread == T then
338 0a61c07d 2004-04-19 devnull lstk();
339 d89ce51a 2005-02-11 devnull else
340 d89ce51a 2005-02-11 devnull contextlstk(T.context);
341 d89ce51a 2005-02-11 devnull setproc(mainpid);
342 0a61c07d 2004-04-19 devnull }
343 0a61c07d 2004-04-19 devnull
344 0a61c07d 2004-04-19 devnull defn threadstk(T){
345 d89ce51a 2005-02-11 devnull complex _Thread T;
346 0a61c07d 2004-04-19 devnull local P, mainpid;
347 0a61c07d 2004-04-19 devnull
348 0a61c07d 2004-04-19 devnull P = (Proc)T.proc;
349 0a61c07d 2004-04-19 devnull mainpid = pid;
350 d89ce51a 2005-02-11 devnull setproc(id2tid(P.osprocid));
351 0a61c07d 2004-04-19 devnull
352 d89ce51a 2005-02-11 devnull if P.thread == T then
353 0a61c07d 2004-04-19 devnull stk();
354 d89ce51a 2005-02-11 devnull else
355 d89ce51a 2005-02-11 devnull contextstk(T.context);
356 0a61c07d 2004-04-19 devnull
357 d89ce51a 2005-02-11 devnull setproc(mainpid);
358 0a61c07d 2004-04-19 devnull }
359 0a61c07d 2004-04-19 devnull
360 0a61c07d 2004-04-19 devnull print(acidfile);