pangen2.c
来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 2,554 行 · 第 1/5 页
C
2,554 行
return 1; if (p->ntyp != q->ntyp || p->ismtyp != q->ismtyp || p->val != q->val || p->indstep != q->indstep || p->sym != q->sym || p->sq != q->sq || p->sl != q->sl) return 0; return identical(p->lft, q->lft) && identical(p->rgt, q->rgt);}static intsamedeads(FSM_use *a, FSM_use *b){ FSM_use *p, *q; for (p = a, q = b; p && q; p = p->nxt, q = q->nxt) if (p->var != q->var || p->special != q->special) return 0; return (!p && !q);}static Element *findnext(Element *f){ Element *g; if (f->n->ntyp == GOTO) { g = get_lab(f->n, 1); return huntele(g, f->status, -1); } return f->nxt;}static Element *advance(Element *e, int stopat){ Element *f = e; if (stopat) while (f && f->seqno != stopat) { f = findnext(f); switch (f->n->ntyp) { case GOTO: case '.': case PRINT: case PRINTM: break; default: return f; } } return (Element *) 0;}static intequiv_merges(Element *a, Element *b){ Element *f, *g; int stopat_a, stopat_b; if (a->merge_start) stopat_a = a->merge_start; else stopat_a = a->merge; if (b->merge_start) stopat_b = b->merge_start; else stopat_b = b->merge; if (!stopat_a && !stopat_b) return 1; for (;;) { f = advance(a, stopat_a); g = advance(b, stopat_b); if (!f && !g) return 1; if (f && g) return identical(f->n, g->n); else return 0; } return 1;}static CaseCache *prev_case(Element *e, int owner){ int j; CaseCache *nc; switch (e->n->ntyp) { case 'r': j = 0; break; case 's': j = 1; break; case 'c': j = 2; break; case ASGN: j = 3; break; case ASSERT: j = 4; break; default: j = 5; break; } for (nc = casing[j]; nc; nc = nc->nxt) if (identical(nc->n, e->n) && samedeads(nc->u, e->dead) && equiv_merges(nc->e, e) && nc->owner == owner) return nc; return (CaseCache *) 0;}static voidnew_case(Element *e, int m, int b, int owner){ int j; CaseCache *nc; switch (e->n->ntyp) { case 'r': j = 0; break; case 's': j = 1; break; case 'c': j = 2; break; case ASGN: j = 3; break; case ASSERT: j = 4; break; default: j = 5; break; } nc = (CaseCache *) emalloc(sizeof(CaseCache)); nc->owner = owner; nc->m = m; nc->b = b; nc->e = e; nc->n = e->n; nc->u = e->dead; nc->nxt = casing[j]; casing[j] = nc;}static intnr_bup(Element *e){ FSM_use *u; Lextok *v; int nr = 0; switch (e->n->ntyp) { case ASGN: nr++; break; case 'r': if (e->n->val >= 1) nr++; /* random recv */ for (v = e->n->rgt; v; v = v->rgt) { if ((v->lft->ntyp == CONST || v->lft->ntyp == EVAL)) continue; nr++; } break; default: break; } for (u = e->dead; u; u = u->nxt) { switch (u->special) { case 2: /* dead after write */ if (e->n->ntyp == ASGN && e->n->rgt->ntyp == CONST && e->n->rgt->val == 0) break; nr++; break; case 1: /* dead after read */ nr++; break; } } return nr;}static intnrhops(Element *e){ Element *f = e, *g; int cnt = 0; int stopat; if (e->merge_start) stopat = e->merge_start; else stopat = e->merge;#if 0 printf("merge: %d merge_start %d - seqno %d\n", e->merge, e->merge_start, e->seqno);#endif do { cnt += nr_bup(f); if (f->n->ntyp == GOTO) { g = get_lab(f->n, 1); if (g->seqno == stopat) f = g; else f = huntele(g, f->status, stopat); } else { f = f->nxt; } if (f && !f->merge && !f->merge_single && f->seqno != stopat) { fprintf(tm, "\n\t\tbad hop %s:%d -- at %d, <", f->n->fn->name,f->n->ln, f->seqno); comment(tm, f->n, 0); fprintf(tm, "> looking for %d -- merge %d:%d:%d\n\t\t", stopat, f->merge, f->merge_start, f->merge_single); break; } } while (f && f->seqno != stopat); return cnt;}static voidcheck_needed(void){ if (multi_needed) { fprintf(tm, "(trpt+1)->bup.ovals = grab_ints(%d);\n\t\t", multi_needed); multi_undo = multi_needed; multi_needed = 0; }}static voiddoforward(FILE *tm, Element *e){ FSM_use *u; putstmnt(tm, e->n, e->seqno); if (e->n->ntyp != ELSE && Det) { fprintf(tm, ";\n\t\tif (trpt->o_pm&1)\n\t\t"); fprintf(tm, "\tuerror(\"non-determinism in D_proctype\")"); } if (deadvar && !has_code) for (u = e->dead; u; u = u->nxt) { fprintf(tm, ";\n\t\t/* dead %d: %s */ ", u->special, u->var->name); switch (u->special) { case 2: /* dead after write -- lval already bupped */ if (e->n->ntyp == ASGN) /* could be recv or asgn */ { if (e->n->rgt->ntyp == CONST && e->n->rgt->val == 0) continue; /* already set to 0 */ } if (e->n->ntyp != 'r') { XZ.sym = u->var; fprintf(tm, "\n#ifdef HAS_CODE\n"); fprintf(tm, "\t\tif (!readtrail)\n"); fprintf(tm, "#endif\n\t\t\t"); putname(tm, "", &XZ, 0, " = 0"); break; } /* else fall through */ case 1: /* dead after read -- add asgn of rval -- needs bup */ YZ[YZmax].sym = u->var; /* store for pan.b */ CnT[YZcnt]++; /* this step added bups */ if (multi_oval) { check_needed(); fprintf(tm, "(trpt+1)->bup.ovals[%d] = ", multi_oval-1); multi_oval++; } else fprintf(tm, "(trpt+1)->bup.oval = "); putname(tm, "", &YZ[YZmax], 0, ";\n"); fprintf(tm, "#ifdef HAS_CODE\n"); fprintf(tm, "\t\tif (!readtrail)\n"); fprintf(tm, "#endif\n\t\t\t"); putname(tm, "", &YZ[YZmax], 0, " = 0"); YZmax++; break; } } fprintf(tm, ";\n\t\t");}static intdobackward(Element *e, int casenr){ if (!any_undo(e->n) && CnT[YZcnt] == 0) { YZcnt--; return 0; } if (!didcase) { fprintf(tb, "\n\tcase %d: ", casenr); fprintf(tb, "/* STATE %d */\n\t\t", e->seqno); didcase++; } _isok++; while (CnT[YZcnt] > 0) /* undo dead variable resets */ { CnT[YZcnt]--; YZmax--; if (YZmax < 0) fatal("cannot happen, dobackward", (char *)0); fprintf(tb, ";\n\t/* %d */\t", YZmax); putname(tb, "", &YZ[YZmax], 0, " = trpt->bup.oval"); if (multi_oval > 0) { multi_oval--; fprintf(tb, "s[%d]", multi_oval-1); } } if (e->n->ntyp != '.') { fprintf(tb, ";\n\t\t"); undostmnt(e->n, e->seqno); } _isok--; YZcnt--; return 1;}static voidlastfirst(int stopat, Element *fin, int casenr){ Element *f = fin, *g; if (f->n->ntyp == GOTO) { g = get_lab(f->n, 1); if (g->seqno == stopat) f = g; else f = huntele(g, f->status, stopat); } else f = f->nxt; if (!f || f->seqno == stopat || (!f->merge && !f->merge_single)) return; lastfirst(stopat, f, casenr);#if 0 fprintf(tb, "\n\t/* merge %d -- %d:%d %d:%d:%d (casenr %d) ", YZcnt, f->merge_start, f->merge, f->seqno, f?f->seqno:-1, stopat, casenr); comment(tb, f->n, 0); fprintf(tb, " */\n"); fflush(tb);#endif dobackward(f, casenr);}static int modifier;static voidlab_transfer(Element *to, Element *from){ Symbol *ns, *s = has_lab(from, (1|2|4)); Symbol *oc; int ltp, usedit=0; if (!s) return; /* "from" could have all three labels -- rename * to prevent jumps to the transfered copies */ oc = context; /* remember */ for (ltp = 1; ltp < 8; ltp *= 2) /* 1, 2, and 4 */ if ((s = has_lab(from, ltp)) != (Symbol *) 0) { ns = (Symbol *) emalloc(sizeof(Symbol)); ns->name = (char *) emalloc((int) strlen(s->name) + 4); sprintf(ns->name, "%s%d", s->name, modifier); context = s->context; set_lab(ns, to); usedit++; } context = oc; /* restore */ if (usedit) { if (modifier++ > 990) fatal("modifier overflow error", (char *) 0); }}static intcase_cache(Element *e, int a){ int bupcase = 0, casenr = uniq, fromcache = 0; CaseCache *Cached = (CaseCache *) 0; Element *f, *g; int j, nrbups, mark, target; extern int ccache; mark = (e->status&ATOM); /* could lose atomicity in a merge chain */ if (e->merge_mark > 0 || (merger && e->merge_in == 0)) { /* state nominally unreachable (part of merge chains) */ if (e->n->ntyp != '.' && e->n->ntyp != GOTO) { fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); fprintf(tt, "settr(0,0,0,0,0,\""); comment(tt, e->n, e->seqno); fprintf(tt, "\",0,0,0);\n"); } else { fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); casenr = 1; /* mhs example */ j = a; goto haveit; /* pakula's example */ } return -1; } fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); if (ccache && Pid != claimnr && Pid != eventmapnr && (Cached = prev_case(e, Pid))) { bupcase = Cached->b; casenr = Cached->m; fromcache = 1; fprintf(tm, "/* STATE %d - line %d %s - [", e->seqno, e->n->ln, e->n->fn->name); comment(tm, e->n, 0); fprintf(tm, "] (%d:%d - %d) same as %d (%d:%d - %d) */\n", e->merge_start, e->merge, e->merge_in, casenr, Cached->e->merge_start, Cached->e->merge, Cached->e->merge_in); goto gotit; } fprintf(tm, "\tcase %d: /* STATE %d - line %d %s - [", uniq++, e->seqno, e->n->ln, e->n->fn->name); comment(tm, e->n, 0); nrbups = (e->merge || e->merge_start) ? nrhops(e) : nr_bup(e); fprintf(tm, "] (%d:%d:%d - %d) */\n\t\t", e->merge_start, e->merge, nrbups, e->merge_in); if (nrbups > MAXMERGE-1) fatal("merge requires more than 256 bups", (char *)0); if (e->n->ntyp != 'r' && Pid != claimnr && Pid != eventmapnr) fprintf(tm, "IfNotBlocked\n\t\t"); if (multi_needed != 0 || multi_undo != 0) fatal("cannot happen, case_cache", (char *) 0); if (nrbups > 1) { multi_oval = 1; multi_needed = nrbups; /* allocated after edge condition */ } else multi_oval = 0; memset(CnT, 0, sizeof(CnT)); YZmax = YZcnt = 0; /* the src xrefs have the numbers in e->seqno builtin */ fprintf(tm, "reached[%d][%d] = 1;\n\t\t", Pid, e->seqno); doforward(tm, e); if (e->merge_start) target = e->merge_start; else target = e->merge; if (target) { f = e;more: if (f->n->ntyp == GOTO) { g = get_lab(f->n, 1); if (g->seqno == target) f = g; else f = huntele(g, f->status, target); } else f = f->nxt; if (f && f->seqno != target) { if (!f->merge && !f->merge_single) { fprintf(tm, "/* stop at bad hop %d, %d */\n\t\t", f->seqno, target); goto out; } fprintf(tm, "/* merge: "); comment(tm, f->n, 0); fprintf(tm, "(%d, %d, %d) */\n\t\t", f->merge, f->seqno, target); fprintf(tm, "reached[%d][%d] = 1;\n\t\t", Pid, f->seqno); YZcnt++; lab_transfer(e, f); mark = f->status&(ATOM|L_ATOM); /* last step wins */ doforward(tm, f); if (f->merge_in == 1) f->merge_mark++; goto more; } }out: fprintf(tm, "_m = %d", getweight(e->n)); if (m_loss && e->n->ntyp == 's') fprintf(tm, "+delta_m; delta_m = 0"); fprintf(tm, "; goto P999; /* %d */\n", YZcnt); multi_needed = 0; didcase = 0; if (target) lastfirst(target, e, casenr); /* mergesteps only */ dobackward(e, casenr); /* the original step */ fprintf(tb, ";\n\t\t"); if (e->merge || e->merge_start) { if (!didcase) { fprintf(tb, "\n\tcase %d: ", casenr); fprintf(tb, "/* STATE %d */", e->seqno); didcase++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?