123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- include("/sys/src/libthread/sched.acid");
- defn labpc(l)
- {
- if objtype == "386" then
- return longjmp;
- return *(l+4);
- }
- defn labsp(l)
- {
- return *l;
- }
- defn labstk(l)
- {
- _stk(labpc(l), labsp(l), 0, 0);
- }
- defn lablstk(l)
- {
- _stk(labpc(l), labsp(l), 0, 1);
- }
- defn altfmt(A){
- local i, s, yes;
- complex Alt A;
- s = "alt(";
- s = s + "tag(*" + itoa(A.tag, "%x") + "=" + itoa(*A.tag, "%x") + ") ";
- i = 0;
- yes = 0;
- while A.op != CHANEND && A.op != CHANNOBLK do{
- if A.op != CHANNOP then{
- if yes then s = s + " ";
- s = s + itoa(i, "%d");
- s = s + ":";
- if A.op == CHANSND then s = s + "send";
- if A.op == CHANRCV then s = s + "recv";
- s = s + "(channel(";
- s = s + itoa(A.c, "%x");
- s = s + "))";
- yes = 1;
- }
- i = i + 1;
- A = (Alt)(A + sizeofAlt);
- }
- if A.op==CHANNOBLK then{
- if yes then s = s + " ";
- s = s + "noblock";
- }
- s = s + ")";
- return s;
- }
- defn alt(A){
- print(altfmt(A), "\n");
- }
- threadignsrc = {
- "^/sys/src/libc",
- "^/sys/src/libthread",
- };
- defn fnname(a){
- local sym, s;
- s = symbols;
- while s do {
- sym = head s;
- if sym[2] == a then
- return sym[0];
- s = tail s;
- }
- return itoa(a, "%x");
- }
- defn threadstkline(T){
- local stk, frame, pc, pc0, file, lastpc0, s, sym, i, stop;
- if T.state == Running then{
- pc = *PC;
- stk = strace(*PC, *SP, linkreg(0));
- }else{
- pc = labpc(T.sched);
- stk = strace(labpc(T.sched), labsp(T.sched), 0);
- }
- lastpc0 = 0;
- pc0 = 0;
- stop = 0;
- while stk && !stop do {
- file = pcfile(pc);
- if !regexp("^/sys/src/libc/", file)
- && !regexp("^/sys/src/libthread/", file) then
- stop = 1;
- else{
- lastpc0 = pc0;
- frame = head stk;
- stk = tail stk;
- pc0 = frame[0];
- pc = frame[1];
- }
- }
- file = pcfile(pc);
- s = file+":"+itoa(pcline(pc), "%d");
- if pc0 != 0 then
- s = s + " "+fnname(pc0);
- return s;
- }
- defn threadfmt(T){
- complex Thread T;
- local A, yes, i, P, s;
- P = (Proc)T.proc;
- s = "t=(Thread)"+itoa(T, "%-10x")+" ";
- if T.state == Running then
- s = s + "Running ";
- else if T.state == Ready then
- s = s + "Ready ";
- else if T.state == Rendezvous then
- s = s + "Rendez ";
- else
- s = s + "Bad state "+itoa(T.state, "%x")+" ";
- A = (Alt)T.alt;
- if 1 then
- s = s + threadstkline(T);
- else if T.chan == Chanalt then
- s = s + altfmt(T.alt);
- else if T.chan == Chansend then
- s = s + "send(Channel("+itoa(A.c, "%x")+"))";
- else if T.chan == Chanrecv then
- s = s + "recv(Channel("+itoa(A.c, "%x")+"))";
- else
- s = s + threadstkline(T);
- if T.moribund == 1 then
- s = s + " Moribund";
- if T.cmdname != 0 then
- s = s + " ["+*(T.cmdname\s)+"]";
- return s;
- }
- defn thread(T){
- print(threadfmt(T), "\n");
- }
- defn pthreads(P){
- complex Proc P;
- local T, Tq, mainpid;
- mainpid = pid;
- setproc(P.pid);
- Tq = (Tqueue)P.threads;
- T = (Thread)Tq.$head;
- while T != 0 do{
- print("\t");
- thread(T);
- T = T.nextt;
- }
- setproc(mainpid);
- }
- defn threads(){
- local P;
- P = (Proc)_threadpq.$head;
- while P != 0 do{
- if P != (Proc)_threadpq.$head then print("\n");
- lproc(P);
- P = P.next;
- }
- }
- defn stacks(){
- local P, mainpid;
- mainpid = pid;
- P = (Proc)_threadpq.$head;
- while P != 0 do{
- proc(P);
- // setproc(P.pid);
- // if P.thread==0 then{
- // print("=== thread scheduler stack\n");
- // stk();
- // }
- // print("threadstks(", P\X, ")\n");
- threadstks(P);
- P = P.next;
- print("\n");
- }
- setproc(mainpid);
- }
- defn stacksizes(){
- local P, T, Tq, top, sp, mainpid;
- mainpid = pid;
- P = (Proc)_threadpq.$head;
- while P != 0 do{
- P = (Proc)P;
- Tq = (Tqueue)P.threads;
- T = (Thread)Tq.$head;
- while T != 0 do{
- top = T.stk+T.stksize;
- if T.state==Running then {
- sp = *SP;
- }else{
- sp = *(T.sched);
- }
- sp = *(T.sched);
- print(top-sp\D, "\n");
- T = T.nextt;
- }
- P = P.next;
- }
- setproc(mainpid);
- }
- defn lproc(P){
- proc(P);
- pthreads(P);
- }
- defn threadstks(P){
- complex Proc P;
- local T, Tq, mainpid, pref, ign;
- mainpid = pid;
- pref = stkprefix;
- stkprefix = pref+"\t\t";
- ign = stkignore;
- stkignore = {
- "^/sys/src/libthread/",
- "^/sys/src/libc/(386|arm|alpha|sparc|power|mips)/"
- };
- setproc(P.pid);
- Tq = (Tqueue)P.threads;
- T = (Thread)Tq.$head;
- while T != 0 do{
- // print("=============================\n");
- // print(" thread(", T\X, ")\n");
- print("\t");
- thread(T);
- threadstk(T);
- T = T.nextt;
- print("\n");
- }
- setproc(mainpid);
- stkprefix = pref;
- stkignore = ign;
- }
- defn proc(P){
- complex Proc P;
- print("p=(Proc)", itoa(P, "%-10x"), " pid ", P.pid\D, " ");
- if P.thread==0 then
- print(" Sched");
- else
- print(" Running");
- print("\n");
- }
- defn procs(){
- local P;
- P = (Proc)_threadpq.$head;
- while P != 0 do{
- proc(P);
- P = P.next;
- }
- }
- defn threadlstk(T){
- complex Thread T;
- local P, mainpid;
- P = (Proc)T.proc;
- mainpid = pid;
- setproc(P.pid);
- if T.state == Running then{
- lstk();
- } else {
- lablstk(T.sched);
- }
- setproc(mainpid);
- }
- defn threadstk(T){
- complex Thread T;
- local P, mainpid;
- P = (Proc)T.proc;
- mainpid = pid;
- setproc(P.pid);
- if T.state == Running then{
- stk();
- } else {
- labstk(T.sched);
- }
- setproc(mainpid);
- }
- defn tqueue(Q) {
- complex Tqueue Q;
- while Q != 0 do {
- print(Q.$head\X, " ");
- Q = *(Q.$tail);
-
- }
- print("#\n");
- }
- defn channel(C) {
- complex Channel C;
- local i, p;
- print("channel ", C\X);
- if C.freed then {
- print(" (moribund)");
- }
- print("\n");
- print("\telementsize=", C.e\D, " buffersize=", C.s, "\n");
- if C.s then {
- print("\t", C.n\D, " values in channel:\n");
- print("\t");
- p = C.v+C.e*(C.f%C.s);
- loop 1,C.n do {
- if C.e==4 then {
- print((*p)\X, " ");
- }else {
- print("data(", (*p)\X, ") ");
- }
- p = p+C.e;
- if p == C.v+C.s*C.e then {
- p = C.v;
- }
- }
- }
- print("\n");
- print(C.nentry\D, " queue slots:\n");
- i=0;
- loop 1,C.nentry do {
- if C.qentry[i] then
- print("\t", altfmt(C.qentry[i]), "\n");
- else
- print("\t<empty>\n");
- i=i+1;
- }
- }
- print("/sys/lib/acid/thread");
|