include("/sys/src/libthread/sched.acid"); defn labstk(l){ if objtype == "386" then _stk(longjmp, *l, linkreg(0), 0); else _stk(*(l+4), *l, linkreg(0), 0);} defn lablstk(l){ if objtype == "386" then _stk(longjmp, *l, linkreg(0), 1); else _stk(*(l+4), *l, linkreg(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); 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); 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");} defn thread(T){ complex Thread T; local A, yes, i, P; P = (Proc)T.proc; if T.cmdname != 0 then{ print("\t", *(T.cmdname\s), ":\n"); } print("\t", T\X, "\t", T.id); if T.state == Running then{ print("\t\tRunning "); } else if T.state == Ready then{ print("\t\tReady "); } else if T.state == Rendezvous then{ print("\t\tRendezvous "); }else{ print("\t\tBad state ", T.state\X, " "); } if T.chan == Chanalt then{ print("\t\t", altfmt(T.alt), "\n"); } else if T.chan == Chansend then{ A = (Alt)T.alt; print("\t\tsend(Channel(", A.c\X, "))"); } else if T.chan == Chanrecv then{ A = (Alt)T.alt; print("\t\trecv(Channel(", A.c\X, "))"); } if T.moribund == 1 then{ print(" (Moribund)"); } print("\n");} defn pthreads(P){ complex Proc P; local T, Tq; mainpid = pid; setproc(P.pid); Tq = (Tqueue)P.threads; T = (Thread)Tq.$head; while T != 0 do{ 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 = pid; P = (Proc)_threadpq.$head; while P != 0 do{ print("=========================================================\n"); proc(P); setproc(P.pid); if P.thread==0 then{ print("=== thread scheduler stack\n"); stk(); } threadstks(P); P = P.next; } setproc(mainpid);} defn stacksizes(){ local P, T, Tq, top, sp; 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 = pid; setproc(P.pid); Tq = (Tqueue)P.threads; T = (Thread)Tq.$head; while T != 0 do{ print("=============================\n"); thread(T); print("\n"); threadstk(T); T = T.nextt; } setproc(mainpid);} defn proc(P){ complex Proc P; print("Proc *p=", P\X, ", p->pid=", P.pid\D); if P.thread==0 then{ print(", p->state=Sched, p->tag=", P\X); }else{ print(", p->state=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");
include("/sys/src/libthread/sched.acid");
defn labstk(l)
{
if objtype == "386" then
_stk(longjmp, *l, linkreg(0), 0);
else
_stk(*(l+4), *l, linkreg(0), 0);
}
defn lablstk(l)
{
if objtype == "386" then
_stk(longjmp, *l, linkreg(0), 1);
else
_stk(*(l+4), *l, linkreg(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);
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);
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");
}
defn thread(T){
complex Thread T;
local A, yes, i, P;
P = (Proc)T.proc;
if T.cmdname != 0 then{
print("\t", *(T.cmdname\s), ":\n");
}
print("\t", T\X, "\t", T.id);
if T.state == Running then{
print("\t\tRunning ");
} else if T.state == Ready then{
print("\t\tReady ");
} else if T.state == Rendezvous then{
print("\t\tRendezvous ");
}else{
print("\t\tBad state ", T.state\X, " ");
}
if T.chan == Chanalt then{
print("\t\t", altfmt(T.alt), "\n");
} else if T.chan == Chansend then{
A = (Alt)T.alt;
print("\t\tsend(Channel(", A.c\X, "))");
} else if T.chan == Chanrecv then{
A = (Alt)T.alt;
print("\t\trecv(Channel(", A.c\X, "))");
}
if T.moribund == 1 then{
print(" (Moribund)");
}
print("\n");
}
defn pthreads(P){
complex Proc P;
local T, Tq;
mainpid = pid;
setproc(P.pid);
Tq = (Tqueue)P.threads;
T = (Thread)Tq.$head;
while T != 0 do{
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 = pid;
P = (Proc)_threadpq.$head;
while P != 0 do{
print("=========================================================\n");
proc(P);
setproc(P.pid);
if P.thread==0 then{
print("=== thread scheduler stack\n");
stk();
}
threadstks(P);
P = P.next;
}
setproc(mainpid);
}
defn stacksizes(){
local P, T, Tq, top, sp;
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 = pid;
setproc(P.pid);
Tq = (Tqueue)P.threads;
T = (Thread)Tq.$head;
while T != 0 do{
print("=============================\n");
thread(T);
print("\n");
threadstk(T);
T = T.nextt;
}
setproc(mainpid);
}
defn proc(P){
complex Proc P;
print("Proc *p=", P\X, ", p->pid=", P.pid\D);
if P.thread==0 then{
print(", p->state=Sched, p->tag=", P\X);
}else{
print(", p->state=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");