tthread - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tthread (5091B)
       ---
            1 //
            2 // pthread-specific access functions
            3 // avoid complicated libthread_db interface
            4 //
            5 
            6 include("pthread-"+systype+"-"+objtype);
            7 
            8 // pick apart system mcontext_t structures
            9 defn mcontext(m)
           10 {
           11         complex mcontext_t m;
           12 
           13         if systype == "linux" then {
           14                 m = m\X;
           15                 return {"PC", m[14], "SP", m[7], "BP", m[6]};
           16         } else if systype == "freebsd" then {
           17                 return {"PC", m.mc_eip, "SP", m.mc_esp, "BP", m.mc_ebp};
           18         } else
           19                 error("do not know how to read mcontext_t on system "+systype);
           20 }
           21 
           22 //
           23 // plan 9 thread library support
           24 // 
           25 defn context(c)
           26 {
           27         c = (Context)c;
           28         return mcontext(c.uc.uc_mcontext);
           29 }
           30 
           31 defn contextstk(c)
           32 {
           33         _stk(context(c), 0);
           34 }
           35 
           36 defn contextlstk(c)
           37 {
           38         _stk(context(c), 1);
           39 }
           40 
           41 defn altfmt(A){
           42         local i, s, yes;
           43         complex Alt A;
           44 
           45         s = "alt(";
           46         s = s + "tag(*" + itoa(A.tag, "%#x") + "=" + itoa(*A.tag, "%#x") + ") ";
           47         i = 0;
           48         yes = 0;
           49         while A.op != CHANEND && A.op != CHANNOBLK do{
           50                 if A.op != CHANNOP then{
           51                         if yes then s = s + " ";
           52                         s = s + itoa(i, "%d");
           53                         s = s + ":";
           54                         if A.op == CHANSND then s = s + "send";
           55                         if A.op == CHANRCV then s = s + "recv";
           56                         s = s + "(channel(";
           57                         s = s + itoa(A.c, "%#x");
           58                         s = s + "))";
           59                         yes = 1;
           60                 }
           61                 i = i + 1;
           62                 A = (Alt)(A + sizeofAlt);
           63         }
           64         if A.op==CHANNOBLK then{
           65                 if yes then s = s + " ";
           66                 s = s + "noblock";
           67         }
           68         s = s + ")";
           69         return s;
           70 }
           71 
           72 defn alt(A){
           73         print(altfmt(A), "\n");
           74 }
           75 
           76 defn channel(C) {
           77         complex Channel C;
           78         local i, p;
           79 
           80         print("channel ", C\X, " // ", *(C.name\s));
           81         if C.freed then {
           82                 print(" (moribund)");
           83         }
           84         print("\n");
           85         print("\telemsize=", C.elemsize\D, " bufsize=", C.bufsize, "\n");
           86         if C.bufsize then {
           87                 print("\t", C.nbuf\D, " values in channel:\n");
           88                 print("\t");
           89                 p = C.buf+C.off*C.elemsize;
           90                 loop 1,C.nbuf do {
           91                         if C.elemsize==4 then {
           92                                 print(*p\X, " ");
           93                         }else {
           94                                 print("data(", p\X, ") ");
           95                         }
           96                         p = p+C.elemsize;
           97                         if p == C.buf+C.bufsize*C.elemsize then {
           98                                 p = C.buf;
           99                         }
          100                 }
          101         }
          102         print("\n");
          103         print(" senders:\n");
          104         _altarray(C.asend);
          105         print(" recvers:\n");
          106         _altarray(C.arecv);
          107 }
          108 
          109 defn _altarray(aa)
          110 {
          111         local i, a, t;
          112 
          113         i = 0;
          114         aa = (_Altarray)aa;
          115         while i < aa.n do {
          116                 a = (Alt)aa.a[i];
          117                 print("\t"+threadstkline(a.thread)+"\n");
          118                 i++;
          119         }
          120 }
          121 
          122 defn fnname(a){
          123         local sym, s;
          124 
          125         s = symbols;
          126         while s do {
          127                 sym = head s;
          128                 if sym[2] == a then
          129                         return sym[0];
          130                 s = tail s;
          131         }
          132         return itoa(a, "%#x");
          133 }
          134 
          135 stkignorelist = {};
          136 defn stkignore(s){
          137         append stkignorelist, s;
          138 }
          139 
          140 defn threadstkline(T){
          141         local stk, frame, pc, pc0, file, s, sym, i, stop, P, mainpid;
          142 
          143         T = (_Thread)T;
          144         P = (Proc)T.proc;
          145         if P.thread == T then {
          146                 mainpid = pid;
          147                 setproc(pthread2tid(P.osprocid));
          148                 stk = strace({});
          149                 setproc(mainpid);
          150         } else
          151                 stk = strace(context(T.context));
          152 
          153         stop = 0;
          154         while stk && !stop do {
          155                 frame = head stk;
          156                 stk = tail stk;
          157                 pc = frame[2];
          158                 pc0 = frame[0];
          159                 file = pcfile(pc);
          160                 if !regexp("plan9/src/lib9/", file)
          161                 && !regexp("plan9/src/libthread/", file) 
          162                 && file != "?file?"
          163                 && match(file, stkignore)==-1 then
          164                         stop = 1;
          165         }
          166         file = pcfile(pc);
          167         s = file+":"+itoa(pcline(pc), "%d");
          168         if pc0 != 0 then 
          169                 s = s + " "+fnname(pc0);
          170         return s;
          171 }
          172 
          173 defn threadfmt(T){
          174         complex _Thread T;
          175         local P, s, name;
          176 
          177         P = (Proc)T.proc;
          178         s = "t=(_Thread)"+itoa(T, "%#-10x")+" // ";
          179 
          180         if P.thread == T then
          181                 s = s + "Running    ";
          182         else
          183                 s = s + "Sleeping   ";
          184         s = s + threadstkline(T);
          185 
          186         name = T+392;        // T+offsetof(_Thread, name);
          187         if *(name\b) != 0 then
          188                 s = s + " ["+*(name\s)+"]";
          189         return s;
          190 }
          191 
          192 defn thread(T){
          193         print(threadfmt(T), "\n");
          194 }
          195 
          196 defn procthreads(P){
          197         complex Proc P;
          198         local T;
          199 
          200         T = (_Thread)P.allthreads.$head;
          201         while T != 0 do{
          202                 print("\t");
          203                 thread(T);
          204                 T = (_Thread)T.allnext;
          205         }
          206 }
          207 
          208 defn prociter(x) {
          209         local P;
          210 
          211         P = (Proc)*_threadprocs;
          212         while P != 0 do{
          213                 if P != (Proc)*_threadprocs then print("\n");
          214                 proc(P);
          215                 if x == 1 then 
          216                         procthreads(P);
          217                 if x == 2 then
          218                         threadstks(P);
          219                 P = (Proc)P.next;
          220         }
          221 }
          222 
          223 defn procs() {
          224         prociter(0);
          225 }
          226 
          227 defn threads() {
          228         prociter(1);
          229 }
          230 
          231 defn stacks() {
          232         prociter(2);
          233 }
          234 
          235 threadstkignore = {
          236         "plan9/src/libthread/",
          237         "plan9/src/lib9/",
          238         "plan9/src/lib9/(fmt|utf)/",
          239 };
          240 defn threadstks(P){
          241         complex Proc P;
          242         local T,  mainpid, pref, ign;
          243 
          244         pref = stkprefix;
          245         stkprefix = pref+"\t\t";
          246         ign = stkignore;
          247         stkignore = threadstkignore;
          248         T = (_Thread)P.allthreads.$head;
          249         while T != 0 do{
          250                 print("\t");
          251                 thread(T);
          252                 threadstk(T);
          253                 T = (_Thread)T.allnext;
          254                 print("\n");
          255         }
          256         stkprefix = pref;
          257         stkignore = ign;
          258 }
          259 
          260 defn proc(P){
          261         complex Proc P;
          262 
          263         print("p=(Proc)", itoa(P, "%#-10x"), "  // pthread ", P.osprocid\X, " pid ", pthread2tid(P.osprocid)\D, " ");
          264         if P.thread==0 then
          265                 print(" Sched");
          266         else
          267                 print(" Running");
          268         print("\n");
          269 }
          270 
          271 defn threadlstk(T){
          272         complex _Thread T;
          273         local P, mainpid;
          274 
          275         P = (Proc)T.proc;
          276         mainpid = pid;
          277         setproc(pthread2tid(P.osprocid));
          278 
          279         if P.thread == T then
          280                 lstk();
          281         else
          282                 contextlstk(T.context);
          283         setproc(mainpid);
          284 }
          285 
          286 defn threadstk(T){
          287         complex _Thread T;
          288         local P, mainpid;
          289 
          290         P = (Proc)T.proc;
          291         mainpid = pid;
          292         setproc(pthread2tid(P.osprocid));
          293 
          294         if P.thread == T then
          295                 stk();
          296         else 
          297                 contextstk(T.context);
          298 
          299         setproc(mainpid);
          300 }
          301 
          302 print(acidfile);