@include l1 = "../l1"; sctl = "../../sctl/sctl"; @define htforeach(f, ht) { @local hp, i, sz; sz = ht->sz; for(i = 0; i < sz; i++){ hp = ht->ht[i]; while(hp){ f(hp->key, hp->val); hp = hp->next; } } } @define enumctls(dom) { @local fn, l; l = []; @define fn(k, v) { append(l, (Ctl*)v); } htforeach(fn, dom`ctltab); return l; } @define checkctls(dom) { @local notebp, ctls, as, bps; ctls = enumctls(dom); as = [:]; bps = [:]; @define notebp(bp) { if(bps[bp] == nil) bps[bp] = 1; else bps[bp]++; } foreach(@lambda(ctl){ if(0)printf("ctl %d %p\n", ctl->id, ctl); as[ctl->as] = ctl->as; if(0)printf("braddr:\n"); htforeach(@lambda(k,v) { @local addr, br; addr = (u64)k; br = (Brkref*)v; if(0)printf("\t%x -> %d %p %x %d\n", addr, br->id, br->bp, br->bp->addr, br->bp->cnt); notebp(br->bp); }, ctl->braddr); if(0)printf("brid:\n"); htforeach(@lambda(k,v) { @local id, br; id = (u64)k; br = (Brkref*)v; if(0)printf("\t%d -> %d %p %x %d\n", id, br->id, br->bp, br->bp->addr, br->bp->cnt); notebp(br->bp); }, ctl->brid); }, ctls); printf("%d as in %d ctls\n", length(as), length(ctls)); foreach(@lambda(a,v) { @local nbp; if(0)printf("as %p\n", a); if(0)printf("bpaddr:\n"); nbp = 0; htforeach(@lambda(k,v) { @local addr, bp; addr = (u64)k; bp = (Brk*)v; if(0)printf("\t%x -> %p %x %d\n", addr, bp, bp->addr, bp->cnt); if(2*bp->cnt != bps[bp]) error("ref count! 2*%d != %d for as %p bpaddr %p\n", bp->cnt, bps[bp], a, bp); nbp++; }, a->bpaddr); printf("\tas %p has %u bps\n", a, nbp); }, as); } @define doit(args) { @local mux, ctl, dom, nexec, sctlpid, tracesctl; @define tracesctl(ctl) { @local dom, ns; ns = ctl.ns(); dom = mkdom(ns, ctl.mem()); dom.xtrap(&dom`writemsg, @lambda(ctl){ @local pd, xmsg, regs; regs = ctl.reg(); pd = mkdom(ns, ctl.mem()); xmsg = (Msg*){pd}regs->rsi; printf("writemsg %e:\n", (enum Mkind)xmsg->op); checkctls(pd); }); } sctlpid = nil; nexec = 0; mux = mkctlmux_local(); push(args, l1); ctl = mux.launch(args, 0); dom = mkdom(ctl.ns(), ctl.mem()); dom.trace(ctlmux`Efork, @lambda(ctl, newctl){ printf("fork %d -> %d\n", ctl.id, newctl.id); if(ctl.id == sctlpid){ printf("releasing %d\n", newctl.id); newctl.detach(); } }); dom.trace(ctlmux`Eexec, @lambda(ctl){ nexec++; printf("exec -> %d\n", ctl.id); if(nexec == 1){ sctlpid = ctl.id; printf("sctl is %d\n", ctl.id); tracesctl(ctl); } if(nexec > 1) ctl.detach(); }); dom.xtrap(&dom`finivm, @lambda(ctl){ printf("l1 is exiting\n"); return nil; }); dom.xcont(); mux.run(); } doit([ "tracelist.cqct", "5", "2" ]);