diff -Nru /n/sources/plan9/sys/src/cmd/spin/LICENSE /sys/src/cmd/spin/LICENSE --- /n/sources/plan9/sys/src/cmd/spin/LICENSE Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/spin/LICENSE Mon Feb 22 00:00:00 2021 @@ -0,0 +1,40 @@ + Spin open source distribution + ============================= + + Copyright (c) 1989-2019 Gerard J. Holzmann. All rights reserved. + + This software was originally authored by employees of Bell Laboratories, + a unit of Lucent Technologies, Inc. All Alcatel-Lucent copyrights in the + software were assigned to Gerard J. Holzmann on 30 December 2015, and + thus no rights are herein granted by Lucent Technologies itself, or by + its successor Alcatel-Lucent. + + This and subsequent versions of the Spin source code are made available + as open source code under the terms of the BSD 3-Clause License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff -Nru /n/sources/plan9/sys/src/cmd/spin/dstep.c /sys/src/cmd/spin/dstep.c --- /n/sources/plan9/sys/src/cmd/spin/dstep.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/dstep.c Mon Feb 22 00:00:00 2021 @@ -1,27 +1,25 @@ /***** spin: dstep.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ +#include #include "spin.h" #include "y.tab.h" #define MAXDSTEP 2048 /* was 512 */ -char *NextLab[64]; +char *NextLab[64]; /* must match value in pangen2.c:41 */ int Level=0, GenCode=0, IsGuard=0, TestOnly=0; static int Tj=0, Jt=0, LastGoto=0; static int Tojump[MAXDSTEP], Jumpto[MAXDSTEP], Special[MAXDSTEP]; static void putCode(FILE *, Element *, Element *, Element *, int); -extern int Pid, separate, OkBreak; +extern int Pid_nr, separate, OkBreak; static void Sourced(int n, int special) @@ -80,10 +78,11 @@ } for (j = i = 0; j < Tj; j++) if (Special[j]) - { Tojump[i] = Tojump[j]; + { if (i >= MAXDSTEP) + { fatal("cannot happen (dstep.c)", (char *)0); + } + Tojump[i] = Tojump[j]; Special[i] = 2; - if (i >= MAXDSTEP) - fatal("cannot happen (dstep.c)", (char *)0); i++; } Tj = i; /* keep only the global exit-labels */ @@ -164,7 +163,7 @@ break; case ELSE: if (inh++ > 0) fprintf(fd, " || "); -/* 4.2.5 */ if (!pid_is_claim(Pid)) +/* 4.2.5 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq == -1 /* else */)"); else fprintf(fd, "(1 /* else */)"); @@ -184,17 +183,17 @@ case 's': if (inh++ > 0) fprintf(fd, " || "); fprintf(fd, "("); TestOnly=1; -/* 4.2.1 */ if (!pid_is_claim(Pid)) fprintf(fd, "(boq == -1) && "); +/* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq == -1) && "); putstmnt(fd, ee->n, ee->seqno); fprintf(fd, ")"); TestOnly=0; break; case 'c': if (inh++ > 0) fprintf(fd, " || "); fprintf(fd, "("); TestOnly=1; - if (!pid_is_claim(Pid)) + if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq == -1 && "); putstmnt(fd, ee->n->lft, e->seqno); - if (!pid_is_claim(Pid)) + if (!pid_is_claim(Pid_nr)) fprintf(fd, ")"); fprintf(fd, ")"); TestOnly=0; break; @@ -204,7 +203,8 @@ int putcode(FILE *fd, Sequence *s, Element *nxt, int justguards, int ln, int seqno) -{ int isg=0; char buf[64]; +{ int isg=0; + static char buf[64]; NextLab[0] = "continue"; filterbad(s->frst); @@ -215,6 +215,7 @@ return putcode(fd, s->frst->n->sl->this, nxt, 0, ln, seqno); case NON_ATOMIC: (void) putcode(fd, s->frst->n->sl->this, ZE, 1, ln, seqno); + if (justguards) return 0; /* 6.2.5 */ break; case IF: fprintf(fd, "if (!("); @@ -245,7 +246,7 @@ case 's': fprintf(fd, "if ("); #if 1 -/* 4.2.1 */ if (!pid_is_claim(Pid)) fprintf(fd, "(boq != -1) || "); +/* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq != -1) || "); #endif fprintf(fd, "!("); TestOnly=1; putstmnt(fd, s->frst->n, s->frst->seqno); @@ -253,7 +254,7 @@ break; case 'c': fprintf(fd, "if (!("); - if (!pid_is_claim(Pid)) fprintf(fd, "boq == -1 && "); + if (!pid_is_claim(Pid_nr)) fprintf(fd, "boq == -1 && "); TestOnly=1; putstmnt(fd, s->frst->n->lft, s->frst->seqno); fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; @@ -262,19 +263,31 @@ fprintf(fd, "if (boq != -1 || ("); if (separate != 2) fprintf(fd, "trpt->"); fprintf(fd, "o_pm&1))\n\t\t\tcontinue;"); + { extern FILE *fd_th; + fprintf(fd_th, "#ifndef ELSE_IN_GUARD\n"); + fprintf(fd_th, " #define ELSE_IN_GUARD\n"); + fprintf(fd_th, "#endif\n"); + } break; case ASGN: /* new 3.0.8 */ fprintf(fd, "IfNotBlocked"); break; + default: + fprintf(fd, "/* default %d */\n\t\t", s->frst->n->ntyp); } + + /* 6.2.5 : before TstOnly */ + fprintf(fd, "\n\n\t\treached[%d][%d] = 1;\n\t\t", Pid_nr, seqno); + fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid_nr); /* next state */ + fprintf(fd, "reached[%d][tt] = 1;\n", Pid_nr); /* current state */ + + /* 6.2.5 : before sv_save() */ + if (s->frst->n->ntyp != NON_ATOMIC) + fprintf(fd, "\n\t\tif (TstOnly) return 1;\n"); /* if called from enabled() */ + if (justguards) return 0; fprintf(fd, "\n\t\tsv_save();\n\t\t"); -#if 1 - fprintf(fd, "reached[%d][%d] = 1;\n\t\t", Pid, seqno); - fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid); /* true next state */ - fprintf(fd, "reached[%d][tt] = 1;\n", Pid); /* true current state */ -#endif sprintf(buf, "Uerror(\"block in d_step seq, line %d\")", ln); NextLab[0] = buf; putCode(fd, s->frst, s->extent, nxt, isg); @@ -359,7 +372,7 @@ case '.': if (LastGoto) break; if (e->nxt && (e->nxt->status & DONE2)) - { i = e->nxt?e->nxt->Seqno:0; + { i = e->nxt->Seqno; fprintf(fd, "\t\tgoto S_%.3d_0;", i); fprintf(fd, " /* '.' */\n"); Dested(i); @@ -375,7 +388,7 @@ break; } i = e->nxt?e->nxt->Seqno:0; - if (e->nxt && e->nxt->status & DONE2 && !LastGoto) + if (e->nxt && (e->nxt->status & DONE2) && !LastGoto) { fprintf(fd, "\t\tgoto S_%.3d_0; ", i); fprintf(fd, "/* ';' */\n"); Dested(i); diff -Nru /n/sources/plan9/sys/src/cmd/spin/flow.c /sys/src/cmd/spin/flow.c --- /n/sources/plan9/sys/src/cmd/spin/flow.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/flow.c Mon Feb 22 00:00:00 2021 @@ -1,19 +1,16 @@ /***** spin: flow.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" extern Symbol *Fname; -extern int nr_errs, lineno, verbose, in_for; +extern int nr_errs, lineno, verbose, in_for, old_scope_rules, s_trail; extern short has_unless, has_badelse, has_xu; extern char CurScope[MAXSCOPESZ]; @@ -21,6 +18,7 @@ Label *labtab = (Label *) 0; int Unique = 0, Elcnt = 0, DstepStart = -1; int initialization_ok = 1; +short has_accept; static Lbreak *breakstack = (Lbreak *) 0; static Lextok *innermost; @@ -39,12 +37,15 @@ open_seq(int top) { SeqList *t; Sequence *s = (Sequence *) emalloc(sizeof(Sequence)); + s->minel = -1; t = seqlist(s, cur_s); cur_s = t; if (top) { Elcnt = 1; initialization_ok = 1; + } else + { initialization_ok = 0; } } @@ -89,6 +90,7 @@ && a->indstep != b->indstep) { lineno = a->ln; Fname = a->fn; + if (!s_trail) fatal("jump into d_step sequence", (char *) 0); } } @@ -156,7 +158,7 @@ { initialization_ok = 1; } - if (nottop > 0 && (z = has_lab(s->frst, 0))) + if (nottop > 0 && s->frst && (z = has_lab(s->frst, 0))) { printf("error: (%s:%d) label %s placed incorrectly\n", (s->frst->n)?s->frst->n->fn->name:"-", (s->frst->n)?s->frst->n->ln:0, @@ -192,12 +194,12 @@ printf("\"Label: { statement ... }\"\n"); break; case 6: - printf("=====>instead of\n"); + printf("=====> instead of\n"); printf(" do (or if)\n"); printf(" :: ...\n"); printf(" :: Label: statement\n"); printf(" od (of fi)\n"); - printf("=====>always use\n"); + printf("=====> use\n"); printf("Label: do (or if)\n"); printf(" :: ...\n"); printf(" :: statement\n"); @@ -207,8 +209,9 @@ printf("cannot happen - labels\n"); break; } - alldone(1); - } + if (nottop != 6) + { alldone(1); + } } if (nottop == 4 && !Rjumpslocal(s->frst, s->last)) @@ -226,13 +229,14 @@ do_unless(Lextok *No, Lextok *Es) { SeqList *Sl; Lextok *Re = nn(ZN, UNLESS, ZN, ZN); + Re->ln = No->ln; Re->fn = No->fn; - has_unless++; + if (Es->ntyp == NON_ATOMIC) - Sl = Es->sl; - else + { Sl = Es->sl; + } else { open_seq(0); add_seq(Es); Sl = seqlist(close_seq(1), 0); } @@ -357,6 +361,31 @@ } } } +void +popbreak(void) +{ + if (!breakstack) + fatal("cannot happen, breakstack", (char *) 0); + + breakstack = breakstack->nxt; /* pop stack */ +} + +static Lbreak *ob = (Lbreak *) 0; + +void +safe_break(void) +{ + ob = breakstack; + popbreak(); +} + +void +restore_break(void) +{ + breakstack = ob; + ob = (Lbreak *) 0; +} + static Element * if_seq(Lextok *n) { int tok = n->ntyp; @@ -410,13 +439,13 @@ e->n = nn(n, tok, ZN, ZN); e->n->sl = s; /* preserve as info only */ e->sub = s; - for (z = s; z; prev_z = z, z = z->nxt) + for (z = s; z; z = z->nxt) add_el(t, z->this); /* append target */ if (tok == DO) { add_el(t, cur_s->this); /* target upfront */ t = new_el(nn(n, BREAK, ZN, ZN)); /* break target */ set_lab(break_dest(), t); /* new exit */ - breakstack = breakstack->nxt; /* pop stack */ + popbreak(); } add_el(e, cur_s->this); add_el(t, cur_s->this); @@ -575,13 +604,6 @@ } void -show_lab(void) -{ Label *l; - for (l = labtab; l; l = l->nxt) - printf("label %s\n", l->s->name); -} - -void set_lab(Symbol *s, Element *e) { Label *l; extern Symbol *context; int cur_uiid = is_inline(); @@ -591,11 +613,17 @@ for (l = labtab; l; l = l->nxt) { if (strcmp(l->s->name, s->name) == 0 && l->c == context + && (old_scope_rules || strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0) && l->uiid == cur_uiid) { non_fatal("label %s redeclared", s->name); break; } } + if (strncmp(s->name, "accept", 6) == 0 + && strncmp(s->name, "accept_all", 10) != 0) + { has_accept = 1; + } + l = (Label *) emalloc(sizeof(Label)); l->s = s; l->c = context; @@ -608,22 +636,41 @@ static Label * get_labspec(Lextok *n) { Symbol *s = n->sym; - Label *l, *anymatch = (Label *) 0; - int cur_uiid = n->uiid; + Label *l, *anymatch = (Label *) 0; + int ln; /* - * try to find a label with the same uiid - * but if it doesn't exist, return any other - * that is defined within the same scope + * try to find a label with the same inline id (uiid) + * but if it doesn't exist, return any other match + * within the same scope */ for (l = labtab; l; l = l->nxt) - { if (strcmp(s->name, l->s->name) == 0 - && s->context == l->s->context) - { anymatch = l; - if (cur_uiid == l->uiid) /* best match */ - { return l; + { if (strcmp(l->s->name, s->name) == 0 /* labelname matches */ + && s->context == l->s->context) /* same scope */ + { +#if 0 + if (anymatch && n->uiid == anymatch->uiid) + { if (0) non_fatal("label %s re-declared", s->name); + } + if (0) + { printf("Label %s uiid now::then %d :: %d bcsp %s :: %s\n", + s->name, n->uiid, l->uiid, s->bscp, l->s->bscp); + printf("get_labspec match on %s %s (bscp goto %s - label %s)\n", + s->name, s->context->name, s->bscp, l->s->bscp); + } +#endif + /* same block scope */ + if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0) + { return l; /* definite match */ + } + /* higher block scope */ + ln = strlen((const char *) l->s->bscp); + if (strncmp((const char *) s->bscp, (const char *) l->s->bscp, ln) == 0) + { anymatch = l; /* possible match */ + } else if (!anymatch) + { anymatch = l; /* somewhere else in same context */ } } } - return anymatch; /* likely to be 0 */ + return anymatch; /* return best match */ } Element * @@ -639,7 +686,6 @@ Fname = n->fn; fatal("undefined label %s", n->sym->name); } - return ZE; } @@ -720,21 +766,46 @@ } l->e->status |= CHECK2; /* treat as if global */ if (l->e->status & (ATOM | L_ATOM | D_ATOM)) - { non_fatal("cannot reference label inside atomic or d_step (%s)", - c->name); + { printf("spin: %s:%d, warning, reference to label ", + Fname->name, lineno); + printf("from inside atomic or d_step (%s)\n", c->name); } } int find_lab(Symbol *s, Symbol *c, int markit) -{ Label *l; +{ Label *l, *pm = (Label *) 0, *apm = (Label *) 0; + int ln; + /* generally called for remote references in never claims */ for (l = labtab; l; l = l->nxt) - { if (strcmp(s->name, l->s->name) == 0 + { + if (strcmp(s->name, l->s->name) == 0 && strcmp(c->name, l->c->name) == 0) - { l->visible |= markit; - return (l->e->seqno); - } } + { ln = strlen((const char *) l->s->bscp); + if (0) + { printf("want '%s' in context '%s', scope ref '%s' - label '%s'\n", + s->name, c->name, s->bscp, l->s->bscp); + } + /* same or higher block scope */ + if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0) + { pm = l; /* definite match */ + break; + } + if (strncmp((const char *) s->bscp, (const char *) l->s->bscp, ln) == 0) + { pm = l; /* possible match */ + } else + { apm = l; /* remote */ + } } } + + if (pm) + { pm->visible |= markit; + return pm->e->seqno; + } + if (apm) + { apm->visible |= markit; + return apm->e->seqno; + } /* else printf("Not Found\n"); */ return 0; } @@ -822,7 +893,7 @@ if (z->type == CHAN) { if (z->ini && z->ini->rgt && z->ini->rgt->sym) - { // dump_sym(z->ini->rgt->sym, "\n:I:"); /* could also be longer list */ + { /* dump_sym(z->ini->rgt->sym, "\n:I:"); -- could also be longer list */ if (z->ini->rgt->rgt || !z->ini->rgt->sym) fatal("chan %s in for should have only one field (a typedef)", z->name); @@ -851,12 +922,12 @@ || !t->ini->rgt || !t->ini->rgt->sym || t->ini->rgt->rgt) - { fatal("chan %s in for should have only one field (a typedef)", t->name); + { fatal("chan %s in for should have only one field (a typedef)", t?t->name:"--"); } /* we already know that s is a STRUCT */ if (0) - { printf("index type %s %p ==\n", s->Snm->name, s->Snm); - printf("chan type %s %p --\n\n", t->ini->rgt->sym->name, t->ini->rgt->sym); + { printf("index type %s %p ==\n", s->Snm->name, (void *) s->Snm); + printf("chan type %s %p --\n\n", t->ini->rgt->sym->name, (void *) t->ini->rgt->sym); } return (s->Snm == t->ini->rgt->sym); @@ -893,7 +964,7 @@ for_index(Lextok *a3, Lextok *a5) { Lextok *z0, *z1, *z2, *z3; Symbol *tmp_cnt; - char tmp_nm[MAXSCOPESZ]; + char tmp_nm[MAXSCOPESZ+16]; /* for ( a3 in a5 ) { ... } */ if (a3->ntyp != NAME) @@ -947,12 +1018,22 @@ in_for = 1; return z3; } else - { if (a5->sym->isarray == 0 - || a5->sym->nel <= 0) - { fatal("bad arrayname %s", a5->sym->name); + { Lextok *leaf = a5; + if (leaf->sym->type == STRUCT) // find leaf node, which should be an array + { while (leaf->rgt + && leaf->rgt->ntyp == '.') + { leaf = leaf->rgt; + } + leaf = leaf->lft; + // printf("%s %d\n", leaf->sym->name, leaf->sym->isarray); + } + + if (leaf->sym->isarray == 0 + || leaf->sym->nel <= 0) + { fatal("bad arrayname %s", leaf->sym->name); } z1 = nn(ZN, CONST, ZN, ZN); z1->val = 0; - z2 = nn(ZN, CONST, ZN, ZN); z2->val = a5->sym->nel - 1; + z2 = nn(ZN, CONST, ZN, ZN); z2->val = leaf->sym->nel - 1; for_setup(a3, z1, z2); return a3; } @@ -967,8 +1048,6 @@ rv = nn(a3, ASGN, a3, rv); add_seq(rv); /* initial increment */ - pushbreak(); - /* completed loop body, main sequence */ t1 = nn(ZN, 0, ZN, ZN); t1->sq = close_seq(8); @@ -988,6 +1067,7 @@ rv = nn(ZN, DO, ZN, ZN); rv->sl = t0->sl; + return rv; } @@ -1002,6 +1082,7 @@ open_seq(0); add_seq(nn(ZN, 'c', nn(a3, LT, a3, a7), ZN)); /* condition */ + pushbreak(); /* new 6.2.1 */ return for_body(a3, 0); /* no else, just a non-deterministic break */ } @@ -1017,7 +1098,7 @@ switch (f->n->ntyp) { case ATOMIC: if (verbose&32) - printf("spin: warning, %s:%d, atomic inside %s (ignored)\n", + printf("spin: %s:%d, warning, atomic inside %s (ignored)\n", f->n->fn->name, f->n->ln, (added)?"d_step":"atomic"); goto mknonat; case D_STEP: @@ -1025,7 +1106,7 @@ { if (added) goto mknonat; break; } - printf("spin: warning, %s:%d, d_step inside ", + printf("spin: %s:%d, warning, d_step inside ", f->n->fn->name, f->n->ln); if (added) { printf("d_step (ignored)\n"); @@ -1062,8 +1143,12 @@ { printf("label %s %d ", l->s->name, l->e->seqno); if (l->uiid == 0) - printf("<%s>\n", l->c->name); + printf("<%s>", l->c->name); else - printf("<%s i%d>\n", l->c->name, l->uiid); + printf("<%s i%d>", l->c->name, l->uiid); + if (!old_scope_rules) + { printf("\t{scope %s}", l->s->bscp); + } + printf("\n"); } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/guided.c /sys/src/cmd/spin/guided.c --- /n/sources/plan9/sys/src/cmd/spin/guided.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/guided.c Mon Feb 22 00:00:00 2021 @@ -1,29 +1,27 @@ /***** spin: guided.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include #include +#include #include "y.tab.h" -extern RunList *run, *X; +extern RunList *run_lst, *X_lst; extern Element *Al_El; extern Symbol *Fname, *oFname; extern int verbose, lineno, xspin, jumpsteps, depth, merger, cutoff; extern int nproc, nstop, Tval, ntrail, columns; -extern short Have_claim, Skip_claim; +extern short Have_claim, Skip_claim, has_code; extern void ana_src(int, int); extern char **trailfilename; -int TstOnly = 0, pno; +int TstOnly = 0, prno; static int lastclaim = -1; static FILE *fd; @@ -33,7 +31,7 @@ whichproc(int p) { RunList *oX; - for (oX = run; oX; oX = oX->nxt) + for (oX = run_lst; oX; oX = oX->nxt) if (oX->pid == p) { printf("(%s) ", oX->n->name); break; @@ -71,7 +69,54 @@ int not_claim(void) { - return (!Have_claim || !X || X->pid != 0); + return (!Have_claim || !X_lst || X_lst->pid != 0); +} + +int globmin = INT_MAX; +int globmax = 0; + +int +find_min(Sequence *s) +{ SeqList *l; + Element *e; + + if (s->minel < 0) + { s->minel = INT_MAX; + for (e = s->frst; e; e = e->nxt) + { if (e->status & 512) + { continue; + } + e->status |= 512; + + if (e->n->ntyp == ATOMIC + || e->n->ntyp == NON_ATOMIC + || e->n->ntyp == D_STEP) + { int n = find_min(e->n->sl->this); + if (n < s->minel) + { s->minel = n; + } + } else if (e->Seqno < s->minel) + { s->minel = e->Seqno; + } + for (l = e->sub; l; l = l->nxt) + { int n = find_min(l->this); + if (n < s->minel) + { s->minel = n; + } } } + } + if (s->minel < globmin) + { globmin = s->minel; + } + return s->minel; +} + +int +find_max(Sequence *s) +{ + if (s->last->Seqno > globmax) + { globmax = s->last->Seqno; + } + return s->last->Seqno; } void @@ -80,6 +125,17 @@ Element *dothis; char snap[512], *q; + if (has_code) + { printf("spin: important:\n"); + printf(" =======================================warning====\n"); + printf(" this model contains embedded c code statements\n"); + printf(" these statements will not be executed when the trail\n"); + printf(" is replayed in this way -- they are just printed,\n"); + printf(" which will likely lead to inaccurate variable values.\n"); + printf(" for an accurate replay use: ./pan -r\n"); + printf(" =======================================warning====\n\n"); + } + /* * if source model name is leader.pml * look for the trail file under these names: @@ -127,9 +183,9 @@ } } okay: if (xspin == 0 && newer(oFname->name, snap)) - printf("spin: warning, \"%s\" is newer than %s\n", - oFname->name, snap); - + { printf("spin: warning, \"%s\" is newer than %s\n", + oFname->name, snap); + } Tval = 1; /* @@ -140,11 +196,24 @@ hookup(); - while (fscanf(fd, "%d:%d:%d\n", &depth, &pno, &nst) == 3) - { if (depth == -2) { start_claim(pno); continue; } - if (depth == -4) { merger = 1; ana_src(0, 1); continue; } - if (depth == -1) + while (fscanf(fd, "%d:%d:%d\n", &depth, &prno, &nst) == 3) + { if (depth == -2) { if (verbose) + { printf("starting claim %d\n", prno); + } + start_claim(prno); + continue; + } + if (depth == -4) + { if (verbose&32) + { printf("using statement merging\n"); + } + merger = 1; + ana_src(0, 1); + continue; + } + if (depth == -1) + { if (1 || verbose) { if (columns == 2) dotag(stdout, " CYCLE>\n"); else @@ -152,6 +221,11 @@ } continue; } + if (depth <= -5 + && depth >= -8) + { printf("spin: used search permutation, replay with ./pan -r\n"); + return; /* permuted: -5, -6, -7, -8 */ + } if (cutoff > 0 && depth >= cutoff) { printf("-------------\n"); @@ -159,7 +233,7 @@ break; } - if (Skip_claim && pno == 0) continue; + if (Skip_claim && prno == 0) continue; for (dothis = Al_El; dothis; dothis = dothis->Nxt) { if (dothis->Seqno == nst) @@ -167,64 +241,78 @@ } if (!dothis) { printf("%3d: proc %d, no matching stmnt %d\n", - depth, pno - Have_claim, nst); + depth, prno - Have_claim, nst); lost_trail(); } i = nproc - nstop + Skip_claim; if (dothis->n->ntyp == '@') - { if (pno == i-1) - { run = run->nxt; + { if (prno == i-1) + { run_lst = run_lst->nxt; nstop++; if (verbose&4) { if (columns == 2) { dotag(stdout, "\n"); continue; } - if (Have_claim && pno == 0) + if (Have_claim && prno == 0) printf("%3d: claim terminates\n", depth); else printf("%3d: proc %d terminates\n", - depth, pno - Have_claim); + depth, prno - Have_claim); } continue; } - if (pno <= 1) continue; /* init dies before never */ + if (prno <= 1) continue; /* init dies before never */ printf("%3d: stop error, ", depth); printf("proc %d (i=%d) trans %d, %c\n", - pno - Have_claim, i, nst, dothis->n->ntyp); + prno - Have_claim, i, nst, dothis->n->ntyp); lost_trail(); } - if (!xspin && (verbose&32)) - { printf("i=%d pno %d\n", i, pno); + if (0 && !xspin && (verbose&32)) + { printf("step %d i=%d pno %d stmnt %d\n", depth, i, prno, nst); } - for (X = run; X; X = X->nxt) - { if (--i == pno) + for (X_lst = run_lst; X_lst; X_lst = X_lst->nxt) + { if (--i == prno) break; } - if (!X) + if (!X_lst) { if (verbose&32) - { printf("%3d: no process %d (step %d)\n", depth, pno - Have_claim, nst); - printf(" max %d (%d - %d + %d) claim %d", + { printf("%3d: no process %d (stmnt %d)\n", depth, prno - Have_claim, nst); + printf(" max %d (%d - %d + %d) claim %d ", nproc - nstop + Skip_claim, nproc, nstop, Skip_claim, Have_claim); printf("active processes:\n"); - for (X = run; X; X = X->nxt) - { printf("\tpid %d\tproctype %s\n", X->pid, X->n->name); + for (X_lst = run_lst; X_lst; X_lst = X_lst->nxt) + { printf("\tpid %d\tproctype %s\n", X_lst->pid, X_lst->n->name); } printf("\n"); continue; } else - { printf("%3d:\tproc %d (?) ", depth, pno); + { printf("%3d:\tproc %d (?) ", depth, prno); lost_trail(); } } else - { X->pc = dothis; + { int min_seq = find_min(X_lst->ps); + int max_seq = find_max(X_lst->ps); + + if (nst < min_seq || nst > max_seq) + { printf("%3d: error: invalid statement", depth); + if (verbose&32) + { printf(": pid %d:%d (%s:%d:%d) stmnt %d (valid range %d .. %d)", + prno, X_lst->pid, X_lst->n->name, X_lst->tn, X_lst->b, + nst, min_seq, max_seq); + } + printf("\n"); + continue; + /* lost_trail(); */ + } + X_lst->pc = dothis; } lineno = dothis->n->ln; @@ -247,13 +335,13 @@ printf("]\n"); } if (verbose&1) dumpglobals(); - if (verbose&2) dumplocal(X); + if (verbose&2) dumplocal(X_lst, 0); if (xspin) printf("\n"); } og = g; } while (g && g != dothis->nxt); - if (X != NULL) - { X->pc = g?huntele(g, 0, -1):g; + if (X_lst != NULL) + { X_lst->pc = g?huntele(g, 0, -1):g; } } else { @@ -262,9 +350,9 @@ else a = dothis->merge; - if (X != NULL) - { X->pc = eval_sub(dothis); - if (X->pc) X->pc = huntele(X->pc, 0, a); + if (X_lst != NULL) + { X_lst->pc = eval_sub(dothis); + if (X_lst->pc) X_lst->pc = huntele(X_lst->pc, 0, a); } if (depth >= jumpsteps @@ -281,25 +369,25 @@ if (a && (verbose&32)) printf("\t", dothis->merge, - (X && X->pc)?X->pc->seqno:-1); + (X_lst && X_lst->pc)?X_lst->pc->seqno:-1); printf("\n"); } if (verbose&1) dumpglobals(); - if (verbose&2) dumplocal(X); + if (verbose&2) dumplocal(X_lst, 0); if (xspin) printf("\n"); - if (X && !X->pc) - { X->pc = dothis; + if (X_lst && !X_lst->pc) + { X_lst->pc = dothis; printf("\ttransition failed\n"); a = 0; /* avoid inf loop */ } } - if (a && X && X->pc && X->pc->seqno != a) - { dothis = X->pc; + if (a && X_lst && X_lst->pc && X_lst->pc->seqno != a) + { dothis = X_lst->pc; goto keepgoing; } } - if (Have_claim && X && X->pid == 0 + if (Have_claim && X_lst && X_lst->pid == 0 && dothis->n && lastclaim != dothis->n->ln) { lastclaim = dothis->n->ln; @@ -334,7 +422,7 @@ int pid = eval(n); RunList *Y; - for (Y = run; Y; Y = Y->nxt) + for (Y = run_lst; Y; Y = Y->nxt) { if (--i == pid) return Y->pc->seqno; } diff -Nru /n/sources/plan9/sys/src/cmd/spin/main.c /sys/src/cmd/spin/main.c --- /n/sources/plan9/sys/src/cmd/spin/main.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/main.c Mon Feb 22 00:00:00 2021 @@ -1,27 +1,23 @@ /***** spin: main.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include +#include #include "spin.h" #include "version.h" #include #include #include -/* #include */ #include #ifdef PC -#include -extern int unlink(const char *); + #include #else -#include + #include #endif #include "y.tab.h" @@ -32,6 +28,13 @@ extern void repro_src(void); extern void qhide(int); extern char CurScope[MAXSCOPESZ]; +extern short has_provided, has_code, has_ltl, has_accept; +extern int realread, buzzed; +extern void ana_src(int, int); +extern void putprelude(void); + +static void add_comptime(char *); +static void add_runtime(char *); Symbol *Fname, *oFname; @@ -43,13 +46,16 @@ int no_print, no_wrapup, Caccess, limited_vis, like_java; int separate; /* separate compilation */ int export_ast; /* pangen5.c */ +int norecompile; /* main.c */ int old_scope_rules; /* use pre 5.3.0 rules */ -int split_decl = 1, product, Strict; +int old_priority_rules; /* use pre 6.2.0 rules */ +int product, Strict; +short replay; -int merger = 1, deadvar = 1; +int merger = 1, deadvar = 1, implied_semis = 1; int ccache = 0; /* oyvind teig: 5.2.0 case caching off by default */ -static int preprocessonly, SeedUsed; +static int preprocessonly, SeedUsed, itsr, itsr_n, sw_or_bt; static int seedy; /* be verbose about chosen seed */ static int inlineonly; /* show inlined code */ static int dataflow = 1; @@ -72,6 +78,9 @@ static char **ltl_file = (char **) 0; static char **nvr_file = (char **) 0; static char *ltl_claims = (char *) 0; +static char *pan_runtime = ""; +static char *pan_comptime = ""; +static char *formula = NULL; static FILE *fd_ltl = (FILE *) 0; static char *PreArg[64]; static int PreCnt = 0; @@ -81,78 +90,510 @@ void explain(int); +#ifndef CPP /* to use visual C++: - #define CPP "CL -E/E" - or call spin as: "spin -PCL -E/E" + #define CPP "cl -E/E" + or call spin as: spin -P"CL -E/E" on OS2: #define CPP "icc -E/Pd+ -E/Q+" - or call spin as: "spin -Picc -E/Pd+ -E/Q+" + or call spin as: spin -P"icc -E/Pd+ -E/Q+" + make sure the -E arg is always at the end, + in each case, because the command line + can later be truncated at that point */ -#ifndef CPP + #if 1 + #define CPP "gcc -std=gnu99 -Wformat-overflow=0 -E -x c" + /* if gcc-4 is available, this setting is modified below */ + #else #if defined(PC) || defined(MAC) - #define CPP "gcc -E -x c" /* most systems have gcc or cpp */ - /* if gcc-4 is available, this setting is modified below */ + #define CPP "gcc -std=gnu99 -E -x c" #else #ifdef SOLARIS #define CPP "/usr/ccs/lib/cpp" #else - #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - #define CPP "cpp" - #else - #define CPP "/bin/cpp" /* classic Unix systems */ - #endif + #define CPP "cpp" /* sometimes: "/lib/cpp" */ #endif #endif + #endif #endif -static char *PreProc = CPP; +static char PreProc[512]; extern int depth; /* at least some steps were made */ -void -alldone(int estatus) +int +WhatSeed(void) { - if (preprocessonly == 0 - && strlen(out1) > 0) - (void) unlink((const char *)out1); + return SeedUsed; +} - if (seedy && !analyze && !export_ast - && !s_trail && !preprocessonly && depth > 0) - printf("seed used: %d\n", SeedUsed); +void +final_fiddle(void) +{ char *has_a, *has_l, *has_f; - if (xspin && (analyze || s_trail)) - { if (estatus) - printf("spin: %d error(s) - aborting\n", - estatus); - else - printf("Exit-Status 0\n"); + /* no -a or -l but has_accept: add -a */ + /* no -a or -l in pan_runtime: add -DSAFETY to pan_comptime */ + /* -a or -l but no -f then add -DNOFAIR */ + + has_a = strstr(pan_runtime, "-a"); + has_l = strstr(pan_runtime, "-l"); + has_f = strstr(pan_runtime, "-f"); + + if (!has_l && !has_a && strstr(pan_comptime, "-DNP")) + { add_runtime("-l"); + has_l = strstr(pan_runtime, "-l"); } - exit(estatus); + + if (!has_a && !has_l + && !strstr(pan_comptime, "-DSAFETY")) + { if (has_accept + && !strstr(pan_comptime, "-DBFS") + && !strstr(pan_comptime, "-DNOCLAIM")) + { add_runtime("-a"); + has_a = pan_runtime; + } else + { add_comptime("-DSAFETY"); + } } + + if ((has_a || has_l) && !has_f + && !strstr(pan_comptime, "-DNOFAIR")) + { add_comptime("-DNOFAIR"); + } +} + +static int +change_param(char *t, char *what, int range, int bottom) +{ char *ptr; + int v; + + assert(range < 1000 && range > 0); + if ((ptr = strstr(t, what)) != NULL) + { ptr += strlen(what); + if (!isdigit((int) *ptr)) + { return 0; + } + v = atoi(ptr) + 1; /* was: v = (atoi(ptr)+1)%range */ + if (v >= range) + { v = bottom; + } + if (v >= 100) + { *ptr++ = '0' + (v/100); v %= 100; + *ptr++ = '0' + (v/10); + *ptr = '0' + (v%10); + } else if (v >= 10) + { *ptr++ = '0' + (v/10); + *ptr++ = '0' + (v%10); + *ptr = ' '; + } else + { *ptr++ = '0' + v; + *ptr++ = ' '; + *ptr = ' '; + } } + return 1; +} + +static void +change_rs(char *t) +{ char *ptr; + int cnt = 0; + long v; + + if ((ptr = strstr(t, "-RS")) != NULL) + { ptr += 3; + /* room for at least 10 digits */ + v = Rand()%1000000000L; + while (v/10 > 0) + { *ptr++ = '0' + v%10; + v /= 10; + cnt++; + } + *ptr++ = '0' + v; + cnt++; + while (cnt++ < 10) + { *ptr++ = ' '; + } } +} + +int +omit_str(char *in, char *s) +{ char *ptr = strstr(in, s); + int i, nr = -1; + + if (ptr) + { for (i = 0; i < (int) strlen(s); i++) + { *ptr++ = ' '; + } + if (isdigit((int) *ptr)) + { nr = atoi(ptr); + while (isdigit((int) *ptr)) + { *ptr++ = ' '; + } } } + return nr; } void -preprocess(char *a, char *b, int a_tmp) -{ char precmd[1024], cmd[2048]; int i; +string_trim(char *t) +{ int n = strlen(t) - 1; + + while (n > 0 && t[n] == ' ') + { t[n--] = '\0'; + } +} + +int +e_system(int v, const char *s) +{ static int count = 1; + + /* v == 0 : checks to find non-linked version of gcc */ + /* v == 1 : all other commands */ + /* v == 2 : preprocessing the promela input */ + + if (v == 1) + { if (verbose&(32|64)) /* -v or -w */ + { printf("cmd%02d: %s\n", count++, s); + fflush(stdout); + } + if (verbose&64) /* only -w */ + { return 0; /* suppress the call to system(s) */ + } } + return system(s); +} + +void +alldone(int estatus) +{ char *ptr; #if defined(WIN32) || defined(WIN64) struct _stat x; -/* struct stat x; */ +#else + struct stat x; #endif -#ifdef PC - extern int try_zpp(char *, char *); - if (PreCnt == 0 && try_zpp(a, b)) - { goto out; + if (preprocessonly == 0 && strlen(out1) > 0) + { (void) unlink((const char *) out1); + } + + (void) unlink(TMP_FILE1); + (void) unlink(TMP_FILE2); + + if (!buzzed && seedy && !analyze && !export_ast + && !s_trail && !preprocessonly && depth > 0) + { printf("seed used: %d\n", SeedUsed); + } + + if (!buzzed && xspin && (analyze || s_trail)) + { if (estatus) + { printf("spin: %d error(s) - aborting\n", + estatus); + } else + { printf("Exit-Status 0\n"); + } } + + if (buzzed && replay && !has_code && !estatus) + { extern QH *qh_lst; + QH *j; + int i; + + pan_runtime = (char *) emalloc(2048); /* more than enough */ + sprintf(pan_runtime, "-n%d ", SeedUsed); + if (jumpsteps) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-j%d ", jumpsteps); + } + if (trailfilename) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-k%s ", *trailfilename); + } + if (cutoff) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-u%d ", cutoff); + } + for (i = 1; i <= PreCnt; i++) + { strcat(pan_runtime, PreArg[i]); + strcat(pan_runtime, " "); + } + for (j = qh_lst; j; j = j->nxt) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-q%d ", j->n); + } + if (strcmp(PreProc, CPP) != 0) + { sprintf(&pan_runtime[strlen(pan_runtime)], "\"-P%s\" ", PreProc); + } + /* -oN options 1..5 are ignored in simulations */ + if (old_priority_rules) strcat(pan_runtime, "-o6 "); + if (!implied_semis) strcat(pan_runtime, "-o7 "); + if (no_print) strcat(pan_runtime, "-b "); + if (no_wrapup) strcat(pan_runtime, "-B "); + if (columns == 1) strcat(pan_runtime, "-c "); + if (columns == 2) strcat(pan_runtime, "-M "); + if (seedy == 1) strcat(pan_runtime, "-h "); + if (like_java == 1) strcat(pan_runtime, "-J "); + if (old_scope_rules) strcat(pan_runtime, "-O "); + if (notabs) strcat(pan_runtime, "-T "); + if (verbose&1) strcat(pan_runtime, "-g "); + if (verbose&2) strcat(pan_runtime, "-l "); + if (verbose&4) strcat(pan_runtime, "-p "); + if (verbose&8) strcat(pan_runtime, "-r "); + if (verbose&16) strcat(pan_runtime, "-s "); + if (verbose&32) strcat(pan_runtime, "-v "); + if (verbose&64) strcat(pan_runtime, "-w "); + if (m_loss) strcat(pan_runtime, "-m "); + + char *tmp = (char *) emalloc(strlen("spin -t") + + strlen(pan_runtime) + strlen(Fname->name) + 8); + + sprintf(tmp, "spin -t %s %s", pan_runtime, Fname->name); + estatus = e_system(1, tmp); /* replay */ + exit(estatus); /* replay without c_code */ } + + if (buzzed && (!replay || has_code) && !estatus) + { char *tmp, *tmp2 = NULL, *P_X; + char *C_X = (buzzed == 2) ? "-O" : ""; + + if (replay && strlen(pan_comptime) == 0) + { +#if defined(WIN32) || defined(WIN64) + P_X = "pan"; +#else + P_X = "./pan"; #endif + if (stat(P_X, (struct stat *)&x) < 0) + { goto recompile; /* no executable pan for replay */ + } + tmp = (char *) emalloc(8 + strlen(P_X) + strlen(pan_runtime) +4); + /* the final +4 is too allow adding " &" in some cases */ + sprintf(tmp, "%s %s", P_X, pan_runtime); + goto runit; + } #if defined(WIN32) || defined(WIN64) - if (strncmp(PreProc, "gcc -E -x c", strlen("gcc -E -x c")) == 0) - { if (stat("/bin/gcc-4.exe", (struct stat *)&x) == 0 /* for PCs with cygwin */ - || stat("c:/cygwin/bin/gcc-4.exe", (struct stat *)&x) == 0) - { PreProc = "gcc-4 -E -x c"; - } else if (stat("/bin/gcc-3.exe", (struct stat *)&x) == 0 - || stat("c:/cygwin/bin/gcc-3.exe", (struct stat *)&x) == 0) - { PreProc = "gcc-3 -E -x c"; + P_X = "-o pan pan.c && pan"; +#else + P_X = "-o pan pan.c && ./pan"; +#endif + /* swarm and biterate randomization additions */ + if (!replay && itsr) /* iterative search refinement */ + { if (!strstr(pan_comptime, "-DBITSTATE")) + { add_comptime("-DBITSTATE"); + } + if (!strstr(pan_comptime, "-DPUTPID")) + { add_comptime("-DPUTPID"); + } + if (!strstr(pan_comptime, "-DT_RAND") + && !strstr(pan_comptime, "-DT_REVERSE")) + { add_runtime("-T0 "); /* controls t_reverse */ + } + if (!strstr(pan_runtime, "-P") /* runtime flag */ + || pan_runtime[2] < '0' + || pan_runtime[2] > '1') /* no -P0 or -P1 */ + { add_runtime("-P0 "); /* controls p_reverse */ + } + if (!strstr(pan_runtime, "-w")) + { add_runtime("-w18 "); /* -w18 = 256K */ + } else + { char nv[32]; + int x; + x = omit_str(pan_runtime, "-w"); + if (x >= 0) + { sprintf(nv, "-w%d ", x); + add_runtime(nv); /* added spaces */ + } } + if (!strstr(pan_runtime, "-h")) + { add_runtime("-h0 "); /* 0..499 */ + /* leave 2 spaces for increments up to -h499 */ + } else if (!strstr(pan_runtime, "-hash")) + { char nv[32]; + int x; + x = omit_str(pan_runtime, "-h"); + if (x >= 0) + { sprintf(nv, "-h%d ", x%500); + add_runtime(nv); /* added spaces */ + } } + if (!strstr(pan_runtime, "-k")) + { add_runtime("-k1 "); /* 1..3 */ + } else + { char nv[32]; + int x; + x = omit_str(pan_runtime, "-k"); + if (x >= 0) + { sprintf(nv, "-k%d ", x%4); + add_runtime(nv); /* added spaces */ + } } + if (strstr(pan_runtime, "-p_rotate")) + { char nv[32]; + int x; + x = omit_str(pan_runtime, "-p_rotate"); + if (x < 0) + { x = 0; + } + sprintf(nv, "-p_rotate%d ", x%256); + add_runtime(nv); /* added spaces */ + } else if (strstr(pan_runtime, "-p_permute") == 0) + { add_runtime("-p_rotate0 "); + } + if (strstr(pan_runtime, "-RS")) + { (void) omit_str(pan_runtime, "-RS"); + } + /* need room for at least 10 digits */ + add_runtime("-RS1234567890 "); + change_rs(pan_runtime); + } +recompile: + if (strstr(PreProc, "cpp")) /* unix/linux */ + { strcpy(PreProc, "gcc"); /* need compiler */ + } else if ((tmp = strstr(PreProc, "-E")) != NULL) + { *tmp = '\0'; /* strip preprocessing flags */ + } + + final_fiddle(); + tmp = (char *) emalloc(8 + /* account for alignment */ + strlen(PreProc) + + strlen(C_X) + + strlen(pan_comptime) + + strlen(P_X) + + strlen(pan_runtime) + + strlen(" -p_reverse & ")); + tmp2 = tmp; + + /* P_X ends with " && ./pan " */ + sprintf(tmp, "%s %s %s %s %s", + PreProc, C_X, pan_comptime, P_X, pan_runtime); + + if (!replay) + { if (itsr < 0) /* swarm only */ + { strcat(tmp, " &"); /* after ./pan */ + itsr = -itsr; /* now same as biterate */ + } + /* do compilation first + * split cc command from run command + * leave cc in tmp, and set tmp2 to run + */ + if ((ptr = strstr(tmp, " && ")) != NULL) + { tmp2 = ptr + 4; /* first run */ + *ptr = '\0'; + } } + + if (has_ltl) + { (void) unlink("_spin_nvr.tmp"); + } + + if (!norecompile) + { /* make sure that if compilation fails we do not continue */ +#ifdef PC + (void) unlink("./pan.exe"); +#else + (void) unlink("./pan"); +#endif + } +runit: + if (norecompile && tmp != tmp2) + { estatus = 0; + } else + { estatus = e_system(1, tmp); /* compile or run */ + } + if (replay || estatus < 0) + { goto skipahead; + } + /* !replay */ + if (itsr == 0 && !sw_or_bt) /* single run */ + { estatus = e_system(1, tmp2); + } else if (itsr > 0) /* iterative search refinement */ + { int is_swarm = 0; + if (tmp2 != tmp) /* swarm: did only compilation so far */ + { tmp = tmp2; /* now we point to the run command */ + estatus = e_system(1, tmp); /* first run */ + itsr--; + } + itsr--; /* count down */ + + /* the following are added back randomly later */ + (void) omit_str(tmp, "-p_reverse"); /* replaced by spaces */ + (void) omit_str(tmp, "-p_normal"); + + if (strstr(tmp, " &") != NULL) + { (void) omit_str(tmp, " &"); + is_swarm = 1; + } + + /* increase -w every itsr_n-th run */ + if ((itsr_n > 0 && (itsr == 0 || (itsr%itsr_n) != 0)) + || (change_param(tmp, "-w", 36, 18) >= 0)) /* max 4G bit statespace */ + { (void) change_param(tmp, "-h", 500, 0); /* hash function 0.499 */ + (void) change_param(tmp, "-p_rotate", 256, 0); /* if defined */ + (void) change_param(tmp, "-k", 4, 1); /* nr bits per state 0->1,2,3 */ + (void) change_param(tmp, "-T", 2, 0); /* with or without t_reverse*/ + (void) change_param(tmp, "-P", 2, 0); /* -P 0..1 != p_reverse */ + change_rs(tmp); /* change random seed */ + string_trim(tmp); + if (rand()%5 == 0) /* 20% of all runs */ + { strcat(tmp, " -p_reverse "); + /* at end, so this overrides -p_rotateN, if there */ + /* but -P0..1 disable this in 50% of the cases */ + /* so its really activated in 10% of all runs */ + } else if (rand()%6 == 0) /* override p_rotate and p_reverse */ + { strcat(tmp, " -p_normal "); + } + if (is_swarm) + { strcat(tmp, " &"); + } + goto runit; + } } +skipahead: + (void) unlink("pan.b"); + (void) unlink("pan.c"); + (void) unlink("pan.h"); + (void) unlink("pan.m"); + (void) unlink("pan.p"); + (void) unlink("pan.t"); + } + exit(estatus); +} +#if 0 + -P0 normal active process creation + -P1 reversed order for *active* process creation != p_reverse + + -T0 normal transition exploration + -T1 reversed order of transition exploration + + -DP_RAND (random starting point +- -DP_REVERSE) + -DPERMUTED (also enables -p_rotateN and -p_reverse) + -DP_REVERSE (same as -DPERMUTED with -p_reverse, but 7% faster) + + -DT_RAND (random starting point -- optionally with -T0..1) + -DT_REVERSE (superseded by -T0..1 options) + + -hash generates new hash polynomial for -h0 + + permutation modes: + -permuted (adds -DPERMUTED) -- this is also the default with -swarm + -t_reverse (same as -T1) + -p_reverse (similar to -P1) + -p_rotateN + -p_normal + + less useful would be (since there is less non-determinism in transitions): + -t_rotateN -- a controlled version of -DT_RAND + + compiling with -DPERMUTED enables a number of new runtime options, + that -swarmN,M will also exploit: + -p_permute (default) + -p_rotateN + -p_reverse +#endif + +void +preprocess(char *a, char *b, int a_tmp) +{ char precmd[1024], cmd[2048]; + int i; +#ifdef PC + /* gcc is sometimes a symbolic link to gcc-4 + that does not work well in cygwin, so we try + to use the actual executable that is used. + the code below assumes we are on a cygwin-like system + */ + if (strncmp(PreProc, "gcc ", strlen("gcc ")) == 0) + { if (e_system(0, "gcc-4 --version > pan.pre 2>&1") == 0) + { strcpy(PreProc, "gcc-4 -std=gnu99 -Wformat-overflow=0 -E -x c"); + } else if (e_system(0, "gcc-3 --version > pan.pre 2>&1") == 0) + { strcpy(PreProc, "gcc-3 -std=gnu99 -Wformat-overflow=0 -E -x c"); } } #endif + + assert(strlen(PreProc) < sizeof(precmd)); strcpy(precmd, PreProc); for (i = 1; i <= PreCnt; i++) { strcat(precmd, " "); @@ -162,16 +603,13 @@ { fprintf(stdout, "spin: too many -D args, aborting\n"); alldone(1); } - sprintf(cmd, "%s %s > %s", precmd, a, b); - if (system((const char *)cmd)) + sprintf(cmd, "%s \"%s\" > \"%s\"", precmd, a, b); + if (e_system(2, (const char *)cmd)) /* preprocessing step */ { (void) unlink((const char *) b); if (a_tmp) (void) unlink((const char *) a); - fprintf(stdout, "spin: preprocessing failed\n"); /* 4.1.2 was stderr */ + fprintf(stdout, "spin: preprocessing failed %s\n", cmd); alldone(1); /* no return, error exit */ } -#ifdef PC -out: -#endif if (a_tmp) (void) unlink((const char *) a); } @@ -203,7 +641,7 @@ printf("\t-k fname use the trailfile stored in file fname, see also -t\n"); printf("\t-L when using -e, use strict language intersection\n"); printf("\t-l print all local variables\n"); - printf("\t-M print msc-flow in Postscript\n"); + printf("\t-M generate msc-flow in tcl/tk format\n"); printf("\t-m lose msgs sent to full queues\n"); printf("\t-N fname use never claim stored in file fname\n"); printf("\t-nN seed for random nr generator\n"); @@ -213,10 +651,49 @@ printf("\t-o3 turn off statement merging in verifier\n"); printf("\t-o4 turn on rendezvous optiomizations in verifier\n"); printf("\t-o5 turn on case caching (reduces size of pan.m, but affects reachability reports)\n"); + printf("\t-o6 revert to the old rules for interpreting priority tags (pre version 6.2)\n"); + printf("\t-o7 revert to the old rules for semi-colon usage (pre version 6.3)\n"); printf("\t-Pxxx use xxx for preprocessing\n"); printf("\t-p print all statements\n"); + printf("\t-pp pretty-print (reformat) stdin, write stdout\n"); printf("\t-qN suppress io for queue N in printouts\n"); printf("\t-r print receive events\n"); + printf("\t-replay replay an error trail-file found earlier\n"); + printf("\t if the model contains embedded c-code, the ./pan executable is used\n"); + printf("\t otherwise spin itself is used to replay the trailfile\n"); + printf("\t note that pan recognizes different runtime options than spin itself\n"); + printf("\t-run (or -search) generate a verifier, and compile and run it\n"); + printf("\t options before -search are interpreted by spin to parse the input\n"); + printf("\t options following a -search are used to compile and run the verifier pan\n"); + printf("\t valid options that can follow a -search argument include:\n"); + printf("\t -bfs perform a breadth-first search\n"); + printf("\t -bfspar perform a parallel breadth-first search\n"); + printf("\t -dfspar perform a parallel depth-first search, same as -DNCORE=4\n"); + printf("\t -bcs use the bounded-context-switching algorithm\n"); + printf("\t -bitstate or -bit, use bitstate storage\n"); + printf("\t -biterateN,M use bitstate with iterative search refinement (-w18..-w35)\n"); + printf("\t perform N randomized runs and increment -w every M runs\n"); + printf("\t default value for N is 10, default for M is 1\n"); + printf("\t (use N,N to keep -w fixed for all runs)\n"); + printf("\t (add -w to see which commands will be executed)\n"); + printf("\t (add -W if ./pan exists and need not be recompiled)\n"); + printf("\t -swarmN,M like -biterate, but running all iterations in parallel\n"); + printf("\t -link file.c link executable pan to file.c\n"); + printf("\t -collapse use collapse state compression\n"); + printf("\t -noreduce do not use partial order reduction\n"); + printf("\t -hc use hash-compact storage\n"); + printf("\t -noclaim ignore all ltl and never claims\n"); + printf("\t -p_permute use process scheduling order random permutation\n"); + printf("\t -p_rotateN use process scheduling order rotation by N\n"); + printf("\t -p_reverse use process scheduling order reversal\n"); + printf("\t -rhash randomly pick one of the -p_... options\n"); + printf("\t -ltl p verify the ltl property named p\n"); + printf("\t -safety compile for safety properties only\n"); + printf("\t -i use the dfs iterative shortening algorithm\n"); + printf("\t -a search for acceptance cycles\n"); + printf("\t -l search for non-progress cycles\n"); + printf("\t similarly, a -D... parameter can be specified to modify the compilation\n"); + printf("\t and any valid runtime pan argument can be specified for the verification\n"); printf("\t-S1 and -S2 separate pan source for claim and model\n"); printf("\t-s print send events\n"); printf("\t-T do not indent printf output\n"); @@ -230,7 +707,7 @@ alldone(1); } -void +int optimizations(int nr) { switch (nr) { @@ -269,11 +746,134 @@ printf("spin: case caching turned %s\n", ccache?"on":"off"); break; + case '6': + old_priority_rules = 1; + if (verbose&32) + printf("spin: using old priority rules (pre version 6.2)\n"); + return 0; /* no break */ + case '7': + implied_semis = 0; + if (verbose&32) + printf("spin: no implied semi-colons (pre version 6.3)\n"); + return 0; /* no break */ default: printf("spin: bad or missing parameter on -o\n"); usage(); break; } + return 1; +} + +static void +add_comptime(char *s) +{ char *tmp; + + if (!s || strstr(pan_comptime, s)) + { return; + } + + tmp = (char *) emalloc(strlen(pan_comptime)+strlen(s)+2); + sprintf(tmp, "%s %s", pan_comptime, s); + pan_comptime = tmp; +} + +static struct { + char *ifsee, *thendo; + int keeparg; +} pats[] = { + { "-bfspar", "-DBFS_PAR", 0 }, + { "-bfs", "-DBFS", 0 }, + { "-bcs", "-DBCS", 0 }, + { "-bitstate", "-DBITSTATE", 0 }, + { "-bit", "-DBITSTATE", 0 }, + { "-hc", "-DHC4", 0 }, + { "-collapse", "-DCOLLAPSE", 0 }, + { "-noclaim", "-DNOCLAIM", 0 }, + { "-noreduce", "-DNOREDUCE", 0 }, + { "-np", "-DNP", 0 }, + { "-permuted", "-DPERMUTED", 0 }, + { "-p_permute", "-DPERMUTED", 1 }, + { "-p_rotate", "-DPERMUTED", 1 }, + { "-p_reverse", "-DPERMUTED", 1 }, + { "-rhash", "-DPERMUTED", 1 }, + { "-safety", "-DSAFETY", 0 }, + { "-i", "-DREACH", 1 }, + { "-l", "-DNP", 1 }, + { 0, 0 } +}; + +static void +set_itsr_n(char *s) /* e.g., -swarm12,3 */ +{ char *tmp; + + if ((tmp = strchr(s, ',')) != NULL) + { tmp++; + if (*tmp != '\0' && isdigit((int) *tmp)) + { itsr_n = atoi(tmp); + if (itsr_n < 2) + { itsr_n = 0; + } } } +} + +static void +add_runtime(char *s) +{ char *tmp; + int i; + + if (strncmp(s, "-biterate", strlen("-biterate")) == 0) + { itsr = 10; /* default nr of sequential iterations */ + sw_or_bt = 1; + if (isdigit((int) s[9])) + { itsr = atoi(&s[9]); + if (itsr < 1) + { itsr = 1; + } + set_itsr_n(s); + } + return; + } + if (strncmp(s, "-swarm", strlen("-swarm")) == 0) + { itsr = -10; /* parallel iterations */ + sw_or_bt = 1; + if (isdigit((int) s[6])) + { itsr = atoi(&s[6]); + if (itsr < 1) + { itsr = 1; + } + itsr = -itsr; + set_itsr_n(s); + } + return; + } + + for (i = 0; pats[i].ifsee; i++) + { if (strncmp(s, pats[i].ifsee, strlen(pats[i].ifsee)) == 0) + { add_comptime(pats[i].thendo); + if (pats[i].keeparg) + { break; + } + return; + } } + if (strncmp(s, "-dfspar", strlen("-dfspar")) == 0) + { add_comptime("-DNCORE=4"); + return; + } + + tmp = (char *) emalloc(strlen(pan_runtime)+strlen(s)+2); + sprintf(tmp, "%s %s", pan_runtime, s); + pan_runtime = tmp; +} + +ssize_t +getline(char **lineptr, size_t *n, FILE *stream) +{ static char buffer[8192]; + + *lineptr = (char *) &buffer; + + if (!fgets(buffer, sizeof(buffer), stream)) + { return 0; + } + return 1; } int @@ -281,21 +881,20 @@ { Symbol *s; int T = (int) time((time_t *)0); int usedopts = 0; - extern void ana_src(int, int); yyin = stdin; yyout = stdout; tl_out = stdout; strcpy(CurScope, "_"); + assert(strlen(CPP) < sizeof(PreProc)); + strcpy(PreProc, CPP); + /* unused flags: y, z, G, L, Q, R, W */ while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { - /* generate code for separate compilation: S1 or S2 */ - case 'S': separate = atoi(&argv[1][2]); - /* fall through */ - case 'a': analyze = 1; break; case 'A': export_ast = 1; break; + case 'a': analyze = 1; break; case 'B': no_wrapup = 1; break; case 'b': no_print = 1; break; case 'C': Caccess = 1; break; @@ -327,31 +926,107 @@ argc--; argv++; break; case 'n': T = atoi(&argv[1][2]); tl_terse = 1; break; case 'O': old_scope_rules = 1; break; - case 'o': optimizations(argv[1][2]); - usedopts = 1; break; - case 'P': PreProc = (char *) &argv[1][2]; break; - case 'p': verbose += 4; break; + case 'o': usedopts += optimizations(argv[1][2]); break; + case 'P': assert(strlen((const char *) &argv[1][2]) < sizeof(PreProc)); + strcpy(PreProc, (const char *) &argv[1][2]); + break; + case 'p': if (argv[1][2] == 'p') + { pretty_print(); + alldone(0); + } + verbose += 4; break; case 'q': if (isdigit((int) argv[1][2])) qhide(atoi(&argv[1][2])); break; - case 'r': verbose += 8; break; - case 's': verbose += 16; break; + case 'r': + if (strcmp(&argv[1][1], "run") == 0) + { Srand((unsigned int) T); +samecase: if (buzzed != 0) + { fatal("cannot combine -x with -run -replay or -search", (char *)0); + } + buzzed = 2; + analyze = 1; + argc--; argv++; + /* process all remaining arguments, except -w/-W, as relating to pan: */ + while (argc > 1 && argv[1][0] == '-') + { switch (argv[1][1]) { + case 'D': /* eg -DNP */ + /* case 'E': conflicts with runtime arg */ + case 'O': /* eg -O2 */ + case 'U': /* to undefine a macro */ + add_comptime(argv[1]); + break; +#if 0 + case 'w': /* conflicts with bitstate runtime arg */ + verbose += 64; + break; +#endif + case 'W': + norecompile = 1; + break; + case 'l': + if (strcmp(&argv[1][1], "ltl") == 0) + { add_runtime("-N"); + argc--; argv++; + add_runtime(argv[1]); /* prop name */ + break; + } + if (strcmp(&argv[1][1], "link") == 0) + { argc--; argv++; + add_comptime(argv[1]); + break; + } + /* else fall through */ + default: + add_runtime(argv[1]); /* -bfs etc. */ + break; + } + argc--; argv++; + } + argc++; argv--; + } else if (strcmp(&argv[1][1], "replay") == 0) + { replay = 1; + add_runtime("-r"); + goto samecase; + } else + { verbose += 8; + } + break; + case 'S': separate = atoi(&argv[1][2]); /* S1 or S2 */ + /* generate code for separate compilation */ + analyze = 1; break; + case 's': + if (strcmp(&argv[1][1], "simulate") == 0) + { break; /* ignore */ + } + if (strcmp(&argv[1][1], "search") == 0) + { goto samecase; + } + verbose += 16; break; case 'T': notabs = 1; break; case 't': s_trail = 1; if (isdigit((int)argv[1][2])) - ntrail = atoi(&argv[1][2]); + { ntrail = atoi(&argv[1][2]); + } break; case 'U': PreArg[++PreCnt] = (char *) &argv[1][0]; break; /* undefine */ - case 'u': cutoff = atoi(&argv[1][2]); break; /* new 3.4.14 */ + case 'u': cutoff = atoi(&argv[1][2]); break; case 'v': verbose += 32; break; case 'V': printf("%s\n", SpinVersion); alldone(0); break; case 'w': verbose += 64; break; -#if 0 - case 'x': split_decl = 0; break; /* experimental */ -#endif + case 'W': norecompile = 1; break; /* 6.4.7: for swarm/biterate */ + case 'x': /* internal - reserved use */ + if (buzzed != 0) + { fatal("cannot combine -x with -run -search or -replay", (char *)0); + } + buzzed = 1; /* implies also -a -o3 */ + pan_runtime = "-d"; + analyze = 1; + usedopts += optimizations('3'); + break; case 'X': xspin = notabs = 1; #ifndef PC signal(SIGPIPE, alldone); /* not posix... */ @@ -365,22 +1040,27 @@ argc--; argv++; } + if (columns == 2 && !cutoff) + { cutoff = 1024; + } + if (usedopts && !analyze) - printf("spin: warning -o[123] option ignored in simulations\n"); + printf("spin: warning -o[1..5] option ignored in simulations\n"); if (ltl_file) - { char formula[4096]; - add_ltl = ltl_file-2; add_ltl[1][1] = 'f'; + { add_ltl = ltl_file-2; add_ltl[1][1] = 'f'; if (!(tl_out = fopen(*ltl_file, "r"))) { printf("spin: cannot open %s\n", *ltl_file); alldone(1); } - if (!fgets(formula, 4096, tl_out)) + size_t linebuffsize = 0; + ssize_t length = getline(&formula, &linebuffsize, tl_out); + if (!formula || !length) { printf("spin: cannot read %s\n", *ltl_file); } fclose(tl_out); tl_out = stdout; - *ltl_file = (char *) formula; + *ltl_file = formula; } if (argc > 1) { FILE *fd = stdout; @@ -390,7 +1070,8 @@ strcpy(out1, "pan.pre"); if (add_ltl || nvr_file) - { sprintf(out2, "%s.nvr", argv[1]); + { assert(strlen(argv[1]) < sizeof(out2)); + sprintf(out2, "%s.nvr", argv[1]); if ((fd = fopen(out2, MFLAGS)) == NULL) { printf("spin: cannot create tmp file %s\n", out2); @@ -413,18 +1094,22 @@ } if (preprocessonly) - alldone(0); + { alldone(0); + } if (!(yyin = fopen(out1, "r"))) { printf("spin: cannot open %s\n", out1); alldone(1); } + assert(strlen(argv[1])+1 < sizeof(cmd)); + if (strncmp(argv[1], "progress", (size_t) 8) == 0 || strncmp(argv[1], "accept", (size_t) 6) == 0) - sprintf(cmd, "_%s", argv[1]); - else - strcpy(cmd, argv[1]); + { sprintf(cmd, "_%s", argv[1]); + } else + { strcpy(cmd, argv[1]); + } oFname = Fname = lookup(cmd); if (oFname->name[0] == '\"') { int i = (int) strlen(oFname->name); @@ -440,22 +1125,24 @@ alldone(1); } printf("%s\n", SpinVersion); - fprintf(stderr, "spin: error, no filename specified"); + fprintf(stderr, "spin: error, no filename specified\n"); fflush(stdout); alldone(1); } if (columns == 2) - { extern void putprelude(void); - if (xspin || verbose&(1|4|8|16|32)) + { if (xspin || (verbose & (1|4|8|16|32))) { printf("spin: -c precludes all flags except -t\n"); alldone(1); } putprelude(); } if (columns && !(verbose&8) && !(verbose&16)) - verbose += (8+16); + { verbose += (8+16); + } if (columns == 2 && limited_vis) - verbose += (1+4); + { verbose += (1+4); + } + Srand((unsigned int) T); /* defined in run.c */ SeedUsed = T; s = lookup("_"); s->type = PREDEF; /* write-only global var */ @@ -463,6 +1150,7 @@ s = lookup("_pid"); s->type = PREDEF; s = lookup("_last"); s->type = PREDEF; s = lookup("_nr_pr"); s->type = PREDEF; /* new 3.3.10 */ + s = lookup("_priority"); s->type = PREDEF; /* new 6.2.0 */ yyparse(); fclose(yyin); @@ -492,18 +1180,25 @@ chanaccess(); if (!Caccess) - { if (!s_trail && (dataflow || merger)) - ana_src(dataflow, merger); + { if (has_provided && merger) + { merger = 0; /* cannot use statement merging in this case */ + } + if (!s_trail && (dataflow || merger) && (!replay || has_code)) + { ana_src(dataflow, merger); + } sched(); alldone(nr_errs); } + return 0; } void ltl_list(char *nm, char *fm) { - if (analyze || dumptab) /* when generating pan.c only */ + if (s_trail + || analyze + || dumptab) /* when generating pan.c or replaying a trace */ { if (!ltl_claims) { ltl_claims = "_spin_nvr.tmp"; if ((fd_ltl = fopen(ltl_claims, MFLAGS)) == NULL) @@ -511,7 +1206,6 @@ } tl_out = fd_ltl; } - add_ltl = (char **) emalloc(5 * sizeof(char *)); add_ltl[1] = "-c"; add_ltl[2] = nm; @@ -521,7 +1215,6 @@ strcat(add_ltl[4], fm); strcat(add_ltl[4], ")"); /* add_ltl[4] = fm; */ - nr_errs += tl_main(4, add_ltl); fflush(tl_out); @@ -529,22 +1222,20 @@ } } -int -yywrap(void) /* dummy routine */ -{ - return 1; -} - void non_fatal(char *s1, char *s2) { extern char yytext[]; printf("spin: %s:%d, Error: ", - oFname?oFname->name:"nofilename", lineno); + Fname?Fname->name:(oFname?oFname->name:"nofilename"), lineno); +#if 1 + printf(s1, s2); /* avoids a gcc warning */ +#else if (s2) printf(s1, s2); else printf(s1); +#endif if (strlen(yytext)>1) printf(" near '%s'", yytext); printf("\n"); @@ -560,7 +1251,11 @@ (void) unlink("pan.h"); (void) unlink("pan.m"); (void) unlink("pan.t"); + (void) unlink("pan.p"); (void) unlink("pan.pre"); + if (!(verbose&32)) + { (void) unlink("_spin_nvr.tmp"); + } alldone(1); } @@ -584,19 +1279,25 @@ void trapwonly(Lextok *n /* , char *unused */) -{ extern int realread; - short i = (n->sym)?n->sym->type:0; +{ short i; - if (i != MTYPE - && i != BIT - && i != BYTE - && i != SHORT - && i != INT - && i != UNSIGNED) - return; + if (!n) + { fatal("unexpected error,", (char *) 0); + } + + i = (n->sym)?n->sym->type:0; - if (realread) - n->sym->hidden |= 128; /* var is read at least once */ + /* printf("%s realread %d type %d\n", n->sym?n->sym->name:"--", realread, i); */ + + if (realread + && (i == MTYPE + || i == BIT + || i == BYTE + || i == SHORT + || i == INT + || i == UNSIGNED)) + { n->sym->hidden |= 128; /* var is read at least once */ + } } void @@ -625,7 +1326,7 @@ static int warn_nn = 0; n->uiid = is_inline(); /* record origin of the statement */ - n->ntyp = (short) t; + n->ntyp = (unsigned short) t; if (s && s->fn) { n->ln = s->ln; n->fn = s->fn; @@ -732,6 +1433,7 @@ has_remote++; has_remvar++; dataflow = 0; /* turn off dead variable resets 4.2.5 */ + merger = 0; /* turn off statement merging for locals 6.4.9 */ tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a; tmp1 = nn(ZN, 'p', tmp1, ndx); tmp1->sym = c; @@ -804,6 +1506,7 @@ case FI: fprintf(fd, "%sfi", Keyword); break; case FULL: fprintf(fd, "%sfull", Function); break; case GE: fprintf(fd, "%s>=", Operator); break; + case GET_P: fprintf(fd, "%sget_priority",Function); break; case GOTO: fprintf(fd, "%sgoto", Keyword); break; case GT: fprintf(fd, "%s>", Operator); break; case HIDDEN: fprintf(fd, "%shidden", Keyword); break; @@ -843,6 +1546,8 @@ case RUN: fprintf(fd, "%srun", Operator); break; case SEP: fprintf(fd, "token: ::"); break; case SEMI: fprintf(fd, ";"); break; + case ARROW: fprintf(fd, "->"); break; + case SET_P: fprintf(fd, "%sset_priority",Function); break; case SHOW: fprintf(fd, "%sshow", Keyword); break; case SND: fprintf(fd, "%s!", Operator); break; case STRING: fprintf(fd, "a string"); break; diff -Nru /n/sources/plan9/sys/src/cmd/spin/mesg.c /sys/src/cmd/spin/mesg.c --- /n/sources/plan9/sys/src/cmd/spin/mesg.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/mesg.c Mon Feb 22 00:00:00 2021 @@ -1,14 +1,13 @@ /***** spin: mesg.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ +#include +#include #include "spin.h" #include "y.tab.h" @@ -16,18 +15,18 @@ #define MAXQ 2500 /* default max # queues */ #endif -extern RunList *X; +extern RunList *X_lst; extern Symbol *Fname; -extern Lextok *Mtype; extern int verbose, TstOnly, s_trail, analyze, columns; extern int lineno, depth, xspin, m_loss, jumpsteps; extern int nproc, nstop; extern short Have_claim; +QH *qh_lst; Queue *qtab = (Queue *) 0; /* linked list of queues */ Queue *ltab[MAXQ]; /* linear list of queues */ -int nqs = 0, firstrow = 1; -char Buf[4096]; +int nrqs = 0, firstrow = 1, has_stdin = 0; +char GBuf[4096]; static Lextok *n_rem = (Lextok *) 0; static Queue *q_rem = (Queue *) 0; @@ -36,8 +35,10 @@ static int a_snd(Queue *, Lextok *); static int sa_snd(Queue *, Lextok *); static int s_snd(Queue *, Lextok *); -extern void sr_buf(int, int); -extern void sr_mesg(FILE *, int, int); +extern Lextok **find_mtype_list(const char *); +extern char *which_mtype(const char *); +extern void sr_buf(int, int, const char *); +extern void sr_mesg(FILE *, int, int, const char *); extern void putarrow(int, int); static void sr_talk(Lextok *, int, char *, char *, int, Queue *); @@ -55,17 +56,17 @@ qmake(Symbol *s) { Lextok *m; Queue *q; - int i; + int i, j; if (!s->ini) return 0; - if (nqs >= MAXQ) + if (nrqs >= MAXQ) { lineno = s->ini->ln; Fname = s->ini->fn; fatal("too many queues (%s)", s->name); } - if (analyze && nqs >= 255) + if (analyze && nrqs >= 255) { fatal("too many channel types", (char *)0); } @@ -73,23 +74,28 @@ return eval(s->ini); q = (Queue *) emalloc(sizeof(Queue)); - q->qid = ++nqs; + q->qid = (short) ++nrqs; q->nslots = s->ini->val; q->nflds = cnt_mpars(s->ini->rgt); q->setat = depth; i = max(1, q->nslots); /* 0-slot qs get 1 slot minimum */ + j = q->nflds * i; - q->contents = (int *) emalloc(q->nflds*i*sizeof(int)); + q->contents = (int *) emalloc(j*sizeof(int)); q->fld_width = (int *) emalloc(q->nflds*sizeof(int)); - q->stepnr = (int *) emalloc(i*sizeof(int)); + q->mtp = (char **) emalloc(q->nflds*sizeof(char *)); + q->stepnr = (int *) emalloc(i*sizeof(int)); for (m = s->ini->rgt, i = 0; m; m = m->rgt) { if (m->sym && m->ntyp == STRUCT) - i = Width_set(q->fld_width, i, getuname(m->sym)); - else + { i = Width_set(q->fld_width, i, getuname(m->sym)); + } else + { if (m->sym) + { q->mtp[i] = m->sym->name; + } q->fld_width[i++] = m->ntyp; - } + } } q->nxt = qtab; qtab = q; ltab[q->qid-1] = q; @@ -130,19 +136,50 @@ if (whichq == -1) { printf("Error: sending to an uninitialized chan\n"); - whichq = 0; + /* whichq = 0; */ return 0; } if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) { ltab[whichq]->setat = depth; if (ltab[whichq]->nslots > 0) - return a_snd(ltab[whichq], n); - else - return s_snd(ltab[whichq], n); - } + { return a_snd(ltab[whichq], n);; + } else + { return s_snd(ltab[whichq], n); + } } return 0; } +#ifndef PC + #include + static struct termios initial_settings, new_settings; + + void + peek_ch_init(void) + { + tcgetattr(0,&initial_settings); + + new_settings = initial_settings; + new_settings.c_lflag &= ~ICANON; + new_settings.c_lflag &= ~ECHO; + new_settings.c_lflag &= ~ISIG; + new_settings.c_cc[VMIN] = 0; + new_settings.c_cc[VTIME] = 0; + } + + int + peek_ch(void) + { int n; + + has_stdin = 1; + + tcsetattr(0, TCSANOW, &new_settings); + n = getchar(); + tcsetattr(0, TCSANOW, &initial_settings); + + return n; + } +#endif + int qrecv(Lextok *n, int full) { int whichq = eval(n->lft)-1; @@ -150,22 +187,37 @@ if (whichq == -1) { if (n->sym && !strcmp(n->sym->name, "STDIN")) { Lextok *m; - +#ifndef PC + static int did_once = 0; + if (!did_once) /* 6.2.4 */ + { peek_ch_init(); + did_once = 1; + } +#endif if (TstOnly) return 1; for (m = n->rgt; m; m = m->rgt) if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL) - { int c = getchar(); + { +#ifdef PC + int c = getchar(); +#else + int c = peek_ch(); /* 6.2.4, was getchar(); */ +#endif + if (c == 27 || c == 3) /* escape or control-c */ + { printf("quit\n"); + exit(0); + } /* else: non-blocking */ + if (c == EOF) return 0; /* no char available */ (void) setval(m->lft, c); } else - fatal("invalid use of STDIN", (char *)0); - - whichq = 0; + { fatal("invalid use of STDIN", (char *)0); + } return 1; } printf("Error: receiving from an uninitialized chan %s\n", n->sym?n->sym->name:""); - whichq = 0; + /* whichq = 0; */ return 0; } if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) @@ -206,8 +258,9 @@ typ_ck(int ft, int at, char *s) { if ((verbose&32) && ft != at - && (ft == CHAN || at == CHAN)) - { char buf[128], tag1[64], tag2[64]; + && (ft == CHAN || at == CHAN) + && (at != PREDEF || strcmp(s, "recv") != 0)) + { char buf[256], tag1[64], tag2[64]; (void) sputtype(tag1, ft); (void) sputtype(tag2, at); sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2); @@ -215,6 +268,40 @@ } } +static void +mtype_ck(char *p, Lextok *arg) +{ char *t, *s = p?p:"_unnamed_"; + + if (!arg + || !arg->sym) + { return; + } + + switch (arg->ntyp) { + case NAME: + if (arg->sym->mtype_name) + { t = arg->sym->mtype_name->name; + } else + { t = "_unnamed_"; + } + break; + case CONST: + t = which_mtype(arg->sym->name); + break; + default: + t = "expression"; + break; + } + + if (strcmp(s, t) != 0) + { printf("spin: %s:%d, Error: '%s' is type '%s', but ", + arg->fn?arg->fn->name:"", arg->ln, + arg->sym->name, t); + printf("should be type '%s'\n", s); + non_fatal("incorrect type of '%s'", arg->sym->name); + } +} + static int a_snd(Queue *q, Lextok *n) { Lextok *m; @@ -222,10 +309,12 @@ int j = 0; /* q field# */ if (q->nslots > 0 && q->qlen >= q->nslots) - return m_loss; /* q is full */ - - if (TstOnly) return 1; + { return m_loss; /* q is full */ + } + if (TstOnly) + { return 1; + } if (n->val) i = sa_snd(q, n); /* sorted insert */ q->stepnr[i/q->nflds] = depth; @@ -233,20 +322,28 @@ for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) { int New = eval(m->lft); q->contents[i+j] = cast_val(q->fld_width[j], New, 0); + + if (q->fld_width[i+j] == MTYPE) + { mtype_ck(q->mtp[i+j], m->lft); /* 6.4.8 */ + } if ((verbose&16) && depth >= jumpsteps) - sr_talk(n, New, "Send ", "->", j, q); - typ_ck(q->fld_width[j], Sym_typ(m->lft), "send"); + { sr_talk(n, New, "Send ", "->", j, q); /* XXX j was i+j in 6.4.8 */ + } + typ_ck(q->fld_width[i+j], Sym_typ(m->lft), "send"); } + if ((verbose&16) && depth >= jumpsteps) { for (i = j; i < q->nflds; i++) - sr_talk(n, 0, "Send ", "->", i, q); + { sr_talk(n, 0, "Send ", "->", i, q); + } if (j < q->nflds) - printf("%3d: warning: missing params in send\n", + { printf("%3d: warning: missing params in send\n", depth); + } if (m) - printf("%3d: warning: too many params in send\n", + { printf("%3d: warning: too many params in send\n", depth); - } + } } q->qlen++; return 1; } @@ -258,30 +355,66 @@ extern int Rvous; if (q->qlen == 0) - return 0; /* q is empty */ + { return 0; /* q is empty */ + } try_slot: /* test executability */ for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++) - if ((m->lft->ntyp == CONST - && q->contents[i*q->nflds+j] != m->lft->val) - || (m->lft->ntyp == EVAL - && q->contents[i*q->nflds+j] != eval(m->lft->lft))) - { if (n->val == 0 /* fifo recv */ + { + if (q->fld_width[i*q->nflds+j] == MTYPE) + { mtype_ck(q->mtp[i*q->nflds+j], m->lft); /* 6.4.8 */ + } + + if (m->lft->ntyp == CONST + && q->contents[i*q->nflds+j] != m->lft->val) + { + if (n->val == 0 /* fifo recv */ || n->val == 2 /* fifo poll */ || ++i >= q->qlen) /* last slot */ - return 0; /* no match */ - goto try_slot; + { return 0; /* no match */ + } + goto try_slot; /* random recv */ } + + if (m->lft->ntyp == EVAL) + { Lextok *fix = m->lft->lft; + + if (fix->ntyp == ',') /* new, usertype7 */ + { do { + assert(j < q->nflds); + if (q->contents[i*q->nflds+j] != eval(fix->lft)) + { if (n->val == 0 + || n->val == 2 + || ++i >= q->qlen) + { return 0; + } + goto try_slot; /* random recv */ + } + j++; + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + j--; + } else + { if (q->contents[i*q->nflds+j] != eval(fix)) + { if (n->val == 0 /* fifo recv */ + || n->val == 2 /* fifo poll */ + || ++i >= q->qlen) /* last slot */ + { return 0; /* no match */ + } + goto try_slot; /* random recv */ + } } } + } + if (TstOnly) return 1; if (verbose&8) { if (j < q->nflds) - printf("%3d: warning: missing params in next recv\n", + { printf("%3d: warning: missing params in next recv\n", depth); - else if (m) - printf("%3d: warning: too many params in next recv\n", + } else if (m) + { printf("%3d: warning: too many params in next recv\n", depth); - } + } } /* set the fields */ if (Rvous) @@ -329,13 +462,17 @@ static int s_snd(Queue *q, Lextok *n) { Lextok *m; - RunList *rX, *sX = X; /* rX=recvr, sX=sendr */ + RunList *rX, *sX = X_lst; /* rX=recvr, sX=sendr */ int i, j = 0; /* q field# */ for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) { q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0); typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send"); - } + + if (q->fld_width[j] == MTYPE) + { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */ + } } + q->qlen = 1; if (!complete_rendez()) { q->qlen = 0; @@ -348,28 +485,41 @@ q->stepnr[0] = depth; if ((verbose&16) && depth >= jumpsteps) { m = n->rgt; - rX = X; X = sX; + rX = X_lst; X_lst = sX; + for (j = 0; m && j < q->nflds; m = m->rgt, j++) - sr_talk(n, eval(m->lft), "Sent ", "->", j, q); + { sr_talk(n, eval(m->lft), "Sent ", "->", j, q); + } + for (i = j; i < q->nflds; i++) - sr_talk(n, 0, "Sent ", "->", i, q); + { sr_talk(n, 0, "Sent ", "->", i, q); + } + if (j < q->nflds) - printf("%3d: warning: missing params in rv-send\n", + { printf("%3d: warning: missing params in rv-send\n", depth); - else if (m) - printf("%3d: warning: too many params in rv-send\n", + } else if (m) + { printf("%3d: warning: too many params in rv-send\n", depth); - X = rX; /* restore receiver's context */ + } + + X_lst = rX; /* restore receiver's context */ if (!s_trail) { if (!n_rem || !q_rem) fatal("cannot happen, s_snd", (char *) 0); m = n_rem->rgt; for (j = 0; m && j < q->nflds; m = m->rgt, j++) - { if (m->lft->ntyp != NAME - || strcmp(m->lft->sym->name, "_") != 0) - i = eval(m->lft); - else i = 0; + { + if (q->fld_width[j] == MTYPE) + { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */ + } + if (m->lft->ntyp != NAME + || strcmp(m->lft->sym->name, "_") != 0) + { i = eval(m->lft); + } else + { i = 0; + } if (verbose&8) sr_talk(n_rem,i,"Recv ","<-",j,q_rem); } @@ -390,47 +540,51 @@ { char lbuf[512]; if (n->sym->type == CHAN) - strcat(Buf, n->sym->name); + strcat(GBuf, n->sym->name); else if (n->sym->type == NAME) - strcat(Buf, lookup(n->sym->name)->name); + strcat(GBuf, lookup(n->sym->name)->name); else if (n->sym->type == STRUCT) { Symbol *r = n->sym; if (r->context) { r = findloc(r); if (!r) - { strcat(Buf, "*?*"); + { strcat(GBuf, "*?*"); return; } } ini_struct(r); printf("%s", r->name); strcpy(lbuf, ""); struct_name(n->lft, r, 1, lbuf); - strcat(Buf, lbuf); + strcat(GBuf, lbuf); } else - strcat(Buf, "-"); + strcat(GBuf, "-"); if (n->lft->lft) { sprintf(lbuf, "[%d]", eval(n->lft->lft)); - strcat(Buf, lbuf); + strcat(GBuf, lbuf); } } static void difcolumns(Lextok *n, char *tr, int v, int j, Queue *q) -{ extern int pno; +{ extern int prno; if (j == 0) - { Buf[0] = '\0'; + { GBuf[0] = '\0'; channm(n); - strcat(Buf, (strncmp(tr, "Sen", 3))?"?":"!"); + strcat(GBuf, (strncmp(tr, "Sen", 3))?"?":"!"); } else - strcat(Buf, ","); - if (tr[0] == '[') strcat(Buf, "["); - sr_buf(v, q->fld_width[j] == MTYPE); + strcat(GBuf, ","); + if (tr[0] == '[') strcat(GBuf, "["); + sr_buf(v, q->fld_width[j] == MTYPE, q->mtp[j]); if (j == q->nflds - 1) { int cnr; - if (s_trail) cnr = pno; else cnr = X?X->pid - Have_claim:0; - if (tr[0] == '[') strcat(Buf, "]"); - pstext(cnr, Buf); + if (s_trail) + { cnr = prno - Have_claim; + } else + { cnr = X_lst?X_lst->pid - Have_claim:0; + } + if (tr[0] == '[') strcat(GBuf, "]"); + pstext(cnr, GBuf); } } @@ -447,41 +601,35 @@ } if (j == 0) { printf("%3d", q->qid); - if (X) - for (i = 0; i < X->pid - Have_claim; i++) + if (X_lst) + for (i = 0; i < X_lst->pid - Have_claim; i++) printf(" ."); printf(" "); - Buf[0] = '\0'; + GBuf[0] = '\0'; channm(n); - printf("%s%c", Buf, (strncmp(tr, "Sen", 3))?'?':'!'); + printf("%s%c", GBuf, (strncmp(tr, "Sen", 3))?'?':'!'); } else printf(","); if (tr[0] == '[') printf("["); - sr_mesg(stdout, v, q->fld_width[j] == MTYPE); + sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]); if (j == q->nflds - 1) { if (tr[0] == '[') printf("]"); printf("\n"); } } -typedef struct QH { - int n; - struct QH *nxt; -} QH; -static QH *qh; - void qhide(int q) { QH *p = (QH *) emalloc(sizeof(QH)); p->n = q; - p->nxt = qh; - qh = p; + p->nxt = qh_lst; + qh_lst = p; } int qishidden(int q) { QH *p; - for (p = qh; p; p = p->nxt) + for (p = qh_lst; p; p = p->nxt) if (p->n == q) return 1; return 0; @@ -531,8 +679,9 @@ snm, n->ln, s); } } else - printf(","); - sr_mesg(stdout, v, q->fld_width[j] == MTYPE); + { printf(","); + } + sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]); if (j == q->nflds - 1) { if (xspin) @@ -541,37 +690,42 @@ return; } printf("\t%s queue %d (", a, eval(n->lft)); - Buf[0] = '\0'; + GBuf[0] = '\0'; channm(n); - printf("%s)\n", Buf); + printf("%s)\n", GBuf); } fflush(stdout); } void -sr_buf(int v, int j) +sr_buf(int v, int j, const char *s) { int cnt = 1; Lextok *n; char lbuf[512]; + Lextok *Mtype = ZN; + if (j) + { Mtype = *find_mtype_list(s?s:"_unnamed_"); + } for (n = Mtype; n && j; n = n->rgt, cnt++) - if (cnt == v) + { if (cnt == v) { if(strlen(n->lft->sym->name) >= sizeof(lbuf)) { non_fatal("mtype name %s too long", n->lft->sym->name); break; } sprintf(lbuf, "%s", n->lft->sym->name); - strcat(Buf, lbuf); + strcat(GBuf, lbuf); return; - } + } } sprintf(lbuf, "%d", v); - strcat(Buf, lbuf); + strcat(GBuf, lbuf); } void -sr_mesg(FILE *fd, int v, int j) -{ Buf[0] ='\0'; - sr_buf(v, j); - fprintf(fd, Buf); +sr_mesg(FILE *fd, int v, int j, const char *s) +{ GBuf[0] ='\0'; + + sr_buf(v, j, s); + fprintf(fd, GBuf, (char *) 0); /* prevent compiler warning */ } void @@ -586,27 +740,31 @@ { if (xspin > 0 && (verbose&4) && q->setat < depth) - continue; - if (q->nslots == 0) - continue; /* rv q always empty */ -#if 0 - if (q->qlen == 0) /* new 7/10 -- dont show if queue is empty */ { continue; } -#endif + if (q->nslots == 0) + { continue; /* rv q always empty */ + } + printf("\t\tqueue %d (", q->qid); if (r) - printf("%s(%d):", r->n->name, r->pid - Have_claim); + { printf("%s(%d):", r->n->name, r->pid - Have_claim); + } + if (s->nel > 1 || s->isarray) - printf("%s[%d]): ", s->name, n); - else - printf("%s): ", s->name); + { printf("%s[%d]): ", s->name, n); + } else + { printf("%s): ", s->name); + } + for (k = 0; k < q->qlen; k++) { printf("["); for (j = 0; j < q->nflds; j++) { if (j > 0) printf(","); - sr_mesg(stdout, q->contents[k*q->nflds+j], - q->fld_width[j] == MTYPE); + sr_mesg(stdout, + q->contents[k*q->nflds+j], + q->fld_width[j] == MTYPE, + q->mtp[j]); } printf("]"); } @@ -616,9 +774,17 @@ } void -nochan_manip(Lextok *p, Lextok *n, int d) +nochan_manip(Lextok *p, Lextok *n, int d) /* p=lhs n=rhs */ { int e = 1; + if (!n + || !p + || !p->sym + || p->sym->type == STRUCT) + { /* if a struct, assignments to structure fields arent checked yet */ + return; + } + if (d == 0 && p->sym && p->sym->type == CHAN) { setaccess(p->sym, ZS, 0, 'L'); @@ -631,10 +797,33 @@ } } + if (!d && n && n->ismtyp) /* rhs is an mtype value (a constant) */ + { char *lhs = "_unnamed_", *rhs = "_unnamed_"; + + if (p->sym) + { lhs = p->sym->mtype_name?p->sym->mtype_name->name:"_unnamed_"; + } + if (n->sym) + { rhs = which_mtype(n->sym->name); /* only for constants */ + } + + if (p->sym && !p->sym->mtype_name && n->sym) + { p->sym->mtype_name = (Symbol *) emalloc(sizeof(Symbol)); + p->sym->mtype_name->name = rhs; + } else if (strcmp(lhs, rhs) != 0) + { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but '%s' is type '%s'\n", + p->fn->name, p->ln, + p->sym?p->sym->name:"?", lhs, + n->sym?n->sym->name:"?", rhs); + non_fatal("type error", (char *) 0); + } } + /* ok on the rhs of an assignment: */ - if (!n || n->ntyp == LEN || n->ntyp == RUN + if (!n + || n->ntyp == LEN || n->ntyp == RUN || n->ntyp == FULL || n->ntyp == NFULL - || n->ntyp == EMPTY || n->ntyp == NEMPTY) + || n->ntyp == EMPTY || n->ntyp == NEMPTY + || n->ntyp == 'R') return; if (n->sym && n->sym->type == CHAN) @@ -646,7 +835,8 @@ if (n->ntyp == NAME || n->ntyp == '.') - e = 0; /* array index or struct element */ + { e = 0; /* array index or struct element */ + } nochan_manip(p, n->lft, e); nochan_manip(p, n->rgt, 1); @@ -657,7 +847,8 @@ int cnt; struct BaseName *nxt; } BaseName; -BaseName *bsn; + +static BaseName *bsn; void newbasename(char *s) @@ -720,7 +911,11 @@ lineno = t->ln; if (t->ntyp == NAME) - { strcat(mn, t->sym->name); + { if (strlen(t->sym->name) + strlen(mn) > 256) // conservative + { fatal("name too long", t->sym->name); + } + + strcat(mn, t->sym->name); strcat(mx, t->sym->name); if (t->lft) /* array index */ { strcat(mn, "[]"); @@ -777,8 +972,9 @@ sp = n->sym->name; if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0) + || (strlen(sp) == strlen("_pid") && strcmp(sp, "_pid") == 0) || (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0)) - { fatal("attempt to assign value to system variable %s", sp); + { fatal("invalid assignment to %s", sp); } no_nested_array_refs(n); diff -Nru /n/sources/plan9/sys/src/cmd/spin/mkfile /sys/src/cmd/spin/mkfile --- /n/sources/plan9/sys/src/cmd/spin/mkfile Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/mkfile Mon Feb 22 00:00:00 2021 @@ -8,6 +8,7 @@ guided.$O\ main.$O\ mesg.$O\ + msc_tcl.$O\ pangen1.$O\ pangen2.$O\ pangen3.$O\ @@ -15,8 +16,6 @@ pangen5.$O\ pangen6.$O\ pangen7.$O\ - pc_zpp.$O\ - ps_msc.$O\ reprosrc.$O\ run.$O\ sched.$O\ diff -Nru /n/sources/plan9/sys/src/cmd/spin/msc_tcl.c /sys/src/cmd/spin/msc_tcl.c --- /n/sources/plan9/sys/src/cmd/spin/msc_tcl.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/spin/msc_tcl.c Mon Feb 22 00:00:00 2021 @@ -0,0 +1,380 @@ +/***** spin: msc_tcl.c *****/ + +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ + +#include +#include "spin.h" +#include "version.h" + +#define MW 500 /* page width */ +#define RH 100 /* right margin */ +#define WW 80 /* distance between process lines */ +#define HH 12 /* vertical distance between steps */ +#define LW 2 /* line width of message arrows */ + +#define RVC "darkred" /* rendezvous arrows */ +#define MPC "darkblue" /* asynchronous message passing arrow */ +#define GRC "lightgrey" /* grid lines */ + +static int MH = 600; /* anticipated page-length */ +static FILE *pfd; +static char **I; /* initial procs */ +static int *D,*R; /* maps between depth (stepnr) and ldepth (msc-step) */ +static short *M; /* x location of each box at index y */ +static short *T; /* y index of match for each box at index y */ +static char **L; /* text labels */ +static int ProcLine[256]; /* active processes */ +static int UsedLine[256]; /* process line has at least one entry */ +static int ldepth = 1; +static int maxx, TotSteps = 2*4096; /* max nr of steps for simulation output */ +static float Scaler = (float) 1.0; + +static int xscale = 2; +static int yscale = 1; +static int no_box; + +extern int ntrail, s_trail, prno, depth; +extern short Have_claim; +extern Symbol *oFname; + +extern void exit(int); +extern void putpostlude(void); + +static void putpages(void); + +static void +psline(int x0, int y0, int x1, int y1, char *color) +{ char *side = "last"; + + if (x0 == x1) /* gridline */ + { fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags grid -width 1 \n", + xscale*(x0+1)*WW-20, yscale*y0+20, + xscale*(x1+1)*WW-20, yscale*y1+20, color); + fprintf(pfd, ".c lower grid\n"); + } else + { int xm = xscale*(x0+1)*WW + (xscale*(x1 - x0)*WW)/2 - 20; /* mid x */ + + if (y1 - y0 <= HH+20) + { y1 = y0+20; /* close enough to horizontal - looks better */ + } + + fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags mesg -width %d\n", + xscale*(x0+1)*WW-20, yscale*y0+20+10, + xm, yscale*y0+20+10, color, LW); + + if (y1 != y0+20) + { fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags mesg -width %d\n", + xm, yscale*y0+20+10, + xm, yscale*y1+20-10, color, LW); + } + + fprintf(pfd, ".c create line %d %d %d %d -fill %s -width %d ", + xm, yscale*y1+20-10, + xscale*(x1+1)*WW-20, yscale*y1+20-10, color, LW); + + if (strcmp(color, RVC) == 0) + { side = "both"; + } + fprintf(pfd, "-arrow %s -arrowshape {5 5 5} -tags mesg\n", side); + fprintf(pfd, ".c raise mesg\n"); + } +} + +static void +colbox(int ix, int iy, int w, int h_unused, char *color) +{ int x = ix*WW; + int y = iy*HH; + + if (ix < 0 || ix > 255) + { fprintf(stderr, "saw ix=%d\n", ix); + fatal("msc_tcl: unexpected\n", (char *) 0); + } + + if (ProcLine[ix] < iy) + { /* if (ProcLine[ix] > 0) */ + { psline(ix-1, ProcLine[ix]*HH+HH+4, + ix-1, iy*HH-HH, GRC); + } + fprintf(pfd, "# ProcLine[%d] from %d to %d (Used %d nobox %d)\n", + ix, ProcLine[ix], iy, UsedLine[ix], no_box); + ProcLine[ix] = iy; + } else + { fprintf(pfd, "# ProcLine[%d] stays at %d (Used %d nobox %d)\n", + ix, ProcLine[ix], UsedLine[ix], no_box); + } + + if (UsedLine[ix]) + { no_box = 2; + } + + if (strcmp(color, "black") == 0) + { if (no_box == 0) /* shadow */ + { fprintf(pfd, ".c create rectangle %d %d %d %d -fill black\n", + xscale*x-(xscale*4*w/3)-20+4, (yscale*y-10)+20+2, + xscale*x+(xscale*4*w/3)-20, (yscale*y+10)+20+2); + } + } else + { if (no_box == 0) /* box with outline */ + { fprintf(pfd, ".c create rectangle %d %d %d %d -fill ivory\n", + xscale*x-(xscale*4*w/3)-20, (yscale*y-10)+20, + xscale*x+(xscale*4*w/3)-20, (yscale*y+10)+20); + UsedLine[ix]++; + } else /* no outline */ + { fprintf(pfd, ".c create rectangle %d %d %d %d -fill white -width 0\n", + xscale*x-(xscale*4*w/3)-20, (yscale*y-10)+20, + xscale*x+(xscale*4*w/3)-20, (yscale*y+10)+20); + } } + if (no_box > 0) + { no_box--; + } +} + +static void +stepnumber(int i) +{ int y = (yscale*i*HH) + 20; + + fprintf(pfd, ".c create text %d %d -fill #eef -text \"%d\"\n", + -10+(xscale*WW)/2, y, i); + + /* horizontal dashed grid line */ + fprintf(pfd, ".c create line %d %d %d %d -fill #eef -dash {6 4}\n", + -20+WW*xscale, y, (maxx+1)*WW*xscale-20, y); +} + +static void +spitbox(int ix, int y, char *s) +{ float bw; /* box width */ + char d[256], *t, *z; + int a, i, x = ix+1; + char *color = "black"; + + if (y > 0) + { stepnumber(y); + } + + bw = (float)1.8*(float)strlen(s); /* guess at default font width */ + colbox(x, y, (int) (bw+1.0), 5, "black"); + if (s[0] == '~') + { switch (s[1]) { + default : + case 'R': color = "red"; break; + case 'B': color = "blue"; break; + case 'G': color = "green"; break; + } + s += 2; + } else if (strchr(s, '!')) + { color = "ivory"; + } else if (strchr(s, '?')) + { color = "azure"; + } else + { color = "pink"; + if (sscanf(s, "%d:%250s", &a, d) == 2 + && a >= 0 && a < TotSteps) + { if (!I[a] || strlen(I[a]) <= strlen(s)) + { I[a] = (char *) emalloc((int) strlen(s)+1); + } + strcpy(I[a], s); + } } + + colbox(x, y, (int) bw, 4, color); + + z = t = (char *) emalloc(2*strlen(s)+1); + + for (i = 0; i < (int) strlen(s); i++) + { if (s[i] == '\n') + { continue; + } + if (s[i] == '[' || s[i] == ']') + { *t++ = '\\'; + } + *t++ = s[i]; + } + + fprintf(pfd, ".c create text %d %d -text \"%s\"\n", + xscale*x*WW-20, yscale*y*HH+20, z); +} + +static void +putpages(void) +{ int i, lasti=0; float nmh; + + if (maxx*xscale*WW > MW-RH/2) + { Scaler = (float) (MW-RH/2) / (float) (maxx*xscale*WW); + nmh = (float) MH; nmh /= Scaler; MH = (int) nmh; + fprintf(pfd, "# Scaler %f, MH %d\n", Scaler, MH); + } + if (ldepth >= TotSteps) + { ldepth = TotSteps-1; + } + +/* W: (maxx+2)*xscale*WW */ +/* H: ldepth*HH*yscale+50 */ + fprintf(pfd, "wm title . \"scenario\"\n"); + fprintf(pfd, "wm geometry . %dx600+650+100\n", (maxx+2)*xscale*WW); + + fprintf(pfd, "canvas .c -width 800 -height 800 \\\n"); + fprintf(pfd, " -scrollregion {0c -1c 30c 100c} \\\n"); + fprintf(pfd, " -xscrollcommand \".hscroll set\" \\\n"); + fprintf(pfd, " -yscrollcommand \".vscroll set\" \\\n"); + fprintf(pfd, " -bg white -relief raised -bd 2\n"); + + fprintf(pfd, "scrollbar .vscroll -relief sunken "); + fprintf(pfd, " -command \".c yview\"\n"); + fprintf(pfd, "scrollbar .hscroll -relief sunken -orient horiz "); + fprintf(pfd, " -command \".c xview\"\n"); + + fprintf(pfd, "pack append . \\\n"); + fprintf(pfd, " .vscroll {right filly} \\\n"); + fprintf(pfd, " .hscroll {bottom fillx} \\\n"); + fprintf(pfd, " .c {top expand fill}\n"); + + fprintf(pfd, ".c yview moveto 0\n"); + + for (i = TotSteps-1; i >= 0; i--) + { if (I[i]) + { spitbox(i, -1, I[i]); + } } + + for (i = 0; i <= ldepth; i++) + { if (!M[i] && !L[i]) + { continue; /* no box */ + } + if (T[i] > 0) /* arrow */ + { if (T[i] == i) /* rv handshake */ + { psline( M[lasti], lasti*HH, + M[i], i*HH, RVC); + } else + { psline( M[i], i*HH, + M[T[i]], T[i]*HH, MPC); + } } + if (L[i]) + { spitbox(M[i], i, L[i]); + lasti = i; + } } +} + +static void +putbox(int x) +{ + if (ldepth >= TotSteps) + { fprintf(stderr, "max length of %d steps exceeded - ps file truncated\n", + TotSteps); + putpostlude(); + } + M[ldepth] = x; + if (x > maxx) + { maxx = x; + fprintf(pfd, "# maxx %d\n", x); + } +} + +/* functions called externally: */ + +extern int WhatSeed(void); + +void +putpostlude(void) +{ char cmd[512]; + + putpages(); + fprintf(pfd, ".c lower grid\n"); + fprintf(pfd, ".c raise mesg\n"); + fclose(pfd); + + fprintf(stderr, "seed used: -n%d\n", WhatSeed()); + sprintf(cmd, "wish -f %s.tcl &", oFname?oFname->name:"msc"); + fprintf(stderr, "%s\n", cmd); + (void) unlink("pan.pre"); + exit (system(cmd)); +} + +void +putprelude(void) +{ char snap[256]; FILE *fd; + + sprintf(snap, "%s.tcl", oFname?oFname->name:"msc"); + if (!(pfd = fopen(snap, MFLAGS))) + { fatal("cannot create file '%s'", snap); + } + if (s_trail) + { if (ntrail) + sprintf(snap, "%s%d.trail", oFname?oFname->name:"msc", ntrail); + else + sprintf(snap, "%s.trail", oFname?oFname->name:"msc"); + if (!(fd = fopen(snap, "r"))) + { snap[strlen(snap)-2] = '\0'; + if (!(fd = fopen(snap, "r"))) + fatal("cannot open trail file", (char *) 0); + } + TotSteps = 1; + while (fgets(snap, 256, fd)) TotSteps++; + fclose(fd); + } + TotSteps *= 2; + R = (int *) emalloc(TotSteps * sizeof(int)); + D = (int *) emalloc(TotSteps * sizeof(int)); + M = (short *) emalloc(TotSteps * sizeof(short)); + T = (short *) emalloc(TotSteps * sizeof(short)); + L = (char **) emalloc(TotSteps * sizeof(char *)); + I = (char **) emalloc(TotSteps * sizeof(char *)); +} + +void +putarrow(int from, int to) +{ + /* from rv if from == to */ + /* which means that D[from] == D[to] */ + /* which means that T[x] == x */ + + if (from < TotSteps + && to < TotSteps + && D[from] < TotSteps) + { T[D[from]] = D[to]; + } +} + +void +pstext(int x, char *s) +{ char *tmp = emalloc((int) strlen(s)+1); + + strcpy(tmp, s); + if (depth == 0) + { I[x] = tmp; + } else + { if (depth >= TotSteps || ldepth >= TotSteps) + { fprintf(stderr, "spin: error: max nr of %d steps exceeded\n", + TotSteps); + fatal("use -uN to limit steps", (char *) 0); + } + putbox(x); + D[depth] = ldepth; + R[ldepth] = depth; + L[ldepth] = tmp; + ldepth += 2; + } +} + +void +dotag(FILE *fd, char *s) +{ extern int columns, notabs; extern RunList *X_lst; + int i = (!strncmp(s, "MSC: ", 5))?5:0; + int pid = s_trail ? (prno - Have_claim) : (X_lst?X_lst->pid:0); + + if (pid < 0) { pid = 0; } + + if (columns == 2) + { pstext(pid, &s[i]); + } else + { if (!notabs) + { printf(" "); + for (i = 0; i <= pid; i++) + { printf(" "); + } } + fprintf(fd, "%s", s); + fflush(fd); + } +} diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen1.c /sys/src/cmd/spin/pangen1.c --- /n/sources/plan9/sys/src/cmd/spin/pangen1.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen1.c Mon Feb 22 00:00:00 2021 @@ -1,14 +1,10 @@ /***** spin: pangen1.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ -/* (c) 2007: small additions for V5.0 to support multi-core verifications */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" @@ -17,21 +13,24 @@ #include "pangen6.h" #include -extern FILE *tc, *th, *tt; +extern FILE *fd_tc, *fd_th, *fd_tt; extern Label *labtab; extern Ordered *all_names; -extern ProcList *rdy; +extern ProcList *ready; extern Queue *qtab; extern Symbol *Fname; -extern int lineno, verbose, Pid, separate, old_scope_rules, nclaims; -extern int nrRdy, nqs, mst, Mpars, claimnr, eventmapnr; -extern short has_sorted, has_random, has_provided; +extern int lineno, verbose, Pid_nr, separate, old_scope_rules, nclaims; +extern int nrRdy, nrqs, mstp, Mpars, claimnr, eventmapnr; +extern short has_sorted, has_random, has_provided, has_priority; extern Queue *ltab[]; int Npars=0, u_sync=0, u_async=0, hastrack = 1; short has_io = 0; short has_state=0; /* code contains c_state */ +extern void c_add_stack(FILE *); +extern void c_stack_size(FILE *); + static Symbol *LstSet=ZS; static int acceptors=0, progressors=0, nBits=0; static int Types[] = { UNSIGNED, BIT, BYTE, CHAN, MTYPE, SHORT, INT, STRUCT }; @@ -51,14 +50,14 @@ { if (!p) return; reverse_names(p->nxt); - fprintf(th, " \"%s\",\n", p->n->name); + fprintf(fd_tc, " \"%s\",\n", p->n->name); } static void reverse_types(ProcList *p) { if (!p) return; reverse_types(p->nxt); - fprintf(th, " %d, /* %s */\n", p->b, p->n->name); + fprintf(fd_tc, " %d, /* %s */\n", p->b, p->n->name); } static int @@ -74,55 +73,57 @@ { ProcList *p; int i; if (separate == 2) - { putunames(th); + { putunames(fd_th); goto here; } /* 5.2.3: gcc 3 no longer seems to compute sizeof at compile time */ - fprintf(th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *)); - fprintf(th, "#define SYNC %d\n", u_sync); - fprintf(th, "#define ASYNC %d\n\n", u_async); - fprintf(th, "#ifndef NCORE\n"); - fprintf(th, " #ifdef DUAL_CORE\n"); - fprintf(th, " #define NCORE 2\n"); - fprintf(th, " #elif QUAD_CORE\n"); - fprintf(th, " #define NCORE 4\n"); - fprintf(th, " #else\n"); - fprintf(th, " #define NCORE 1\n"); - fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); - - putunames(th); - - fprintf(tc, "short Air[] = { "); - for (p = rdy, i=0; p; p = p->nxt, i++) - fprintf(tc, "%s (short) Air%d", (p!=rdy)?",":"", i); - fprintf(tc, ", (short) Air%d", i); /* np_ */ + fprintf(fd_th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *)); + fprintf(fd_th, "#define SYNC %d\n", u_sync); + fprintf(fd_th, "#define ASYNC %d\n\n", u_async); + fprintf(fd_th, "#ifndef NCORE\n"); + fprintf(fd_th, " #ifdef DUAL_CORE\n"); + fprintf(fd_th, " #define NCORE 2\n"); + fprintf(fd_th, " #elif QUAD_CORE\n"); + fprintf(fd_th, " #define NCORE 4\n"); + fprintf(fd_th, " #else\n"); + fprintf(fd_th, " #define NCORE 1\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n\n"); + + putunames(fd_th); + + fprintf(fd_tc, "\nshort Air[] = { "); + for (p = ready, i=0; p; p = p->nxt, i++) + fprintf(fd_tc, "%s (short) Air%d", (p!=ready)?",":"", i); + fprintf(fd_tc, ", (short) Air%d", i); /* np_ */ if (nclaims > 1) - { fprintf(tc, "\n#ifndef NOCLAIM\n"); - fprintf(tc, " , (short) Air%d", i+1); /* Multi */ - fprintf(tc, "\n#endif\n\t"); - } - fprintf(tc, " };\n"); - - fprintf(th, "char *procname[] = {\n"); - reverse_names(rdy); - fprintf(th, " \":np_:\",\n"); - fprintf(th, "};\n\n"); - - fprintf(th, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM); - fprintf(th, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC); - fprintf(th, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n", + { fprintf(fd_tc, "\n#ifndef NOCLAIM\n"); + fprintf(fd_tc, " , (short) Air%d", i+1); /* Multi */ + fprintf(fd_tc, "\n#endif\n\t"); + } + fprintf(fd_tc, " };\n"); + + fprintf(fd_tc, "char *procname[] = {\n"); + reverse_names(ready); + fprintf(fd_tc, " \":np_:\",\n"); + fprintf(fd_tc, " 0\n"); + fprintf(fd_tc, "};\n\n"); + + fprintf(fd_tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM); + fprintf(fd_tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC); + fprintf(fd_tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n", P_PROC, E_TRACE, N_TRACE); - fprintf(th, "int Btypes[] = {\n"); - reverse_types(rdy); - fprintf(th, " 0 /* :np_: */\n"); - fprintf(th, "};\n\n"); + + fprintf(fd_tc, "int Btypes[] = {\n"); + reverse_types(ready); + fprintf(fd_tc, " 0 /* :np_: */\n"); + fprintf(fd_tc, "};\n\n"); here: - for (p = rdy; p; p = p->nxt) - put_ptype(p->n->name, p->tn, mst, nrRdy+1, p->b); + for (p = ready; p; p = p->nxt) + put_ptype(p->n->name, p->tn, mstp, nrRdy+1, p->b); /* +1 for np_ */ - put_ptype("np_", nrRdy, mst, nrRdy+1, 0); + put_ptype("np_", nrRdy, mstp, nrRdy+1, 0); if (nclaims > 1) { /* this is the structure that goes into the state-vector @@ -135,31 +136,38 @@ * that there is one never-claim, which will now be this one */ - i = blog(mst); - fprintf(th, "\n"); - fprintf(th, "#ifndef NOCLAIM\n"); - fprintf(th, " #undef VERI\n"); - fprintf(th, " #define VERI %d\n", nrRdy+1); - fprintf(th, " #define Pclaim P%d\n\n", nrRdy+1); - fprintf(th, "typedef struct P%d {\n", nrRdy+1); - fprintf(th, " unsigned _pid : 8; /* always zero */\n"); - fprintf(th, " unsigned _t : %d; /* active-claim type */\n", + i = blog(mstp); + fprintf(fd_th, "\n"); + + fprintf(fd_th, "#ifndef NOCLAIM\n"); + fprintf(fd_th, " #ifndef NP\n"); + fprintf(fd_th, " #undef VERI\n"); + fprintf(fd_th, " #define VERI %d\n", nrRdy+1); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #define Pclaim P%d\n\n", nrRdy+1); + fprintf(fd_th, "typedef struct P%d {\n", nrRdy+1); + fprintf(fd_th, " unsigned _pid : 8; /* always zero */\n"); + fprintf(fd_th, " unsigned _t : %d; /* active-claim type */\n", blog(nrRdy+1)); - fprintf(th, " unsigned _p : %d; /* active-claim state */\n", + fprintf(fd_th, " unsigned _p : %d; /* active-claim state */\n", i); - fprintf(th, " unsigned _n : %d; /* active-claim index */\n", + fprintf(fd_th, " unsigned _n : %d; /* active-claim index */\n", blog(nclaims)); if (i <= 255) /* in stdint.h = UCHAR_MAX from limits.h */ - { fprintf(th, " uchar c_cur[NCLAIMS]; /* claim-states */\n"); + { fprintf(fd_th, " uchar c_cur[NCLAIMS]; /* claim-states */\n"); } else if (i <= 65535) /* really USHRT_MAX from limits.h */ - { fprintf(th, " ushort c_cur[NCLAIMS]; /* claim-states */\n"); + { fprintf(fd_th, " ushort c_cur[NCLAIMS]; /* claim-states */\n"); } else /* the most unlikely case */ - { fprintf(th, " uint c_cur[NCLAIMS]; /* claim-states */\n"); + { fprintf(fd_th, " uint c_cur[NCLAIMS]; /* claim-states */\n"); } - fprintf(th, "} P%d;\n", nrRdy+1); - fprintf(th, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); - fprintf(th, " #define Air%d (0)\n\n", nrRdy+1); - fprintf(th, "#endif\n"); + fprintf(fd_th, "} P%d;\n", nrRdy+1); + + fprintf(fd_tc, "#ifndef NOCLAIM\n"); + fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_th, " #define Air%d (0)\n\n", nrRdy+1); + fprintf(fd_th, "#endif\n"); /* * find special states as: * stopstate [ claimnr ][ curstate ] == 1 @@ -171,68 +179,67 @@ * mapstate [ claimnr ][ curstate ] */ } else - { fprintf(th, "\n#define Pclaim P0\n"); - fprintf(th, "#ifndef NCLAIMS\n"); - fprintf(th, " #define NCLAIMS 1\n"); - fprintf(th, "#endif\n"); - fprintf(th, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); + { fprintf(fd_th, "#define Pclaim P0\n"); + fprintf(fd_th, "#ifndef NCLAIMS\n"); + fprintf(fd_th, " #define NCLAIMS 1\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); } - ntimes(th, 0, 1, Head0); + ntimes(fd_th, 0, 1, Head0); if (separate != 2) - { extern void c_add_stack(FILE *); - extern void c_stack_size(FILE *); - - ntimes(th, 0, 1, Header); - fprintf(th, "#define StackSize ("); - c_stack_size(th); - fprintf(th, ")\n"); + { + ntimes(fd_th, 0, 1, Header); + fprintf(fd_th, "#define StackSize ("); + c_stack_size(fd_th); + fprintf(fd_th, ")\n"); - c_add_stack(th); - ntimes(th, 0, 1, Header0); + c_add_stack(fd_th); + ntimes(fd_th, 0, 1, Header0); + } else + { fprintf(fd_th, "extern char *emalloc(unsigned long);\n"); } - ntimes(th, 0, 1, Head1); + ntimes(fd_th, 0, 1, Head1); LstSet = ZS; (void) doglobal("", PUTV); - hastrack = c_add_sv(th); + hastrack = c_add_sv(fd_th); - fprintf(th, "#ifdef TRIX\n"); - fprintf(th, " /* room for 512 proc+chan ptrs, + safety margin */\n"); - fprintf(th, " char *_ids_[MAXPROC+MAXQ+4];\n"); - fprintf(th, "#else\n"); - fprintf(th, " uchar sv[VECTORSZ];\n"); - fprintf(th, "#endif\n"); + fprintf(fd_th, "#ifdef TRIX\n"); + fprintf(fd_th, " /* room for 512 proc+chan ptrs, + safety margin */\n"); + fprintf(fd_th, " char *_ids_[MAXPROC+MAXQ+4];\n"); + fprintf(fd_th, "#else\n"); + fprintf(fd_th, " uchar sv[VECTORSZ];\n"); + fprintf(fd_th, "#endif\n"); - fprintf(th, "} State"); + fprintf(fd_th, "} State"); #ifdef SOLARIS - fprintf(th,"\n#ifdef GCC\n"); - fprintf(th, "\t__attribute__ ((aligned(8)))"); - fprintf(th, "\n#endif\n\t"); + fprintf(fd_th,"\n#ifdef GCC\n"); + fprintf(fd_th, "\t__attribute__ ((aligned(8)))"); + fprintf(fd_th, "\n#endif\n\t"); #endif - fprintf(th, ";\n\n"); - - fprintf(th, "#ifdef TRIX\n"); - fprintf(th, "typedef struct TRIX_v6 {\n"); - fprintf(th, " uchar *body; /* aligned */\n"); - fprintf(th, "#ifndef BFS\n"); - fprintf(th, " short modified;\n"); - fprintf(th, "#endif\n"); - fprintf(th, " short psize;\n"); - fprintf(th, " short parent_pid;\n"); - fprintf(th, " struct TRIX_v6 *nxt;\n"); - fprintf(th, "} TRIX_v6;\n"); - fprintf(th, "TRIX_v6 *freebodies;\n"); - fprintf(th, "TRIX_v6 *processes[MAXPROC+1];\n"); - fprintf(th, "TRIX_v6 *channels[MAXQ+1]; \n"); - fprintf(th, "long _p_count[MAXPROC];\n"); - fprintf(th, "long _c_count[MAXPROC];\n"); - fprintf(th, "#endif\n\n"); - - fprintf(th, "#define HAS_TRACK %d\n", hastrack); + fprintf(fd_th, ";\n\n"); + fprintf(fd_th, "#ifdef TRIX\n"); + fprintf(fd_th, "typedef struct TRIX_v6 {\n"); + fprintf(fd_th, " uchar *body; /* aligned */\n"); + fprintf(fd_th, "#ifndef BFS\n"); + fprintf(fd_th, " short modified;\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_th, " short psize;\n"); + fprintf(fd_th, " short parent_pid;\n"); + fprintf(fd_th, " struct TRIX_v6 *nxt;\n"); + fprintf(fd_th, "} TRIX_v6;\n"); + fprintf(fd_th, "#endif\n\n"); + + fprintf(fd_th, "#define HAS_TRACK %d\n", hastrack); + if (0 && hastrack) /* not really a problem */ + { fprintf(fd_th, "#ifdef BFS_PAR\n"); + fprintf(fd_th, " #error cannot use BFS_PAR on models with c_track stmnts\n"); + fprintf(fd_th, "#endif\n"); + } if (separate != 2) dohidden(); } @@ -240,90 +247,85 @@ void genaddproc(void) { ProcList *p; - int i = 0, j; + int i = 0; if (separate == 2) goto shortcut; - fprintf(tc, "\n#ifdef TRIX\n"); - fprintf(tc, "int what_p_size(int);\n"); - fprintf(tc, "int what_q_size(int);\n\n"); + ntimes(fd_tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */ + + fprintf(fd_tc, "#ifdef TRIX\n"); + fprintf(fd_tc, "int what_p_size(int);\n"); + fprintf(fd_tc, "int what_q_size(int);\n\n"); + /* the number of processes just changed by 1 (up or down) */ /* this means that the channel indices move up or down by one slot */ /* not all new channels may have a valid index yet, but we move */ /* all of them anyway, as if they existed */ - fprintf(tc, "void\nre_mark_all(int whichway)\n"); - fprintf(tc, "{ int j;\n"); - fprintf(tc, " #ifdef V_TRIX\n"); - fprintf(tc, " printf(\"%%d: re_mark_all channels %%d\\n\", depth, whichway);\n"); - fprintf(tc, " #endif\n"); - fprintf(tc, " #ifndef BFS\n"); - fprintf(tc, " for (j = 0; j < now._nr_qs; j++)\n"); - fprintf(tc, " channels[j]->modified = 1; /* channel index moved */\n"); - fprintf(tc, " #endif\n"); - fprintf(tc, " #ifndef TRIX_ORIG\n"); - fprintf(tc, " if (whichway > 0)\n"); - fprintf(tc, " { for (j = now._nr_pr + now._nr_qs - 1; j >= now._nr_pr; j--)\n"); - fprintf(tc, " now._ids_[j] = now._ids_[j-1];\n"); - fprintf(tc, " } else\n"); - fprintf(tc, " { for (j = now._nr_pr; j < now._nr_pr + now._nr_qs; j++)\n"); - fprintf(tc, " now._ids_[j] = now._ids_[j+1];\n"); - fprintf(tc, " }\n"); - fprintf(tc, " #endif\n"); - fprintf(tc, "}\n"); + ntimes(fd_tc, 0, 1, R7a); + fprintf(fd_tc, "#endif\n\n"); - fprintf(tc, "#endif\n\n"); + ntimes(fd_tc, 0, 1, R7b); - fprintf(tc, "int\naddproc(int calling_pid, int n"); + fprintf(fd_tc, "int\naddproc(int calling_pid, int priority, int n"); for (/* i = 0 */; i < Npars; i++) - fprintf(tc, ", int par%d", i); + fprintf(fd_tc, ", int par%d", i); - ntimes(tc, 0, 1, Addp0); - ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */ + ntimes(fd_tc, 0, 1, Addp0); + ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */ if (nclaims > 1) - { fprintf(tc, "#ifndef NOCLAIM\n"); - ntimes(tc, nrRdy+1, nrRdy+2, R5); - fprintf(tc, "#endif\n"); + { fprintf(fd_tc, "#ifndef NOCLAIM\n"); + ntimes(fd_tc, nrRdy+1, nrRdy+2, R5); + fprintf(fd_tc, "#endif\n"); } - ntimes(tc, 0, 1, Addp1); + ntimes(fd_tc, 0, 1, Addp1); if (has_provided) - { fprintf(tt, "\nint\nprovided(int II, unsigned char ot, "); - fprintf(tt, "int tt, Trans *t)\n"); - fprintf(tt, "{\n\tswitch(ot) {\n"); + { fprintf(fd_tt, "\nint\nprovided(int II, unsigned char ot, "); + fprintf(fd_tt, "int tt, Trans *t)\n"); + fprintf(fd_tt, "{\n\tswitch(ot) {\n"); } shortcut: if (nclaims > 1) { multi_init(); } tc_predef_np(); - for (p = rdy; p; p = p->nxt) - { Pid = p->tn; + for (p = ready; p; p = p->nxt) + { Pid_nr = p->tn; put_pinit(p); } if (separate == 2) return; - Pid = 0; + Pid_nr = 0; if (has_provided) - { fprintf(tt, "\tdefault: return 1; /* e.g., a claim */\n"); - fprintf(tt, "\t}\n\treturn 0;\n}\n"); + { fprintf(fd_tt, "\tdefault: return 1; /* e.g., a claim */\n"); + fprintf(fd_tt, "\t}\n\treturn 0;\n}\n"); } - ntimes(tc, i, i+1, R6); + ntimes(fd_tc, i, i+1, R6); if (separate == 0) - ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */ + ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */ else - ntimes(tc, 1, nrRdy, R5); - ntimes(tc, 0, 1, R8a); + ntimes(fd_tc, 1, nrRdy, R5); + ntimes(fd_tc, 0, 1, R8a); } void do_locinits(FILE *fd) { ProcList *p; - for (p = rdy; p; p = p->nxt) - c_add_locinit(fd, p->tn, p->n->name); + /* the locinit functions may refer to pptr or qptr */ + fprintf(fd, "#if VECTORSZ>32000\n"); + fprintf(fd, " extern int \n"); + fprintf(fd, "#else\n"); + fprintf(fd, " extern short \n"); + fprintf(fd, "#endif\n"); + fprintf(fd, " *proc_offset, *q_offset;\n"); + + for (p = ready; p; p = p->nxt) + { c_add_locinit(fd, p->tn, p->n->name); + } } void @@ -333,82 +335,94 @@ switch (separate) { case 2: if (nclaims > 0) - { for (p = rdy; p; p = p->nxt) + { for (p = ready; p; p = p->nxt) { if (p->b == N_CLAIM) - { ntimes(tc, p->tn, p->tn+1, R0); /* claims only */ + { ntimes(fd_tc, p->tn, p->tn+1, R0); /* claims only */ + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + ntimes(fd_tc, p->tn, p->tn+1, R00); + fprintf(fd_tc, "#endif\n"); } } } break; case 1: - ntimes(tc, 0, 1, Code0); - for (p = rdy; p; p = p->nxt) + ntimes(fd_tc, 0, 1, Code0); + for (p = ready; p; p = p->nxt) { if (p->b != N_CLAIM) - { ntimes(tc, p->tn, p->tn+1, R0); /* all except claims */ + { ntimes(fd_tc, p->tn, p->tn+1, R0); /* all except claims */ + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + ntimes(fd_tc, p->tn, p->tn+1, R00); + fprintf(fd_tc, "#endif\n"); } } break; case 0: - ntimes(tc, 0, 1, Code0); - ntimes(tc, 0, nrRdy+1, R0); /* +1 for np_ */ + ntimes(fd_tc, 0, 1, Code0); + ntimes(fd_tc, 0, nrRdy+1, R0); /* +1 for np_ */ + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + ntimes(fd_tc, 0, nrRdy+1, R00); /* +1 for np_ */ + fprintf(fd_tc, "#endif\n"); break; } + /* new place, make sure Maxbody is set to its final value here */ + fprintf(fd_tc, "\n"); + + if (separate != 2) + { ntimes(fd_tc, 1, u_sync+u_async+1, R3); /* nrqs is still 0 */ + fprintf(fd_tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n"); + fprintf(fd_tc, "\tif ((Maxbody %% WS) != 0)\n"); + fprintf(fd_tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n"); + } - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) end_labs(p->n, p->tn); switch (separate) { case 2: if (nclaims > 0) - { for (p = rdy; p; p = p->nxt) + { for (p = ready; p; p = p->nxt) { if (p->b == N_CLAIM) - { ntimes(tc, p->tn, p->tn+1, R0a); /* claims only */ + { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* claims only */ } } } return; case 1: - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { if (p->b != N_CLAIM) - { ntimes(tc, p->tn, p->tn+1, R0a); /* all except claims */ + { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* all except claims */ } } - fprintf(tc, " if (state_tables)\n"); - fprintf(tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */ + fprintf(fd_tc, " if (state_tables)\n"); + fprintf(fd_tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */ if (acceptors == 0) { acceptors = 1; /* assume at least 1 acceptstate */ } break; case 0: - ntimes(tc, 0, nrRdy, R0a); /* all */ + ntimes(fd_tc, 0, nrRdy, R0a); /* all */ break; } - ntimes(th, acceptors, acceptors+1, Code1); - ntimes(th, progressors, progressors+1, Code3); - ntimes(th, nrRdy+1, nrRdy+2, R2); /* +1 for np_ */ - - ntimes(tc, 0, 1, Code2a); /* dfs, bfs */ - ntimes(tc, 0, 1, Code2c); /* multicore */ - ntimes(tc, 0, 1, Code2d); - - fprintf(tc, "void\ndo_reach(void)\n{\n"); - ntimes(tc, 0, nrRdy, R4); - fprintf(tc, "}\n\n"); - - fprintf(tc, "void\niniglobals(int calling_pid)\n{\n"); - ntimes(tc, 1, u_sync+u_async+1, R3); /* because nqs is still 0 */ - fprintf(tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n"); - fprintf(tc, "\tif ((Maxbody %% WS) != 0)\n"); - fprintf(tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n"); + ntimes(fd_th, acceptors, acceptors+1, Code1); + ntimes(fd_th, progressors, progressors+1, Code3); - /* after the value of Maxbody has settled */ + ntimes(fd_tc, 0, 1, Code2a); /* dfs, bfs */ + ntimes(fd_tc, 0, 1, Code2e); /* multicore */ + ntimes(fd_tc, 0, 1, Code2c); /* multicore */ + ntimes(fd_tc, 0, 1, Code2d); + + fprintf(fd_tc, "void\ndo_reach(void)\n{\n"); + ntimes(fd_tc, 0, nrRdy, R4); + fprintf(fd_tc, "}\n\n"); + + fprintf(fd_tc, "void\niniglobals(int calling_pid)\n{\n"); if (doglobal("", INIV) > 0) - { fprintf(tc, "#ifdef VAR_RANGES\n"); + { fprintf(fd_tc, "#ifdef VAR_RANGES\n"); (void) doglobal("logval(\"", LOGV); - fprintf(tc, "#endif\n"); + fprintf(fd_tc, "#endif\n"); } - fprintf(tc, "}\n\n"); + fprintf(fd_tc, "}\n\n"); } void gensvmap(void) { - ntimes(tc, 0, 1, SvMap); + ntimes(fd_tc, 0, 1, SvMap); } static struct { @@ -435,9 +449,9 @@ for (j = 0; ln[j].n; j++) { if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0 && strcmp(l->c->name, s->name) == 0) - { fprintf(tc, "\t%s[%d][%d] = 1;\n", + { fprintf(fd_tc, "\t%s[%d][%d] = 1;\n", ln[j].t, i, l->e->seqno); - acceptors += ln[j].m; + acceptors += ln[j].m; progressors += ln[j].p; if (l->e->status & D_ATOM) { sprintf(foo, "%s label inside d_step", @@ -456,7 +470,7 @@ for (l = labtab; l; l = l->nxt) if (l->visible && strcmp(l->s->context->name, s->name) == 0) - fprintf(tc, "\tvisstate[%d][%d] = 1;\n", + fprintf(fd_tc, "\tvisstate[%d][%d] = 1;\n", i, l->e->seqno); lineno = oln; @@ -464,7 +478,7 @@ } void -ntimes(FILE *fd, int n, int m, char *c[]) +ntimes(FILE *fd, int n, int m, const char *c[]) { int i, j; for (j = 0; c[j]; j++) @@ -499,7 +513,7 @@ if (sp->hidden&16) /* formal parameter */ { ProcList *p; Lextok *f, *t; int posnr = 0; - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) if (p->n->name && strcmp(s, p->n->name) == 0) break; @@ -604,8 +618,8 @@ int i; if (!qtab) - { fprintf(fd, "void\nc_chandump(int unused) "); - fprintf(fd, "{ unused++; /* avoid complaints */ }\n"); + { fprintf(fd, "void\nc_chandump(int unused)\n"); + fprintf(fd, "{\tunused++; /* avoid complaints */\n}\n"); return; } @@ -628,11 +642,18 @@ fprintf(fd, "{ printf(\" [\");\n\t\t"); for (i = 0; i < q->nflds; i++) { if (q->fld_width[i] == MTYPE) - { fprintf(fd, "\tprintm(%scontents[slot].fld%d);\n\t\t", - buf, i); + { fprintf(fd, "\tprintm(%scontents[slot].fld%d", + buf, i); + if (q->mtp[i]) + { fprintf(fd, ", \"%s\"", q->mtp[i]); + } else + { fprintf(fd, ", 0"); + } } else - fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d);\n\t\t", - buf, i); + { fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d", + buf, i); + } + fprintf(fd, ");\n\t\t"); } fprintf(fd, " printf(\"],\");\n\t\t"); fprintf(fd, "}\n\t\t"); @@ -651,7 +672,7 @@ { fatal("cannot happen - c_var", 0); } - ptr = sp?sp->name:""; + ptr = sp->name; if (!old_scope_rules) { while (*ptr == '_' || isdigit((int)*ptr)) { ptr++; @@ -665,13 +686,20 @@ sprintf(buf, "%s%s.", pref, sp->name); c_struct(fd, buf, sp); break; + case MTYPE: case BIT: case BYTE: case SHORT: case INT: case UNSIGNED: sputtype(buf, sp->type); if (sp->nel == 1 && sp->isarray == 0) - { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n", - buf, ptr, pref, sp->name); + { + if (sp->type == MTYPE && ismtype(sp->name)) + { fprintf(fd, "\tprintf(\"\t%s %s:\t%d\\n\");\n", + buf, ptr, ismtype(sp->name)); + } else + { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n", + buf, ptr, pref, sp->name); + } } else { fprintf(fd, "\t{\tint l_in;\n"); fprintf(fd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel); @@ -744,28 +772,27 @@ void c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */ -{ Ordered *walk; +{ Ordered *walk; ProcList *p; - Symbol *sp; - Lextok *n; - extern Lextok *Mtype; - int j; + Symbol *sp; + Mtypes_t *lst; + Lextok *n; + int j; + extern Mtypes_t *Mtypes; fprintf(fd, "void\nc_globals(void)\n{\t/* int i; */\n"); fprintf(fd, " printf(\"global vars:\\n\");\n"); for (walk = all_names; walk; walk = walk->next) { sp = walk->entry; - if (sp->context || sp->owner || (sp->hidden&1) - || (sp->type == MTYPE && ismtype(sp->name))) + if (sp->context || sp->owner || (sp->hidden&1)) continue; - c_var(fd, "now.", sp); } fprintf(fd, "}\n"); fprintf(fd, "void\nc_locals(int pid, int tp)\n{\t/* int i; */\n"); fprintf(fd, " switch(tp) {\n"); - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { fprintf(fd, " case %d:\n", p->tn); if (c_splurge_any(p)) { fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n", @@ -778,13 +805,17 @@ } fprintf(fd, " }\n}\n"); - fprintf(fd, "void\nprintm(int x)\n{\n"); - fprintf(fd, " switch (x) {\n"); - for (n = Mtype, j = 1; n && j; n = n->rgt, j++) - fprintf(fd, "\tcase %d: Printf(\"%s\"); break;\n", - j, n->lft->sym->name); - fprintf(fd, " default: Printf(\"%%d\", x);\n"); - fprintf(fd, " }\n"); + fprintf(fd, "void\nprintm(int x, char *s)\n{\n"); + fprintf(fd, " if (!s) { s = \"_unnamed_\"; }\n"); + for (lst = Mtypes; lst; lst = lst->nxt) + { fprintf(fd, " if (strcmp(s, \"%s\") == 0)\n", lst->nm); + fprintf(fd, " switch (x) {\n"); + for (n = lst->mt, j = 1; n && j; n = n->rgt, j++) + fprintf(fd, "\tcase %d: Printf(\"%s\"); return;\n", + j, n->lft->sym->name); + fprintf(fd, " default: Printf(\"%%d\", x); return;\n"); + fprintf(fd, " }\n"); + } fprintf(fd, "}\n"); } @@ -808,14 +839,14 @@ break; if (sp->hidden&1) break; - do_var(tc, dowhat, "", sp, + do_var(fd_tc, dowhat, "", sp, pre, "\", now.", ");\n"); break; case INIV: checktype(sp, (char *) 0); cnt++; /* fall through */ case PUTV: - do_var(tc, dowhat, + do_var(fd_tc, dowhat, (sp->hidden&1)?"":"now.", sp, "", " = ", ";\n"); break; @@ -835,13 +866,12 @@ if ((sp->hidden&1) && sp->type == Types[j]) { if (sp->context || sp->owner) - fatal("cannot hide non-globals (%s)", sp->name); + fatal("cannot hide non-globals (%s)", sp->name); if (sp->type == CHAN) - fatal("cannot hide channels (%s)", sp->name); - fprintf(th, "/* hidden variable: */"); + fatal("cannot hide channels (%s)", sp->name); + fprintf(fd_th, "/* hidden variable: */"); typ2c(sp); } } - fprintf(th, "int _; /* a predefined write-only variable */\n\n"); } void @@ -898,20 +928,38 @@ do_init(ofd, sp); fprintf(ofd, "%s", ter); } - } else - { fprintf(ofd, "\t{\tint l_in;\n"); - fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel); - fprintf(ofd, "\t\t{\n"); - fprintf(ofd, "\t\t\t%s%s%s[l_in]%s", + } else if (sp->ini) + { if (dowhat != LOGV && sp->isarray && sp->ini->ntyp == ',') + { Lextok *z, *y; + z = sp->ini; + for (i = 0; i < sp->nel; i++) + { if (z && z->ntyp == ',') + { y = z->lft; + z = z->rgt; + } else + { y = z; + } + fprintf(ofd, "\t\t%s%s%s[%d]%s", + pre, s, sp->name, i, sep); + putstmnt(ofd, y, 0); + fprintf(ofd, "%s", ter); + } + } else + { fprintf(ofd, "\t{\tint l_in;\n"); + fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", + sp->nel); + fprintf(ofd, "\t\t{\n"); + fprintf(ofd, "\t\t\t%s%s%s[l_in]%s", pre, s, sp->name, sep); - if (dowhat == LOGV) - fprintf(ofd, "%s%s[l_in]", s, sp->name); - else - putstmnt(ofd, sp->ini, 0); - fprintf(ofd, "%s", ter); - fprintf(ofd, "\t\t}\n"); - fprintf(ofd, "\t}\n"); - } } + if (dowhat == LOGV) + { fprintf(ofd, "%s%s[l_in]", s, sp->name); + } else + { putstmnt(ofd, sp->ini, 0); + } + fprintf(ofd, "%s", ter); + fprintf(ofd, "\t\t}\n"); + fprintf(ofd, "\t}\n"); + } } } break; } } @@ -939,81 +987,84 @@ { int k; if (b == I_PROC) - { fprintf(th, "#define Pinit ((P%d *)this)\n", i); + { fprintf(fd_th, "#define Pinit ((P%d *)_this)\n", i); } else if (b == P_PROC || b == A_PROC) - { fprintf(th, "#define P%s ((P%d *)this)\n", s, i); + { fprintf(fd_th, "#define P%s ((P%d *)_this)\n", s, i); } - fprintf(th, "typedef struct P%d { /* %s */\n", i, s); - fprintf(th, " unsigned _pid : 8; /* 0..255 */\n"); - fprintf(th, " unsigned _t : %d; /* proctype */\n", blog(m1)); - fprintf(th, " unsigned _p : %d; /* state */\n", blog(m0)); + fprintf(fd_th, "typedef struct P%d { /* %s */\n", i, s); + fprintf(fd_th, " unsigned _pid : 8; /* 0..255 */\n"); + fprintf(fd_th, " unsigned _t : %d; /* proctype */\n", blog(m1)); + fprintf(fd_th, " unsigned _p : %d; /* state */\n", blog(m0)); + fprintf(fd_th, "#ifdef HAS_PRIORITY\n"); + fprintf(fd_th, " unsigned _priority : 8; /* 0..255 */\n"); + fprintf(fd_th, "#endif\n"); LstSet = ZS; nBits = 8 + blog(m1) + blog(m0); - k = dolocal(tc, "", PUTV, i, s, b); /* includes pars */ + k = dolocal(fd_tc, "", PUTV, i, s, b); /* includes pars */ + c_add_loc(fd_th, s); - c_add_loc(th, s); - - fprintf(th, "} P%d;\n", i); + fprintf(fd_th, "} P%d;\n", i); if ((!LstSet && k > 0) || has_state) - fprintf(th, "#define Air%d 0\n", i); + fprintf(fd_th, "#define Air%d 0\n\n", i); else if (LstSet || k == 0) /* 5.0, added condition */ - { fprintf(th, "#define Air%d (sizeof(P%d) - ", i, i); + { fprintf(fd_th, "#define Air%d (sizeof(P%d) - ", i, i); if (k == 0) - { fprintf(th, "%d", (nBits+7)/8); + { fprintf(fd_th, "%d", (nBits+7)/8); goto done; } if ((LstSet->type != BIT && LstSet->type != UNSIGNED) || LstSet->nel != 1) - { fprintf(th, "Offsetof(P%d, %s) - %d*sizeof(", + { fprintf(fd_th, "Offsetof(P%d, %s) - %d*sizeof(", i, LstSet->name, LstSet->nel); } switch(LstSet->type) { case UNSIGNED: - fprintf(th, "%d", (nBits+7)/8); + fprintf(fd_th, "%d", (nBits+7)/8); break; case BIT: if (LstSet->nel == 1) - { fprintf(th, "%d", (nBits+7)/8); + { fprintf(fd_th, "%d", (nBits+7)/8); break; } /* else fall through */ case MTYPE: case BYTE: case CHAN: - fprintf(th, "uchar)"); break; + fprintf(fd_th, "uchar)"); break; case SHORT: - fprintf(th, "short)"); break; + fprintf(fd_th, "short)"); break; case INT: - fprintf(th, "int)"); break; + fprintf(fd_th, "int)"); break; default: fatal("cannot happen Air %s", LstSet->name); } -done: fprintf(th, ")\n"); +done: fprintf(fd_th, ")\n\n"); } } static void tc_predef_np(void) -{ int i = nrRdy; /* 1+ highest proctype nr */ +{ + fprintf(fd_th, "#define _NP_ %d\n", nrRdy); /* 1+ highest proctype nr */ - fprintf(th, "#define _NP_ %d\n", i); -/* if (separate == 2) fprintf(th, "extern "); */ - fprintf(th, "uchar reached%d[3]; /* np_ */\n", i); - fprintf(th, "uchar *loopstate%d; /* np_ */\n", i); - - fprintf(th, "#define nstates%d 3 /* np_ */\n", i); - fprintf(th, "#define endstate%d 2 /* np_ */\n\n", i); - fprintf(th, "#define start%d 0 /* np_ */\n", i); + fprintf(fd_th, "#define _nstates%d 3 /* np_ */\n", nrRdy); + fprintf(fd_th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy); + fprintf(fd_th, "#define _start%d 0 /* np_ */\n", nrRdy); - fprintf(tc, "\tcase %d: /* np_ */\n", i); + fprintf(fd_tc, "\tcase %d: /* np_ */\n", nrRdy); if (separate == 1) - { fprintf(tc, "\t\tini_claim(%d, h);\n", i); + { fprintf(fd_tc, "\t\tini_claim(%d, h);\n", nrRdy); } else - { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i); - fprintf(tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", i); - fprintf(tc, "\t\treached%d[0] = 1;\n", i); - fprintf(tc, "\t\taccpstate[%d][1] = 1;\n", i); + { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy); + + fprintf(fd_tc, "#ifdef HAS_PRIORITY\n"); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_tc, "\t\treached%d[0] = 1;\n", nrRdy); + fprintf(fd_tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy); } - fprintf(tc, "\t\tbreak;\n"); + fprintf(fd_tc, "\t\tbreak;\n"); } static void @@ -1024,38 +1075,38 @@ int ini, j; int nrc = nclaims; - fprintf(tc, "#ifndef NOCLAIM\n"); - fprintf(tc, "\tcase %d: /* claim select */\n", i); - for (p = rdy, j = 0; p; p = p->nxt, j++) + fprintf(fd_tc, "#ifndef NOCLAIM\n"); + fprintf(fd_tc, "\tcase %d: /* claim select */\n", i); + for (p = ready, j = 0; p; p = p->nxt, j++) { if (p->b == N_CLAIM) { e = p->s->frst; ini = huntele(e, e->status, -1)->seqno; - fprintf(tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n", + fprintf(fd_tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n", j, p->tn, p->n->name); - fprintf(tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n", + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n", i, j, ini); - fprintf(tc, "\t\treached%d[%d]=1;\n", p->tn, ini); + fprintf(fd_tc, "\t\treached%d[%d]=1;\n", p->tn, ini); /* the default initial claim is first one in model */ if (--nrc == 0) - { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn); - fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); - fprintf(tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n", + { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n", i, j, p->n->name); - fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", p->tn); - fprintf(tc, "#ifndef BFS\n"); - fprintf(tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n"); - fprintf(tc, "\t\t\tprintf(\"0: Claim %s (%d), from state %d\\n\");\n", - p->n->name, p->tn, ini); - fprintf(tc, "#endif\n"); + fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", p->tn); + fprintf(fd_tc, "#ifndef BFS\n"); + fprintf(fd_tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n"); + fprintf(fd_tc, "\t\t\tprintf(\"pan: ltl formula %s\\n\");\n", + p->n->name); + fprintf(fd_tc, "#endif\n"); } } } - fprintf(tc, "\t\tif (whichclaim != -1)\n"); - fprintf(tc, "\t\t{ select_claim(whichclaim);\n"); - fprintf(tc, "\t\t}\n"); - fprintf(tc, "\t\tbreak;\n\n"); - fprintf(tc, "#endif\n"); + fprintf(fd_tc, "\t\tif (whichclaim != -1)\n"); + fprintf(fd_tc, "\t\t{ select_claim(whichclaim);\n"); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tbreak;\n\n"); + fprintf(fd_tc, "#endif\n"); } static void @@ -1069,9 +1120,9 @@ if (pid_is_claim(i) && separate == 1) - { fprintf(tc, "\tcase %d: /* %s */\n", i, s->name); - fprintf(tc, "\t\tini_claim(%d, h);\n", i); - fprintf(tc, "\t\tbreak;\n"); + { fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name); + fprintf(fd_tc, "\t\tini_claim(%d, h);\n", i); + fprintf(fd_tc, "\t\tbreak;\n"); return; } if (!pid_is_claim(i) @@ -1079,32 +1130,38 @@ return; ini = huntele(e, e->status, -1)->seqno; - fprintf(th, "#define start%d %d\n", i, ini); + fprintf(fd_th, "#define _start%d %d\n", i, ini); if (i == eventmapnr) - fprintf(th, "#define start_event %d\n", ini); + fprintf(fd_th, "#define start_event %d\n", ini); + + fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name); + + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); + fprintf(fd_tc, "#ifdef HAS_PRIORITY\n"); - fprintf(tc, "\tcase %d: /* %s */\n", i, s->name); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n", + i, (P->priority<1)? 1 : P->priority); - fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i); - fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); - fprintf(tc, "\t\treached%d[%d]=1;\n", i, ini); + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\t\treached%d[%d]=1;\n", i, ini); if (P->b == N_CLAIM) - { fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", i); + { fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", i); } if (has_provided) - { fprintf(tt, "\tcase %d: /* %s */\n\t\t", i, s->name); + { fprintf(fd_tt, "\tcase %d: /* %s */\n\t\t", i, s->name); if (P->prov) - { fprintf(tt, "if ("); - putstmnt(tt, P->prov, 0); - fprintf(tt, ")\n\t\t\t"); + { fprintf(fd_tt, "if ("); + putstmnt(fd_tt, P->prov, 0); + fprintf(fd_tt, ")\n\t\t\t"); } - fprintf(tt, "return 1;\n"); + fprintf(fd_tt, "return 1;\n"); if (P->prov) - fprintf(tt, "\t\tbreak;\n"); + fprintf(fd_tt, "\t\tbreak;\n"); } - fprintf(tc, "\t\t/* params: */\n"); + fprintf(fd_tc, "\t\t/* params: */\n"); for (fp = p, j=0; fp; fp = fp->rgt) for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++) { t = (fpt->ntyp == ',') ? fpt->lft : fpt; @@ -1114,32 +1171,32 @@ fatal("array in parameter list, %s", t->sym->name); } - fprintf(tc, "\t\t((P%d *)pptr(h))->", i); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->", i); if (t->sym->type == STRUCT) - { if (full_name(tc, t, t->sym, 1)) + { if (full_name(fd_tc, t, t->sym, 1)) { lineno = t->ln; Fname = t->fn; fatal("hidden array in parameter %s", t->sym->name); } } else - fprintf(tc, "%s", t->sym->name); - fprintf(tc, " = par%d;\n", j); + fprintf(fd_tc, "%s", t->sym->name); + fprintf(fd_tc, " = par%d;\n", j); } - fprintf(tc, "\t\t/* locals: */\n"); - k = dolocal(tc, "", INIV, i, s->name, P->b); + fprintf(fd_tc, "\t\t/* locals: */\n"); + k = dolocal(fd_tc, "", INIV, i, s->name, P->b); if (k > 0) - { fprintf(tc, "#ifdef VAR_RANGES\n"); - (void) dolocal(tc, "logval(\"", LOGV, i, s->name, P->b); - fprintf(tc, "#endif\n"); + { fprintf(fd_tc, "#ifdef VAR_RANGES\n"); + (void) dolocal(fd_tc, "logval(\"", LOGV, i, s->name, P->b); + fprintf(fd_tc, "#endif\n"); } - fprintf(tc, "#ifdef HAS_CODE\n"); - fprintf(tc, "\t\tlocinit%d(h);\n", i); - fprintf(tc, "#endif\n"); + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + fprintf(fd_tc, "\t\tlocinit%d(h);\n", i); + fprintf(fd_tc, "#endif\n"); - dumpclaims(tc, i, s->name); - fprintf(tc, "\t break;\n"); + dumpclaims(fd_tc, i, s->name); + fprintf(fd_tc, "\t break;\n"); } Element * @@ -1158,17 +1215,19 @@ } } if (cnt >= 200 || !e) - fatal("confusing control structure", (char *) 0); + { lineno = (f && f->n)?f->n->ln:lineno; + fatal("confusing control. structure", (char *) 0); + } return e; } Element * -huntele(Element *f, int o, int stopat) +huntele(Element *f, unsigned int o, int stopat) { Element *g, *e = f; int cnt=0; /* a precaution against loops */ if (e) - for ( ; cnt < 200 && e->n; cnt++) + for ( ; cnt < 500 && e->n; cnt++) { if (e->seqno == stopat) break; @@ -1176,6 +1235,10 @@ switch (e->n->ntyp) { case GOTO: g = get_lab(e->n,1); + if (e == g) + { lineno = (f && f->n)?f->n->ln:lineno; + fatal("infinite goto loop", (char *) 0); + } cross_dsteps(e->n, g->n); break; case '.': @@ -1186,6 +1249,9 @@ break; case UNLESS: g = huntele(e->sub->this->frst, o, stopat); + if (!g) + { fatal("unexpected error 1", (char *) 0); + } break; case D_STEP: case ATOMIC: @@ -1197,8 +1263,10 @@ return e; e = g; } - if (cnt >= 200 || !e) + if (cnt >= 500 || !e) + { lineno = (f && f->n)?f->n->ln:lineno; fatal("confusing control structure", (char *) 0); + } return e; } @@ -1208,9 +1276,9 @@ switch (sp->type) { case UNSIGNED: if (sp->hidden&1) - fprintf(th, "\tuchar %s;", sp->name); + fprintf(fd_th, "\tuchar %s;", sp->name); else - fprintf(th, "\tunsigned %s : %d", + fprintf(fd_th, "\tunsigned %s : %d", sp->name, sp->nbits); LstSet = sp; if (nBits%wsbits > 0 @@ -1222,7 +1290,7 @@ break; case BIT: if (sp->nel == 1 && sp->isarray == 0 && !(sp->hidden&1)) - { fprintf(th, "\tunsigned %s : 1", sp->name); + { fprintf(fd_th, "\tunsigned %s : 1", sp->name); LstSet = sp; nBits++; break; @@ -1234,21 +1302,21 @@ case MTYPE: case BYTE: case CHAN: /* good for up to 255 channels */ - fprintf(th, "\tuchar %s", sp->name); + fprintf(fd_th, "\tuchar %s", sp->name); LstSet = sp; break; case SHORT: - fprintf(th, "\tshort %s", sp->name); + fprintf(fd_th, "\tshort %s", sp->name); LstSet = sp; break; case INT: - fprintf(th, "\tint %s", sp->name); + fprintf(fd_th, "\tint %s", sp->name); LstSet = sp; break; case STRUCT: if (!sp->Snm) fatal("undeclared structure element %s", sp->name); - fprintf(th, "\tstruct %s %s", + fprintf(fd_th, "\tstruct %s %s", sp->Snm->name, sp->name); LstSet = ZS; @@ -1261,12 +1329,12 @@ } if (sp->nel > 1 || sp->isarray) - fprintf(th, "[%d]", sp->nel); - fprintf(th, ";\n"); + fprintf(fd_th, "[%d]", sp->nel); + fprintf(fd_th, ";\n"); } static void -ncases(FILE *fd, int p, int n, int m, char *c[]) +ncases(FILE *fd, int p, int n, int m, const char *c[]) { int i, j; for (j = 0; c[j]; j++) @@ -1279,14 +1347,14 @@ void qlen_type(int qmax) { - fprintf(th, "\t"); + fprintf(fd_th, "\t"); if (qmax < 256) - fprintf(th, "uchar"); + fprintf(fd_th, "uchar"); else if (qmax < 65535) - fprintf(th, "ushort"); + fprintf(fd_th, "ushort"); else - fprintf(th, "uint"); - fprintf(th, " Qlen; /* q_size */\n"); + fprintf(fd_th, "uint"); + fprintf(fd_th, " Qlen; /* q_size */\n"); } void @@ -1295,13 +1363,12 @@ int j, qmax = 0; Queue *q; - ntimes(tc, 0, 1, Addq0); - if (has_io && !nqs) - fprintf(th, "#define NQS 1 /* nqs=%d, but has_io */\n", nqs); + ntimes(fd_tc, 0, 1, Addq0); + + if (has_io && !nrqs) + fprintf(fd_th, "#define NQS 1 /* nrqs=%d, but has_io */\n", nrqs); else - fprintf(th, "#define NQS %d\n", nqs); - fprintf(th, "short q_flds[%d];\n", nqs+1); - fprintf(th, "short q_max[%d];\n", nqs+1); + fprintf(fd_th, "#define NQS %d\n", nrqs); for (q = qtab; q; q = q->nxt) if (q->nslots > qmax) @@ -1309,219 +1376,225 @@ for (q = qtab; q; q = q->nxt) { j = q->qid; - fprintf(tc, "\tcase %d: j = sizeof(Q%d);", j, j); - fprintf(tc, " q_flds[%d] = %d;", j, q->nflds); - fprintf(tc, " q_max[%d] = %d;", j, max(1,q->nslots)); - fprintf(tc, " break;\n"); + fprintf(fd_tc, "\tcase %d: j = sizeof(Q%d);", j, j); + fprintf(fd_tc, " q_flds[%d] = %d;", j, q->nflds); + fprintf(fd_tc, " q_max[%d] = %d;", j, max(1,q->nslots)); + fprintf(fd_tc, " break;\n"); - fprintf(th, "typedef struct Q%d {\n", j); + fprintf(fd_th, "typedef struct Q%d {\n", j); qlen_type(qmax); /* 4.2.2 */ - fprintf(th, " uchar _t; /* q_type */\n"); - fprintf(th, " struct {\n"); + fprintf(fd_th, " uchar _t; /* q_type */\n"); + fprintf(fd_th, " struct {\n"); for (j = 0; j < q->nflds; j++) { switch (q->fld_width[j]) { case BIT: if (q->nflds != 1) - { fprintf(th, "\t\tunsigned"); - fprintf(th, " fld%d : 1;\n", j); + { fprintf(fd_th, "\t\tunsigned"); + fprintf(fd_th, " fld%d : 1;\n", j); break; } /* else fall through: smaller struct */ case MTYPE: case CHAN: case BYTE: - fprintf(th, "\t\tuchar fld%d;\n", j); + fprintf(fd_th, "\t\tuchar fld%d;\n", j); break; case SHORT: - fprintf(th, "\t\tshort fld%d;\n", j); + fprintf(fd_th, "\t\tshort fld%d;\n", j); break; case INT: - fprintf(th, "\t\tint fld%d;\n", j); + fprintf(fd_th, "\t\tint fld%d;\n", j); break; default: fatal("bad channel spec", ""); } } - fprintf(th, " } contents[%d];\n", max(1, q->nslots)); - fprintf(th, "} Q%d;\n", q->qid); + fprintf(fd_th, " } contents[%d];\n", max(1, q->nslots)); + fprintf(fd_th, "} Q%d;\n", q->qid); } - fprintf(th, "typedef struct Q0 {\t/* generic q */\n"); + fprintf(fd_th, "typedef struct Q0 {\t/* generic q */\n"); qlen_type(qmax); /* 4.2.2 */ - fprintf(th, " uchar _t;\n"); - fprintf(th, "} Q0;\n"); + fprintf(fd_th, " uchar _t;\n"); + fprintf(fd_th, "} Q0;\n"); - ntimes(tc, 0, 1, Addq1); + ntimes(fd_tc, 0, 1, Addq1); - fprintf(tc, "#ifdef TRIX\n"); - fprintf(tc, "int\nwhat_p_size(int t)\n{\tint j;\n"); - fprintf(tc, " switch (t) {\n"); - ntimes(tc, 0, nrRdy+1, R5); /* +1 for np_ */ - fprintf(tc, " default: Uerror(\"bad proctype\");\n"); - fprintf(tc, " }\n return j;\n}\n\n"); - - fprintf(tc, "int\nwhat_q_size(int t)\n{\tint j;\n"); - fprintf(tc, " switch (t) {\n"); - for (j = 0; j < nqs+1; j++) - { fprintf(tc, " case %d: j = sizeof(Q%d); break;\n", j, j); - } - fprintf(tc, " default: Uerror(\"bad qtype\");\n"); - fprintf(tc, " }\n return j;\n}\n"); - fprintf(tc, "#endif\n\n"); + fprintf(fd_tc, "#ifdef TRIX\n"); + fprintf(fd_tc, "int\nwhat_p_size(int t)\n{\tint j;\n"); + fprintf(fd_tc, " switch (t) {\n"); + ntimes(fd_tc, 0, nrRdy+1, R5); /* +1 for np_ */ + fprintf(fd_tc, " default: Uerror(\"bad proctype\");\n"); + fprintf(fd_tc, " }\n return j;\n}\n\n"); + + fprintf(fd_tc, "int\nwhat_q_size(int t)\n{\tint j;\n"); + fprintf(fd_tc, " switch (t) {\n"); + for (j = 0; j < nrqs+1; j++) + { fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", j, j); + } + fprintf(fd_tc, " default: Uerror(\"bad qtype\");\n"); + fprintf(fd_tc, " }\n return j;\n}\n"); + fprintf(fd_tc, "#endif\n\n"); if (has_random) - { fprintf(th, "int Q_has(int"); + { fprintf(fd_th, "int Q_has(int"); for (j = 0; j < Mpars; j++) - fprintf(th, ", int, int"); - fprintf(th, ");\n"); + fprintf(fd_th, ", int, int"); + fprintf(fd_th, ");\n"); - fprintf(tc, "int\nQ_has(int into"); + fprintf(fd_tc, "int\nQ_has(int into"); for (j = 0; j < Mpars; j++) - fprintf(tc, ", int want%d, int fld%d", j, j); - fprintf(tc, ")\n"); - fprintf(tc, "{ int i;\n\n"); - fprintf(tc, " if (!into--)\n"); - fprintf(tc, " uerror(\"ref to unknown chan "); - fprintf(tc, "(recv-poll)\");\n\n"); - fprintf(tc, " if (into >= now._nr_qs || into < 0)\n"); - fprintf(tc, " Uerror(\"qrecv bad queue#\");\n\n"); - fprintf(tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;"); - fprintf(tc, " i++)\n"); - fprintf(tc, " {\n"); + fprintf(fd_tc, ", int want%d, int fld%d", j, j); + fprintf(fd_tc, ")\n"); + fprintf(fd_tc, "{ int i;\n\n"); + fprintf(fd_tc, " if (!into--)\n"); + fprintf(fd_tc, " uerror(\"ref to unknown chan "); + fprintf(fd_tc, "(recv-poll)\");\n\n"); + fprintf(fd_tc, " if (into >= now._nr_qs || into < 0)\n"); + fprintf(fd_tc, " Uerror(\"qrecv bad queue#\");\n\n"); + fprintf(fd_tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;"); + fprintf(fd_tc, " i++)\n"); + fprintf(fd_tc, " {\n"); for (j = 0; j < Mpars; j++) - { fprintf(tc, " if (want%d && ", j); - fprintf(tc, "qrecv(into+1, i, %d, 0) != fld%d)\n", + { fprintf(fd_tc, " if (want%d && ", j); + fprintf(fd_tc, "qrecv(into+1, i, %d, 0) != fld%d)\n", j, j); - fprintf(tc, " continue;\n"); + fprintf(fd_tc, " continue;\n"); } - fprintf(tc, " return i+1;\n"); - fprintf(tc, " }\n"); - fprintf(tc, " return 0;\n"); - fprintf(tc, "}\n"); + fprintf(fd_tc, " return i+1;\n"); + fprintf(fd_tc, " }\n"); + fprintf(fd_tc, " return 0;\n"); + fprintf(fd_tc, "}\n"); } - fprintf(tc, "#if NQS>0\n"); - fprintf(tc, "void\nqsend(int into, int sorted"); + fprintf(fd_tc, "#if NQS>0\n"); + fprintf(fd_tc, "void\nqsend(int into, int sorted"); for (j = 0; j < Mpars; j++) - fprintf(tc, ", int fld%d", j); - fprintf(tc, ", int args_given)\n"); - ntimes(tc, 0, 1, Addq11); + fprintf(fd_tc, ", int fld%d", j); + fprintf(fd_tc, ", int args_given)\n"); + ntimes(fd_tc, 0, 1, Addq11); for (q = qtab; q; q = q->nxt) { sprintf(buf0, "((Q%d *)z)->", q->qid); - fprintf(tc, "\tcase %d:%s\n", q->qid, + fprintf(fd_tc, "\tcase %d:%s\n", q->qid, (q->nslots)?"":" /* =rv= */"); if (q->nslots == 0) /* reset handshake point */ - fprintf(tc, "\t\t(trpt+2)->o_m = 0;\n"); + fprintf(fd_tc, "\t\t(trpt+2)->o_m = 0;\n"); if (has_sorted) - { fprintf(tc, "\t\tif (!sorted) goto append%d;\n", q->qid); - fprintf(tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0); - fprintf(tc, "\t\t{\t/* find insertion point */\n"); + { fprintf(fd_tc, "\t\tif (!sorted) goto append%d;\n", q->qid); + fprintf(fd_tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0); + fprintf(fd_tc, "\t\t{\t/* find insertion point */\n"); sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid); for (j = 0; j < q->nflds; j++) - { fprintf(tc, "\t\t\tif (fld%d > %s%d) continue;\n", + { fprintf(fd_tc, "\t\t\tif (fld%d > %s%d) continue;\n", j, buf0, j); - fprintf(tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j); - fprintf(tc, "goto found%d;\n\n", q->qid); + fprintf(fd_tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j); + fprintf(fd_tc, "goto found%d;\n\n", q->qid); } - fprintf(tc, "\t\t}\n"); - fprintf(tc, "\tfound%d:\n", q->qid); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\tfound%d:\n", q->qid); sprintf(buf0, "((Q%d *)z)->", q->qid); - fprintf(tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0); - fprintf(tc, "\t\t{\t/* shift up */\n"); + fprintf(fd_tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0); + fprintf(fd_tc, "\t\t{\t/* shift up */\n"); for (j = 0; j < q->nflds; j++) - { fprintf(tc, "\t\t\t%scontents[k+1].fld%d = ", + { fprintf(fd_tc, "\t\t\t%scontents[k+1].fld%d = ", buf0, j); - fprintf(tc, "%scontents[k].fld%d;\n", + fprintf(fd_tc, "%scontents[k].fld%d;\n", buf0, j); } - fprintf(tc, "\t\t}\n"); - fprintf(tc, "\tappend%d:\t/* insert in slot j */\n", q->qid); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\tappend%d:\t/* insert in slot j */\n", q->qid); } - fprintf(tc, "#ifdef HAS_SORTED\n"); - fprintf(tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */ - fprintf(tc, "#endif\n"); - fprintf(tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0); + fprintf(fd_tc, "#ifdef HAS_SORTED\n"); + fprintf(fd_tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */ + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0); sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid); for (j = 0; j < q->nflds; j++) - fprintf(tc, "\t\t%s%d = fld%d;\n", buf0, j, j); - fprintf(tc, "\t\tif (args_given != %d)\n", q->nflds); - fprintf(tc, "\t\t{ if (args_given > %d)\n", q->nflds); - fprintf(tc, "\t\t uerror(\"too many parameters in send stmnt\");\n"); - fprintf(tc, "\t\t else\n"); - fprintf(tc, "\t\t uerror(\"too few parameters in send stmnt\");\n"); - fprintf(tc, "\t\t}\n"); - fprintf(tc, "\t\tbreak;\n"); + { fprintf(fd_tc, "\t\t%s%d = fld%d;", buf0, j, j); + if (q->fld_width[j] == MTYPE) + { fprintf(fd_tc, "\t/* mtype %s */", + q->mtp[j]?q->mtp[j]:"_unnamed_"); + } + fprintf(fd_tc, "\n"); + } + fprintf(fd_tc, "\t\tif (args_given != %d)\n", q->nflds); + fprintf(fd_tc, "\t\t{ if (args_given > %d)\n", q->nflds); + fprintf(fd_tc, "\t\t uerror(\"too many parameters in send stmnt\");\n"); + fprintf(fd_tc, "\t\t else\n"); + fprintf(fd_tc, "\t\t uerror(\"too few parameters in send stmnt\");\n"); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tbreak;\n"); } - ntimes(tc, 0, 1, Addq2); + ntimes(fd_tc, 0, 1, Addq2); for (q = qtab; q; q = q->nxt) - fprintf(tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots)); + fprintf(fd_tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots)); - ntimes(tc, 0, 1, Addq3); + ntimes(fd_tc, 0, 1, Addq3); for (q = qtab; q; q = q->nxt) - fprintf(tc, "\tcase %d: return (q_sz(from) == %d);\n", + fprintf(fd_tc, "\tcase %d: return (q_sz(from) == %d);\n", q->qid, max(1, q->nslots)); - ntimes(tc, 0, 1, Addq4); + ntimes(fd_tc, 0, 1, Addq4); for (q = qtab; q; q = q->nxt) { sprintf(buf0, "((Q%d *)z)->", q->qid); - fprintf(tc, " case %d:%s\n\t\t", + fprintf(fd_tc, " case %d:%s\n\t\t", q->qid, (q->nslots)?"":" /* =rv= */"); if (q->nflds == 1) - { fprintf(tc, "if (fld == 0) r = %s", buf0); - fprintf(tc, "contents[slot].fld0;\n"); + { fprintf(fd_tc, "if (fld == 0) r = %s", buf0); + fprintf(fd_tc, "contents[slot].fld0;\n"); } else - { fprintf(tc, "switch (fld) {\n"); - ncases(tc, q->qid, 0, q->nflds, R12); - fprintf(tc, "\t\tdefault: Uerror"); - fprintf(tc, "(\"too many fields in recv\");\n"); - fprintf(tc, "\t\t}\n"); + { fprintf(fd_tc, "switch (fld) {\n"); + ncases(fd_tc, q->qid, 0, q->nflds, R12); + fprintf(fd_tc, "\t\tdefault: Uerror"); + fprintf(fd_tc, "(\"too many fields in recv\");\n"); + fprintf(fd_tc, "\t\t}\n"); } - fprintf(tc, "\t\tif (done)\n"); + fprintf(fd_tc, "\t\tif (done)\n"); if (q->nslots == 0) - { fprintf(tc, "\t\t{ j = %sQlen - 1;\n", buf0); - fprintf(tc, "\t\t %sQlen = 0;\n", buf0); + { fprintf(fd_tc, "\t\t{ j = %sQlen - 1;\n", buf0); + fprintf(fd_tc, "\t\t %sQlen = 0;\n", buf0); sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid); } else - { fprintf(tc, "\t\t{ j = %sQlen;\n", buf0); - fprintf(tc, "\t\t %sQlen = --j;\n", buf0); - fprintf(tc, "\t\t for (k=slot; kcontents", q->qid); for (j = 0; j < q->nflds; j++) - { fprintf(tc, "\t%s[k].fld%d = \n", buf0, j); - fprintf(tc, "\t\t%s[k+1].fld%d;\n", buf0, j); + { fprintf(fd_tc, "\t%s[k].fld%d = \n", buf0, j); + fprintf(fd_tc, "\t\t%s[k+1].fld%d;\n", buf0, j); } - fprintf(tc, "\t\t }\n"); + fprintf(fd_tc, "\t\t }\n"); } for (j = 0; j < q->nflds; j++) - fprintf(tc, "%s[j].fld%d = 0;\n", buf0, j); - fprintf(tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds); - fprintf(tc, "\tuerror(\"missing pars in receive\");\n"); + fprintf(fd_tc, "%s[j].fld%d = 0;\n", buf0, j); + fprintf(fd_tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds); + fprintf(fd_tc, "\tuerror(\"missing pars in receive\");\n"); /* incompletely received msgs cannot be unrecv'ed */ - fprintf(tc, "\t\t}\n"); - fprintf(tc, "\t\tbreak;\n"); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tbreak;\n"); } - ntimes(tc, 0, 1, Addq5); + ntimes(fd_tc, 0, 1, Addq5); for (q = qtab; q; q = q->nxt) - fprintf(tc, " case %d: j = sizeof(Q%d); break;\n", + fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", q->qid, q->qid); - ntimes(tc, 0, 1, R8b); + ntimes(fd_tc, 0, 1, R8b); + ntimes(fd_th, 0, 1, Proto); /* function prototypes */ - ntimes(th, 0, 1, Proto); /* tag on function prototypes */ - fprintf(th, "void qsend(int, int"); + fprintf(fd_th, "void qsend(int, int"); for (j = 0; j < Mpars; j++) - fprintf(th, ", int"); - fprintf(th, ", int);\n"); + fprintf(fd_th, ", int"); + fprintf(fd_th, ", int);\n\n"); - fprintf(th, "#define Addproc(x) addproc(256, x"); + fprintf(fd_th, "#define Addproc(x,y) addproc(256, y, x"); /* 256 is param outside the range of valid pids */ for (j = 0; j < Npars; j++) - fprintf(th, ", 0"); - fprintf(th, ")\n"); + fprintf(fd_th, ", 0"); + fprintf(fd_th, ")\n"); } diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen1.h /sys/src/cmd/spin/pangen1.h --- /n/sources/plan9/sys/src/cmd/spin/pangen1.h Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen1.h Mon Feb 22 00:00:00 2021 @@ -1,16 +1,12 @@ /***** spin: pangen1.h *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ -/* (c) 2007-2011: additions, enhancements, and bugfixes GJH */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ -static char *Code2a[] = { /* the tail of procedure run() */ +static const char *Code2a[] = { /* the tail of procedure run() */ " if (state_tables)", " { if (dodot) exit(0);", " printf(\"\\nTransition Type: \");", @@ -35,15 +31,26 @@ " channels[i]->body = (uchar *) emalloc(Maxbody * sizeof(char));", " } }", "#endif", + "#ifdef BFS_PAR", + " bfs_setup_mem();", + " #ifdef COLLAPSE", + " /* this must be the very first allocation from the shared heap */", + " #ifdef BFS_SEP_HASH", + " ncomps = (ulong *) emalloc((ulong)((256+2) * sizeof(ulong)));", + " #else", + " ncomps = (ulong *) sh_pre_malloc((ulong)((256+2) * sizeof(ulong)));", + " #endif", + " #endif", + "#endif", " iniglobals(258); /* arg outside range of pids */", - "#if defined(VERI) && !defined(NOREDUCE) && !defined(NP)", + "#if defined(VERI) && !defined(NOREDUCE) && !defined(NP) && !defined(BFS) && !defined(HAS_LTL)", " if (!state_tables", - "#ifdef HAS_CODE", + " #ifdef HAS_CODE", " && !readtrail", - "#endif", - "#if NCORE>1", + " #endif", + " #if NCORE>1", " && core_id == 0", - "#endif", + " #endif", " )", " { printf(\"warning: for p.o. reduction to be valid \");", " printf(\"the never claim must be stutter-invariant\\n\");", @@ -53,25 +60,8 @@ "#endif", " UnBlock; /* disable rendez-vous */", "#ifdef BITSTATE", - " if (udmem)", - " { udmem *= 1024L*1024L;", - " #if NCORE>1", - " if (!readtrail)", - " { void init_SS(unsigned long);", - " init_SS((unsigned long) udmem);", - " } else", - " #endif", - " SS = (uchar *) emalloc(udmem);", - " bstore = bstore_mod;", - " } else", - " #if NCORE>1", - " { void init_SS(unsigned long);", - " init_SS(ONE_L<<(ssize-3));", - " }", - " #else", - " SS = (uchar *) emalloc(ONE_L<<(ssize-3));", - " #endif", - "#else", /* if not BITSTATE */ + " sinit();", + "#else", " hinit();", "#endif", "#if defined(FULLSTACK) && defined(BITSTATE)", @@ -89,7 +79,7 @@ " (void) write(svfd, (uchar *) &vprefix, sizeof(int));", "#endif", "#ifdef VERI", - " Addproc(VERI); /* pid = 0 */", + " Addproc(VERI,1); /* pid = 0, priority 1 */", " #if NCLAIMS>1", " if (claimname != NULL)", " { whichclaim = find_claim(claimname);", @@ -111,23 +101,21 @@ "#endif", " do_the_search();", "#ifdef BITSTATE", - " if (--Nrun > 0 && HASH_CONST[++HASH_NR])", + " if (--Nrun > 0 && HASH_CONST[++HASH_NR])", /* last entry is 0 */ " { printf(\"Run %%d:\\n\", HASH_NR);", " wrap_stats();", " printf(\"\\n\");", - " if (udmem) /* Dillinger 3/2/09 */", " { memset(SS, 0, udmem);", " } else", " { memset(SS, 0, ONE_L<<(ssize-3));", " }", - "#ifdef CNTRSTACK", " memset(LL, 0, ONE_L<<(ssize-3));", "#endif", "#ifdef FULLSTACK", " memset((uchar *) S_Tab, 0, ", - " maxdepth*sizeof(struct H_el *));", + " maxdepth*sizeof(H_el *));", "#endif", " nstates=nlinks=truncs=truncs2=ngrabs = 0;", " nlost=nShadow=hcmp = 0;", @@ -137,70 +125,157 @@ " }", "#endif", "}", - "#ifdef HAS_PROVIDED", - "int provided(int, uchar, int, Trans *);", - "#endif", - - "#if NCORE>1", - "#define GLOBAL_LOCK (0)", - "#ifndef CS_N", - "#define CS_N (256*NCORE)", /* must be a power of 2 */ - "#endif", - - "#ifdef NGQ", /* no global queue */ - "#define NR_QS (NCORE)", - "#define CS_NR (CS_N+1) /* 2^N + 1, nr critical sections */", - "#define GQ_RD GLOBAL_LOCK", /* not really used in this mode */ - "#define GQ_WR GLOBAL_LOCK", /* but just in case... */ - "#define CS_ID (1 + (int) (j1_spin & (CS_N-1))) /* mask: 2^N - 1, zero reserved */", - "#define QLOCK(n) (1+n)", /* overlaps first n zones of hashtable */ - "#else", - "#define NR_QS (NCORE+1)", /* add a global queue */ - "#define CS_NR (CS_N+3)", /* 2 extra locks for global q */ - "#define GQ_RD (1)", /* read access to global q */ - "#define GQ_WR (2)", /* write access to global q */ - "#define CS_ID (3 + (int) (j1_spin & (CS_N-1)))", - "#define QLOCK(n) (3+n)",/* overlaps first n zones of hashtable */ - "#endif", - "", - "void e_critical(int);", - "void x_critical(int);", - "", - "#ifndef SEP_STATE", - " #define enter_critical(w) e_critical(w)", - " #define leave_critical(w) x_critical(w)", - "#else", - " #ifdef NGQ", - " #define enter_critical(w) { if (w < 1+NCORE) e_critical(w); }", - " #define leave_critical(w) { if (w < 1+NCORE) x_critical(w); }", - " #else", - " #define enter_critical(w) { if (w < 3+NCORE) e_critical(w); }", - " #define leave_critical(w) { if (w < 3+NCORE) x_critical(w); }", - " #endif", + "#ifdef HAS_PRIORITY", + "extern int highest_priority(int, short, Trans *);", + "extern int get_priority(int);", + "extern int set_priority(int, int);", + "#endif", + "#ifdef SPIN_HEAP", + "void *", + "spin_malloc(int n) /* reserved for use by Modex generated models */", + "{ char *spin_heap_ptr = &(now.spin_heap[now.spin_heap_n]);", + " if (now.spin_heap_n + n >= sizeof(now.spin_heap))", + " { Uerror(\"spin_heap limit reached\");", + " }", + " now.spin_heap_n += n;", + " return spin_heap_ptr;", + "}", + "void", + "spin_free(void *unused)", + "{ unused; /* ignore */", + "}", "#endif", + "int", + "spin_join(int p, void **unused)", + "{ /* fprintf(stderr, \"join %%d when %%d\\n \", p, now._nr_pr); */", + " return (now._nr_pr <= p); /* process *p has stopped */", + "}", "", "int", - "cpu_printf(const char *fmt, ...)", /* only used with VERBOSE/CHECK/DEBUG */ - "{ va_list args;", - " enter_critical(GLOBAL_LOCK); /* printing */", - " printf(\"cpu%%d: \", core_id);", - " fflush(stdout);", - " va_start(args, fmt);", - " vprintf(fmt, args);", - " va_end(args);", - " fflush(stdout);", - " leave_critical(GLOBAL_LOCK);", - " return 1;", + "spin_mutex_free(int *m)", + "{ return (*m == 0);", "}", - "#else", + "", "int", - "cpu_printf(const char *fmt, ...)", - "{ va_list args;", - " va_start(args, fmt);", - " vprintf(fmt, args);", - " va_end(args);", + "spin_mutex_lock(int *m)", + "{ *m = 1;", " return 1;", "}", + "void", + "spin_mutex_destroy(int *m)", + "{ *m = 0;", + "}", + "void", + "spin_mutex_unlock(int *m)", + "{ *m = 0;", + "}", + "void", + "spin_mutex_init(int *m, void *val)", + "{", + " if (!val)", /* the 2nd arg must be NULL, for now */ + " { *m = 0;", + " } else", + " { Uerror(\"pthread_mutex_init: unsupported non-default init\");", + " }", + "}", + "", + "int", + "spin_cond_wait(int *cond, int *lck)", /*release and re-acquire lock *lck */ + "{ /* this version does not scale very far alas */", + " if (((P0 *)_this)->_pid + 1 >= WS*8)", /* 32 or 64 */ + " { Uerror(\"pid exceeds range supported by pthread_cond_wait\");", + " }", + " if (((*cond)&1) == 0)", /* repeatedly tested, so: */ + " { spin_mutex_unlock(lck);", /* avoid double counting */ + " *cond |= (1<<(((P0 *)_this)->_pid + 1));", + " return 0;", /* blocked, must test again */ + " } else", + " { /* if other processes are already waiting */", + " /* while our wait flag is 0, then they should go first */", + " if (((*cond)&(~(1 | (1<<(((P0 *)_this)->_pid + 1))))) != 0)", + " { spin_mutex_unlock(lck);", + " return 0;", /* wait for the others to go first */ + " }", + " *cond &= ~1;", /* clear the 'go' bit andy wait flag */ + " *cond &= ~(1<<(((P0 *)_this)->_pid + 1));", + " return 1;", /* okay to proceed */ + " }", + "}", + "void", + "spin_cond_signal(int *cond)", + "{", + " if ( ((*cond)&(~1)) != 0 )", /* procs are waiting */ + " { *cond |= 1;", /* set the 'go' bit */ + " }", + "}", + "", + "#ifdef HAS_PROVIDED", + " int provided(int, uchar, int, Trans *);", + "#endif", + "#ifdef BFS_PAR", + " extern void bfs_shutdown(const char *);", + "#endif", + "", + "#if NCORE>1", + " #define GLOBAL_LOCK (0)", + " #ifndef CS_N", + " #define CS_N (256*NCORE)", /* must be a power of 2 */ + " #endif", + + " #ifdef NGQ", /* no global queue */ + " #define NR_QS (NCORE)", + " #define CS_NR (CS_N+1) /* 2^N + 1, nr critical sections */", + " #define GQ_RD GLOBAL_LOCK", /* not really used in this mode */ + " #define GQ_WR GLOBAL_LOCK", /* but just in case... */ + " #define CS_ID (1 + (int) (j1_spin & (CS_N-1))) /* mask: 2^N - 1, zero reserved */", + " #define QLOCK(n) (1+n)", /* overlaps first n zones of hashtable */ + " #else", + " #define NR_QS (NCORE+1)", /* add a global queue */ + " #define CS_NR (CS_N+3)", /* 2 extra locks for global q */ + " #define GQ_RD (1)", /* read access to global q */ + " #define GQ_WR (2)", /* write access to global q */ + " #define CS_ID (3 + (int) (j1_spin & (CS_N-1)))", + " #define QLOCK(n) (3+n)",/* overlaps first n zones of hashtable */ + " #endif", + "", + " #ifndef SEP_STATE", + " #define enter_critical(w) e_critical(w)", + " #define leave_critical(w) x_critical(w)", + " #else", + " #ifdef NGQ", + " #define enter_critical(w) { if (w < 1+NCORE) e_critical(w); }", + " #define leave_critical(w) { if (w < 1+NCORE) x_critical(w); }", + " #else", + " #define enter_critical(w) { if (w < 3+NCORE) e_critical(w); }", + " #define leave_critical(w) { if (w < 3+NCORE) x_critical(w); }", + " #endif", + " #endif", + "", + " int", + " cpu_printf(const char *fmt, ...)", /* only used with VERBOSE/CHECK/DEBUG */ + " { va_list args;", + " enter_critical(GLOBAL_LOCK); /* printing */", + " printf(\"cpu%%d: \", core_id);", + " fflush(stdout);", + " va_start(args, fmt);", + " vprintf(fmt, args);", + " va_end(args);", + " fflush(stdout);", + " leave_critical(GLOBAL_LOCK);", + " return 1;", + " }", + "#else", + " #define enter_critical(w) /* none */", + " #define leave_critical(w) /* none */", + "", + " int", + " cpu_printf(const char *fmt, ...)", + " { va_list args;", + " va_start(args, fmt);", + " vprintf(fmt, args);", + " va_end(args);", + " return 1;", + " }", "#endif", #ifndef PRINTF @@ -234,7 +309,7 @@ " return 1;", "}", #endif - "extern void printm(int);", + "extern void printm(int, char *);", "#ifndef SC", "#define getframe(i) &trail[i];", @@ -245,7 +320,7 @@ "static int stackread;", "static Trail frameptr;", "Trail *", - "getframe(int d)", + "getframe(long d)", "{", " if (CNT1 == CNT2)", " return &trail[d];", @@ -266,28 +341,9 @@ " return &frameptr;", "}", "#endif", - - "#if !defined(SAFETY) && !defined(BITSTATE)", - "#if !defined(FULLSTACK) || defined(MA)", - "#define depth_of(x) A_depth /* an estimate */", - "#else", - "int", - "depth_of(struct H_el *s)", - "{ Trail *t; int d;", - " for (d = 0; d <= A_depth; d++)", - " { t = getframe(d);", - " if (s == t->ostate)", - " return d;", - " }", - " printf(\"pan: cannot happen, depth_of\\n\");", - " return depthfound;", - "}", - "#endif", - "#endif", - "#if NCORE>1", "extern void cleanup_shm(int);", - "volatile unsigned int *search_terminated; /* to signal early termination */", + "volatile uint *search_terminated; /* to signal early termination */", /* * Meaning of bitflags in search_terminated: * 1 set by pan_exit @@ -310,7 +366,11 @@ "#endif", "void", "pan_exit(int val)", - "{ void stop_timer(void);", + "{ void stop_timer(int);", + "#ifdef BFS_PAR", + " extern void bfs_mark_done(int);", + " extern void bfs_drop_shared_memory(void);", + "#endif", " if (signoff)", " { printf(\"--end of output--\\n\");", " }", @@ -327,18 +387,25 @@ " { cleanup_shm(1);", " }", "#endif", + "#ifdef BFS_PAR", + " if (who_am_i != 0)", + " { bfs_mark_done(3); /* stopped */", + " }", + " bfs_drop_shared_memory();", + "#endif", " if (val == 2)", " { val = 0;", - " } else", - " { stop_timer();", " }", + "#ifdef BFS_PAR", + " if (who_am_i == 0)", + "#endif", + " stop_timer(1);", "", "#ifdef C_EXIT", " C_EXIT; /* trust that it defines a fct */", "#endif", " exit(val);", "}", - "#ifdef HAS_CODE", "static char tbuf[2][2048];", "", @@ -375,7 +442,10 @@ "#else", "char * transmognify(char *s) { return s; }", "#endif", - + "" + "char o_cmdline[512];", + "char o_cmdname[128];", + "" "#ifdef HAS_CODE", "void", "add_src_txt(int ot, int tt)", @@ -465,7 +535,7 @@ "FILE *", "findtrail(void)", "{ FILE *fd;", - " char fnm[512], *q;", + " char fnm[1024], *q;", " char MyFile[512];", /* avoid using a non-writable string */ " char MySuffix[16];", " int try_core;", @@ -588,21 +658,88 @@ "}", "", "uchar do_transit(Trans *, short);", + "#ifdef PERMUTED", + "void set_permuted(int);", + "void set_reversed(int);", + "void set_rotated(int);", + "void set_randrot(int);", + "void (*p_reorder)(int) = set_permuted;", + "short p_rotate;", + "#endif", "", "void", "getrail(void)", "{ FILE *fd;", - " char *q;", - " int i, t_id, lastnever=-1; short II;", + " char *q, *pnm;", + " int i, t_id, lastnever = -1; short II;", " Trans *t;", " P0 *z;", - "", + "#ifdef PERMUTED", + " char sbuf[128];", + " memset(sbuf, 0, sizeof(sbuf));", + "#endif", " fd = findtrail(); /* exits if unsuccessful */", " while (fscanf(fd, \"%%ld:%%d:%%d\\n\", &depth, &i, &t_id) == 3)", " { if (depth == -1)", - " printf(\"<<<<>>>>\\n\");", + " { printf(\"<<<<>>>>\\n\");", + " }", + "#ifdef PERMUTED", " if (depth < 0)", - " continue;", + " { switch (depth) {", + " case -5:", + " if (i && !t_reverse)", + " { strcat(sbuf, \"-t_reverse \");", + " }", + " break;", + " case -6:", + " if (i && p_reorder != set_permuted)", + " { strcat(sbuf, \"-p_permute \");", + " } else", + " if (t_id && p_reorder != set_reversed)", + " { strcat(sbuf, \"-p_reverse \");", + " }", + " break;", + " case -7:", + " if (i", + " && (p_reorder != set_rotated || p_rotate != t_id))", + " { char tmp[32];", + " sprintf(tmp, \"-p_rotate%%d \", t_id);", + " strcat(sbuf, tmp);", + " }", + " break;", + " case -8:", + " if (i && p_reorder != set_randrot)", + " { strcat(sbuf, \"-p_randrot \");", + " }", + " if (s_rand != t_id)", /* +1 if before -r */ + " { char tmp[32];", + " sprintf(tmp, \"-RS%%u \", (uint) t_id);", + " strcat(sbuf, tmp);", + " }", + " break;", + " default:", + " continue;", + " }", + " }", + "#endif", + " if (depth < 0)", + " { continue;", + " }", + "#ifdef PERMUTED", + " if (strlen(sbuf) > 0)", + " { char *restart = emalloc(", + " strlen(o_cmdname) + 1 +", + " strlen(sbuf) + 1 + ", + " strlen(o_cmdline) + 1);" + " sprintf(restart, \"%%s %%s %%s\",", + " o_cmdname, o_cmdline, sbuf);", + " if (system(restart) < 0)" + " {", + " fprintf(efd, \"command failed: %%s\\n\", restart);", + " }", + " exit(1);", + " }", + "#endif", " if (i > now._nr_pr)", " { printf(\"pan: Error, proc %%d invalid pid \", i);", " printf(\"transition %%d\\n\", t_id);", @@ -635,11 +772,13 @@ " q = transmognify(t->tp);", " if (gui) simvals[0] = \'\\0\';", - " this = pptr(II);", + " pnm = procname[z->_t];", + " _this = pptr(II);", " trpt->tau |= 1;", /* timeout always possible */ " if (!do_transit(t, II))", " { if (onlyproc >= 0 && II != onlyproc)", " goto moveon;", + " if (!verbose) break;", " printf(\"pan: error, next transition UNEXECUTABLE on replay\\n\");", " printf(\" most likely causes: missing c_track statements\\n\");", " printf(\" or illegal side-effects in c_expr statements\\n\");", @@ -649,7 +788,7 @@ " goto moveon;", " if (verbose)", - " { printf(\"%%3ld: proc %%2d (%%s) \", depth, II, procname[z->_t]);", + " { printf(\"%%3ld: proc %%2d (%%s) \", depth, II, pnm);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", @@ -686,12 +825,16 @@ " { printf(\"%%ld: \", depth);", " for (i = 0; i < II; i++)", " printf(\"\\t\\t\");", - " printf(\"%%s(%%d):\", procname[z->_t], II);", + " printf(\"%%s(%%d):\", pnm, II);", " printf(\"[%%s]\\n\", q?q:\"\");", " } else if (!silent)", - " { if (strlen(simvals) > 0) {", + " {", + "#ifdef MYSTEP", + " #include \"mystep.c\"", + "#endif", + " if (strlen(simvals) > 0) {", " printf(\"%%3ld: proc %%2d (%%s)\", ", - " depth, II, procname[z->_t]);", + " depth, II, pnm);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", " { printf(\" %%s:%%d \",", @@ -702,7 +845,7 @@ " printf(\"(state %%d)\t[values: %%s]\\n\", z->_p, simvals);", " }", " printf(\"%%3ld: proc %%2d (%%s)\", ", - " depth, II, procname[z->_t]);", + " depth, II, pnm);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", " { printf(\" %%s:%%d \",", @@ -730,23 +873,6 @@ " return -1;", "}", "", - "#if !defined(HASH64) && !defined(HASH32)", - " #if WS>4", - " #define HASH64", - " #else", - " #define HASH32", - " #endif", - "#endif", - "#if defined(HASH32) && defined(SAFETY) && !defined(SFH) && !defined(SPACE)", - " #define SFH", - "#endif", - "#if defined(SFH) && (defined(BITSTATE) || defined(COLLAPSE) || defined(HC) || defined(HASH64) || defined(MA))", - " #undef SFH", /* need 2 hash fcts, for which Jenkins is best */ - "#endif", /* or a 64 bit hash, which we dont have for SFH */ - /* for MA, it would slow down the search to use a larger sv then possible */ - "#if defined(SFH) && !defined(NOCOMP)", - " #define NOCOMP /* go for speed */", - "#endif", "#if NCORE>1 && !defined(GLOB_HEAP)", " #define SEP_HEAP /* version 5.1.2 */", "#endif", @@ -754,11 +880,14 @@ "#ifdef BITSTATE", "int", "bstore_mod(char *v, int n) /* hasharray size not a power of two */", - "{ unsigned long x, y;", - " unsigned int i = 1;", - "", - " d_hash((uchar *) v, n); /* sets j3, j4, K1, K2 */", - " x = K1; y = j3;", /* was K2 before 5.1.1 */ + "{ ulong x, y;", + " uint i = 1;", + "#if defined(MURMUR) && (WS==8)", + " m_hash((uchar *) v, n); /* bstore_mod - sets j3_spin, j4_spin, K1, K2 */", + "#else", + " d_hash((uchar *) v, n); /* bstore_mod - sets j3_spin, j4_spin, K1, K2 */", + "#endif", + " x = K1; y = j3_spin;", /* was K2 before 5.1.1 */ " for (;;)", " { if (!(SS[x%%udmem]&(1< 0)", - " { sprintf(fnm, \"%%s%%d.%%s\",", + " {", + "#ifdef PUTPID", + " sprintf(fnm, \"%%s_%%s_%%d_%%d.%%s\",", + " MyFile, progname, getpid(), Nr_Trails-1, tprefix);", + "#else", + " sprintf(fnm, \"%%s%%d.%%s\",", " MyFile, Nr_Trails-1, tprefix);", + "#endif", " } else", " {", "#ifdef PUTPID", @@ -905,6 +1043,9 @@ " memcpy(processes[i]->body, b, processes[i]->psize);", "#ifdef TRIX_RIX", " ((P0 *)pptr(i))->_pid = i;", + " if (BASE > 0 && h > 0)", + " { ((P0 *)pptr(i))->_pid -= BASE;", + " }", "#endif", "#ifndef BFS", " processes[i]->modified = 1; /* re-populate */", @@ -922,104 +1063,61 @@ "#endif\n", "#ifdef BFS", /* breadth-first search */ - "#define Q_PROVISO", - " #ifndef INLINE_REV", - " #define INLINE_REV", - " #endif", - "", - "typedef struct SV_Hold {", - " State *sv;", - " int sz;", - " struct SV_Hold *nxt;", - "} SV_Hold;", - "", - "typedef struct EV_Hold {", - " char *sv;", /* Mask */ - " int sz;", /* vsize */ - " int nrpr;", - " int nrqs;", - "#ifndef TRIX", - " char *po, *qo;", - " char *ps, *qs;", - "#endif", - " struct EV_Hold *nxt;", - "} EV_Hold;", - "", - "typedef struct BFS_Trail {", - " Trail *frame;", - " SV_Hold *onow;", - " EV_Hold *omask;", - "#ifdef Q_PROVISO", - " struct H_el *lstate;", - "#endif", - " short boq;", - "#ifdef VERBOSE", - " unsigned long nr;", - "#endif", - " struct BFS_Trail *nxt;", - "} BFS_Trail;", - "", - "BFS_Trail *bfs_trail, *bfs_bot, *bfs_free;", - "", - "SV_Hold *svhold, *svfree;", - "", - "#ifdef BFS_DISK", - " #ifndef BFS_LIMIT", - " #define BFS_LIMIT 100000", - " #endif", - " #ifndef BFS_DSK_LIMIT", - " #define BFS_DSK_LIMIT 1000000", - " #endif", - " #if defined(WIN32) || defined(WIN64)", - " #define RFLAGS (O_RDONLY|O_BINARY)", - " #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC|O_BINARY)", + " #ifndef BFS_PAR", + " BFS_State *bfs_trail, *bfs_bot, *bfs_free;", + " SV_Hold *svfree;", " #else", - " #define RFLAGS (O_RDONLY)", - " #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC)", + " static ulong bfs_pre_allocated;", + " #endif", + " #ifdef BFS_DISK", + " #ifndef BFS_LIMIT", + " #define BFS_LIMIT 100000", + " #endif", + " #ifndef BFS_DSK_LIMIT", + " #define BFS_DSK_LIMIT 1000000", + " #endif", + " #if defined(WIN32) || defined(WIN64)", + " #define RFLAGS (O_RDONLY|O_BINARY)", + " #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC|O_BINARY)", + " #define RWFLAGS (O_RDWR|O_BINARY)", + " #else", + " #define RFLAGS (O_RDONLY)", + " #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC)", + " #define RWFLAGS (O_RDWR)", + " #endif", + "", + " long bfs_size_limit;", + " int bfs_dsk_write = -1;", + " int bfs_dsk_read = -1;", + " long bfs_dsk_writes, bfs_dsk_reads;", + " int bfs_dsk_seqno_w, bfs_dsk_seqno_r;", " #endif", - - "long bfs_size_limit;", - "int bfs_dsk_write = -1;", - "int bfs_dsk_read = -1;", - "long bfs_dsk_writes, bfs_dsk_reads;", - "int bfs_dsk_seqno_w, bfs_dsk_seqno_r;", - "#endif", "", "uchar do_reverse(Trans *, short, uchar);", "void snapshot(void);", - "", + "#if 0", "void", "select_claim(int x) /* ignored in BFS mode */", "{ if (verbose)", " { printf(\"select %%d (ignored)\\n\", x);", " }", "}", + "#endif", + "Trail *ntrpt;", "", + "#ifndef BFS_PAR", "SV_Hold *", "getsv(int n)", - "{ SV_Hold *h = (SV_Hold *) 0, *oh;", - "", - " oh = (SV_Hold *) 0;", - " for (h = svfree; h; oh = h, h = h->nxt)", - " { if (n == h->sz)", - " { if (!oh)", - " svfree = h->nxt;", - " else", - " oh->nxt = h->nxt;", - " h->nxt = (SV_Hold *) 0;", - " break;", - " }", - " if (n < h->sz)", - " { h = (SV_Hold *) 0;", - " break;", - " }", - " /* else continue */", - " }", + "{ SV_Hold *h;", "", - " if (!h)", + " if (svfree && n <= svfree->sz)", + " { h = svfree;", + " svfree = h->nxt;", + " h->nxt = (SV_Hold *) 0;", + " } else", " { h = (SV_Hold *) emalloc(sizeof(SV_Hold));", " h->sz = n;", - "#ifdef BFS_DISK", + " #ifdef BFS_DISK", " if (bfs_size_limit >= BFS_LIMIT)", " { h->sv = (State *) 0; /* means: read disk */", " bfs_dsk_writes++; /* count */", @@ -1042,7 +1140,7 @@ " return h; /* no memcpy */", " }", /* else */ " bfs_size_limit++;", - "#endif", + " #endif", " h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n);", " }", "", @@ -1057,22 +1155,24 @@ "", " for (h = kept; h; h = h->nxt)", " if (n == h->sz", + "#if !defined(NOCOMP) && !defined(HC)", " && (memcmp((char *) Mask, (char *) h->sv, n) == 0)", + "#endif", " && (now._nr_pr == h->nrpr)", " && (now._nr_qs == h->nrqs)", - "#ifdef TRIX", + " #ifdef TRIX", " )", - "#else", - " #if VECTORSZ>32000", + " #else", + " #if VECTORSZ>32000", " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(int)) == 0)", " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(int)) == 0)", - " #else", + " #else", " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(short)) == 0)", " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(short)) == 0)", - " #endif", + " #endif", " && (memcmp((char *) proc_skip, (char *) h->ps, now._nr_pr * sizeof(uchar)) == 0)", " && (memcmp((char *) q_skip, (char *) h->qs, now._nr_qs * sizeof(uchar)) == 0))", - "#endif", + " #endif", " break;", " if (!h)", " { h = (EV_Hold *) emalloc(sizeof(EV_Hold));", @@ -1081,31 +1181,33 @@ " h->nrqs = now._nr_qs;", "", " h->sv = (char *) emalloc(n * sizeof(char));", + "#if !defined(NOCOMP) && !defined(HC)", " memcpy((char *) h->sv, (char *) Mask, n);", - "#ifndef TRIX", + "#endif", + " #ifndef TRIX", " if (now._nr_pr > 0)", " { h->ps = (char *) emalloc(now._nr_pr * sizeof(int));", " memcpy((char *) h->ps, (char *) proc_skip, now._nr_pr * sizeof(uchar));", - " #if VECTORSZ>32000", + " #if VECTORSZ>32000", " h->po = (char *) emalloc(now._nr_pr * sizeof(int));", " memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(int));", - " #else", + " #else", " h->po = (char *) emalloc(now._nr_pr * sizeof(short));", " memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(short));", - " #endif", + " #endif", " }", " if (now._nr_qs > 0)", " { h->qs = (char *) emalloc(now._nr_qs * sizeof(int));", " memcpy((char *) h->qs, (char *) q_skip, now._nr_qs * sizeof(uchar));", - " #if VECTORSZ>32000", + " #if VECTORSZ>32000", " h->qo = (char *) emalloc(now._nr_qs * sizeof(int));", " memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(int));", - " #else", + " #else", " h->qo = (char *) emalloc(now._nr_qs * sizeof(short));", " memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(short));", - " #endif", + " #endif", " }", - "#endif", + " #endif", " h->nxt = kept;", " kept = h;", " }", @@ -1118,7 +1220,7 @@ "", " oh = (SV_Hold *) 0;", " for (h = svfree; h; oh = h, h = h->nxt)", - " { if (h->sz >= p->sz)", + " { if (p->sz >= h->sz)", " break;", " }", " if (!oh)", @@ -1130,16 +1232,16 @@ " }", "}", "", - "BFS_Trail *", + "BFS_State *", "get_bfs_frame(void)", - "{ BFS_Trail *t;", + "{ BFS_State *t;", "", " if (bfs_free)", " { t = bfs_free;", " bfs_free = bfs_free->nxt;", - " t->nxt = (BFS_Trail *) 0;", + " t->nxt = (BFS_State *) 0;", " } else", - " { t = (BFS_Trail *) emalloc(sizeof(BFS_Trail));", + " { t = (BFS_State *) emalloc(sizeof(BFS_State));", " }", " t->frame = (Trail *) emalloc(sizeof(Trail));", /* always new */ " /* new because we keep a ptr to the frame of parent states */", @@ -1149,38 +1251,42 @@ "", "void", "push_bfs(Trail *f, int d)", - "{ BFS_Trail *t;", + "{ BFS_State *t;", "", " t = get_bfs_frame();", " memcpy((char *)t->frame, (char *)f, sizeof(Trail));", " t->frame->o_tt = d; /* depth */", "", " t->boq = boq;", - "#ifdef TRIX", + " #ifdef TRIX", " sv_populate();", - "#endif", + " #endif", " t->onow = getsv(vsize);", " t->omask = getsv_mask(vsize);", - "#if defined(FULLSTACK) && defined(Q_PROVISO)", - " t->lstate = Lstate;", - "#endif", + " #if defined(FULLSTACK) && defined(Q_PROVISO)", + " t->lstate = Lstate; /* bfs */", + " #endif", " if (!bfs_bot)", " { bfs_bot = bfs_trail = t;", " } else", " { bfs_bot->nxt = t;", " bfs_bot = t;", " }", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " t->nr = nstates;", - "#endif", - "#ifdef CHECK", - " printf(\"PUSH %%u (depth %%d, nr %%d)\\n\", t->frame, d, t->nr);", - "#endif", + " #endif", + " #ifdef CHECK", + " #ifdef VERBOSE", + " printf(\"PUSH %%lu (depth %%d, nr %%lu)\\n\", (ulong) t->frame, d, t->nr);", + " #else", + " printf(\"PUSH %%lu (depth %%d)\\n\", (ulong) t->frame, d);", + " #endif", + " #endif", "}", "", "Trail *", "pop_bfs(void)", - "{ BFS_Trail *t;", + "{ BFS_State *t;", "", " if (!bfs_trail)", " { return (Trail *) 0;", @@ -1188,19 +1294,19 @@ " t = bfs_trail;", " bfs_trail = t->nxt;", " if (!bfs_trail)", - " { bfs_bot = (BFS_Trail *) 0;", + " { bfs_bot = (BFS_State *) 0;", " }", - "#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)", - " if (t->lstate)", - " { t->lstate->tagged = 0;", + " #if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)", + " if (t->lstate) /* bfs */", + " { t->lstate->tagged = 0; /* bfs */", " }", - "#endif", + " #endif", " t->nxt = bfs_free;", " bfs_free = t;", "", " vsize = t->onow->sz;", " boq = t->boq;", - "#ifdef BFS_DISK", + " #ifdef BFS_DISK", " if (t->onow->sv == (State *) 0)", " { char dsk_nm[32];", " bfs_dsk_reads++; /* count */", @@ -1220,136 +1326,145 @@ " if (read(bfs_dsk_read, (char *) &now, vsize) != vsize)", " { Uerror(\"bad bfs disk file read\");", " }", - " #ifndef NOVSZ", + " #ifndef NOVSZ", " if (now._vsz != vsize)", " { Uerror(\"disk read vsz mismatch\");", " }", - " #endif", + " #endif", " } else", - "#endif", + " #endif", " { memcpy((uchar *) &now, (uchar *) t->onow->sv, vsize);", + " #ifndef NOVSZ", + " vsize = now._vsz;", + " #endif", " }", + "#if !defined(NOCOMP) && !defined(HC)", " memcpy((uchar *) Mask, (uchar *) t->omask->sv, vsize);", - "#ifdef TRIX", - " re_populate();", - "#else", + "#endif", + " #ifdef TRIX", + " re_populate();", + " #else", " if (now._nr_pr > 0)", - " #if VECTORSZ>32000", + " #if VECTORSZ>32000", " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(int));", - " #else", + " #else", " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(short));", - " #endif", + " #endif", " memcpy((char *)proc_skip, (char *)t->omask->ps, now._nr_pr * sizeof(uchar));", " }", " if (now._nr_qs > 0)", - " #if VECTORSZ>32000", + " #if VECTORSZ>32000", " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(int));", - " #else", + " #else", " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(short));", - " #endif", + " #endif", " memcpy((uchar *)q_skip, (uchar *)t->omask->qs, now._nr_qs * sizeof(uchar));", " }", - "#endif", - "#ifdef BFS_DISK", + " #endif", + " #ifdef BFS_DISK", " if (t->onow->sv != (State *) 0)", - "#endif", + " #endif", " { freesv(t->onow); /* omask not freed */", " }", - "#ifdef CHECK", - " printf(\"POP %%u (depth %%d, nr %%d)\\n\", t->frame, t->frame->o_tt, t->nr);", - "#endif", + " #ifdef CHECK", + " #ifdef VERBOSE", + " printf(\"POP %%lu (depth %%d, nr %%lu)\\n\", (ulong) t->frame, t->frame->o_tt, t->nr);", + " #else", + " printf(\"POP %%lu (depth %%d)\\n\", (ulong) t->frame, t->frame->o_tt);", + " #endif", + " #endif", " return t->frame;", "}", "", "void", "store_state(Trail *ntrpt, int shortcut, short oboq)", "{", - "#ifdef VERI", + " #ifdef VERI", " Trans *t2 = (Trans *) 0;", " uchar ot; int tt, E_state;", - " uchar o_opm = trpt->o_pm, *othis = this;", + " uchar o_opm = trpt->o_pm, *othis = _this;", "", " if (shortcut)", " {", - " #ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"claim: shortcut\\n\");", - " #endif", + " #endif", " goto store_it; /* no claim move */", " }", "", - " this = pptr(0); /* 0 = never claim */", + " _this = pptr(0); /* 0 = never claim */", " trpt->o_pm = 0;", /* to interpret else in never claim */ "", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", "", - " #ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " E_state = 0;", - " #endif", + " #endif", " for (t2 = trans[ot][tt]; t2; t2 = t2?t2->nxt:(Trans *)0)", " {", - " #ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " if (E_state > 0 && E_state != t2->e_trans)", " { break;", " }", - " #endif", + " #endif", " if (do_transit(t2, 0))", " {", - " #ifdef VERBOSE", + " #ifdef VERBOSE", " if (!reached[ot][t2->st])", " printf(\"depth: %%d -- claim move from %%d -> %%d\\n\",", - " trpt->o_tt, ((P0 *)this)->_p, t2->st);", - " #endif", - " #ifdef HAS_UNLESS", + " trpt->o_tt, ((P0 *)_this)->_p, t2->st);", + " #endif", + " #ifdef HAS_UNLESS", " E_state = t2->e_trans;", - " #endif", + " #endif", " if (t2->st > 0)", - " { ((P0 *)this)->_p = t2->st;", + " { ((P0 *)_this)->_p = t2->st;", " reached[ot][t2->st] = 1;", - " #ifndef NOCLAIM", + " #ifndef NOCLAIM", " if (stopstate[ot][t2->st])", " { uerror(\"end state in claim reached\");", " }", - " #endif", + " #endif", " }", " if (now._nr_pr == 0) /* claim terminated */", " uerror(\"end state in claim reached\");", "", - " #ifdef PEG", + " #ifdef PEG", " peg[t2->forw]++;", - " #endif", + " #endif", " trpt->o_pm |= 1;", " if (t2->atom&2)", " { Uerror(\"atomic in claim not supported in BFS\");", " }", "store_it:", "", - "#endif", /* VERI */ + " #endif", /* VERI */ "", - "#if defined(BITSTATE)", - " if (!bstore((char *)&now, vsize))", - "#elif defined(MA)", - " if (!gstore((char *)&now, vsize, 0))", - "#else", - " if (!hstore((char *)&now, vsize))", - "#endif", + " #if defined(BITSTATE)", + " if (!b_store((char *)&now, vsize))", + " #elif defined(MA)", + " if (!g_store((char *)&now, vsize, 0))", + " #else", + " if (!h_store((char *)&now, vsize))", + " #endif", " { static long sdone = (long) 0; long ndone;", " nstates++;", - "#ifndef NOREDUCE", + " #ifndef NOREDUCE", " trpt->tau |= 64;", /* bfs: succ definitely outside stack */ - "#endif", - " ndone = (unsigned long) (nstates/(freq));", + " #endif", + " ndone = (ulong) (nstates/(freq));", " if (ndone != sdone && mreached%%10 != 0)", " { snapshot();", " sdone = ndone;", - "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", + " #if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", " if (nstates > ((double)(1<<(ssize+1))))", " { void resize_hashtable(void);", " resize_hashtable();", " }", - "#endif", + " #endif", " }", - "#if SYNC", + " #if SYNC", " if (boq != -1)", " midrv++;", " else if (oboq != -1)", @@ -1357,42 +1472,40 @@ " x = (Trail *) trpt->ostate; /* pre-rv state */", " if (x) x->o_pm |= 4; /* mark success */", " }", - "#endif", + " #endif", " push_bfs(ntrpt, trpt->o_tt+1);", " } else", " { truncs++;", - "#if !defined(NOREDUCE) && defined(FULLSTACK) && defined(Q_PROVISO)", - " #if !defined(BITSTATE)", + " #if defined(Q_PROVISO) && !defined(NOREDUCE) && defined(FULLSTACK)", + " #if !defined(BITSTATE)", " if (Lstate && Lstate->tagged)", " { trpt->tau |= 64;", " }", - " #else", + " #else", " if (trpt->tau&32)", - " { BFS_Trail *tprov;", + " { BFS_State *tprov;", " for (tprov = bfs_trail; tprov; tprov = tprov->nxt)", " if (tprov->onow->sv != (State *) 0", " && memcmp((uchar *)&now, (uchar *)tprov->onow->sv, vsize) == 0)", " { trpt->tau |= 64;", " break; /* state is in queue */", " } }", + " #endif", " #endif", - "#endif", " }", - "#ifdef VERI", - " ((P0 *)this)->_p = tt; /* reset claim */", + " #ifdef VERI", + " ((P0 *)_this)->_p = tt; /* reset claim */", " if (t2)", " do_reverse(t2, 0, 0);", " else", " break;", " } }", - " this = othis;", + " _this = othis;", " trpt->o_pm = o_opm;", - "#endif", + " #endif", "}", "", - "Trail *ntrpt;", /* 4.2.8 */ - "", "void", "bfs(void)", "{ Trans *t; Trail *otrpt, *x;", @@ -1402,7 +1515,7 @@ " short oboq = boq;", "", " ntrpt = (Trail *) emalloc(sizeof(Trail));", - " trpt->ostate = (struct H_el *) 0;", + " trpt->ostate = (H_el *) 0;", " trpt->tau = 0;", "", " trpt->o_tt = -1;", @@ -1410,41 +1523,41 @@ "", " while ((otrpt = pop_bfs())) /* also restores now */", " { memcpy((char *) trpt, (char *) otrpt, sizeof(Trail));", - "#if defined(C_States) && (HAS_TRACK==1)", + " #if defined(C_States) && (HAS_TRACK==1)", " c_revert((uchar *) &(now.c_state[0]));", - "#endif", + " #endif", " if (trpt->o_pm & 4)", " {", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"Revisit of atomic not needed (%%d)\\n\",", " trpt->o_pm);", /* at least 1 rv succeeded */ - "#endif", + " #endif", " continue;", " }", - "#ifndef NOREDUCE", + " #ifndef NOREDUCE", " nps = 0;", - "#endif", + " #endif", " if (trpt->o_pm == 8)", " { revrv++;", " if (trpt->tau&8)", " {", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"Break atomic (pm:%%d,tau:%%d)\\n\",", " trpt->o_pm, trpt->tau);", - "#endif", + " #endif", " trpt->tau &= ~8;", " }", - "#ifndef NOREDUCE", + " #ifndef NOREDUCE", " else if (trpt->tau&32)", /* was a preselected move */ " {", - " #ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"Void preselection (pm:%%d,tau:%%d)\\n\",", " trpt->o_pm, trpt->tau);", - " #endif", + " #endif", " trpt->tau &= ~32;", " nps = 1; /* no preselection in repeat */", " }", - "#endif", + " #endif", " }", " trpt->o_pm &= ~(4|8);", " if (trpt->o_tt > mreached)", @@ -1456,13 +1569,13 @@ " if (depth >= maxdepth)", " {", - "#if SYNC", + " #if SYNC", " Trail *x;", " if (boq != -1)", " { x = (Trail *) trpt->ostate;", " if (x) x->o_pm |= 4; /* not failing */", " }", - "#endif", + " #endif", " truncs++;", " if (!warned)", " { warned = 1;", @@ -1473,13 +1586,13 @@ " }", " continue;", " }", - "#ifndef NOREDUCE", + " #ifndef NOREDUCE", " if (boq == -1 && !(trpt->tau&8) && nps == 0)", " for (II = now._nr_pr-1; II >= BASE; II -= 1)", " {", - "Pickup: this = pptr(II);", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", + "Pickup: _this = pptr(II);", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", " if (trans[ot][tt]->atom & 8)", /* safe */ " { t = trans[ot][tt];", " if (t->qu[0] != 0)", @@ -1490,14 +1603,14 @@ " }", " From = To = II;", " trpt->tau |= 32; /* preselect marker */", - " #ifdef DEBUG", + " #ifdef DEBUG", " printf(\"%%3ld: proc %%d PreSelected (tau=%%d)\\n\", ", " depth, II, trpt->tau);", - " #endif", + " #endif", " goto MainLoop;", " } }", " trpt->tau &= ~32;", /* not preselected */ - "#endif", /* if !NOREDUCE */ + " #endif", /* if !NOREDUCE */ "Repeat:", " if (trpt->tau&8) /* atomic */", " { From = To = (short ) trpt->pr;", @@ -1510,36 +1623,44 @@ " _n = _m = 0;", " for (II = From; II >= To; II -= 1)", " {", - " this = pptr(II);", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", - "#if SYNC", + " _this = pptr(II);", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", + " #if SYNC", " /* no rendezvous with same proc */", " if (boq != -1 && trpt->pr == II)", " { continue;", " }", - "#endif", + " #endif", " ntrpt->pr = (uchar) II;", " ntrpt->st = tt; ", " trpt->o_pm &= ~1; /* no move yet */", - "#ifdef EVENT_TRACE", + " #ifdef EVENT_TRACE", " trpt->o_event = now._event;", - "#endif", - "#ifdef HAS_PROVIDED", + " #endif", + + " #ifdef HAS_PRIORITY", + " if (!highest_priority(((P0 *)_this)->_pid, II, t))", + " { continue;", + " }", + " #else", + " #ifdef HAS_PROVIDED", " if (!provided(II, ot, tt, t))", " { continue;", " }", - "#endif", - "#ifdef HAS_UNLESS", + " #endif", + " #endif", + + " #ifdef HAS_UNLESS", " E_state = 0;", - "#endif", + " #endif", " for (t = trans[ot][tt]; t; t = t->nxt)", " {", - "#ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " if (E_state > 0", " && E_state != t->e_trans)", " break;", - "#endif", + " #endif", " ntrpt->o_t = t;", "", " oboq = boq;", @@ -1549,81 +1670,79 @@ "", " trpt->o_pm |= 1; /* we moved */", " (trpt+1)->o_m = _m; /* for unsend */", - "#ifdef PEG", + " #ifdef PEG", " peg[t->forw]++;", - "#endif", - "#ifdef CHECK", + " #endif", + " #ifdef CHECK", " printf(\"%%3ld: proc %%d exec %%d, \",", " depth, II, t->forw);", " printf(\"%%d to %%d, %%s %%s %%s\",", " tt, t->st, t->tp,", " (t->atom&2)?\"atomic\":\"\",", " (boq != -1)?\"rendez-vous\":\"\");", - " #ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " if (t->e_trans)", " printf(\" (escapes to state %%d)\", t->st);", - " #endif", + " #endif", " printf(\" %%saccepting [tau=%%d]\\n\",", " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);", - "#endif", - "#ifdef HAS_UNLESS", + " #endif", + " #ifdef HAS_UNLESS", " E_state = t->e_trans;", - " #if SYNC>0", + " #if SYNC>0", " if (t->e_trans > 0 && (boq != -1 /* || oboq != -1 */))", " { fprintf(efd, \"error:\ta rendezvous stmnt in the escape clause\\n\");", " fprintf(efd, \"\tof an unless stmnt is not compatible with -DBFS\\n\");", " pan_exit(1);", " }", + " #endif", " #endif", - "#endif", " if (t->st > 0)", - " { ((P0 *)this)->_p = t->st;", + " { ((P0 *)_this)->_p = t->st;", " }", "", - " /* ptr to pred: */ ntrpt->ostate = (struct H_el *) otrpt;", + " /* ptr to pred: */ ntrpt->ostate = (H_el *) otrpt;", " ntrpt->st = tt;", " if (boq == -1 && (t->atom&2)) /* atomic */", " ntrpt->tau = 8; /* record for next move */", " else", " ntrpt->tau = 0;", " store_state(ntrpt, (boq != -1 || (t->atom&2)), oboq);", - "#ifdef EVENT_TRACE", + " #ifdef EVENT_TRACE", " now._event = trpt->o_event;", - "#endif", + " #endif", " /* undo move and continue */", " trpt++; /* this is where ovals and ipt are set */", " do_reverse(t, II, _m); /* restore now. */", " trpt--;", - "#ifdef CHECK", - " #if NCORE>1", + " #ifdef CHECK", " enter_critical(GLOBAL_LOCK); /* verbose mode */", + " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", - " #endif", - " printf(\"%%3d: proc %%d \", depth, II);", + " #endif", + " printf(\"%%3lu: proc %%d \", depth, II);", " printf(\"reverses %%d, %%d to %%d,\",", " t->forw, tt, t->st);", - " printf(\" %%s [abit=%%d,adepth=%%d,\",", + " printf(\" %%s [abit=%%d,adepth=%%ld,\",", " t->tp, now._a_t, A_depth);", " printf(\"tau=%%d,%%d]\\n\",", " trpt->tau, (trpt-1)->tau);", - " #if NCORE>1", " leave_critical(GLOBAL_LOCK);", " #endif", - "#endif", " reached[ot][t->st] = 1;", " reached[ot][tt] = 1;", "", - " ((P0 *)this)->_p = tt;", + " ((P0 *)_this)->_p = tt;", " _n |= _m;", " } }", - "#ifndef NOREDUCE", /* with PO */ + " #ifndef NOREDUCE", /* with PO */ " /* preselected - no succ definitely outside stack */", " if ((trpt->tau&32) && !(trpt->tau&64))", " { From = now._nr_pr-1; To = BASE;", - " #ifdef DEBUG", + " #ifdef DEBUG", " cpu_printf(\"%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", " depth, II+1, (int) _n, trpt->tau);", - " #endif", + " #endif", " _n = 0; trpt->tau &= ~32;", " if (II >= BASE)", " { goto Pickup;", @@ -1631,14 +1750,14 @@ " goto MainLoop;", " }", " trpt->tau &= ~(32|64);", - "#endif", /* PO */ + " #endif", /* PO */ " if (_n != 0)", " { continue;", " }", - "#ifdef DEBUG", + " #ifdef DEBUG", " printf(\"%%3ld: no move [II=%%d, tau=%%d, boq=%%d, _nr_pr=%%d]\\n\",", " depth, II, trpt->tau, boq, now._nr_pr);", - "#endif", + " #endif", " if (boq != -1)", " { failedrv++;", " x = (Trail *) trpt->ostate; /* pre-rv state */", @@ -1647,50 +1766,51 @@ " }", " if ((x->tau&8) || (x->tau&32)) /* break atomic or preselect at parent */", " { x->o_pm |= 8; /* mark failure */", - " this = pptr(otrpt->pr);", - "#ifdef VERBOSE", + " _this = pptr(otrpt->pr);", + " #ifdef VERBOSE", " printf(\"\\treset state of %%d from %%d to %%d\\n\",", - " otrpt->pr, ((P0 *)this)->_p, otrpt->st);", - "#endif", - " ((P0 *)this)->_p = otrpt->st;", + " otrpt->pr, ((P0 *)_this)->_p, otrpt->st);", + " #endif", + " ((P0 *)_this)->_p = otrpt->st;", " unsend(boq); /* retract rv offer */", " boq = -1;", " push_bfs(x, x->o_tt);", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"failed rv, repush with %%d\\n\", x->o_pm);", - "#endif", + " #endif", " }", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " else", " { printf(\"failed rv, tau at parent: %%d\\n\", x->tau);", " }", - "#endif", + " #endif", " } else if (now._nr_pr > 0)", " {", " if ((trpt->tau&8)) /* atomic */", " { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */", - "#ifdef DEBUG", + " #ifdef DEBUG", " printf(\"%%3ld: atomic step proc %%d blocks\\n\",", " depth, II+1);", - "#endif", + " #endif", " goto Repeat;", " }", "", " if (!(trpt->tau&1)) /* didn't try timeout yet */", " { trpt->tau |= 1;", - "#ifdef DEBUG", - " printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #ifdef DEBUG", + " printf(\"%%ld: timeout\\n\", depth);", + " #endif", " goto MainLoop;", " }", - "#ifndef VERI", + " #ifndef VERI", " if (!noends && !a_cycles && !endstate())", " { uerror(\"invalid end state\");", " }", - "#endif", + " #endif", " } }", "}", + "#endif", /* !BFS_PAR */ "", "void", "putter(Trail *trpt, int fd)", @@ -1712,29 +1832,35 @@ "}", "", "void", - "nuerror(char *str)", + "n_ewrite(int fd, char *s, int n)", + "{ if (write(fd, s, strlen(s)) != strlen(s))", + " { printf(\"pan: error writing %%s\\n\", fnm);", + " pan_exit(1);", + " }", + "}", + "", + "void", + "nuerror(void)", "{ int fd = make_trail();", " int j;", "", " if (fd < 0) return;", - "#ifdef VERI", - " sprintf(snap, \"-2:%%d:-2\\n\", (uchar) ((P0 *)pptr(0))->_t);", - " (void) write(fd, snap, strlen(snap));", - "#endif", - "#ifdef MERGED", - " sprintf(snap, \"-4:-4:-4\\n\");", - " (void) write(fd, snap, strlen(snap));", - "#endif", + " #ifdef VERI", + " sprintf(snap, \"-2:%%d:-2\\n\", (uchar) ((P0 *)pptr(0))->_t);", + " n_ewrite(fd, snap, strlen(snap));", + " #endif", + " #ifdef MERGED", + " sprintf(snap, \"-4:-4:-4\\n\");", + " n_ewrite(fd, snap, strlen(snap));", + " #endif", " trcnt = 1;", " putter(trpt, fd);", " if (ntrpt->o_t)", /* 4.2.8 -- Alex example, missing last transition */ " { sprintf(snap, \"%%d:%%d:%%d\\n\",", " trcnt++, ntrpt->pr, ntrpt->o_t->t_id);", " j = strlen(snap);", - " if (write(fd, snap, j) != j)", - " { printf(\"pan: error writing %%s\\n\", fnm);", - " pan_exit(1);", - " } }", + " n_ewrite(fd, snap, j);", + " }", " close(fd);", " if (errors >= upto && upto != 0)", " { wrapup();", @@ -1744,7 +1870,7 @@ 0, }; -static char *Code2d[] = { +static const char *Code2d[] = { "clock_t start_time;", "#if NCORE>1", "clock_t crash_stamp;", @@ -1753,6 +1879,11 @@ "struct tms start_tm;", "#endif", "", + "#if SYNC", + "extern int q_zero(int);", + "extern int not_RV(int);", + "#endif", + "", "void", "start_timer(void)", "{", @@ -1763,10 +1894,23 @@ "#endif", "}", "", + "double delta_time;", + "", + "void", + "report_time(void)", + "{", + " printf(\"\\npan: elapsed time %%.3g seconds\\n\", delta_time);", + " if (delta_time > 0.01)", + " { printf(\"pan: rate %%9.8g states/second\\n\", nstates/delta_time);", + " if (verbose)", + " { printf(\"pan: avg transition delay %%.5g usec\\n\",", + " delta_time/(nstates+truncs));", + " } }", + "}", + "", "void", - "stop_timer(void)", + "stop_timer(int report)", "{ clock_t stop_time;", - " double delta_time;", "#if !defined(WIN32) && !defined(WIN64)", " struct tms stop_tm;", " stop_time = times(&stop_tm);", @@ -1787,13 +1931,9 @@ " check_overkill();", " } }", "#else", - " printf(\"\\npan: elapsed time %%.3g seconds\\n\", delta_time);", - " if (delta_time > 0.01)", - " { printf(\"pan: rate %%9.8g states/second\\n\", nstates/delta_time);", - " if (verbose)", - " { printf(\"pan: avg transition delay %%.5g usec\\n\",", - " delta_time/(nstates+truncs));", - " } }", + " if (report)", + " { report_time();", + " }", "#endif", "}", "", @@ -1860,6 +2000,10 @@ "}", "#endif", "", + "#ifdef BFS_PAR", + "int ncores = 0;", + "#endif", + "", "void", "do_the_search(void)", "{ int i;", @@ -1874,11 +2018,13 @@ " if (!(trpt->o_pm&2)", " && accpstate[ptr->_t][ptr->_p])", " { trpt->o_pm |= 2;", + " break;", " }", "#else", " if (!(trpt->o_pm&4)", " && progstate[ptr->_t][ptr->_p])", " { trpt->o_pm |= 4;", + " break;", " }", "#endif", " }", @@ -1893,20 +2039,20 @@ " }", "#endif", "#endif", - "#ifndef NOCOMP", + "#if !defined(NOCOMP) && !defined(HC)", " Mask[0] = Mask[1] = 1; /* _nr_pr, _nr_qs */", " if (!a_cycles)", " { i = &(now._a_t) - (uchar *) &now;", " Mask[i] = 1; /* _a_t */", " }", - "#ifndef NOFAIR", - " if (!fairness)", - " { int j = 0;", - " i = &(now._cnt[0]) - (uchar *) &now;", - " while (j++ < NFAIR)", - " Mask[i++] = 1; /* _cnt[] */", - " }", - "#endif", + " #ifndef NOFAIR", + " if (!fairness)", + " { int j = 0;", + " i = &(now._cnt[0]) - (uchar *) &now;", + " while (j++ < NFAIR)", + " Mask[i++] = 1; /* _cnt[] */", + " }", + " #endif", "#endif", "#ifndef NOFAIR", " if (fairness", @@ -1935,24 +2081,30 @@ "#ifdef HAS_CODE", " if (readtrail) getrail(); /* no return */", "#endif", + "#ifndef BFS_PAR", " start_timer();", + "#endif", "#ifdef BFS", - " bfs();", + " #ifdef BFS_PAR", + " bfs_main(ncores,0);", + " #else", + " bfs();", + " #endif", "#else", - "#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)", - " /* initial state of tracked & unmatched objects */", - " c_stack((uchar *) &(svtack->c_stack[0]));", - "#endif", + " #if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)", + " /* initial state of tracked & unmatched objects */", + " c_stack((uchar *) &(svtack->c_stack[0]));", + " #endif", - "#if defined(P_RAND) || defined(T_RAND)", - " srand(s_rand);", - "#endif", + " #if defined(P_RAND) || defined(T_RAND)", + " srand(s_rand+HASH_NR);", /* do_the_search */ + " #endif", - "#if NCORE>1", - " mem_get();", - "#else", - " new_state(); /* start 1st DFS */", - "#endif", + " #if NCORE>1", + " mem_get();", + " #else", + " new_state(); /* start 1st DFS */", + " #endif", "#endif", "}", @@ -1960,41 +2112,41 @@ "uchar", "do_reverse(Trans *t, short II, uchar M)", "{ uchar _m = M;", - " int tt = (int) ((P0 *)this)->_p;", - "#include REVERSE_MOVES", + " int tt = (int) ((P0 *)_this)->_p;", + "#include BACKWARD_MOVES", "R999: return _m;", "}", "#endif", "#ifndef INLINE", - "#ifdef EVENT_TRACE", + " #ifdef EVENT_TRACE", "static char _tp = 'n'; static int _qid = 0;", - "#endif", + " #endif", "uchar", "do_transit(Trans *t, short II)", "{ uchar _m = 0;", - " int tt = (int) ((P0 *)this)->_p;", - "#ifdef M_LOSS", + " int tt = (int) ((P0 *)_this)->_p;", + " #ifdef M_LOSS", " uchar delta_m = 0;", - "#endif", - "#ifdef EVENT_TRACE", + " #endif", + " #ifdef EVENT_TRACE", " short oboq = boq;", - " uchar ot = (uchar) ((P0 *)this)->_t;", + " uchar ot = (uchar) ((P0 *)_this)->_t;", " if (II == -EVENT_TRACE) boq = -1;", "#define continue { boq = oboq; return 0; }", - "#else", + " #else", "#define continue return 0", "#ifdef SEPARATE", - " uchar ot = (uchar) ((P0 *)this)->_t;", + " uchar ot = (uchar) ((P0 *)_this)->_t;", "#endif", - "#endif", + " #endif", "#include FORWARD_MOVES", "P999:", - "#ifdef EVENT_TRACE", + " #ifdef EVENT_TRACE", " if (II == -EVENT_TRACE) boq = oboq;", - "#endif", + " #endif", " return _m;", - "#undef continue", + " #undef continue", "}", "#ifdef EVENT_TRACE", "void", @@ -2007,81 +2159,148 @@ " { if (do_transit(t, -EVENT_TRACE))", " { now._event = t->st;", " reached[EVENT_TRACE][t->st] = 1;", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\" event_trace move to -> %%d\\n\", t->st);", - "#endif", - "#ifndef BFS", - "#ifndef NP", + " #endif", + " #ifndef BFS", + " #ifndef NP", " if (accpstate[EVENT_TRACE][now._event])", " (trpt+1)->o_pm |= 2;", - "#else", + " #else", " if (progstate[EVENT_TRACE][now._event])", " (trpt+1)->o_pm |= 4;", - "#endif", - "#endif", - "#ifdef NEGATED_TRACE", + " #endif", + " #endif", + " #ifdef NEGATED_TRACE", " if (now._event == endevent)", " {", - "#ifndef BFS", + " #ifndef BFS", " depth++; trpt++;", - "#endif", + " #endif", " uerror(\"event_trace error (all events matched)\");", - "#ifndef BFS", + " #ifndef BFS", " trpt--; depth--;", - "#endif", + " #endif", " break;", " }", - "#endif", + " #endif", " for (t = t->nxt; t; t = t->nxt)", " { if (do_transit(t, -EVENT_TRACE))", " Uerror(\"non-determinism in event-trace\");", " }", " return;", " }", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " else", " printf(\" event_trace miss '%%c' -- %%d, %%d, %%d\\n\",", " tp, qid, now._event, t->forw);", - "#endif", + " #endif", " }", - "#ifdef NEGATED_TRACE", + " #ifdef NEGATED_TRACE", " now._event = endevent; /* only 1st try will count -- fixed 4.2.6 */", - "#else", - "#ifndef BFS", + " #else", + " #ifndef BFS", " depth++; trpt++;", - "#endif", + " #endif", " uerror(\"event_trace error (no matching event)\");", - "#ifndef BFS", + " #ifndef BFS", " trpt--; depth--;", - "#endif", - "#endif", + " #endif", + " #endif", "}", "#endif", "int", "enabled(int iam, int pid)", - "{ Trans *t; uchar *othis = this;", + "{ Trans *t; uchar *othis = _this;", " int res = 0; int tt; uchar ot;", - "#ifdef VERI", - " /* if (pid > 0) */ pid++;", - "#endif", + "", + " pid += BASE;", " if (pid == iam)", " Uerror(\"used: enabled(pid=thisproc)\");", " if (pid < 0 || pid >= (int) now._nr_pr)", " return 0;", - " this = pptr(pid);", + " _this = pptr(pid);", " TstOnly = 1;", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", " for (t = trans[ot][tt]; t; t = t->nxt)", " if (do_transit(t, (short) pid))", " { res = 1;", " break;", " }", " TstOnly = 0;", - " this = othis;", + " _this = othis;", " return res;", "}", "#endif", + "", + "#ifdef HAS_PRIORITY", + "int", + "highest_priority(int pid, short nII, Trans *t)", + "{ int i = pid; uchar *othis = _this;", + "", + "#ifdef VERI", + " if (nII == 0)", + " { return 1;", /* never claim */ + " }", + "#endif", + "#ifdef HAS_PROVIDED", + " i = pid+BASE;", /* uncorrected process number */ + "#endif", + " if (i < 0", + " || i >= (int) now._nr_pr", + "#ifdef HAS_PROVIDED", + " || !provided(i, (uchar) ((P0 *)_this)->_t, (int) ((P0 *)_this)->_p, t)", + "#endif", + " )", + " { return 0;", + " }", + "", + " for (i = BASE; i < now._nr_pr; i++)", /* all except never, if present */ + " { _this = pptr(i);", + " if (i != pid+BASE", + " && ((P0 *)_this)->_priority > ((P0 *)pptr(pid+BASE))->_priority", + "#ifdef HAS_PROVIDED", + " && provided(i, (uchar) ((P0 *)_this)->_t, (int) ((P0 *)_this)->_p, 0)", + "#endif", + " && enabled(i+1, i-BASE))", /* enabled adds back BASE in 2nd arg */ + " { _this = othis;", + " return 0;", + " } }", + " _this = othis;", + " return 1;", + "}", + "int", + "get_priority(int pid)", + "{ pid += BASE; /* 6.2.7 */", + " if (pid < 0 || pid >= (int) now._nr_pr)", + " return 0;", + " return ((P0 *)pptr(pid))->_priority;", + "}", + "int", + "set_priority(int pid, int pr)", + "{ pid += BASE; /* 6.2.7 */", + " if (pid < 0 || pid >= (int) now._nr_pr)", + " {", + " #ifdef VERBOSE", + " printf(\"warning: bad pid %%d, no such process (set_priority)\\n\", pid);", + " #endif", + " return 1;", + " }", + " if (pr < 1 || pr > 255)", + " { Uerror(\"priority is out of range\");", + " }", + + " if (!TstOnly)", + " { (trpt+1)->o_priority = ", + " (((P0 *)pptr(pid))->_priority & 255) | (pid << 8);", + " ((P0 *)pptr(pid))->_priority = pr;", + " }", + + " return 1;", /* always executable */ + "}", + "#endif", + "", "void", "snap_time(void)", "{ clock_t stop_time;", @@ -2113,8 +2332,12 @@ "void", "snapshot(void)", "{", + "#ifdef BFS_PAR", + " e_critical(BFS_GLOB); /* bfs_par / snapshot */", + " printf(\"cpu%%d: \", who_am_i);", + "#endif", "#if NCORE>1", - " enter_critical(GLOBAL_LOCK); /* snapshot */", + " enter_critical(GLOBAL_LOCK); /* ncore / snapshot */", " printf(\"cpu%%d: \", core_id);", "#endif", " printf(\"Depth= %%7ld States= %%8.3g \",", @@ -2124,7 +2347,7 @@ " mreached, nstates);", " printf(\"Transitions= %%8.3g \", nstates+truncs);", "#ifdef MA", - " printf(\"Nodes= %%7d \", nr_states);", + " printf(\"Nodes= %%7lu \", nr_states);", "#endif", " printf(\"Memory= %%9.3f\\t\", memcnt/1048576.);", " snap_time();", @@ -2132,6 +2355,9 @@ "#if NCORE>1", " leave_critical(GLOBAL_LOCK);", "#endif", + "#ifdef BFS_PAR", + " x_critical(BFS_GLOB);", + "#endif", "}", "#ifdef SC", "void", @@ -2197,35 +2423,6 @@ " else", " return (uchar *) qptr(x);", "}\n", - - "int qs_empty(void);", - "#if !defined(BFS) && (!defined(BITSTATE) || !defined(MA))", - "#ifdef NSUCC", - "int N_succ[512];", - "void", - "tally_succ(int cnt)", - "{ if (cnt < 512) N_succ[cnt]++;", - " else printf(\"tally_succ: cnt %%d exceeds range\\n\", cnt);", - "}", - "", - "void", - "dump_succ(void)", - "{ int i; double sum = 0.0;", - " double w_avg = 0.0;", - " printf(\"Successor counts:\\n\");", - " for (i = 0; i < 512; i++)", - " { sum += (double) N_succ[i];", - " }", - " for (i = 0; i < 512; i++)", - " { if (N_succ[i] > 0)", - " { printf(\"%%3d\t%%10d\t(%%.4g %%%% of total)\\n\",", - " i, N_succ[i], (100.0 * (double) N_succ[i])/sum);", - " w_avg += (double) i * (double) N_succ[i];", - " } }", - " if (sum > N_succ[0])", - " printf(\"mean %%.4g (without 0: %%.4g)\\n\", w_avg / sum, w_avg / (sum - (double) N_succ[0]));", - "}", - "#endif", "", "#if NCLAIMS>1", "void", @@ -2239,6 +2436,9 @@ " { printf(\"%%d: Claim %%s (%%d), from state %%d\\n\",", " (int) depth, procname[spin_c_typ[n]],", " n, ((Pclaim *)pptr(0))->c_cur[n]);", + " } else", + " { printf(\"pan: ltl formula %%s\\n\",", + " procname[spin_c_typ[n]]);", " }", " ((Pclaim *)pptr(0))->c_cur[m] = ((Pclaim *)pptr(0))->_p;", " ((Pclaim *)pptr(0))->_t = spin_c_typ[n];", @@ -2259,20 +2459,146 @@ "{ if (n != 0) uerror(\"non-existing claim\");", "}", "#endif", + + "int qs_empty(void);", + "#if !defined(BFS) && (!defined(BITSTATE) || !defined(MA))", + "#ifdef NSUCC", + "int N_succ[512];", + "void", + "tally_succ(int cnt)", + "{ if (cnt < 512) N_succ[cnt]++;", + " else printf(\"tally_succ: cnt %%d exceeds range\\n\", cnt);", + "}", + "", + "void", + "dump_succ(void)", + "{ int i; double sum = 0.0;", + " double w_avg = 0.0;", + " printf(\"Successor counts:\\n\");", + " for (i = 0; i < 512; i++)", + " { sum += (double) N_succ[i];", + " }", + " for (i = 0; i < 512; i++)", + " { if (N_succ[i] > 0)", + " { printf(\"%%3d\t%%10d\t(%%.4g %%%% of total)\\n\",", + " i, N_succ[i], (100.0 * (double) N_succ[i])/sum);", + " w_avg += (double) i * (double) N_succ[i];", + " } }", + " if (sum > N_succ[0])", + " printf(\"mean %%.4g (without 0: %%.4g)\\n\", w_avg / sum, w_avg / (sum - (double) N_succ[0]));", + "}", + "#endif", "", - "#ifdef REVERSE", + "#ifdef P_REVERSE", " #define FROM_P (BASE)", " #define UPTO_P (now._nr_pr-1)", - " #define MORE_P (II <= To)", /* p.o. only */ - " #define INI_P (From-1)", /* fairness only */ + " #define MORE_P (II <= To)", /* p.o. only */ + " #define INI_P (From-1)", /* fairness only */ + " #define CNT_P (1 + (To - From))", /* P_RAND start */ + " #define NDONE_P (From <= To)", /* P_RAND continue */ " #define ALL_P (II = From; II <= To; II++)", "#else", " #define FROM_P (now._nr_pr-1)", " #define UPTO_P (BASE)", " #define MORE_P (II >= BASE)", " #define INI_P (From+1)", + " #define CNT_P (1 + (From - To))", + " #define NDONE_P (From >= To)", " #define ALL_P (II = From; II >= To; II--)", "#endif", + "", + "#ifdef PERMUTED", + " #define CONTINUE0 { if (reversing&2) { II = oII; } continue; }", + " #define CONTINUE { if (reversing&2) { p_reorder(seed); II = oII; } continue; }", + "#else", + " #define CONTINUE0 { continue; }", + " #define CONTINUE { continue; }", + "#endif", + + "#ifdef PERMUTED", + "uchar _permutation_[256];", + "void", + "set_reversed(int unused)", + "{ int i, n = now._nr_pr;", + " #ifdef VERBOSE", + " printf(\"%%ld: Set_reversed\\n\", depth);", + " #endif", + " #if defined(VERI) && !defined(NOCLAIM)", + " for (i = 1; i < n; i++)", + " { _permutation_[i] = n-i;", + " }", + " #else", + " for (i = 0; i < n; i++)", + " { _permutation_[i] = n-1-i;", + " }", + " #endif", + "}", + "void", + "set_rotated(int unused)", + "{ int i, n = now._nr_pr;", + " #ifdef VERBOSE", + " printf(\"%%ld: Set_rotated %%d\\n\", depth, p_rotate);", + " #endif", + " #if defined(VERI) && !defined(NOCLAIM)", + " for (i = 1; i < n; i++)", + " { _permutation_[i] = 1+(i-1+p_rotate)%%(n-1);", + " }", + " #else", + " for (i = 0; i < n; i++)", + " { _permutation_[i] = (i+p_rotate)%%n;", + " }", + " #endif", + "}", + "void", + "set_randrot(int unused)", + "{", + " if (now._nr_pr > 1)", + " { p_rotate = 1+rand()%%(now._nr_pr-1);", + " } else", + " { p_rotate = 0;", + " }", + " set_rotated(0);", + "}", + "void", + "set_permuted(int T)", + "{ /* permute nrs 1..n-1, leave 0 in place */", + " int i, j, k, n = now._nr_pr;", + " char tmp, *in = &(_permutation_[0]);", + " #ifdef VERBOSE", + " printf(\"%%ld: Set_permuted %%d\\n\", depth, T);", + " #endif", + " srand(T);", /* set_permuted */ + " for (i = 0; i < n; i++)", + " { in[i] = i;", + " }", + " if (n > 1)", + " { for (i = 0; i < n; i++)", + " {", + " #if defined(VERI) && !defined(NOCLAIM)", + " j = 1 + rand()%%(n-1);", + " k = 1 + rand()%%(n-1);", + " #else", + " j = rand()%%(n);", + " k = rand()%%(n);", + " #endif", + " tmp = in[j];", + " in[j] = in[k];", + " in[k] = tmp;", + " } }", + "}", + "", + " #ifdef VERBOSE", + " short", + " get_permuted(int x)", + " { printf(\"%%ld: Get_permuted %%d -> %%d\\n\",", + " depth, x, _permutation_[x]);", + " return (short) _permutation_[x];", + " }", + " #else", + " #define get_permuted(x) (short) _permutation_[x]", + " #endif", + "", + "#endif", "/*", " * new_state() is the main DFS search routine in the verifier", " * it has a lot of code ifdef-ed together to support", @@ -2291,7 +2617,9 @@ "#ifdef T_RAND", " short ooi, eoi;", "#endif", - + "#ifdef PERMUTED", + " short oII; uint seed;", + "#endif", "#ifdef M_LOSS", " uchar delta_m = 0;", "#endif", @@ -2319,7 +2647,7 @@ " hiwater += DDD;", " trpt -= DDD;", " if(verbose)", - " printf(\"zap %%d: %%d (maxdepth now %%d)\\n\",", + " printf(\"zap %%ld: %%ld (maxdepth now %%ld)\\n\",", " CNT1, hiwater, maxdepth);", " }", "#endif", @@ -2382,34 +2710,52 @@ "#endif", " if (boq == -1) { /* if not mid-rv */", "#ifndef SAFETY", - " /* this check should now be redundant", - " * because the seed state also appears", - " * on the 1st dfs stack and would be", - " * matched in hstore below", - " */", +#if 0 + we want to skip nrpr, nrqs, _a_t and cnt[NFAIR] (in the case of fairness) + this is calculated in S_A, but S_A subtracts 2 bytes, + because nrpr and nrqs are masked in the default state comparisons + so we add those two bytes back here + -- in default comparisons (h_store) we skip _a_t and cnt in the + -- first comparison to find a match on the base-state + -- the _a_t and cnt fields are then separately updated if there was + -- a match on the base state +#endif " if ((now._a_t&1) && depth > A_depth)", - " { if (!memcmp((char *)&A_Root, ", - " (char *)&now, vsize))", + " { int delta = S_A + 2;", + " if (!memcmp((char *)&A_Root + delta, ", + " (char *)&now + delta, vsize - delta))", " {", - " depthfound = A_depth;", - "#ifdef CHECK", - " printf(\"matches seed\\n\");", - "#endif", - "#ifdef NP", - " uerror(\"non-progress cycle\");", - "#else", - " uerror(\"acceptance cycle\");", - "#endif", - "#if NCORE>1 && defined(FULL_TRAIL)", - " if (upto > 0)", - " { Pop_Stack_Tree();", - " }", + "#ifndef NOFAIR", + " if (fairness && now._cnt[1] != 1) /* was > 1 */", + " {", + " #ifdef CHECK", + " printf(\"\tfairness count non-zero\\n\");", + " #endif", + " /* treat as new state */", + " } else", "#endif", - " goto Up;", + " { depthfound = A_depth;", + " #ifdef CHECK", + " printf(\"matches seed\\n\");", + " #endif", + " #ifdef NP", + " uerror(\"non-progress cycle\");", + " #else", + " uerror(\"acceptance cycle\");", + " #endif", + " #if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", + " #endif", + " goto Up;", + " } }", + " #ifdef CHECK", + " else", + " {", + " printf(\"not seed\\n\");", " }", - "#ifdef CHECK", - " printf(\"not seed\\n\");", - "#endif", + " #endif", " }", "#endif", " if (!(trpt->tau&8)) /* if no atomic move */", @@ -2424,62 +2770,62 @@ " { int xj;", " for (xj = trpt->sched_limit; xj <= sched_max; xj++)", " { now._ctx = xj;", - " II = bstore((char *)&now, vsize);", - " trpt->j6 = j1_spin; trpt->j7 = j2;", - " JJ = LL[j1_spin] && LL[j2];", + " II = b_store((char *)&now, vsize);", + " trpt->j6 = j1_spin; trpt->j7 = j2_spin;", + " JJ = LL[j1_spin] && LL[j2_spin];", " if (II != 0) { break; }", " }", " now._ctx = 0; /* just in case */", " }", " #else", - " II = bstore((char *)&now, vsize);", - " trpt->j6 = j1_spin; trpt->j7 = j2;", - " JJ = LL[j1_spin] && LL[j2];", + " II = b_store((char *)&now, vsize);", + " trpt->j6 = j1_spin; trpt->j7 = j2_spin;", + " JJ = LL[j1_spin] && LL[j2_spin];", " #endif", "#else", - " #ifdef FULLSTACK", /* bstore after onstack_now, to preserve j1-j4 */ + " #ifdef FULLSTACK", /* b_store after onstack_now, to preserve j1-j4 */ " #if defined(BCS) && defined(STORE_CTX)", " { int xj;", " now._ctx = 0;", " JJ = onstack_now();", /* mangles j1 */ " for (xj = trpt->sched_limit; xj <= sched_max; xj++)", " { now._ctx = xj;", - " II = bstore((char *)&now, vsize);", /* sets j1-j4 */ + " II = b_store((char *)&now, vsize);", /* sets j1-j4 */ " if (II != 0) { break; }", " }", " now._ctx = 0;", " }", " #else", " JJ = onstack_now();", /* mangles j1 */ - " II = bstore((char *)&now, vsize);", /* sets j1-j4 */ + " II = b_store((char *)&now, vsize);", /* sets j1-j4 */ " #endif", " #else", " #if defined(BCS) && defined(STORE_CTX)", " { int xj;", " for (xj = trpt->sched_limit; xj <= sched_max; xj++)", " { now._ctx = xj;", - " II = bstore((char *)&now, vsize);", /* sets j1-j4 */ + " II = b_store((char *)&now, vsize);", /* sets j1-j4 */ " JJ = II; /* worstcase guess for p.o. - order corrected in 5.2.1 */", " if (II != 0) { break; }", " }", " now._ctx = 0;", " }", " #else", - " II = bstore((char *)&now, vsize);", /* sets j1-j4 */ + " II = b_store((char *)&now, vsize);", /* sets j1-j4 */ " JJ = II; /* worstcase guess for p.o. - order corrected in 5.2.1 */", " #endif", " #endif", "#endif", "#else", "#ifdef MA", - " II = gstore((char *)&now, vsize, 0);", + " II = g_store((char *)&now, vsize, 0);", "#ifndef FULLSTACK", " JJ = II;", "#else", " JJ = (II == 2)?1:0;", "#endif", "#else", - " II = hstore((char *)&now, vsize);", + " II = h_store((char *)&now, vsize);", " /* @hash j1_spin II */", "#ifdef FULLSTACK", " JJ = (II == 2)?1:0;", @@ -2497,16 +2843,14 @@ /* II==2 on current dfs stack */ /* II==3 on 1st dfs stack */ "#ifndef SAFETY", - - "#if NCORE==1 || defined (SEP_STATE)", /* or else we don't know which stack its on */ + /* with multicore we don't know which stack its on */ + /* with HC there's a small chance of a false match - example fifoq 2012 */ + "#if !defined(HC) && (NCORE==1 || defined (SEP_STATE))", " if (II == 2 && ((trpt->o_pm&2) || ((trpt-1)->o_pm&2)))", " #ifndef NOFAIR", - "#if 0", - " if (!fairness || ((now._a_t&1) && now._cnt[1] == 1)) /* 5.1.4 */", - "#else", " if (a_cycles && !fairness) /* 5.1.6 -- example by Hirofumi Watanabe */", - "#endif", " #endif", + " if (depth > A_depth) /* forum example by adl */", " {", " II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */", "#ifdef VERBOSE", @@ -2534,11 +2878,11 @@ " if (II == 3 && a_cycles && (now._a_t&1))", " {", "#ifndef NOFAIR", - " if (fairness && now._cnt[1] > 1) /* was != 0 */", + " if (fairness && now._cnt[1] != 1) /* was > 1 */", " {", - "#ifdef VERBOSE", + " #ifdef CHECK", " printf(\"\tfairness count non-zero\\n\");", - "#endif", + " #endif", " II = 0;", /* treat as new state */ " } else", "#endif", @@ -2615,7 +2959,7 @@ "#if defined(ZAPH) && defined(BITSTATE)", " zstates += (double) hfns;", "#endif", - " ndone = (unsigned long) (nstates/(freq));", + " ndone = (ulong) (nstates/(freq));", " if (ndone != sdone)", " { snapshot();", " sdone = ndone;", @@ -2641,10 +2985,10 @@ " if (HASH_NR != 0)", " { int oh = HASH_NR;", " HASH_NR = 0;", - " d_hash((char *) &now, vsize); /* set K1 */", + " d_hash((uchar *) &now, vsize); /* SHO - set K1 */", " HASH_NR = oh;", " }", - " if (write(svfd, (uchar *) &K1, sizeof(unsigned long)) != sizeof(unsigned long))", + " if (write(svfd, (uchar *) &K1, sizeof(ulong)) != sizeof(ulong))", " #else", " if (write(svfd, (uchar *) &now, vprefix) != vprefix)", " #endif", @@ -2653,7 +2997,7 @@ " }", "#endif", "#if defined(MA) && defined(W_XPT)", - " if ((unsigned long) nstates%%W_XPT == 0)", + " if ((ulong) nstates%%W_XPT == 0)", " { void w_xpoint(void);", " w_xpoint();", " }", @@ -2690,30 +3034,35 @@ "#endif", "#ifdef VERI", " if (now._nr_pr == 0) /* claim terminated */", - " uerror(\"end state in claim reached\");", - "", + " { uerror(\"end state in claim reached\");", + " }", " if (stopstate[((Pclaim *)pptr(0))->_t][((Pclaim *)pptr(0))->_p])", " { uerror(\"end state in claim reached\");", " }", "Stutter:", " if (trpt->tau&4) /* must make a claimmove */", " {", - "#ifndef NOFAIR", + " #ifndef NOFAIR", " if ((now._a_t&2) /* A-bit set */", " && now._cnt[now._a_t&1] == 1)", " { now._a_t &= ~2;", " now._cnt[now._a_t&1] = 0;", " trpt->o_pm |= 16;", - "#ifdef DEBUG", - " printf(\"%%3d: fairness Rule 3.: _a_t = %%d\\n\",", - " depth, now._a_t);", - "#endif", + "#ifdef DEBUG", + " printf(\"%%3ld: fairness Rule 3.: _a_t = %%d\\n\", depth, now._a_t);", + "#endif", " }", - "#endif", + " #endif", " II = 0; /* never */", " goto Veri0;", " }", "#endif", + "#ifdef PERMUTED", + " if (reversing&2)", + " { seed = rand();", + " p_reorder(seed);", + " }", + "#endif", "#ifndef NOREDUCE", " /* Look for a process with only safe transitions */", " /* (special rules apply in the 2nd dfs) */", @@ -2762,21 +3111,21 @@ "#ifdef BCS", " if (trpt->sched_limit < sched_max)", /* po only if we can switch */ "#endif", - " { for ALL_P", - " {", + " { for ALL_P {", /* PO preselect */ "Resume: /* pick up here if preselect fails */", - " this = pptr(II);", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", + " _this = pptr(II);", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", " if (trans[ot][tt]->atom & 8)", " { t = trans[ot][tt];", " if (t->qu[0] != 0)", " { Ccheck++;", " if (!q_cond(II, t))", - " continue;", + " { continue;", + " }", " Cholds++;", " }", - "SelectIt: From = To = II; /* preselect process */", + " From = To = II; /* preselect process */", "#ifdef NIBIS", " t->om = 0;", "#endif", @@ -2786,6 +3135,8 @@ " depth, II, trpt->tau);", "#endif", " goto Again;", + " } else", + " { continue;", " } } }", " trpt->tau &= ~32;", "#endif", @@ -2844,11 +3195,7 @@ "#endif", "#ifdef P_RAND", - " #ifdef REVERSE", - " trpt->p_left = 1 + (To - From);", - " #else", - " trpt->p_left = 1 + (From - To);", - " #endif", + " trpt->p_left = CNT_P;", " if (trpt->p_left > 1)", " { trpt->p_skip = rand() %% (trpt->p_left);", " } else", @@ -2861,9 +3208,14 @@ " #endif", "#endif", - " /* Main Expansion Loop over Processes */", - " for ALL_P", - " {", + " for ALL_P {", /* Main Loop */ + "#ifdef PERMUTED", + " if (reversing&2)", + " { oII = II;", + " if (From != To)", /* not atomic or preselected */ + " { II = get_permuted(II);", + " } }", + "#endif", "#ifdef P_RAND", " if (trpt->p_skip >= 0)", " { trpt->p_skip--; /* skip random nr of procs */", @@ -2871,7 +3223,7 @@ " printf(\"%%3ld: P_RAND skipping %%d [new p_skip=%%d p_left=%%d]\\n\",", " depth, II, trpt->p_skip, trpt->p_left);", " #endif", - " continue;", + " CONTINUE0;", " }", " if (trpt->p_left == 0)", " {", @@ -2889,7 +3241,9 @@ "#if SYNC", " /* no rendezvous with same proc */", - " if (boq != -1 && trpt->pr == II) continue;", + " if (boq != -1 && trpt->pr == II)", + " { CONTINUE0;", + " }", "#endif", "#ifdef BCS", /* never claim with II==0 cannot get here */ @@ -2900,7 +3254,7 @@ " printf(\"%%3ld: BCS NotPre II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", " #endif", - " continue;", /* avoid context switch */ + " CONTINUE0;", /* avoid context switch */ " }", " #ifdef VERBOSE", " else if ((trpt->bcs & B_PHASE1) && trpt->b_pno == II)", @@ -2915,7 +3269,7 @@ " printf(\"%%3ld: BCS NoRepeat II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", " #endif", - " continue;", + " CONTINUE0;", " }", " if (!(trpt->bcs & B_FORCED) /* unless forced */", " && trpt->sched_limit >= sched_max)", @@ -2924,16 +3278,16 @@ " printf(\"%%3ld: BCS Bound II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", " #endif", - " continue; /* enforce bound */", + " CONTINUE0; /* enforce bound */", " } }", "#endif", "#ifdef VERI", "Veri0:", "#endif", - " this = pptr(II);", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", + " _this = pptr(II);", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", "#ifdef NIBIS", " /* don't repeat a previous preselected expansion */", @@ -2948,8 +3302,10 @@ " { if (t->qu[0] == 0", /* unconditional */ " || q_cond(II, t))", /* true condition */ " { _m = t->om;", - " if (_m>_n||(_n>3&&_m!=0)) _n=_m;", - " continue; /* did it before */", + " if (_m>_n||(_n>3&&_m!=0))", + " { _n=_m;", + " }", + " CONTINUE0; /* did it before */", " } }", "#endif", " trpt->o_pm &= ~1; /* no move in this pid yet */", @@ -2978,9 +3334,19 @@ " trpt->o_pm |= (32|64);", " }", "#endif", - "#ifdef HAS_PROVIDED", - " if (!provided(II, ot, tt, t)) continue;", + + "#ifdef HAS_PRIORITY", + " if (!highest_priority(((P0 *)_this)->_pid, II, t))", + " { CONTINUE0;", + " }", + "#else", + " #ifdef HAS_PROVIDED", + " if (!provided(II, ot, tt, t))", + " { CONTINUE0;", + " }", + " #endif", "#endif", + " /* check all trans of proc II - escapes first */", "#ifdef HAS_UNLESS", " trpt->e_state = 0;", @@ -2991,9 +3357,9 @@ "#ifdef T_RAND", " for (ooi = eoi = 0, t = trans[ot][tt]; t; t = t->nxt, ooi++)", " { if (strcmp(t->tp, \"else\") == 0", - "#ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " || t->e_trans != 0", - "#endif", + " #endif", " )", " { eoi++;", /* no break, must count ooi */ " } }", @@ -3002,7 +3368,7 @@ " #ifdef VERBOSE", " printf(\"randomizer: suppressed, saw else or escape\\n\");", " #endif", - " } else", + " } else if (ooi > 0)", " { eoi = rand()%%ooi;", " #ifdef VERBOSE", " printf(\"randomizer: skip %%d in %%d\\n\", eoi, ooi);", @@ -3038,7 +3404,9 @@ "#include FORWARD_MOVES", "P999: /* jumps here when move succeeds */", "#else", - " if (!(_m = do_transit(t, II))) continue;", + " if (!(_m = do_transit(t, II)))", + " { continue;", + " }", "#endif", "#ifdef BCS", " if (depth > BASE", /* has prior move */ @@ -3123,7 +3491,7 @@ " trpt->st = tt;", " trpt->o_pm &= ~(2|4);", " if (t->st > 0)", - " { ((P0 *)this)->_p = t->st;", + " { ((P0 *)_this)->_p = t->st;", "/* moved down reached[ot][t->st] = 1; */", " }", "#ifndef SAFETY", @@ -3160,8 +3528,14 @@ " trpt->o_ot = ot; trpt->o_tt = tt;", " trpt->o_To = To; trpt->o_m = _m;", " trpt->tau = 0;", + "#ifdef PERMUTED", + " if (reversing&2)", + " { trpt->seed = seed;", + " trpt->oII = oII;", + " }", + "#endif", - "#ifdef T_RAND", + "#if defined(T_RAND) && !defined(BFS)", " trpt->oo_i = ooi;", "#endif", " if (boq != -1 || (t->atom&2))", @@ -3252,7 +3626,7 @@ " maxdepth -= DDD;", " hiwater -= DDD;", " if(verbose)", - " printf(\"unzap %%d: %%d\\n\", CNT2, hiwater);", + " printf(\"unzap %%ld: %%ld\\n\", CNT2, hiwater);", " }", "#endif", @@ -3275,7 +3649,7 @@ "#ifdef HAS_LAST", "#ifdef VERI", - " { int d; Trail *trl;", + " { long d; Trail *trl;", " now._last = 0;", " for (d = 1; d < depth; d++)", " { trl = getframe(depth-d); /* was (trpt-d) */", @@ -3292,22 +3666,28 @@ "#endif", " t = trpt->o_t; _n = trpt->o_n;", " ot = trpt->o_ot; II = trpt->pr;", - " tt = trpt->o_tt; this = Pptr(II);", + " tt = trpt->o_tt; _this = Pptr(II);", " To = trpt->o_To; _m = trpt->o_m;", - "#ifdef T_RAND", + "#ifdef PERMUTED", + " if (reversing&2)", + " { seed = trpt->seed;", + " oII = trpt->oII;", + " }", + "#endif", + "#if defined(T_RAND) && !defined(BFS)", " ooi = trpt->oo_i;", "#endif", "#ifdef INLINE_REV", " _m = do_reverse(t, II, _m);", "#else", - "#include REVERSE_MOVES", + "#include BACKWARD_MOVES", "R999: /* jumps here when done */", "#endif", "#ifdef VERBOSE", " cpu_printf(\"%%3ld: proc %%d reverses %%d, %%d to %%d\\n\",", " depth, II, t->forw, tt, t->st);", - " cpu_printf(\"\\t%%s [abit=%%d,adepth=%%d,tau=%%d,%%d]\\n\", ", + " cpu_printf(\"\\t%%s [abit=%%d,adepth=%%ld,tau=%%d,%%d]\\n\", ", " t->tp, now._a_t, A_depth, trpt->tau, (trpt-1)->tau);", "#endif", "#ifndef NOREDUCE", @@ -3348,7 +3728,7 @@ "#endif", " if (_m>_n||(_n>3&&_m!=0)) _n=_m;", - " ((P0 *)this)->_p = tt;", + " ((P0 *)_this)->_p = tt;", " } /* all options */", "#ifdef T_RAND", @@ -3389,18 +3769,20 @@ " II = INI_P;", /* after loop incr II == From */ " } } }", "#endif", - "#ifdef VERI", - " if (II == 0) break; /* never claim */", + " if (II == 0)", + " { break; /* never claim */", + " }", "#endif", - " } /* all processes */", + " CONTINUE;", + " } /* ALL_P */", "#ifdef NSUCC", " tally_succ(trpt->n_succ);", "#endif", "#ifdef P_RAND", - " if (trpt->p_left > 0)", + " if (trpt->p_left > 0 && NDONE_P)", " { trpt->p_skip = -1; /* probably rendundant */", " #ifdef VERBOSE", " printf(\"%%3ld: P_RAND -- explore remainder\\n\", depth);", @@ -3464,12 +3846,8 @@ " && !(trpt->tau&4) /* in program move */", "#endif", " && !(trpt->tau&8) /* not an atomic one */", - "#ifdef OTIM", - " && ((trpt->tau&1) || endstate())", - "#else", - "#ifdef ETIM", - " && (trpt->tau&1) /* already tried timeout */", - "#endif", + "#ifdef ETIM", + " && (trpt->tau&1) /* already tried timeout */", "#endif", "#ifndef NOREDUCE", " /* see below */", @@ -3518,25 +3896,25 @@ "#ifndef NOREDUCE", "#ifdef SAFETY", " #ifdef LOOPSTATE", - " /* at least one move that was preselected at this */", - " /* level, blocked or was a loop control flow point */", - " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", + " /* at least one move that was preselected at this */", + " /* level, blocked or was a loop control flow point */", + " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", " #else", - " /* preselected move - no successors outside stack */", - " if ((trpt->tau&32) && !(trpt->tau&64))", + " /* preselected move - no successors outside stack */", + " if ((trpt->tau&32) && !(trpt->tau&64))", " #endif", - " { From = FROM_P; To = UPTO_P;", + " { From = FROM_P; To = UPTO_P; /* undo From == To */", " #ifdef DEBUG", " printf(\"%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", " depth, II+1, _n, trpt->tau);", " #endif", " _n = 0; trpt->tau &= ~(16|32|64);", - " if (MORE_P) /* II already decremented */", - " goto Resume;", - " else", - " goto Again;", - " }", + " if (MORE_P) /* II already restored and updated */", + " { goto Resume;", + " } else", + " { goto Again;", + " } }", "#else", " /* at least one move that was preselected at this */", " /* level, blocked or truncated at the next level */", @@ -3582,11 +3960,11 @@ " } else", " { From = FROM_P; To = UPTO_P;", " _n = 0; trpt->tau &= ~(16|32|64);", - " if (MORE_P) /* II already decremented */", - " goto Resume;", - " else", - " goto Again;", - " } }", + " if (MORE_P) /* II already updated */", + " { goto Resume;", + " } else", + " { goto Again;", + " } } }", "#endif", "#endif", @@ -3602,9 +3980,6 @@ "#endif", " /* ok if no procs or we're at maxdepth */", " if ((now._nr_pr == 0 && (!strict || qs_empty()))", - "#ifdef OTIM", - " || endstate()", - "#endif", " || depth >= maxdepth-1) goto Done; /* undo change from 5.2.3 */", " if ((trpt->tau&8) && !(trpt->tau&4))", @@ -3631,9 +4006,9 @@ "#endif", " { trpt->tau |= 1;", " trpt->tau &= ~2;", - "#ifdef DEBUG", + " #ifdef DEBUG", " cpu_printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #endif", " goto Stutter;", " } }", " else", @@ -3641,23 +4016,22 @@ " if ((trpt->tau&8)", " && !((trpt-1)->tau&4))", "/* blocks inside an atomic */ goto BreakOut;", - "#ifdef DEBUG", + " #ifdef DEBUG", " cpu_printf(\"%%d: req timeout\\n\",", " depth);", - "#endif", + " #endif", " (trpt-1)->tau |= 2; /* request */", - "#if NCORE>1 && defined(FULL_TRAIL)", + " #if NCORE>1 && defined(FULL_TRAIL)", " if (upto > 0)", " { Pop_Stack_Tree();", " }", - "#endif", + " #endif", " goto Up;", " }", "#else", - - "#ifdef DEBUG", + " #ifdef DEBUG", " cpu_printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #endif", " trpt->tau |= 1;", " goto Again;", "#endif", @@ -3710,7 +4084,7 @@ " {", "#ifdef DEBUG2", "#if defined(FULLSTACK)", - " printf(\"%%d: zapping %%u (%%d)\\n\",", + " printf(\"%%ld: zapping %%u (%%d)\\n\",", " depth, trpt->ostate,", " (trpt->ostate)?trpt->ostate->tagged:0);", "#endif", @@ -3728,12 +4102,12 @@ "#endif", " {", "#ifdef DEBUG", - " printf(\"%%d: zapping\\n\", depth);", + " printf(\"%%ld: zapping\\n\", depth);", "#endif", " onstack_zap();", "#ifndef NOREDUCE", " if (trpt->proviso)", - " gstore((char *) &now, vsize, 1);", + " g_store((char *) &now, vsize, 1);", "#endif", " }", "#endif", @@ -3815,6 +4189,7 @@ " return x;", "}", "#endif", + "int do_hashgen = 0;", "void", "wrap_stats(void)", "{", @@ -3823,18 +4198,22 @@ " nstates - nShadow, nstates);", " else", " printf(\"%%9.8g states, stored\\n\", nstates);", + "#ifdef BFS_PAR", + " if (bfs_punt > 0)", + " printf(\"%%9.8g states lost (lack of queue memory)\\n\", (double) bfs_punt);", + "#endif", "#ifdef BFS", - "#if SYNC", + " #if SYNC", " printf(\" %%8g nominal states (- rv and atomic)\\n\", nstates-midrv-nlinks+revrv);", " printf(\" %%8g rvs succeeded\\n\", midrv-failedrv);", - "#else", + " #else", " printf(\" %%8g nominal states (stored-atomic)\\n\", nstates-nlinks);", - "#endif", - "#ifdef DEBUG", + " #endif", + " #ifdef DEBUG", " printf(\" %%8g midrv\\n\", midrv);", " printf(\" %%8g failedrv\\n\", failedrv);", " printf(\" %%8g revrv\\n\", revrv);", - "#endif", + " #endif", "#endif", " printf(\"%%9.8g states, matched\\n\", truncs);", "#ifdef CHECK", @@ -3852,11 +4231,25 @@ "#ifndef BITSTATE", " #ifndef MA", " printf(\"hash conflicts: %%9.8g (resolved)\\n\", hcmp);", - " #ifndef AUTO_RESIZE", + " #if !defined(AUTO_RESIZE) && !defined(BFS_PAR)", " if (hcmp > (double) (1< 1.0)", + " { fp = 100. / fp;", + " while (fp > 2.) { fi++; fp /= 2.; }", + " if (fi > 0)", + " { printf(\" (hint: rerun with -w%%d to reduce runtime)\",", + " ssize-fi);", + " } }", + " printf(\"\\n\");", + " }", + " #endif", " #endif", "#else", "#ifdef CHECK", @@ -3867,19 +4260,15 @@ " (double)(((double) udmem) * 8.0) / (double) nstates);", " else", " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",", - " (double)(1<<(ssize-8)) / (double) nstates * 256.0);", + " ((double)(((ulong)1)<<(ssize-10)) / (double) nstates) * 1024.0);", + /* the -10 and *1024 stuff is to avoid overflow */ " printf(\"bits set per state: %%u (-k%%u)\\n\", hfns, hfns);", - " #if 0", - " if (udmem)", - " { printf(\"total bits available: %%8g (-M%%ld)\\n\",", - " ((double) udmem) * 8.0, udmem/(1024L*1024L));", - " } else", - " { printf(\"total bits available: %%8g (-w%%d)\\n\",", - " ((double) (ONE_L << (ssize-4)) * 16.0), ssize);", - " }", - " #endif", + " if (do_hashgen)", + " printf(\"hash polynomial used: 0x%%.8x\\n\", HASH_CONST[HASH_NR]);", + " if (s_rand != 12345)", + " printf(\"random seed used: %%u\\n\", (uint) (s_rand-1));", "#endif", - "#ifdef BFS_DISK", + "#if defined(BFS_DISK) && !defined(BFS_PAR)", " printf(\"bfs disk reads: %%ld writes %%ld -- diff %%ld\\n\",", " bfs_dsk_reads, bfs_dsk_writes, bfs_dsk_writes-bfs_dsk_reads);", " if (bfs_dsk_read >= 0) (void) close(bfs_dsk_read);", @@ -3891,19 +4280,19 @@ "void", "wrapup(void)", "{ double nr1, nr2, nr3 = 0.0, nr4, nr5 = 0.0;", - "#if !defined(MA) && (defined(MEMCNT) || defined(MEMLIM))", - " int mverbose = 1;", - "#else", - " int mverbose = verbose;", + "#ifdef BFS_PAR", + " if (who_am_i != 0)", + " { pan_exit(0);", + " }", "#endif", "#if NCORE>1", - " if (verbose) cpu_printf(\"wrapup -- %%d error(s)\\n\", errors);", + " if (verbose) cpu_printf(\"wrapup -- %%lu error(s)\\n\", errors);", " if (core_id != 0)", " {", - "#ifdef USE_DISK", + " #ifdef USE_DISK", " void dsk_stats(void);", " dsk_stats();", - "#endif", + " #endif", " if (search_terminated != NULL)", " { *search_terminated |= 2; /* wrapup */", " }", @@ -3915,9 +4304,21 @@ "#endif", " printf(\"\\n(%%s)\\n\", SpinVersion);", " if (!done) printf(\"Warning: Search not completed\\n\");", + "#if defined(BFS_PAR) && !defined(BITSTATE)", + " if (bfs_punt > 0) printf(\"Warning: Search incomplete\\n\");", + "#endif", "#ifdef SC", " (void) unlink((const char *)stackfile);", "#endif", + "#ifdef BFS_PAR", + " printf(\" + Multi-Core (using %%d cores)\\n\", Cores);", + " #ifdef BFS_SEP_HASH", + " printf(\" + Separate Hash Tables\\n\");", + " #endif", + " #ifdef BFS_DISK", + " printf(\" + Disk storage\\n\");", + " #endif", + "#endif", "#if NCORE>1", " if (a_cycles)", " { printf(\" + Multi-Core (NCORE=%%d)\\n\", NCORE);", @@ -3926,17 +4327,19 @@ " }", "#endif", "#ifdef BFS", - " printf(\" + Using Breadth-First Search\\n\");", + " printf(\" + Breadth-First Search\\n\");", "#endif", "#ifndef NOREDUCE", " printf(\" + Partial Order Reduction\\n\");", "#endif", - "#ifdef REVERSE", + "#ifdef PERMUTED", + " printf(\" + Process Scheduling Permutation\\n\");", + "#endif", + "#ifdef P_REVERSE", " printf(\" + Reverse Depth-First Search Order\\n\");", "#endif", - "#ifdef T_REVERSE", + " if (t_reverse)", " printf(\" + Reverse Transition Ordering\\n\");", - "#endif", "#ifdef T_RAND", " printf(\" + Randomized Transition Ordering\\n\");", "#endif", @@ -3966,6 +4369,21 @@ " printf(\" + CntrStack Matching\\n\");", " #endif", "#endif", + "#ifdef PERMUTED", + " if (reversing & 2)", + " { if (p_reorder == set_permuted)", + " { printf(\" + Permuted\\n\");", + " }", + " if (p_reorder == set_reversed)", + " { printf(\" + Reversed\\n\");", + " }", + " if (p_reorder == set_rotated)", + " { printf(\" + Rotated %%d\\n\", p_rotate);", + " }", + " if (p_reorder == set_randrot)", + " { printf(\" + RandRotated\\n\");", + " } }", + "#endif", "#ifdef BITSTATE", " printf(\"\\nBit statespace search for:\\n\");", "#else", @@ -4013,7 +4431,11 @@ " fairness?\"en\":\"dis\");", " else printf(\"- (not selected)\\n\");", "#else", + " #if !defined(BFS_PAR) || !defined(L_BOUND)", " printf(\"\tcycle checks \t- (disabled by -DSAFETY)\\n\");", + " #else", + " printf(\"\tcycle checks \t+ (bound %%d)\\n\", L_bound);", + " #endif", "#endif", "#ifdef VERI", " printf(\"\tinvalid end states\t- \");", @@ -4034,7 +4456,7 @@ " (nr_handoffs * z_handoff) +", "#endif", " mreached);", - " printf(\", errors: %%d\\n\", errors);", + " printf(\", errors: %%lu\\n\", errors);", " fflush(stdout);", "#ifdef MA", " if (done)", @@ -4063,7 +4485,7 @@ "", "#if 1", /* omitted 5.2.0: defined(BITSTATE) || !defined(NOCOMP) */ " nr1 = (nstates-nShadow)*", - " (double)(hmax+sizeof(struct H_el)-sizeof(unsigned));", + " (double)(hmax+sizeof(H_el)-sizeof(unsigned));", " #ifdef BFS", " nr2 = 0.0;", " #else", @@ -4072,7 +4494,7 @@ " #ifndef BITSTATE", "#if !defined(MA) || defined(COLLAPSE)", - " nr3 = (double) (ONE_L< 0.)", - " { if (tmp_nr > nr1) printf(\"unsuccessful \");", - " printf(\"compression: %%.2f%%%%)\\n\",", - " (100.0*tmp_nr)/nr1);", - " } else", - " printf(\"less than 1k)\\n\");", - "#ifndef MA", - " if (tmp_nr > 0.)", - " { printf(\" \tstate-vector as stored = %%.0f byte\",", - " (tmp_nr)/(nstates-nShadow) -", - " (double) (sizeof(struct H_el) - sizeof(unsigned)));", - " printf(\" + %%ld byte overhead\\n\",", - " (long int) sizeof(struct H_el)-sizeof(unsigned));", - " }", - "#endif", - "#if !defined(MA) || defined(COLLAPSE)", - " printf(\"%%9.3f\tmemory used for hash table (-w%%d)\\n\",", - " nr3/1048576., ssize);", - " remainder -= nr3;", - "#endif", - "#endif", + " #else", + " #ifndef USE_TDH", + " printf(\"%%9.3f\tactual memory usage for states\",", + " tmp_nr/1048576.);", + " remainder -= tmp_nr;", + " if (tmp_nr > 0.)", + " { if (tmp_nr < nr1) ", + " { printf(\" (compression: %%.2f%%%%)\\n\",", + " (100.0*tmp_nr)/nr1);", + " } else", + " { printf(\"\\n\");", + " }", + " } else", + " { printf(\" (less than 1k)\\n\");", + " }", + " #ifndef MA", + " if (tmp_nr > 0. && tmp_nr < nr1)", + " { printf(\" \tstate-vector as stored = %%.0f byte\",", + " (tmp_nr)/(nstates-nShadow) -", + " (double) (sizeof(H_el) - sizeof(unsigned)));", + " printf(\" + %%ld byte overhead\\n\",", + " (long int) sizeof(H_el)-sizeof(unsigned));", + " }", + " #endif", + " #endif", + " #if !defined(MA) || defined(COLLAPSE)", + " #ifdef BFS_PAR", + " printf(\"%%9.3f\tshared memory used for hash table (-w%%d)\\n\",", + " ((double) bfs_pre_allocated)/1048576., ssize);", + " #else", + " printf(\"%%9.3f\tmemory used for hash table (-w%%d)\\n\",", + " nr3/1048576., ssize);", + " remainder -= nr3;", + " #endif", + " #endif", + " #endif", " #ifndef BFS", " printf(\"%%9.3f\tmemory used for DFS stack (-m%%ld)\\n\",", " nr2/1048576., maxdepth);", " remainder -= nr2;", " #endif", - "#if NCORE>1", + " #if NCORE>1", " remainder -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE;", " printf(\"%%9.3f\tshared memory used for work-queues\\n\",", " (GWQ_SIZE + (double) NCORE * LWQ_SIZE) /1048576.);", @@ -4168,13 +4600,20 @@ " #endif", " #endif", " if (remainder - fragment > 1048576.)", - " printf(\"%%9.3f\tother (proc and chan stacks)\\n\",", + " { printf(\"%%9.3f\tother (proc and chan stacks)\\n\",", " (remainder-fragment)/1048576.);", + " }", " if (fragment > 1048576.)", - " printf(\"%%9.3f\tmemory lost to fragmentation\\n\",", + " { printf(\"%%9.3f\tmemory lost to fragmentation\\n\",", " fragment/1048576.);", + " }", + " #ifdef BFS_PAR", + " printf(\"%%9.3f\ttotal non-shared memory usage\\n\\n\",", + " memcnt/1048576.);", + " #else", " printf(\"%%9.3f\ttotal actual memory usage\\n\\n\",", " memcnt/1048576.);", + " #endif", " }", " #ifndef MA", " else", @@ -4184,22 +4623,26 @@ "#if !defined(BITSTATE) && defined(NOCOMP)", "jump_here:", "#endif", - - "#ifndef MA", - " printf(\"%%9.3f\tmemory usage (Mbyte)\\n\\n\",", - " memcnt/1048576.);", - "#endif", + "#ifndef MA", + " printf(\"%%9.3f\tmemory usage (Mbyte)\\n\",", + " memcnt/1048576.);", + "#endif", + "#ifdef BFS_PAR", + " bfs_report_mem();", + "#else", + " printf(\"\\n\");", + "#endif", "#ifdef COLLAPSE", - " printf(\"nr of templates: [ globals chans procs ]\\n\");", + " printf(\"nr of templates: [ 0:globals 1:chans 2:procs ]\\n\");", " printf(\"collapse counts: [ \");", " { int i; for (i = 0; i < 256+2; i++)", " if (ncomps[i] != 0)", - " printf(\"%%d \", (int) ncomps[i]);", + " printf(\"%%d:%%lu \", i, ncomps[i]);", " printf(\"]\\n\");", " }", "#endif", " #ifdef TRIX", - " if (mverbose)", + " if (verbose)", " { int i;", " printf(\"TRIX counts:\\n\");", " printf(\" processes: \");", @@ -4241,11 +4684,17 @@ "#if NCORE>1 && defined(T_ALERT)", " crash_report();", "#endif", + "#ifndef BFS_PAR", " pan_exit(0);", + "#endif", "}\n", "void", "stopped(int arg)", - "{ printf(\"Interrupted\\n\");", + "{", + "#ifdef BFS_PAR", + " bfs_shutdown(\"interrupted\");", + "#endif", + " printf(\"Interrupted\\n\");", "#if NCORE>1", " was_interrupted = 1;", "#endif", @@ -4253,25 +4702,21 @@ " pan_exit(0);", "}", "", - "#ifdef SFH", "/*", " * super fast hash, based on Paul Hsieh's function", " * http://www.azillionmonkeys.com/qed/hash.html", " */", "#include ", /* for uint32_t etc */ - " #undef get16bits", - " #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \\", - " || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)", - " #define get16bits(d) (*((const uint16_t *) (d)))", - " #endif", - "", - " #ifndef get16bits", - " #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\\", - " +(uint32_t)(((const uint8_t *)(d))[0]) )", - " #endif", + " #undef get16bits", + " #if defined(__GNUC__) && defined(__i386__)", + " #define get16bits(d) (*((const uint16_t *) (d)))", + " #else", + " #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\\", + " +(uint32_t)(((const uint8_t *)(d))[0]) )", + " #endif", "", "void", - "d_sfh(const char *s, int len)", + "d_sfh(uchar *s, int len)", /* sets one 32-bit number, in K1 */ "{ uint32_t h = len, tmp;", " int rem;", "", @@ -4309,10 +4754,8 @@ "", " K1 = h;", "}", - "#endif", /* SFH */ "", - "#include ", /* uint32_t etc. */ - "#if defined(HASH64) || defined(WIN64)", + "#if WS>4", "/* 64-bit Jenkins hash, 1997", " * http://burtleburtle.net/bob/c/lookup8.c", " */", @@ -4357,14 +4800,14 @@ "#endif", "", "void", - "d_hash(uchar *kb, int nbytes)", + "d_hash(uchar *kb, int nbytes)", /* sets two 64-bit or 32-bit nrs, depending on WS */ "{ uint8_t *bp;", - "#if defined(HASH64) || defined(WIN64)", + "#if WS>4", " uint64_t a = 0, b, c, n;", - " uint64_t *k = (uint64_t *) kb;", + " const uint64_t *k = (uint64_t *) kb;", "#else", " uint32_t a = 0, b, c, n;", - " uint32_t *k = (uint32_t *) kb;", + " const uint32_t *k = (uint32_t *) kb;", "#endif", " n = nbytes/WS; /* nr of words */", " /* extend to multiple of words, if needed */", @@ -4373,7 +4816,7 @@ " { n++;", " bp = kb + nbytes;", " switch (a) {", - "#if defined(HASH64) || defined(WIN64)", + "#if WS>4", " case 7: *bp++ = 0; /* fall thru */", " case 6: *bp++ = 0; /* fall thru */", " case 5: *bp++ = 0; /* fall thru */", @@ -4384,7 +4827,7 @@ " case 1: *bp = 0;", " case 0: break;", " } }", - "#if defined(HASH64) || defined(WIN64)", + "#if WS>4", " b = HASH_CONST[HASH_NR];", " c = 0x9e3779b97f4a7c13LL; /* arbitrary value */", " while (n >= 3)", @@ -4421,38 +4864,151 @@ " case 0: break;", " }", "#endif", - " j1_spin = c&nmask; j3 = a&7; /* 1st bit */", - " j2 = b&nmask; j4 = (a>>3)&7; /* 2nd bit */", + " j1_spin = c&nmask; j3_spin = a&7; /* 1st bit */", + " j2_spin = b&nmask; j4_spin = (a>>3)&7; /* 2nd bit */", " K1 = c; K2 = b;", "}", "", - "void", - "s_hash(uchar *cp, int om)", - "{", - "#if defined(SFH)", - " d_sfh((const char *) cp, om); /* sets K1 */", - "#else", - " d_hash(cp, om); /* sets K1 etc */", - "#endif", + "#if defined(MURMUR) && (WS==8)", + "/* public-domain, 64-bit MurmurHash3, by Austin Appleby */", + "/* https://code.google.com/p/smhasher/wiki/MurmurHash3 */", + "void", + "m_hash(uchar *v, int len)", + "{ uint8_t *bp, *data = (uint8_t*) v;", + " int i, nblocks = len / 16;", + "", + " uint64_t h1 = HASH_CONST[HASH_NR];", + " uint64_t h2 = 0x9e3779b97f4a7c13LL;", + "", + " uint64_t c1 = 0x87c37b91114253d5;", + " uint64_t c2 = 0x4cf5ad432745937f;", + "", + " uint64_t *blocks = (uint64_t *)(data);", + "", + " /* guarantee a multiple of 16 bytes */", + " i = 16 - (len %% 16);", + " if (i > 0 && i < 16)", + " { nblocks++;", + " bp = v + len;", + " switch (i) {", + " case 15: *bp++ = 0; /* fall thru */", + " case 14: *bp++ = 0;", + " case 13: *bp++ = 0;", + " case 12: *bp++ = 0;", + " case 11: *bp++ = 0;", + " case 10: *bp++ = 0;", + " case 9: *bp++ = 0;", + " case 8: *bp++ = 0;", + " case 7: *bp++ = 0;", + " case 6: *bp++ = 0;", + " case 5: *bp++ = 0;", + " case 4: *bp++ = 0;", + " case 3: *bp++ = 0;", + " case 2: *bp++ = 0;", + " case 1: *bp = 0;", + " case 0: break;", + " } }", + "", + " for (i = 0; i < nblocks; i++)", + " { uint64_t k1 = blocks[i*2];", + " uint64_t k2 = blocks[i*2+1];", + "", + " k1 *= c1;", + " k1 = (k1 << 31) | (k1 >> 33);", + " k1 *= c2;", + " h1 ^= k1;", + "", + " h1 = (h1 << 27) | (h1 >> 37);", + " h1 += h2;", + " h1 = h1 * 5 + 0x52dce729;", + "", + " k2 *= c2;", + " k2 = (k2 << 33) | (k2 >> 31);", + " k2 *= c1;", + " h2 ^= k2;", + "", + " h2 = (h2 << 31) | (h2 >> 33);", + " h2 += h1;", + " h2 = h2 * 5 + 0x38495ab5;", + " }", + "", + " uint8_t *tail = (uint8_t*)(data + (nblocks * 16));", + "", + " uint64_t k1 = 0;", + " uint64_t k2 = 0;", + "", + " switch(len & 15) {", + " case 15: k2 ^= ((uint64_t) tail[14]) << 48; break;", + " case 14: k2 ^= ((uint64_t) tail[13]) << 40; break;", + " case 13: k2 ^= ((uint64_t) tail[12]) << 32; break;", + " case 12: k2 ^= ((uint64_t) tail[11]) << 24; break;", + " case 11: k2 ^= ((uint64_t) tail[10]) << 16; break;", + " case 10: k2 ^= ((uint64_t) tail[ 9]) << 8; break;", + " case 9: k2 ^= ((uint64_t) tail[ 8]) << 0; break;", + " k2 *= c2;", + " k2 = (k2 << 33) | (k2 >> 31);", + " k2 *= c1;", + " h2 ^= k2; break;", + " case 8: k1 ^= ((uint64_t) tail[7]) << 56; break;", + " case 7: k1 ^= ((uint64_t) tail[6]) << 48; break;", + " case 6: k1 ^= ((uint64_t) tail[5]) << 40; break;", + " case 5: k1 ^= ((uint64_t) tail[4]) << 32; break;", + " case 4: k1 ^= ((uint64_t) tail[3]) << 24; break;", + " case 3: k1 ^= ((uint64_t) tail[2]) << 16; break;", + " case 2: k1 ^= ((uint64_t) tail[1]) << 8; break;", + " case 1: k1 ^= ((uint64_t) tail[0]) << 0; break;", + " k1 *= c1;", + " k1 = (k1 << 31) | (k1 >> 33);", + " k1 *= c2;", + " h1 ^= k1;", + " };", + "", + " h1 ^= len; h2 ^= len;", + " h1 += h2;", + " h2 += h1;", + " h1 ^= h1 >> 33;", + " h1 *= 0xff51afd7ed558ccd;", + " h1 ^= h1 >> 33;", + " h1 *= 0xc4ceb9fe1a85ec53;", + " h1 ^= h1 >> 33;", + " h2 ^= h2 >> 33;", + " h2 *= 0xff51afd7ed558ccd;", + " h2 ^= h2 >> 33;", + " h2 *= 0xc4ceb9fe1a85ec53;", + " h2 ^= h2 >> 33;", + " h1 += h2;", + " h2 += h1;", + "", + " j1_spin = h1&nmask; j3_spin = (h1>>48)&7;", + " j2_spin = h2&nmask; j4_spin = (h2>>48)&7;", + " K1 = h1; K2 = h2;", + "}", + "#endif", + "", + "void", + "s_hash(uchar *cp, int om)", /* uses either d_sfh (1x32bit), or d_hash (2x64bit) */ + "{", /* depending on ssize ie the -w parameter */ + " hasher(cp, om); /* sets K1 */", "#ifdef BITSTATE", " if (S_Tab == H_tab)", /* state stack in bitstate search */ " j1_spin = K1 %% omaxdepth;", " else", - "#endif", /* if (S_Tab != H_Tab) */ - " if (ssize < 8*WS)", - " j1_spin = K1&mask;", - " else", - " j1_spin = K1;", + "#endif", + " if (ssize < 8*WS)", + " j1_spin = K1&mask;", + " else", + " j1_spin = K1;", "}", "#ifndef RANDSTOR", "int *prerand;", "void", "inirand(void)", "{ int i;", - " srand(123); /* fixed startpoint */", + " srand(s_rand+HASH_NR);", /* inirand */ " prerand = (int *) emalloc((omaxdepth+3)*sizeof(int));", " for (i = 0; i < omaxdepth+3; i++)", - " prerand[i] = rand();", + " { prerand[i] = rand();", + " }", "}", "int", "pan_rand(void)", @@ -4462,7 +5018,7 @@ "#endif", "", "void", - "set_masks(void) /* 4.2.5 */", + "set_masks(void)", "{", " if (WS == 4 && ssize >= 32)", " { mask = 0xffffffff;", @@ -4491,30 +5047,32 @@ " }", "}", "", - "static long reclaim_size;", - "static char *reclaim_mem;", "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", "#if NCORE>1", - " #error cannot combine AUTO_RESIZE with NCORE>1 yet", + " #error cannot combine AUTO_RESIZE with NCORE>1", "#endif", - "static struct H_el **N_tab;", + "static long reclaim_size;", + "static char *reclaim_mem;", + "static H_el **N_tab;", "void", - "reverse_capture(struct H_el *p)", + "reverse_capture(H_el *p)", "{ if (!p) return;", " reverse_capture(p->nxt);", " /* last element of list moves first */", " /* to preserve list-order */", - " j2 = p->m_K1;", + " j2_spin = p->m_K1;", " if (ssize < 8*WS) /* probably always true */", - " { j2 &= mask;", + " { j2_spin &= mask;", " }", - " p->nxt = N_tab[j2];", - " N_tab[j2] = p;", + " p->nxt = N_tab[j2_spin];", + " N_tab[j2_spin] = p;", "}", "void", "resize_hashtable(void)", "{", + "#ifndef BFS_PAR", /* ssize and mask/nmask are not in shared mem */ " if (WS == 4 && ssize >= 27 - 1)", + "#endif", " { return; /* cannot increase further */", " }", "", @@ -4522,9 +5080,7 @@ "", " printf(\"pan: resizing hashtable to -w%%d.. \", ssize);", "", - " N_tab = (struct H_el **)", - " emalloc((ONE_L< and compile with -lm */", + "blog2(int n) /* n >= 1 */", + "{ int m=1, r=2;", + " if (n == 1) { return 0; }", + " if (n == 2) { return 1; }", + " while (n > r) { m++; r *= 2; }", + " return m;", + "}", + "#endif", + "", + "uint pp[33];", + "", + "uint ", + "mul(uint a, uint b, uint p)", + "{ int c = 0;", + " while (a)", + " { if (a&1)", + " { a ^= 1;", + " c ^= b;", + " }", + " a = (a>>1);", + " if (b & 0x80000000)", + " { b += b;", + " b ^= p;", + " } else", + " { b += b;", + " } }", + " return c;", + "}", + "", + "uint", + "ppow(int n, uint p)", + "{ uint t = 1; int i;", + " for (i = 0; i < 32; i++)", + " { if (n & (1<0)", " s_rand = P_RAND;", - "#endif", /* else, could use time as seed... */ + "#endif", "", "#ifdef PUTPID", " { char *ptr = strrchr(argv[0], '/');", @@ -4600,11 +5237,14 @@ "#endif", "", "#ifdef BITSTATE", - " bstore = bstore_reg; /* default */", + " b_store = bstore_reg; /* default */", "#endif", - "#if NCORE>1", - " { int i, j;", + + " { int j;", " strcpy(o_cmdline, \"\");", + " if (strlen(argv[0]) < sizeof(o_cmdname))", + " { strcpy(o_cmdname, argv[0]);", + " }", " for (j = 1; j < argc; j++)", " { strcat(o_cmdline, argv[j]);", " strcat(o_cmdline, \" \");", @@ -4613,23 +5253,35 @@ " if (strlen(o_cmdline) >= sizeof(o_cmdline))", " { Uerror(\"option list too long\");", " } }", - "#endif", + " while (argc > 1 && argv[1][0] == '-')", " { switch (argv[1][1]) {", "#ifndef SAFETY", - "#ifdef NP", - " case 'a': fprintf(efd, \"error: -a disabled\");", - " usage(efd); break;", - "#else", + " #ifdef NP", + " case 'a': fprintf(efd, \"warning: -a is disabled by -DNP, ignored\\n\");", + " break;", + " #else", " case 'a': a_cycles = 1; break;", - "#endif", + " #endif", + "#else", + " #if defined(BFS_PAR) && defined(L_BOUND)", + " case 'a': if (isdigit(argv[1][2]))", + " { L_bound = atoi(&argv[1][2]);", + " if (L_bound < 1 || L_bound > 255)", + " { printf(\"usage: -aN with 00", " case 'C': coltrace = 1; goto samething;", + " #endif", "#endif", - " case 'c': upto = atoi(&argv[1][2]); break;", + " case 'c': upto = atoi(&argv[1][2]); break;", " case 'D': dodot++; state_tables++; break;", " case 'd': state_tables++; break;", " case 'e': every_error = 1; upto = 0; Nr_Trails = 1; break;", @@ -4643,12 +5295,29 @@ " case 'f': fairness = 1; break;", "#endif", "#ifdef HAS_CODE", + " #if HAS_CODE>0", " case 'g': gui = 1; goto samething;", + " #endif", "#endif", - " case 'h': if (!argv[1][2]) usage(efd); else", - " HASH_NR = atoi(&argv[1][2])%%100; break;", + " case 'h':", + " if (strncmp(&argv[1][1], \"hash\", strlen(\"hash\")) == 0)", + " { do_hashgen = 1;", + " break;", + " }", + " if (!argv[1][2] || !isdigit((int) argv[1][2]))", + " { usage(efd); /* exits */", + " }", + " HASH_NR = atoi(&argv[1][2])%%(sizeof(HASH_CONST)/sizeof(uint));", + " break;", " case 'I': iterative = 2; every_error = 1; break;", - " case 'i': iterative = 1; every_error = 1; break;", + " case 'i':", + " if (strncmp(&argv[1][1], \"i_reverse\", strlen(\"i_reverse\")) == 0)", + " { reversing |= 1;", + " } else", + " { iterative = 1;", + " every_error = 1;", + " }", + " break;", " case 'J': like_java = 1; break; /* Klaus Havelund */", "#ifdef BITSTATE", " case 'k': hfns = atoi(&argv[1][2]); break;", @@ -4672,7 +5341,7 @@ "#ifdef NP", " case 'l': a_cycles = 1; break;", "#else", - " case 'l': fprintf(efd, \"error: -l disabled\");", + " case 'l': fprintf(efd, \"error: -l not available (compile with -DNP)\");", " usage(efd); break;", "#endif", "#endif", @@ -4685,39 +5354,112 @@ " break;", "#endif", " case 'm': maxdepth = atoi(&argv[1][2]); break;", -"#ifndef NOCLAIM", + "#ifndef NOCLAIM", " case 'N':", - "#if NCLAIMS>1", - " if (isdigit(argv[1][2]))", - " whichclaim = atoi(&argv[1][2]);", - " else if (isalpha(argv[1][2]))", + " #if NCLAIMS>1", + " if (isdigit((int)argv[1][2]))", + " { whichclaim = atoi(&argv[1][2]);", + " } else if (isalpha((int)argv[1][2]))", " { claimname = &argv[1][2];", " } else if (argc > 2 && argv[2][0] != '-') /* check next arg */", " { claimname = argv[2];", " argc--; argv++; /* skip next arg */", " }", - "#else", - " #if NCLAIMS==1", - " fprintf(stderr, \"warning: only one claim defined, -N ignored\\n\");", " #else", + " #if NCLAIMS==1", + " fprintf(stderr, \"warning: only one claim defined, -N ignored\\n\");", + " #else", " fprintf(stderr, \"warning: no claims defined, -N ignored\\n\");", - " #endif", - " if (!isdigit(argv[1][2]) && argc > 2 && argv[2][0] != '-')", + " #endif", + " if (!isdigit((int)argv[1][2]) && argc > 2 && argv[2][0] != '-')", " { argc--; argv++;", " }", + " #endif", "#endif", -"#endif", " break;\n", " case 'n': no_rck = 1; break;", - " case 'P': readtrail = 1; onlyproc = atoi(&argv[1][2]);", - " if (argv[2][0] != '-') /* check next arg */", + "", + " case 'P':", + " if (!readtrail", + " && isdigit((int) argv[1][2]))", /* was argv[1][2] == '_' */ + " { int x = atoi(&argv[1][2]);", + " if (x != 0 && x != 1)", + " { fprintf(efd, \"pan: bad option -P[01], ignored\\n\");", + " }", + " if (x == 0)", + " { reversing &= ~1;", + " break;", + " }", + " if (x == 1)", + " { reversing |= 1;", + " break;", + " }", + " if (verbose)", + " fprintf(efd, \"pan: reversed *active* process creation %%s\\n\",", + " reversing&1?\"on\":\"off\");", + " break;", + " } /* else */", + "#ifdef HAS_CODE", + " #if HAS_CODE>0", + " readtrail = 1; onlyproc = atoi(&argv[1][2]);", + " if (argc > 2 && argv[2][0] != '-') /* check next arg */", " { trailfilename = argv[2];", " argc--; argv++; /* skip next arg */", " }", + " #else", + " fprintf(efd, \"pan: option -P not recognized, ignored\\n\");", + " #endif", + "#else", + " fprintf(efd, \"pan: option -P not recognized, ignored\\n\");", + "#endif", " break;", + "", + " case 'p':", + " #if !defined(BFS) && !defined(BFS_PAR)", + " #ifdef PERMUTED", + " if (strncmp(&argv[1][1], \"p_normal\", strlen(\"p_normal\")) == 0)", + " { reversing &= ~2;", + " break;", + " }", + " reversing |=2;", + " if (strncmp(&argv[1][1], \"p_permute\", strlen(\"p_permute\")) == 0)", + " { p_reorder = set_permuted;", + " break;", + " }", + " if (strncmp(&argv[1][1], \"p_rotate\", strlen(\"p_rotate\")) == 0)", + " { p_reorder = set_rotated;", + " if (isdigit((int) argv[1][9]))", + " { p_rotate = atoi(&argv[1][9]);", + " } else", + " { p_rotate = 1;", + " }", + " break;", + " }", + " if (strncmp(&argv[1][1], \"p_randrot\", strlen(\"p_randrot\")) == 0)", + " { p_reorder = set_randrot;", + " break;", + " }", + " if (strncmp(&argv[1][1], \"p_reverse\", strlen(\"p_reverse\")) == 0)", + " { p_reorder = set_reversed;", + " break;", + " }", + " #else", + " if (strncmp(&argv[1][1], \"p_permute\", strlen(\"p_permute\")) == 0", + " || strncmp(&argv[1][1], \"p_rotate\", strlen(\"p_rotate\")) == 0", + " || strncmp(&argv[1][1], \"p_randrot\", strlen(\"p_randrot\")) == 0", + " || strncmp(&argv[1][1], \"p_reverse\", strlen(\"p_reverse\")) == 0)", + " { fprintf(efd, \"option %%s required compilation with -DPERMUTED\\n\",", + " argv[1]);", + " exit(1);", + " }", + " #endif", + " #endif", "#ifdef SVDUMP", - " case 'p': vprefix = atoi(&argv[1][2]); break;", + " vprefix = atoi(&argv[1][2]);", + "#else", + " fprintf(efd, \"invalid option '%%s' -- ignored\\n\", argv[1]);", "#endif", + " break;", "#if NCORE==1", " case 'Q': quota = (double) 60.0 * (double) atoi(&argv[1][2]);", " #ifndef FREQ", @@ -4727,18 +5469,65 @@ "#endif", " case 'q': strict = 1; break;", " case 'R':", - "#if defined(T_RAND) || defined(P_RAND) || defined(RANDSTOR)", " if (argv[1][2] == 'S') /* e.g., -RS76842 */", - " { s_rand = atoi(&argv[1][3]);", - " } else", - "#endif", - " { Nrun = atoi(&argv[1][2]);", + " { s_rand = atoi(&argv[1][3]);", /* RS */ + " break;", + " }", + "#ifdef BITSTATE", + " Nrun = atoi(&argv[1][2]);", + " if (Nrun > 100)", + " { Nrun = 100;", + " } else if (Nrun < 1)", + " { Nrun = 1;", " }", + "#else", + " usage(efd);", " break;", - "#ifdef HAS_CODE", + "#endif", " case 'r':", + " if (strncmp(&argv[1][1], \"rhash\", strlen(\"rhash\")) == 0)", + " { if (s_rand == 12345) /* default seed */", + " {", + "#if defined(WIN32) || defined(WIN64)", + " s_rand = (uint) clock();", + "#else", + " struct tms dummy_tm;", + " s_rand = (uint) times(&dummy_tm);", + "#endif", + " }", + " srand(s_rand++);", + " #ifdef PERMUTED", + " do_hashgen = 1;", /* + randomize p_rotate, p_reverse, p_permute */ + " switch (rand()%%5) {", + " case 0: p_reorder = set_permuted;", + " reversing |=2;", + " break;", + " case 1: p_reorder = set_reversed;", + " reversing |=2;", + " break;", + " /* fully randomize p_rotate: */", + " case 2: p_reorder = set_randrot;", + " reversing |=2;", + " break;", + " /* choose once, then keep p_rotate fixed: */", + " case 3: p_reorder = set_rotated;", + " p_rotate = rand()%%3;", + " reversing |=2;", + " break;", + " default: /* standard search */ break;", + " }", + " if (rand()%%2 == 0)", + " { t_reverse = 1;", + " }", + " break;", + " #else", + " fprintf(efd, \"option -rhash requires compilation with -DPERMUTED\\n\");", + " exit(1);", + " #endif", + " }", + "#if defined(HAS_CODE) && HAS_CODE>0", "samething: readtrail = 1;", - " if (isdigit(argv[1][2]))", + " if (isdigit((int)argv[1][2]))", " whichtrail = atoi(&argv[1][2]);", " else if (argc > 2 && argv[2][0] != '-') /* check next arg */", " { trailfilename = argv[2];", @@ -4746,27 +5535,53 @@ " }", " break;", " case 'S': silent = 1; goto samething;", + "#else", + " fprintf(efd, \"options -r is for models with embedded C code\\n\");", + " break;", "#endif", - "#ifdef BITSTATE", - " case 's': hfns = 1; break;", - "#endif", - " case 'T': TMODE = 0444; break;", - " case 't': if (argv[1][2]) tprefix = &argv[1][2]; break;", + " case 'T':", + " if (isdigit((int) argv[1][2]))", /* was argv[1][2] == '_' */ + " { t_reverse = atoi(&argv[1][2]);", + " if (verbose)", + " printf(\"pan: reverse transition ordering %%s\\n\",", + " t_reverse?\"on\":\"off\");", + " break;", + " }", + " TMODE = 0444;", + " break;", + " case 't':", + " if (strncmp(&argv[1][1], \"t_reverse\", strlen(\"t_reverse\")) == 0)", + " { t_reverse = 1;", + " break;", + " }", /* i.e., a trail prefix cannot be '_reverse' */ + " if (argv[1][2])", + " { tprefix = &argv[1][2];", + " }", + " break;", + " case 'u':", + " #ifdef BFS_PAR", + " ncores = atoi(&argv[1][2]);", + " #endif", + " break;", " case 'V': start_timer(); printf(\"Generated by %%s\\n\", SpinVersion);", " to_compile(); pan_exit(2); break;", " case 'v': verbose++; break;", - " case 'w': ssize = atoi(&argv[1][2]); break;", + " case 'w': ssize = atoi(&argv[1][2]);", + " #if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + " used_w = 1;", + " #endif", + " break;", " case 'Y': signoff = 1; break;", " case 'X': efd = stdout; break;", " case 'x': exclusive = 1; break;", - "#if NCORE>1", + " #if NCORE>1", " /* -B ip is passthru to proxy of remote ip address: */", " case 'B': argc--; argv++; break;", " case 'Q': worker_pids[0] = atoi(&argv[1][2]); break;", - " /* -Un means that the nth worker should be instantiated as a proxy */", + " /* -Un means that the nth worker should be instantiated as a proxy */", " case 'U': proxy_pid = atoi(&argv[1][2]); break;", - " /* -W means that this copy is started by a cluster-server as a remote */", - " /* this flag is passed to ./pan_proxy, which interprets it */", + " /* -W means this copy is started by a cluster-server as a remote */", + " /* this flag is passed to ./pan_proxy, which interprets it */", " case 'W': remote_party++; break;", " case 'Z': core_id = atoi(&argv[1][2]);", " if (verbose)", @@ -4775,28 +5590,72 @@ " }", " break;", " case 'z': z_handoff = atoi(&argv[1][2]); break;", - "#else", + " #else", " case 'z': break; /* ignored for single-core */", - "#endif", - " default : fprintf(efd, \"saw option -%%c\\n\", argv[1][1]); usage(efd); break;", + " #endif", + " default : fprintf(efd, \"saw option -%%c\\n\",", + " argv[1][1]); usage(efd); break;", " }", " argc--; argv++;", " }", + "#if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + " if (used_w == 0)", + " { if (ncores == 0) /* all cores used, by default */", + " { ssize -= blog2(BFS_MAXPROCS - 1);", + " } else", + " { ssize -= blog2(ncores);", + " } }", + "#endif", + " if (do_hashgen)", + " { hashgen();", /* placed here so that -RSn can appear after -hash */ + " }", + "#ifndef SAFETY", + " if (fairness && !a_cycles)", + " { fprintf(efd, \"error: -f requires the use of -a or -l\\n\");", + " usage(efd);", + " }", + " #if ACCEPT_LAB==0", + " if (a_cycles)", + " { fprintf(efd, \"warning: no accept labels are defined, \");", + " fprintf(efd, \"so option -a has no effect (ignored)\\n\");", + " a_cycles = 0;", + " }", + " #endif", + "#endif", + "", + "#ifdef BFS_PAR", + " uerror = bfs_uerror;", + " Uerror = bfs_Uerror;", + "#else", + " uerror = dfs_uerror;", + " Uerror = dfs_Uerror;", + "#endif", + " if (ssize <= 32) /* 6.2.0 */", + " { hasher = d_sfh;", + "#if !defined(BITSTATE) && defined(USE_TDH)", + " o_hash = o_hash32;", + "#endif", + " } else", + " { hasher = d_hash;", + "#if !defined(BITSTATE) && defined(USE_TDH)", + " o_hash = o_hash64;", + "#endif", + " }", " if (iterative && TMODE != 0666)", " { TMODE = 0666;", " fprintf(efd, \"warning: -T ignored when -i or -I is used\\n\");", " }", - "#if defined(HASH32) && !defined(SFH)", - " if (WS > 4)", - " { fprintf(efd, \"strong warning: compiling -DHASH32 on a 64-bit machine\\n\");", - " fprintf(efd, \" without -DSFH can slow down performance a lot\\n\");", - " }", - "#endif", "#if defined(WIN32) || defined(WIN64)", + " #ifndef _S_IWRITE", + " #define S_IWRITE 0000200 /* write permission, owner */", + " #endif", + " #ifndef _S_IREAD", + " #define S_IREAD 0000400 /* read permission, owner */", + " #endif", " if (TMODE == 0666)", - " TMODE = _S_IWRITE | _S_IREAD;", + " TMODE = S_IWRITE | S_IREAD;", " else", - " TMODE = _S_IREAD;", + " TMODE = S_IREAD;", "#endif", "#if NCORE>1", " store_proxy_pid = proxy_pid; /* for checks in mem_file() and someone_crashed() */", @@ -4828,6 +5687,9 @@ " #error cannot use hidden variables when compiling multi-core", " #endif", "#endif", + "#if defined(T_RAND) && defined(ELSE_IN_GUARD)", + " #error cannot hide 'else' as guard in d_step, when using -DT_RAND", + "#endif", "#ifdef BITSTATE", " if (hfns <= 0)", " { hfns = 1;", @@ -4841,7 +5703,7 @@ " fprintf(efd, \"warning: using -w%%d as max usable value\\n\", ssize);", "/*", " * -w35 would not work: 35-3 = 32 but 1^31 is the largest", - " * power of 2 that can be represented in an unsigned long", + " * power of 2 that can be represented in an ulong", " */", " }", "#else", @@ -4904,6 +5766,23 @@ " #ifdef MA", " #error cannot combine -DTRIX and -DMA", " #endif", + " #if defined(BFS_PAR) && defined(BFS_SEP_HEAP)", + " #error cannot combined -DBFS_SEP_HEAP with -DTRIX", + " #endif", + "#endif", + + "#ifdef BFS_PAR", + " #ifdef NP", + " #error cannot combine -DBFS_PAR and -DNP", + " #undef NP", + " #endif", + "#endif", + + "#ifdef NOCLAIM", + " #ifdef NP", + " #warning using -DNP overrides -DNOCLAIM", + " #undef NOCLAIM", + " #endif", "#endif", "#ifdef BCS", @@ -4918,14 +5797,9 @@ "#if defined(MERGED) && defined(PEG)", " #error to use -DPEG use: spin -o3 -a", "#endif", - "#ifdef HC", - " #ifdef SFH", /* cannot happen -- undef-ed in this case */ - " #error cannot combine -DHC and -DSFH", - " /* use of NOCOMP is the real reason */", - " #else", - " #ifdef NOCOMP", + "#if defined(HC) && !defined(BFS_PAR)", + " #ifdef NOCOMP", " #error cannot combine -DHC and -DNOCOMP", - " #endif", " #endif", " #ifdef BITSTATE", " #error cannot combine -DHC and -DBITSTATE", @@ -4941,18 +5815,19 @@ " #if MA <= 0", " #error usage: -DMA=N with N > 0 and N < VECTORSZ", " #endif", + " #ifndef NOREDUCE", + " if (a_cycles)", + " { fprintf(stderr, \"warning: liveness checking with -DMA \");", + " fprintf(stderr, \"but without -DNOREDUCE may be incomplete\\n\");", + " }", + " #endif", "#endif", "#ifdef COLLAPSE", " #ifdef BITSTATE", " #error cannot combine -DBITSTATE and -DCOLLAPSE", " #endif", - " #ifdef SFH", - " #error cannot combine -DCOLLAPSE and -DSFH", - " /* use of NOCOMP is the real reason */", - " #else", - " #ifdef NOCOMP", + " #ifdef NOCOMP", " #error cannot combine -DCOLLAPSE and -DNOCOMP", - " #endif", " #endif", "#endif", " if (maxdepth <= 0 || ssize <= 1) usage(efd);", @@ -4974,33 +5849,20 @@ " pan_exit(1);", " }", "#endif", - "#ifdef MEMLIM", " memlim = ((double) MEMLIM) * (double) (1<<20); /* size in Mbyte */", "#endif", - - "#ifndef BITSTATE", - " if (Nrun > 1) HASH_NR = Nrun - 1;", - "#endif", - " if (Nrun < 1 || Nrun > 32)", - " { fprintf(efd, \"error: invalid arg for -R\\n\");", - " usage(efd);", - " }", - "#ifndef SAFETY", - " if (fairness && !a_cycles)", - " { fprintf(efd, \"error: -f requires -a or -l\\n\");", - " usage(efd);", - " }", - " #if ACCEPT_LAB==0", - " if (a_cycles)", - " { fprintf(efd, \"error: no accept labels defined \");", - " fprintf(efd, \"in model (for option -a)\\n\");", - " usage(efd);", - " }", + "#if SYNC>0", + " #ifdef HAS_PRIORITY", + " #error use of priorities cannot be combined with rendezvous", + " #elif HAS_ENABLED", + " #error use of enabled() cannot be combined with rendezvous", " #endif", "#endif", "#ifndef NOREDUCE", - " #ifdef HAS_ENABLED", + " #ifdef HAS_PRIORITY", + " #warning use of priorities requires -DNOREDUCE", + " #elif HAS_ENABLED", " #error use of enabled() requires -DNOREDUCE", " #endif", " #ifdef HAS_PCVALUE", @@ -5025,7 +5887,8 @@ " #endif", "#endif", "#if SYNC>0 && defined(BFS)", - " #warning use of rendezvous with BFS does not preserve all invalid endstates", + " if (!noends)", + " fprintf(efd, \"warning: use of rendezvous with BFS does not preserve all invalid endstates\\n\");", "#endif", "#if !defined(REACH) && !defined(BITSTATE)", " if (iterative != 0 && a_cycles == 0)", @@ -5052,11 +5915,16 @@ " && core_id == 0", " #endif", " && !state_tables)", + "#ifdef NP", + " { fprintf(efd, \"warning: non-progress claim \");", + " fprintf(efd, \"requires -l flag to fully verify\\n\");", + "#else", " { fprintf(efd, \"warning: never claim + accept labels \");", " fprintf(efd, \"requires -a flag to fully verify\\n\");", + "#endif", " }", " #else", - " if (!state_tables", + " if (verbose && !state_tables", " #ifdef HAS_CODE", " && !readtrail", " #endif", @@ -5068,6 +5936,7 @@ " #endif", "#endif", "#ifndef SAFETY", + " #if 0", " if (!a_cycles", " #ifdef HAS_CODE", " && !readtrail", @@ -5079,6 +5948,7 @@ " { fprintf(efd, \"hint: this search is more efficient \");", " fprintf(efd, \"if pan.c is compiled -DSAFETY\\n\");", " }", + " #endif", " #ifndef NOCOMP", " if (!a_cycles)", " { S_A = 0;", @@ -5095,13 +5965,17 @@ "#endif", " signal(SIGINT, stopped);", " set_masks();", - "#ifdef BFS", + "#if defined(BFS) || defined(BFS_PAR)", " trail = (Trail *) emalloc(6*sizeof(Trail));", " trail += 3;", "#else", " trail = (Trail *) emalloc((maxdepth+3)*sizeof(Trail));", " trail++; /* protect trpt-1 refs at depth 0 */", "#endif", + " trpt = &trail[0]; /* precaution -- in case uerror is called early */", + "#ifdef BFS", + " ntrpt = trpt;", + "#endif", "#ifdef SVDUMP", " if (vprefix > 0)", " { char nm[64];", @@ -5112,7 +5986,7 @@ " } }", "#endif", "#ifdef RANDSTOR", - " srand(s_rand);", + " srand(s_rand+HASH_NR);", /* main - RANDSTOR */ "#endif", "#if SYNC>0 && ASYNC==0", " set_recvs();", @@ -5152,7 +6026,9 @@ "#ifndef NOFAIR", " fprintf(fd, \"\t-f add weak fairness (to -a or -l)\\n\");", "#endif", - " fprintf(fd, \"\t-hN use different hash-seed N:1..32\\n\");", + " fprintf(fd, \"\t-hN use different hash-seed N:0..499 (defaults to -h0)\\n\");", + " fprintf(fd, \"\t-hash generate a random hash-polynomial for -h0 (see also -rhash)\\n\");", + " fprintf(fd, \"\t using a seed set with -RSn (default %%u)\\n\", s_rand);", " fprintf(fd, \"\t-i search for shortest path to error\\n\");", " fprintf(fd, \"\t-I like -i, but approximate and faster\\n\");", " fprintf(fd, \"\t-J reverse eval order of nested unlesses\\n\");", @@ -5181,6 +6057,11 @@ " fprintf(fd, \"\t-Nn -- use claim number n\\n\");", "#endif", " fprintf(fd, \"\t-n no listing of unreached states\\n\");", + "#ifdef PERMUTED", + " fprintf(fd, \"\t-p_permute randomize order in which processes are scheduled (see also -rhash)\\n\");", + " fprintf(fd, \"\t-p_reverse reverse order in which processes are scheduled (see also -rhash)\\n\");", + " fprintf(fd, \"\t-p_rotateN rotate by N the process scheduling order (see also -rhash)\\n\");", + "#endif", "#ifdef SVDUMP", " fprintf(fd, \"\t-pN create svfile (save N bytes per state)\\n\");", "#endif", @@ -5188,21 +6069,21 @@ " fprintf(fd, \"\t-q require empty chans in valid end states\\n\");", "#ifdef HAS_CODE", " fprintf(fd, \"\t-r read and execute trail - can add -v,-n,-PN,-g,-C\\n\");", + " fprintf(fd, \"\t-r trailfilename read and execute trail in file\\n\");", " fprintf(fd, \"\t-rN read and execute N-th error trail\\n\");", " fprintf(fd, \"\t-C read and execute trail - columnated output (can add -v,-n)\\n\");", - " fprintf(fd, \"\t-PN read and execute trail - restrict trail output to proc N\\n\");", + " fprintf(fd, \"\t-r -PN read and execute trail - restrict trail output to proc N\\n\");", " fprintf(fd, \"\t-g read and execute trail + msc gui support\\n\");", " fprintf(fd, \"\t-S silent replay: only user defined printfs show\\n\");", "#endif", - "#if defined(T_RAND) || defined(P_RAND) || defined(RANDSTOR)", - " fprintf(fd, \"\t-RSN use randomization seed N\\n\");", - "#endif", + " fprintf(fd, \"\t-RSn use randomization seed n\\n\");", + " fprintf(fd, \"\t-rhash use random hash-polynomial and randomly choose -p_rotateN, -p_permute, or p_reverse\\n\");", "#ifdef BITSTATE", - " fprintf(fd, \"\t-RN repeat run Nx with N \");", - " fprintf(fd, \"[1..32] independent hash functions\\n\");", - " fprintf(fd, \"\t-s same as -k1 (single bit per state)\\n\");", + " fprintf(fd, \"\t-Rn run n times n: [1..100] using n \");", + " fprintf(fd, \" different hash functions\\n\");", "#endif", " fprintf(fd, \"\t-T create trail files in read-only mode\\n\");", + " fprintf(fd, \"\t-t_reverse reverse order in which transitions are explored\\n\");", " fprintf(fd, \"\t-tsuf replace .trail with .suf on trailfiles\\n\");", " fprintf(fd, \"\t-V print SPIN version number\\n\");", " fprintf(fd, \"\t-v verbose -- filenames in unreached state listing\\n\");", @@ -5223,7 +6104,7 @@ "}", "", "char *", - "Malloc(unsigned long n)", + "Malloc(ulong n)", "{ char *tmp;", "#ifdef MEMLIM", " if (memcnt + (double) n > memlim)", @@ -5233,7 +6114,11 @@ "#endif", " tmp = (char *) malloc(n);", " if (!tmp)", - " { printf(\"pan: out of memory\\n\");", + " {", + "#ifdef BFS_PAR", + " Uerror(\"out of non-shared memory\");", + "#endif", + " printf(\"pan: out of memory\\n\");", "#ifdef MEMLIM", "err:", " printf(\"\t%%g bytes used\\n\", memcnt);", @@ -5277,13 +6162,13 @@ "#define CHUNK (100*VECTORSZ)", "", "char *", - "emalloc(unsigned long n) /* never released or reallocated */", + "emalloc(ulong n) /* never released or reallocated */", "{ char *tmp;", " if (n == 0)", " return (char *) NULL;", " if (n&(sizeof(void *)-1)) /* for proper alignment */", " n += sizeof(void *)-(n&(sizeof(void *)-1));", - " if ((unsigned long) left < n)", /* was: (left < (long)n) */ + " if ((ulong) left < n)", /* was: (left < (long)n) */ " { grow = (n < CHUNK) ? CHUNK : n;", #if 1 " have = Malloc(grow);", @@ -5308,12 +6193,15 @@ "}", "void", - "Uerror(char *str)", + "dfs_Uerror(char *str)", "{ /* always fatal */", " uerror(str);", "#if NCORE>1", " sudden_stop(\"Uerror\");", "#endif", + "#ifdef BFS_PAR", + " bfs_shutdown(\"Uerror\");", + "#endif", " wrapup();", "}\n", "#if defined(MA) && !defined(SAFETY)", @@ -5332,9 +6220,14 @@ " trpt = getframe(depth);", "#endif", "#ifdef VERBOSE", - " printf(\"%%d State: \", depth);", + " printf(\"%%ld State: \", depth);", + "#if !defined(NOCOMP) && !defined(HC)", " for (i = 0; i < vsize; i++) printf(\"%%d%%s,\",", " ((char *)&now)[i], Mask[i]?\"*\":\"\");", + "#else", + " for (i = 0; i < vsize; i++)", + " printf(\"%%d,\", ((char *)&now)[i]);", + "#endif", " printf(\"\\n\");", "#endif", "#ifndef NOFAIR", @@ -5351,7 +6244,7 @@ "#endif", "#ifdef HAS_LAST", "#ifdef VERI", - " { int d; Trail *trl;", + " { long d; Trail *trl;", " now._last = 0;", " for (d = 1; d < depth; d++)", " { trl = getframe(depth-d); /* was trl = (trpt-d); */", @@ -5374,13 +6267,13 @@ " }", " t = trpt->o_t;", " ot = trpt->o_ot; II = trpt->pr;", - " tt = trpt->o_tt; this = pptr(II);", + " tt = trpt->o_tt; _this = pptr(II);", " _m = do_reverse(t, II, trpt->o_m);", "#ifdef VERBOSE", " printf(\"%%3ld: proc %%d \", depth, II);", " printf(\"reverses %%d, %%d to %%d,\",", " t->forw, tt, t->st);", - " printf(\" %%s [abit=%%d,adepth=%%d,\", ", + " printf(\" %%s [abit=%%d,adepth=%%ld,\", ", " t->tp, now._a_t, A_depth);", " printf(\"tau=%%d,%%d] \\n\", ", " trpt->tau, (trpt-1)->tau);", @@ -5392,7 +6285,7 @@ " trpt--;", "#endif", " /* reached[ot][t->st] = 1; 3.4.13 */", - " ((P0 *)this)->_p = tt;", + " ((P0 *)_this)->_p = tt;", "#ifndef NOFAIR", " if ((trpt->o_pm&32))", " {", @@ -5419,21 +6312,21 @@ "#endif", "static char unwinding;", "void", - "uerror(char *str)", + "dfs_uerror(char *str)", "{ static char laststr[256];", " int is_cycle;", "", " if (unwinding) return; /* 1.4.2 */", " if (strncmp(str, laststr, 254))", "#if NCORE>1", - " cpu_printf(\"pan:%%d: %%s (at depth %%ld)\\n\", errors+1, str,", + " cpu_printf(\"pan:%%lu: %%s (at depth %%ld)\\n\", errors+1, str,", "#else", - " printf(\"pan:%%d: %%s (at depth %%ld)\\n\", errors+1, str,", + " printf(\"pan:%%lu: %%s (at depth %%ld)\\n\", errors+1, str,", "#endif", "#if NCORE>1", " (nr_handoffs * z_handoff) + ", "#endif", - " ((depthfound==-1)?depth:depthfound));", + " ((depthfound == -1)?depth:depthfound));", " strncpy(laststr, str, 254);", " errors++;", "#ifdef HAS_CODE", @@ -5460,7 +6353,7 @@ "#endif", "#ifdef BFS", " if (depth > 1) trpt--;", - " nuerror(str);", + " nuerror();", " if (depth > 1) trpt++;", "#else", " putrail();", @@ -5494,6 +6387,9 @@ "#endif", " if (errors >= upto && upto != 0)", " {", + "#ifdef BFS_PAR", + " bfs_shutdown(\"uerror\"); /* no return */", + "#endif", "#if NCORE>1", " sudden_stop(\"uerror\");", "#endif", @@ -5618,6 +6514,19 @@ " sprintf(snap, \"-4:-4:-4\\n\");", " if (write(fd, snap, strlen(snap)) < 0) return;", "#endif", + "#ifdef PERMUTED", + " sprintf(snap, \"-5:%%d:%%d\\n\", t_reverse, reversing&2);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "", + " sprintf(snap, \"-6:%%d:%%d\\n\", p_reorder==set_permuted, p_reorder==set_reversed);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "", + " sprintf(snap, \"-7:%%d:%%d\\n\", p_reorder==set_rotated, p_rotate);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "", + " sprintf(snap, \"-8:%%d:%%d\\n\", p_reorder==set_randrot, --s_rand);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "#endif", "#if NCORE>1 && !defined(SEP_STATE) && defined(FULL_TRAIL)", " rev_trail_cnt = 1;", " enter_critical(GLOBAL_LOCK);", @@ -5706,11 +6615,16 @@ "#ifdef DEBUG", " cpu_printf(\" sv_restor\\n\");", "#endif", - "}\n", + "}", + "", "void", "p_restor(int h)", "{ int i;", " char *z = (char *) &now;\n", + "", + "#ifdef BFS_PAR", + " bfs_prepmask(1); /* p_restor */", + "#endif", "#ifndef TRIX", " proc_offset[h] = stack->o_offset;", " proc_skip[h] = (uchar) stack->o_skip;", @@ -5739,14 +6653,14 @@ " memcpy((char *)pptr(h), stack->b_ptr, stack->o_delta);", " oi = stack->b_ptr;", "#else", - " #ifndef NOCOMP", + " #if !defined(NOCOMP) && !defined(HC)", " for (i = vsize + stack->o_skip; i > vsize; i--)", " Mask[i-1] = 1; /* align */", " #endif", " vsize += stack->o_skip;", " memcpy(z+vsize, stack->body, stack->o_delta);", " vsize += stack->o_delta;", - " #ifndef NOCOMP", + " #if !defined(NOCOMP) && !defined(HC)", " for (i = 1; i <= Air[((P0 *)pptr(h))->_t]; i++)", " Mask[vsize - i] = 1; /* pad */", " Mask[proc_offset[h]] = 1; /* _pid */", @@ -5755,6 +6669,9 @@ " ((P0 *)pptr(h))->_pid = h-BASE;", " else", " ((P0 *)pptr(h))->_pid = h;", + " #ifdef BFS_PAR", + " bfs_fixmask(1); /* p_restor */", + " #endif", "#endif", " now._nr_pr += 1;", "#ifndef NOVSZ", @@ -5764,7 +6681,7 @@ " if (!stack->lst)", " Uerror(\"error: p_restor\");", " stack = stack->lst;", - " this = pptr(h);", + " _this = pptr(h);", " while (i-- > 0)", " q_restor();", "#ifdef TRIX", @@ -5798,6 +6715,9 @@ " #ifndef NOCOMP", " int k, k_end;", " #endif", + " #ifdef BFS_PAR", + " bfs_prepmask(2); /* q_restor */", + " #endif", " q_offset[h] = stack->o_offset;", " q_skip[h] = (uchar) stack->o_skip;", " vsize += stack->o_skip;", @@ -5811,18 +6731,21 @@ " now._vsz = vsize;", "#endif", " now._nr_qs += 1;", - "#ifndef NOCOMP", "#ifndef TRIX", - " k_end = stack->o_offset;", - " k = k_end - stack->o_skip;", - " #if SYNC", - " #ifndef BFS", - " if (q_zero(now._nr_qs)) k_end += stack->o_delta;", + " #if !defined(NOCOMP) && !defined(HC)", + " k_end = stack->o_offset;", + " k = k_end - stack->o_skip;", + " #if SYNC", + " #ifndef BFS", + " if (q_zero(now._nr_qs)) k_end += stack->o_delta;", + " #endif", + " #endif", + " for ( ; k < k_end; k++)", + " Mask[k] = 1;", " #endif", + " #ifdef BFS_PAR", + " bfs_fixmask(2); /* q_restor */", " #endif", - " for ( ; k < k_end; k++)", - " Mask[k] = 1;", - "#endif", "#endif", " if (!stack->lst)", " Uerror(\"error: q_restor\");", @@ -5938,9 +6861,15 @@ " now._nr_pr -= 1;", " memset((char *)pptr(h), 0, d);", " vsize -= (int) proc_skip[h];", - " #ifndef NOCOMP", - " for (i = vsize; i < o_vsize; i++)", - " Mask[i] = 0; /* reset */", + " #if !defined(NOCOMP) && !defined(HC)", + " #ifdef BFS_PAR", + " bfs_prepmask(3); /* delproc - no chance in proc_offset or proc_skip */", + " #endif", + " for (i = vsize; i < o_vsize; i++)", + " Mask[i] = 0; /* reset */", + " #ifdef BFS_PAR", + " bfs_fixmask(3); /* delproc */", + " #endif", " #endif", "#endif", "#ifndef NOVSZ", @@ -5996,9 +6925,15 @@ "#else", " vsize = q_offset[h];", " vsize -= (int) q_skip[h];", - " #ifndef NOCOMP", + " #if !defined(NOCOMP) && !defined(HC)", + " #ifdef BFS_PAR", + " bfs_prepmask(3); /* delq - no change in q_offset or q_skip */", + " #endif", " for (k = vsize; k < o_vsize; k++)", " Mask[k] = 0; /* reset */", + " #ifdef BFS_PAR", + " bfs_fixmask(3); /* delq */", + " #endif", " #endif", "#endif", " now._nr_qs -= 1;", @@ -6032,7 +6967,7 @@ " return 0;", " }", " if (strict) return qs_empty();", - "#if defined(EVENT_TRACE) && !defined(OTIM)", + "#if defined(EVENT_TRACE)", " if (!stopstate[EVENT_TRACE][now._event] && !a_cycles)", " { printf(\"pan: event_trace not completed\\n\");", " return 0;", @@ -6040,50 +6975,51 @@ "#endif", " return 1;", "}\n", - "#ifndef SAFETY", + "#if !defined(SAFETY) && !defined(BFS)", "void", "checkcycles(void)", "{ uchar o_a_t = now._a_t;", - "#ifndef NOFAIR", - " uchar o_cnt = now._cnt[1];", - "#endif", - "#ifdef FULLSTACK", - "#ifndef MA", - " struct H_el *sv = trpt->ostate; /* save */", - "#else", - " uchar prov = trpt->proviso; /* save */", - "#endif", - "#endif", - "#ifdef DEBUG", - " { int i; uchar *v = (uchar *) &now;", - " printf(\" set Seed state \");", - "#ifndef NOFAIR", - " if (fairness) printf(\"(cnt = %%d:%%d, nrpr=%%d) \",", - " now._cnt[0], now._cnt[1], now._nr_pr);", - "#endif", - " /* for (i = 0; i < n; i++) printf(\"%%d,\", v[i]); */", - " printf(\"\\n\");", - " }", - " printf(\"%%ld: cycle check starts\\n\", depth);", - "#endif", + " #ifndef NOFAIR", + " uchar o_cnt = now._cnt[1];", + " #endif", + " #ifdef FULLSTACK", + " #ifndef MA", + " H_el *sv = trpt->ostate; /* save */", + " #else", + " uchar prov = trpt->proviso; /* save */", + " #endif", + " #endif", + " #ifdef DEBUG", + " { int i; uchar *v = (uchar *) &now;", + " printf(\" set Seed state \");", + " #ifndef NOFAIR", + " if (fairness)", + " printf(\"(cnt = %%d:%%d, nrpr=%%d) \",", + " now._cnt[0], now._cnt[1], now._nr_pr);", + " #endif", + " /* for (i = 0; i < n; i++) printf(\"%%d,\", v[i]); */", + " printf(\"\\n\");", + " }", + " printf(\"%%ld: cycle check starts\\n\", depth);", + " #endif", " now._a_t |= (1|16|32);", - " /* 1 = 2nd DFS; (16|32) to help hasher */", - "#ifndef NOFAIR", - " now._cnt[1] = now._cnt[0];", - "#endif", + " /* 1 = 2nd DFS; (16|32) to improve hashing */", + " #ifndef NOFAIR", + " now._cnt[1] = now._cnt[0];", + " #endif", " memcpy((char *)&A_Root, (char *)&now, vsize);", " A_depth = depthfound = depth;", - "#if NCORE>1", - " mem_put_acc();", /* handoff accept states */ - "#else", - " new_state(); /* start 2nd DFS */", - "#endif", + " #if NCORE>1", + " mem_put_acc();", /* handoff accept states */ + " #else", + " new_state(); /* start 2nd DFS */", + " #endif", " now._a_t = o_a_t;", - "#ifndef NOFAIR", - " now._cnt[1] = o_cnt;", - "#endif", + " #ifndef NOFAIR", + " now._cnt[1] = o_cnt;", + " #endif", " A_depth = 0; depthfound = -1;", "#ifdef DEBUG", " printf(\"%%ld: cycle check returns\\n\", depth);", @@ -6096,83 +7032,109 @@ "#endif", "#endif", "}", - "#endif\n", + "#endif", + "", "#if defined(FULLSTACK) && defined(BITSTATE)", - "struct H_el *Free_list = (struct H_el *) 0;", + "H_el *Free_list = (H_el *) 0;", "void", "onstack_init(void) /* to store stack states in a bitstate search */", - "{ S_Tab = (struct H_el **) emalloc(maxdepth*sizeof(struct H_el *));", + "{ S_Tab = (H_el **) emalloc(maxdepth*sizeof(H_el *));", "}", - "struct H_el *", - "grab_state(int n)", - "{ struct H_el *v, *last = 0;", - " if (H_tab == S_Tab)", - " { for (v = Free_list; v && ((int) v->tagged >= n); v=v->nxt)", - " { if ((int) v->tagged == n)", - " { if (last)", - " last->nxt = v->nxt;", - " else", - "gotcha: Free_list = v->nxt;", - " v->tagged = 0;", - " v->nxt = 0;", - "#ifdef COLLAPSE", - " v->ln = 0;", - "#endif", - " return v;", - " }", - " Fh++; last=v;", - " }", - " /* new: second try */", - " v = Free_list;", /* try to avoid emalloc */ - " if (v && ((int) v->tagged >= n))", - " goto gotcha;", - " ngrabs++;", - " }", - " return (struct H_el *)", - " emalloc(sizeof(struct H_el)+n-sizeof(unsigned));", - "}\n", - "#else", + "#endif", - "#if NCORE>1", - "struct H_el *", - "grab_state(int n)", - "{ struct H_el *grab_shared(int);", - " return grab_shared(sizeof(struct H_el)+n-sizeof(unsigned));", - "}", - "#else", - " #ifndef AUTO_RESIZE", - " #define grab_state(n) (struct H_el *) \\", - " emalloc(sizeof(struct H_el)+n-sizeof(unsigned long));", - " #else", - " struct H_el *", - " grab_state(int n)", - " { struct H_el *p;", - " int cnt = sizeof(struct H_el)+n-sizeof(unsigned long);", - "", - " if (reclaim_size >= cnt+WS)", - " { if ((cnt & (WS-1)) != 0) /* alignment */", - " { cnt += WS - (cnt & (WS-1));", - " }", - " p = (struct H_el *) reclaim_mem;", - " reclaim_mem += cnt;", - " reclaim_size -= cnt;", - " memset(p, 0, cnt);", - " } else", - " { p = (struct H_el *) emalloc(cnt);", + "#if !defined(BFS_PAR)", + " #if defined(FULLSTACK) && defined(BITSTATE)", + "H_el *", + "grab_state(int n)", + "{ H_el *v, *last = 0;", + " if (H_tab == S_Tab)", + " { for (v = Free_list; v && ((int) v->tagged >= n); v=v->nxt)", + " { if ((int) v->tagged == n)", + " { if (last)", + " last->nxt = v->nxt;", + " else", + "gotcha: Free_list = v->nxt;", + " v->tagged = 0;", + " v->nxt = 0;", + " #ifdef COLLAPSE", + " v->ln = 0;", + " #endif", + " return v;", + " }", + " Fh++; last=v;", + " }", + " /* new: second try */", + " v = Free_list;", /* try to avoid emalloc */ + " if (v && ((int) v->tagged >= n))", + " goto gotcha;", + " ngrabs++;", + " }", + " return (H_el *) emalloc(sizeof(H_el)+n-sizeof(unsigned));", + "}", + " #else", /* !FULLSTACK || !BITSTATE */ + "#if NCORE>1", + "H_el *", + "grab_state(int n)", + "{ H_el *grab_shared(int);", + " return grab_shared(sizeof(H_el)+n-sizeof(unsigned));", + "}", + "#else", /* ! NCORE>1 */ + "#ifndef AUTO_RESIZE", + " #define grab_state(n) (H_el *) \\", + " emalloc(sizeof(H_el)+n-sizeof(ulong));", + "#else", /* AUTO_RESIZE */ + "H_el *", + "grab_state(int n)", + "{ H_el *p;", + " int cnt = sizeof(H_el)+n-sizeof(ulong);", + "#ifndef MA", + " if (reclaim_size >= cnt+WS)", + " { if ((cnt & (WS-1)) != 0) /* alignment */", + " { cnt += WS - (cnt & (WS-1));", + " }", + " p = (H_el *) reclaim_mem;", + " reclaim_mem += cnt;", + " reclaim_size -= cnt;", + " memset(p, 0, cnt);", + " } else", + "#endif", + " { p = (H_el *) emalloc(cnt);", + " }", + " return p;", + "}", + "#endif", /* AUTO_RESIZE */ + "#endif", /* NCORE>1 */ + " #endif", /* FULLSTACK && !BITSTATE */ + "#else", /* BFS_PAR */ + " extern volatile uchar *sh_pre_malloc(ulong);", + " extern volatile uchar *sh_malloc(ulong);", + " H_el *", + " grab_state(int n) /* bfs_par */", + " { volatile uchar *rval = NULL;", + " int m = sizeof(H_el) + n - sizeof(unsigned);", + "", + " if (n == 0) m = m/n;", + " #ifdef BFS_SEP_HASH", + " rval = emalloc((ulong) m);", + " #else", + " rval = sh_malloc((ulong) m);", + " #endif", + " memset((void *) rval, 0, (size_t) m);", + "", + " return (H_el *) rval;", " }", - " return p;", - " }", - " #endif", - "#endif", + "#endif", /* BFS_PAR */ - "#endif", "#ifdef COLLAPSE", - "unsigned long", + "ulong", "ordinal(char *v, long n, short tp)", - "{ struct H_el *tmp, *ntmp; long m;", - " struct H_el *olst = (struct H_el *) 0;", + "{ H_el *tmp, *ntmp; long m;", + " H_el *olst = (H_el *) 0;", " s_hash((uchar *)v, n);", + "#if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " e_critical(BFS_ID); /* bfs_par / collapse */", + "#endif", "#if NCORE>1 && !defined(SEP_STATE)", " enter_critical(CS_ID); /* uses spinlock - 1..128 */", "#endif", @@ -6212,7 +7174,13 @@ "#if NCORE>1 && !defined(SEP_STATE)", " enter_critical(GLOBAL_LOCK);", "#endif", + "#ifdef BFS_PAR", + " e_critical(BFS_ORD); /* bfs_par */", + "#endif", " m = ++ncomps[tp];", + "#ifdef BFS_PAR", + " x_critical(BFS_ORD);", + "#endif", "#if NCORE>1 && !defined(SEP_STATE)", " leave_critical(GLOBAL_LOCK);", "#endif", @@ -6229,7 +7197,10 @@ "done:", "#if NCORE>1 && !defined(SEP_STATE)", - " leave_critical(CS_ID); /* uses spinlock */", + " leave_critical(CS_ID);", + "#endif", + "#if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", "#endif", "#ifdef FULLSTACK", @@ -6243,7 +7214,7 @@ "compress(char *vin, int nin) /* collapse compression */", "{ char *w, *v = (char *) &comp_now;", " int i, j;", - " unsigned long n;", + " ulong n;", " static char *x;", " static uchar nbytes[513]; /* 1 + 256 + 256 */", " static unsigned short nbytelen;", @@ -6336,7 +7307,7 @@ "#if VECTORSZ<65536", " w = (char *) &(now._vsz) + sizeof(unsigned short);", "#else", - " w = (char *) &(now._vsz) + sizeof(unsigned long);", + " w = (char *) &(now._vsz) + sizeof(ulong);", "#endif", "#endif", " x = scratch;", @@ -6348,8 +7319,14 @@ " else", " n = pptr(0) - (uchar *) w;", " j = w - (char *) &now;", + "", + "#if !defined(NOCOMP) && !defined(HC)", " for (i = 0; i < (int) n; i++, w++)", " if (!Mask[j++]) *x++ = *w;", + "#else", + " memcpy(x, w, n); x += n;", + "#endif", + "", "#ifndef SEPQS", " for (i = 0; i < (int) now._nr_qs; i++)", " x += col_q(i, x);", @@ -6385,7 +7362,7 @@ " return v - (char *)&comp_now;", "}", -"#else", +"#else", /* !COLLAPSE */ "#if !defined(NOCOMP)", "int", "compress(char *vin, int n) /* default compression */", @@ -6439,9 +7416,7 @@ " case 1: *v = *vv++; v += 1 - Mask[i++];", " case 0: break;", " }", - "#if 1", " n = i = v - (char *)&comp_now; /* bytes written so far */", - "#endif", " r = (n+WS-1)/WS; /* in words, rounded up */", " r *= WS; /* total bytes to fill */", " i = r - i; /* remaining bytes */", @@ -6473,7 +7448,7 @@ "#endif", "}", "#endif", -"#endif", +"#endif", /* COLLAPSE */ "#if defined(FULLSTACK) && defined(BITSTATE)", "#if defined(MA)", "#if !defined(onstack_now)", @@ -6486,10 +7461,12 @@ "void onstack_zap(void) {}", /* of directives */ "#endif", "#else", + "int compact_stack(char *, int);", + "" "void", "onstack_zap(void)", - "{ struct H_el *v, *w, *last = 0;", - " struct H_el **tmp = H_tab;", + "{ H_el *v, *w, *last = 0;", + " H_el **tmp = H_tab;", " char *nv; int n, m;", " static char warned = 0;", "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", @@ -6541,7 +7518,7 @@ "#if !defined(NOREDUCE) && !defined(SAFETY)", " v->proviso = 0;", "#endif", - " v->nxt = last = (struct H_el *) 0;", + " v->nxt = last = (H_el *) 0;", " for (w = Free_list; w; Fa++, last=w, w = w->nxt)", " { if ((int) w->tagged <= n)", " { if (last)", @@ -6564,100 +7541,148 @@ "#endif", " return;", "}", + "", + "#ifndef BFS_PAR", + " void", + " onstack_put(void)", + " { H_el **tmp = H_tab;", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " uchar was_last = now._last;", + " now._last = 0;", + " #endif", + " H_tab = S_Tab;", + " if (h_store((char *)&now, vsize) != 0)", + " #if defined(BITSTATE) && defined(LC)", + " printf(\"pan: warning, double stack entry\\n\");", + " #else", + " #ifndef ZAPH", + " Uerror(\"cannot happen - unstack_put\");", + " #endif", + " #endif", + " H_tab = tmp;", + " trpt->ostate = Lstate;", + " PUT++;", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " now._last = was_last;", + " #endif", + " }", + " int", + " onstack_now(void)", + " { H_el *tmp;", + " H_el **tmp2 = H_tab;", + " char *v; int n, m = 1;\n", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " uchar was_last = now._last;", + " now._last = 0;", + " #endif", + " H_tab = S_Tab;", + " #ifdef NOCOMP", + " #if defined(BITSTATE) && defined(LC)", + " v = (char *) &comp_now;", + " n = compact_stack((char *)&now, vsize);", + " #else", + " v = (char *) &now;", + " n = vsize;", + " #endif", + " #else", + " v = (char *) &comp_now;", + " n = compress((char *)&now, vsize);", + " #endif", + " #if !defined(HC) && !(defined(BITSTATE) && defined(LC))", + " s_hash((uchar *)v, n);", + " #endif", + " H_tab = tmp2;", + " for (tmp = S_Tab[j1_spin]; tmp; Zn++, tmp = tmp->nxt)", + " { m = memcmp(((char *)&(tmp->state)),v,n);", + " if (m <= 0)", + " { Lstate = (H_el *) tmp; /* onstack_now */", + " break;", + " } }", + " PROBE++;", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " now._last = was_last;", + " #endif", + " return (m == 0);", + " }", + "#endif", /* !BFS_PAR */ +"#endif", /* !MA */ + "#endif", /* FULLSTACK && BITSTATE */ + + "#ifdef BITSTATE", + "void init_SS(ulong);", + "", "void", - "onstack_put(void)", - "{ struct H_el **tmp = H_tab;", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " uchar was_last = now._last;", - " now._last = 0;", - "#endif", - " H_tab = S_Tab;", - " if (hstore((char *)&now, vsize) != 0)", - "#if defined(BITSTATE) && defined(LC)", - " printf(\"pan: warning, double stack entry\\n\");", - "#else", - " #ifndef ZAPH", - " Uerror(\"cannot happen - unstack_put\");", + "sinit(void)", + "{", + " if (udmem)", + " { udmem *= 1024L*1024L;", + " #if NCORE>1", + " if (!readtrail)", + " { init_SS((ulong) udmem);", + " } else", " #endif", - "#endif", - " H_tab = tmp;", - " trpt->ostate = Lstate;", - " PUT++;", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " now._last = was_last;", - "#endif", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " SS = (uchar *) sh_pre_malloc((ulong) udmem);", + " #else", + " SS = (uchar *) emalloc(udmem);", + " #endif", + " b_store = bstore_mod;", + " } else", + " {", + " #if NCORE>1", + " init_SS(ONE_L<<(ssize-3));", + " #else", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " SS = (uchar *) sh_pre_malloc((ulong)(ONE_L<<(ssize-3)));", + " #else", + " SS = (uchar *) emalloc(ONE_L<<(ssize-3));", + " #endif", + " #endif", + " }", "}", - "int", - "onstack_now(void)", - "{ struct H_el *tmp;", - " struct H_el **tmp2 = H_tab;", - " char *v; int n, m = 1;\n", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " uchar was_last = now._last;", - " now._last = 0;", - "#endif", - " H_tab = S_Tab;", - "#ifdef NOCOMP", - "#if defined(BITSTATE) && defined(LC)", - " v = (char *) &comp_now;", - " n = compact_stack((char *)&now, vsize);", - "#else", - " v = (char *) &now;", - " n = vsize;", - "#endif", "#else", - " v = (char *) &comp_now;", - " n = compress((char *)&now, vsize);", - "#endif", - "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", - " s_hash((uchar *)v, n);", - "#endif", - " H_tab = tmp2;", - " for (tmp = S_Tab[j1_spin]; tmp; Zn++, tmp = tmp->nxt)", - " { m = memcmp(((char *)&(tmp->state)),v,n);", - " if (m <= 0)", - " { Lstate = (struct H_el *) tmp;", - " break;", - " } }", - " PROBE++;", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " now._last = was_last;", - "#endif", - " return (m == 0);", - "}", - "#endif", -"#endif", - - "#ifndef BITSTATE", + " #if !defined(MA) || defined(COLLAPSE)", + " void", + " set_H_tab(void)", + " {", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " H_tab = (H_el **) sh_pre_malloc((ulong)((ONE_L<1 && !defined(COLLAPSE)", - " if (!readtrail)", - " { void init_HT(unsigned long);", - " init_HT(0L);", - " }", - "#endif", - "#endif", - " #endif", - " #if !defined(MA) || defined(COLLAPSE)", - "#if NCORE>1", - " if (!readtrail)", - " { void init_HT(unsigned long);", - " init_HT((unsigned long) (ONE_L<1 && !defined(COLLAPSE)", + " if (!readtrail)", + " { void init_HT(ulong);", + " init_HT(0L);", + " }", + " #endif", + " #endif", + " #endif", + " #if !defined(MA) || defined(COLLAPSE)", + " #if NCORE>1 || (defined(BFS_PAR) && defined(USE_TDH) && !defined(WIN32) && !defined(WIN64))", + " if (!readtrail)", + " { void init_HT(ulong);", + " init_HT((ulong) (ONE_L< (int) maxgs)", - " { maxgs = (unsigned int) n;", + " { maxgs = (uint) n;", " }", " for (i = 0; i < n; i++)", " { Info[i] = v[i];", @@ -6724,6 +7753,9 @@ " Info[0] = 0;", " }", "", + "#ifdef BFS_PAR", + " e_critical(BFS_STATE); /* bfs_par / g_store */", + "#endif", "#if NCORE>1 && !defined(SEP_STATE)", " enter_critical(GLOBAL_LOCK); /* crude, but necessary */", " /* to make this mode work, also replace emalloc with grab_shared inside store MA routines */", @@ -6776,6 +7808,9 @@ " printf(\"old state\\n\");", "#endif", "done:", + "#ifdef BFS_PAR", + " x_critical(BFS_STATE);", + "#endif", "#if NCORE>1 && !defined(SEP_STATE)", " leave_critical(GLOBAL_LOCK);", "#endif", @@ -6811,7 +7846,7 @@ "again:", " for (i = 0; i < bound; i++)", " { if (base[i] != NULL)", - " { struct H_el *tmp;", + " { H_el *tmp;", " int m, n; uchar *v;", "#ifndef BFS", " if (base[i]->modified == 0)", @@ -6840,7 +7875,7 @@ " H_tab[j1_spin] = tmp;", " m = 1; /* non-zero */", " } else", - " { struct H_el *ntmp, *olst = (struct H_el *) 0;", + " { H_el *ntmp, *olst = (H_el *) 0;", " for (;; hcmp++, olst = tmp, tmp = tmp->nxt)", " { m = memcmp(((char *)&(tmp->state)), v, n);", " if (m == 0) /* match */", @@ -6864,16 +7899,19 @@ "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", " tmp->m_K1 = K1; /* set via s_hash */", "#endif", - " if (base == processes)", - " { _p_count[i]++;", - " } else", - " { _c_count[i]++;", - " } }", + " if (verbose)", + " { if (base == processes)", + " { _p_count[i]++;", + " } else", + " { _c_count[i]++;", + " } } }", " now._ids_[cnt++] = (char *)&(tmp->state);", "#ifdef TRIX_RIX", " if (base == processes)", " { ((P0 *)pptr(i))->_pid = i;", - " }", + " if (BASE > 0 && i > 0)", + " { ((P0 *)pptr(i))->_pid -= BASE;", + " } }", "#endif", " } }", #if 0 @@ -6896,20 +7934,19 @@ " }", "}", "#endif\n", + "#if !defined(BFS_PAR) || (!defined(BITSTATE) && !defined(USE_TDH))", "int", - "hstore(char *vin, int nin) /* hash table storage */", - "{ struct H_el *ntmp;", - " struct H_el *tmp, *olst = (struct H_el *) 0;", + "h_store(char *vin, int nin) /* hash table storage */", + "{ H_el *ntmp;", + " H_el *tmp, *olst = (H_el *) 0;", " char *v; int n, m=0;", - "#ifdef HC", + " #ifdef HC", " uchar rem_a;", - "#endif", - - "#ifdef TRIX", + " #endif", + " #ifdef TRIX", " sv_populate(); /* update proc and chan ids */", - "#endif", - - "#ifdef NOCOMP", /* defined by BITSTATE */ + " #endif", + " #ifdef NOCOMP", /* defined by BITSTATE */ " #if defined(BITSTATE) && defined(LC)", " if (S_Tab == H_tab)", " { v = (char *) &comp_now;", @@ -6920,7 +7957,7 @@ " #else", " v = vin; n = nin;", " #endif", - "#else", + " #else", " v = (char *) &comp_now;", " #ifdef HC", " rem_a = now._a_t;", /* new 5.0 */ @@ -6942,18 +7979,22 @@ " m = 0;", " }", " #endif", - "#endif", - "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", + " #endif", + " #if !defined(HC) && !(defined(BITSTATE) && defined(LC))", " s_hash((uchar *)v, n);", - "#endif", - "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", - " enter_critical(CS_ID); /* uses spinlock */", - "#endif", - + " #endif", + " /* for BFS_PAR we can only get here in BITSTATE mode */", + " /* and in that case we don't use locks */", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " e_critical(BFS_ID); /* bfs_par / h_store */", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " enter_critical(CS_ID);", + " #endif", " tmp = H_tab[j1_spin];", " if (!tmp)", - " { tmp = grab_state(n);", - "#if NCORE>1", + " { tmp = grab_state(n);", /* no zero-returns with bfs_par */ + " #if NCORE>1", " if (!tmp)", " { /* if we get here -- we've already issued a warning */", " /* but we want to allow the normal distributed termination */", @@ -6963,28 +8004,27 @@ " #endif", " return 1; /* allow normal termination */", " }", - "#endif", + " #endif", " H_tab[j1_spin] = tmp;", " } else", " { for (;; hcmp++, olst = tmp, tmp = tmp->nxt)", " { /* skip the _a_t and the _cnt bytes */", - "#ifdef COLLAPSE", + " #ifdef COLLAPSE", " if (tmp->ln != 0)", " { if (!tmp->nxt) goto Append;", " continue;", " }", - "#endif", + " #endif", " m = memcmp(((char *)&(tmp->state)) + S_A, ", " v + S_A, n - S_A);", " if (m == 0) {", - "#ifdef SAFETY", + " #ifdef SAFETY", "#define wasnew 0", - "#else", + " #else", " int wasnew = 0;", - "#endif", + " #endif", - "#ifndef SAFETY", - "#ifndef NOCOMP", + " #if !defined(SAFETY) && !defined(NOCOMP)", " if (S_A)", " { if ((((char *)&(tmp->state))[0] & V_A) != V_A)", " { wasnew = 1; nShadow++;", @@ -6993,7 +8033,7 @@ "#ifndef NOFAIR", " if (S_A > NFAIR)", " { /* 0 <= now._cnt[now._a_t&1] < MAXPROC */", - " unsigned ci, bp; /* index, bit pos */", + " uint ci, bp; /* index, bit pos */", " ci = (now._cnt[now._a_t&1] / 8);", " bp = (now._cnt[now._a_t&1] - 8*ci);", " if (now._a_t&1) /* use tail-bits in _cnt */", @@ -7013,17 +8053,16 @@ " /* else: wasnew == 0, i.e., old state */", "#endif", " }", - "#endif", - "#endif", + " #endif", - "#if NCORE>1", - " Lstate = (struct H_el *) tmp;", - "#endif", + " #if NCORE>1", + " Lstate = (H_el *) tmp; /* h_store */", + " #endif", "#ifdef FULLSTACK", "#ifndef SAFETY", /* or else wasnew == 0 */ " if (wasnew)", - " { Lstate = (struct H_el *) tmp;", + " { Lstate = (H_el *) tmp; /* h_store */", " tmp->tagged |= V_A;", " if ((now._a_t&1)", " && (tmp->tagged&A_V)", @@ -7031,36 +8070,42 @@ " {", "intersect:", "#ifdef CHECK", - "#if NCORE>1", + " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", - "#endif", + " #endif", " printf(\"1st dfs-stack intersected on state %%d+\\n\",", " (int) tmp->st_id);", "#endif", - "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", - "#endif", + " #endif", " return 3;", " }", "#ifdef CHECK", - "#if NCORE>1", + " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", - "#endif", + " #endif", " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(1, (char *)&(tmp->state),n,tmp->tagged);", "#endif", - "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", - "#endif", + " #endif", " return 0;", " } else", "#endif", " if ((S_A)?(tmp->tagged&V_A):tmp->tagged)", - " { Lstate = (struct H_el *) tmp;", + " { Lstate = (H_el *) tmp; /* h_store */", "#ifndef SAFETY", " /* already on current dfs stack */", " /* but may also be on 1st dfs stack */", @@ -7077,34 +8122,40 @@ " goto intersect;", "#endif", "#ifdef CHECK", - "#if NCORE>1", + " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", - "#endif", + " #endif", " printf(\"\tStack state %%d\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(0, (char *)&(tmp->state),n,tmp->tagged);", "#endif", - "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", - "#endif", + " #endif", " return 2; /* match on stack */", " }", "#else", " if (wasnew)", " {", "#ifdef CHECK", - "#if NCORE>1", + " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", - "#endif", + " #endif", " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(1, (char *)&(tmp->state), n, 0);", "#endif", - "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", - "#endif", + " #endif", " return 0;", " }", "#endif", @@ -7121,7 +8172,7 @@ " #ifdef CONSERVATIVE", " if (tmp->ctx_low > trpt->sched_limit)", " { tmp->ctx_low = trpt->sched_limit;", - " tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%8); /* new */", + " tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%%8); /* new */", " #ifdef CHECK", " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", @@ -7129,13 +8180,16 @@ " printf(\"\t\tRevisit with fewer context switches\\n\");", " #endif", " nstates--;", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", " #endif", " return 0;", " } else if ((tmp->ctx_low == trpt->sched_limit", - " && (tmp->ctx_pid[(now._last)/8] & ( 1 << ((now._last)%8) )) == 0 ))", - " { tmp->ctx_pid[(now._last)/8] |= 1 << ((now._last)%8); /* add */", + " && (tmp->ctx_pid[(now._last)/8] & ( 1 << ((now._last)%%8) )) == 0 ))", + " { tmp->ctx_pid[(now._last)/8] |= 1 << ((now._last)%%8); /* add */", " #ifdef CHECK", " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", @@ -7143,6 +8197,9 @@ " printf(\"\t\tRevisit with same nr of context switches\\n\");", " #endif", " nstates--;", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", " #endif", @@ -7150,7 +8207,7 @@ " }", " #endif", "#endif", - "#ifdef REACH", + " #ifdef REACH", " if (tmp->D > depth)", " { tmp->D = depth;", " #ifdef CHECK", @@ -7160,6 +8217,9 @@ " printf(\"\t\tReVisiting (from smaller depth)\\n\");", " #endif", " nstates--;", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", " #endif", @@ -7178,18 +8238,21 @@ #endif " return 0;", " }", - "#endif", - "#if (defined(BFS) && defined(Q_PROVISO)) || NCORE>1", - " Lstate = (struct H_el *) tmp;", - "#endif", - "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " #endif", + " #if (defined(BFS) && defined(Q_PROVISO)) || NCORE>1", + " Lstate = (H_el *) tmp; /* h_store */", + " #endif", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", - "#endif", + " #endif", " return 1; /* match outside stack */", " } else if (m < 0)", " { /* insert state before tmp */", " ntmp = grab_state(n);", - "#if NCORE>1", + " #if NCORE>1", " if (!ntmp)", " {", " #if !defined(SEP_STATE) && !defined(BITSTATE)", @@ -7197,7 +8260,7 @@ " #endif", " return 1; /* allow normal termination */", " }", - "#endif", + " #endif", " ntmp->nxt = tmp;", " if (!olst)", " H_tab[j1_spin] = ntmp;", @@ -7207,11 +8270,11 @@ " break;", " } else if (!tmp->nxt)", " { /* append after tmp */", - "#ifdef COLLAPSE", + " #ifdef COLLAPSE", "Append:", - "#endif", + " #endif", " tmp->nxt = grab_state(n);", - "#if NCORE>1", + " #if NCORE>1", " if (!tmp->nxt)", " {", " #if !defined(SEP_STATE) && !defined(BITSTATE)", @@ -7219,38 +8282,37 @@ " #endif", " return 1; /* allow normal termination */", " }", - "#endif", + " #endif", " tmp = tmp->nxt;", " break;", " } }", " }", - "#ifdef CHECK", + " #ifdef CHECK", " tmp->st_id = (unsigned) nstates;", - "#if NCORE>1", + " #if NCORE>1", " printf(\"cpu%%d: \", core_id);", - "#endif", + " #endif", "#ifdef BITSTATE", " printf(\" Push state %%d\\n\", ((int) nstates) - 1);", "#else", " printf(\" New state %%d\\n\", (int) nstates);", "#endif", "#endif", - "#if defined(BCS)", + " #if defined(BCS)", " tmp->ctx_low = trpt->sched_limit;", " #ifdef CONSERVATIVE", - " tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%8); /* new limit */", + " tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%%8); /* new limit */", " #endif", - "#endif", - "#if !defined(SAFETY) || defined(REACH)", + " #endif", + " #if !defined(SAFETY) || defined(REACH)", " tmp->D = depth;", - "#endif", - "#ifndef SAFETY", - "#ifndef NOCOMP", + " #endif", + " #if !defined(SAFETY) && !defined(NOCOMP)", " if (S_A)", " { v[0] = V_A;", "#ifndef NOFAIR", " if (S_A > NFAIR)", - " { unsigned ci, bp; /* as above */", + " { uint ci, bp; /* as above */", " ci = (now._cnt[now._a_t&1] / 8);", " bp = (now._cnt[now._a_t&1] - 8*ci);", " if (now._a_t&1)", @@ -7261,40 +8323,409 @@ " }", "#endif", " }", - "#endif", - "#endif", - "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", + " #endif", + " #if defined(AUTO_RESIZE) && !defined(BITSTATE)", " tmp->m_K1 = K1;", - "#endif", + " #endif", " memcpy(((char *)&(tmp->state)), v, n);", - "#ifdef FULLSTACK", + " #ifdef FULLSTACK", " tmp->tagged = (S_A)?V_A:(depth+1);", "#ifdef DEBUG", " dumpstate(-1, v, n, tmp->tagged);", "#endif", - " Lstate = (struct H_el *) tmp;", - "#else", + " Lstate = (H_el *) tmp; /* end of h_store */", + " #else", " #ifdef DEBUG", " dumpstate(-1, v, n, 0);", " #endif", " #if NCORE>1", - " Lstate = (struct H_el *) tmp;", + " Lstate = (H_el *) tmp; /* end of h_store */", " #endif", - "#endif", + " #endif", - "/* #if NCORE>1 && !defined(SEP_STATE) */", - "#if NCORE>1", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1", " #ifdef V_PROVISO", " tmp->cpu_id = core_id;", " #endif", " #if !defined(SEP_STATE) && !defined(BITSTATE)", " leave_critical(CS_ID);", " #endif", - "#endif", + " #endif", " return 0;", + "}", /* end of h_store */ + "#endif", /* !BFS_PAR || !USE_TDH */ + "", + "void", + "o_hash32(uchar *s, int len, int h) /* 32-bit, like d_sfh, but with seed */", + "{ uint32_t tmp;", + " int rem;", + "", + " rem = len & 3;", + " len >>= 2;", + "", + " for ( ; len > 0; len--)", + " { h += get16bits(s);", + " tmp = (get16bits(s+2) << 11) ^ h;", + " h = (h << 16) ^ tmp;", + " s += 2*sizeof(uint16_t);", + " h += h >> 11;", + " }", + " switch (rem) {", + " case 3: h += get16bits(s);", + " h ^= h << 16;", + " h ^= s[sizeof(uint16_t)] << 18;", + " h += h >> 11;", + " break;", + " case 2: h += get16bits(s);", + " h ^= h << 11;", + " h += h >> 17;", + " break;", + " case 1: h += *s;", + " h ^= h << 10;", + " h += h >> 1;", + " break;", + " }", + " h ^= h << 3;", + " h += h >> 5;", + " h ^= h << 4;", + " h += h >> 17;", + " h ^= h << 25;", + " h += h >> 6;", + "", + " K1 = h;", + "}", + "void", + "o_hash64(uchar *kb, int nbytes, int seed)", /* 64-bit hash */ + "{ uint8_t *bp;", + " uint64_t a, b, c, n;", + " const uint64_t *k = (uint64_t *) kb;", + " n = nbytes/WS; /* nr of 8-byte chunks */", + " /* extend to multiple of words, if needed */", + " a = WS - (nbytes %% WS);", + " if (a > 0 && a < WS)", + " { n++;", + " bp = kb + nbytes;", + " switch (a) {", + " case 7: *bp++ = 0; /* fall thru */", + " case 6: *bp++ = 0; /* fall thru */", + " case 5: *bp++ = 0; /* fall thru */", + " case 4: *bp++ = 0; /* fall thru */", + " case 3: *bp++ = 0; /* fall thru */", + " case 2: *bp++ = 0; /* fall thru */", + " case 1: *bp = 0;", + " case 0: break;", + " } }", + " a = (uint64_t) seed;", + " b = HASH_CONST[HASH_NR];", + " c = 0x9e3779b97f4a7c13LL; /* arbitrary */", + " while (n >= 3)", + " { a += k[0];", + " b += k[1];", + " c += k[2];", + " mix(a,b,c);", + " n -= 3;", + " k += 3;", + " }", + " c += (((uint64_t) nbytes)<<3);", + " switch (n) {", + " case 2: b += k[1];", + " case 1: a += k[0];", + " case 0: break;", + " }", + " mix(a,b,c);", + "", + " K1 = a;", "}", + "", + "#if defined(USE_TDH) && !defined(WIN32) && !defined(WIN64)", +#if 0 + some problems with this storage mode: + + 0. pre-allocates full hash-table with slots equal to max statevector size + e.g. with -w26 we allocate 2^26 (64 M) slots of VECTORSZ large + which can accomodate up to 64 M states + once you get close to or exceed the max, the search aborts + with a 'hashtable full' message + in HC mode the max storage needed per state is more modest and independent + of the maximum vectorsize; which makes this mode attractive as a default + + 1. does not support PO reduction through the Lstate->ostate->tagged + to distinguish open from closed states - this can reduce states by 50% + could add this as another bit from the hash value + e.g., could add it in HC mode to the first hash? + + 2. the same state may be stored multiple times +#endif + "#ifdef HC", + " #ifndef T_HC", + " #ifdef BFS_HC", + " #define T_HC BFS_HC", + " #else", + " #define T_HC 2", + " #endif", + " #endif", + " #if T_HC<1 || T_HC>4", + " #error \"BFS_HC must be 1, 2, 3, or 4 (default is 2)\"", + " #endif", + "#endif", + "", + "#define T_ROW 6", /* related to cache line size */ + "#define T_ROW_SIZE (1< x))", + " { Uerror(\"assertion x * (ulong) T_VSZ > x fails\");", + " }", + " #ifdef BFS_SEP_HASH", + " ohash_sd = (char *) emalloc(x * (ulong) T_VSZ);", + " #else", + " ohash_sd = (volatile char *) sh_pre_malloc(x * (ulong) T_VSZ);", + " #endif", + "#else", /* assume T_HC >= 1, and normally 2 */ + " ohash_hc_sz = (ulong) (T_HC * (ulong) sizeof(uint32_t));", + " if (!(x * ohash_hc_sz > x))", /* watch for overflow */ + " { Uerror(\"assertion x * ohash_hc_sz > x fails\");", + " }", + " #ifdef BFS_SEP_HASH", + " ohash_sd = (char *) emalloc(x * ohash_hc_sz);", + " #else", + " ohash_sd = (volatile char *) sh_pre_malloc(x * ohash_hc_sz);", + " #endif", + "#endif", + "#ifdef BFS_SEP_HASH", + " ohash_hv = (uint32_t *) emalloc(x * (ulong) sizeof(uint32_t));", + "#else", + " ohash_hv = (volatile uint32_t *) sh_pre_malloc(x * (ulong) sizeof(uint32_t));", + "#endif", + " ohash_mask = (((ulong)1)<o_pm &= ~2;", + "#ifdef VERBOSE", + " bfs_printf(\"check to mark\\n\");", + "#endif", + " for (i = 0; i < (int) now._nr_pr; i++)", + " { P0 *ptr = (P0 *) pptr(i);", + " if (accpstate[ptr->_t][ptr->_p])", + " { trpt->o_pm |= 2;", + " now._l_bnd = L_bound;", + " now._l_sds = (uchar *) 0;", + "#ifdef VERBOSE", + " bfs_printf(\"mark state live\\n\");", + "#endif", + " break;", + " } }", + "}", + "void", + "bfs_check_live(uchar b, uchar *s)", + "{ /* assert(b>0); */", + " now._l_bnd = b-1; /* decrease bound */", + "#ifdef VERBOSE", + " bfs_printf(\"check live %%d\\n\", b);", + "#endif", + " if (b == L_bound && boq == -1)", /* never mid rv */ + " { now._l_sds = (uchar *) Lstate; /* new target */", + " } else", + " { now._l_sds = s; /* restore target */", + " if (s == (uchar *) Lstate)", + " { depthfound = depth - (BASE+1)*(L_bound - now._l_bnd - 1);", + " uerror(\"accept cycle found\");", + " depthfound = -1;", + " now._l_bnd = 0;", + " now._l_sds = (uchar *) 0;", + " } }", + "#ifdef VERBOSE", + " bfs_printf(\"set l_bound to %%d -- sds %%p\\n\", b-1, (void *) now._l_sds);", + "#endif", + "}", + "#endif", + "/* closed hashing with locality - similar to ltsmin */", + "int", + "o_store(const char *vin, int nin)", + "{ int i, seed = 0;", + " ulong hash_v, ix, ex;", + " uint32_t T_BUSY, T_DONE;", + " volatile uint32_t *t_entry;", + "#ifdef HC", + " ulong vs = ohash_hc_sz;", + "#else", + " ulong vs = (ulong) T_VSZ;", + "#endif", + "#ifdef L_BOUND", + " uchar o_bnd, *o_sds;", + "#endif", + "#ifndef STOP_ON_FULL", + " if (h_table_full)", + " { goto done;", + " }", + "#endif", + "#ifdef L_BOUND", + " if (now._l_bnd == 0)", + " { bfs_mark_live();", + " }", + " #ifdef VERBOSE", + " else", + " { bfs_printf(\"non-markable state %%d\\n\", now._l_bnd);", + " }", + " #endif", + " o_bnd = now._l_bnd;", + " o_sds = now._l_sds;", + " now._l_bnd = (o_bnd)?1:0; /* mark nested phase of bounded search */", + " now._l_sds = (uchar *) 0;", + "#endif", + "#if !defined(HC) && !defined(T_NOCOMP)", + " nin = compress((char *)vin, nin);", + " vin = (char *) &comp_now;", + "#endif", + " do { o_hash((uchar *)vin, nin, seed++);", + " hash_v = K1;", + " } while (hash_v == T_FREE || hash_v == T_STAT); /* unlikely, hash_v 0 or 1 */", + "", + " T_BUSY = ((uint32_t) hash_v & ~((uint32_t) T_STAT)); /* hash with status bit 0 */", + " T_DONE = ((uint32_t) hash_v | ((uint32_t) T_STAT)); /* hash with status bit 1 */", + "#ifdef HC", + " d_hash((uchar *)vin, nin);", /* HC */ + " ohash_hc[0] = (uint32_t) K1;", + " #if T_HC>1", + " ohash_hc[1] = (uint32_t) (K1>>32);", /* assumes ulong = 64 bits */ + " #endif", + " #if T_HC>2", + " ohash_hc[2] = (uint32_t) K2;", + " #endif", + " #if T_HC>3", + " ohash_hc[3] = (uint32_t) (K2>>32);", + " #endif", + "#endif", + " while (seed < ohash_max)", + " { ix = hash_v & ohash_mask;", + " ex = (ix & T_ROW_MASK) + T_ROW_SIZE;", + " for (i = 0; i < T_ROW_SIZE; i++)", + " { t_entry = (uint32_t *) &ohash_hv[ix];", + " if (*t_entry == T_FREE && cas(t_entry, T_FREE, T_BUSY))", + " {", + "#ifndef HC", + " memcpy((char *) &ohash_sd[ix * vs], vin, nin);", + "#else", + " memcpy((char *) &ohash_sd[ix * vs], (char *) ohash_hc, vs);", + "#endif", + "#if defined(USE_TDH) && defined(Q_PROVISO)", + " ohash_inq[ix] = (uchar) BFS_INQ;", + " Lstate = (H_el *) &ohash_inq[ix];", + "#endif", + " *t_entry = T_DONE;", + "#ifdef VERBOSE", + " #ifdef L_BOUND", + " bfs_printf(\"New state %%p [%%p]\\n\",", + " (void *) Lstate, (void *) o_sds);", + " #else", + " bfs_printf(\"New state %%p\\n\", (void *) Lstate);", + " #endif", + "#endif", + "#ifdef L_BOUND", + " if (o_bnd) { bfs_check_live(o_bnd, o_sds); }", + "#endif", + " return 0; /* New State */", + " }", + " while (*t_entry == T_BUSY)", + " { usleep(2); /* wait */", + " }", + " if (*t_entry == T_DONE /* (first) hash matches, check data */", + "#ifndef HC", + " && memcmp((char *) &ohash_sd[ix * vs], vin, nin) == 0)", + "#else", + " && memcmp((char *) &ohash_sd[ix * vs], (char *) ohash_hc, vs) == 0)", + "#endif", + " {", + "#if defined(USE_TDH) && defined(Q_PROVISO)", + " Lstate = (H_el *) &ohash_inq[ix];", + "#endif", + "#ifdef VERBOSE", + " #ifdef L_BOUND", + " bfs_printf(\"Old state %%p [%%p]\\n\",", + " (void *) Lstate, (void *) o_sds);", + " #else", + " bfs_printf(\"Old state %%p\\n\", (void *) Lstate);", + " #endif", + "#endif", + "#ifdef L_BOUND", + " if (o_bnd) { bfs_check_live(o_bnd, o_sds); }", + "#endif", + " return 1; /* Old State */", + " }", + " hcmp++; ix++;", + " ix = (ix==ex) ? ex - T_ROW_SIZE : ix;", + " }", + " /* find a new slot: */", + " do { o_hash((uchar *)vin, nin, (int) (hash_v + seed++));", + " hash_v = K1;", + " } while (hash_v == T_FREE || hash_v == T_STAT);", + " T_BUSY = ((uint32_t) hash_v & ~((uint32_t) T_STAT));", + " T_DONE = ((uint32_t) hash_v | ((uint32_t) T_STAT));", + " }", + "#ifdef STOP_ON_FULL", + " Uerror(\"hash table full\");", + " /* no return from Uerror */", + "#else", + " if (!h_table_full)", + " { h_table_full++;", + " if (who_am_i == 0)", + " { bfs_printf(\"hash table is full\\n\");", + " } }", + "done:", + " bfs_punt++; /* counts this as a lost state */", + "#endif", + "#ifdef L_BOUND", + " now._l_bnd = 0; /* no more checking */", + " now._l_sds = (uchar *) 0;", + "#endif", + " return 1; /* technically should be 0, but we want to throttle down */", + "}", + "#endif", /* USE_TDH && !WIN32 && !WIN64 */ + "#endif", /* !BITSTATE || FULLSTACK */ "#include TRANSITIONS", 0, }; diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen2.c /sys/src/cmd/spin/pangen2.c --- /n/sources/plan9/sys/src/cmd/spin/pangen2.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen2.c Mon Feb 22 00:00:00 2021 @@ -1,14 +1,10 @@ /***** spin: pangen2.c *****/ -/* Copyright (c) 1989-2009 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ -/* (c) 2007: small additions for V5.0 to support multi-core verifications */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "version.h" @@ -16,34 +12,40 @@ #include "pangen2.h" #include "pangen4.h" #include "pangen5.h" +#include "pangen7.h" #define DELTA 500 /* sets an upperbound on nr of chan names */ #define blurb(fd, e) { fprintf(fd, "\n"); if (!merger) fprintf(fd, "\t\t/* %s:%d */\n", \ e->n->fn->name, e->n->ln); } -#define tr_map(m, e) { if (!merger) fprintf(tt, "\t\ttr_2_src(%d, \"%s\", %d);\n", \ +#define tr_map(m, e) { if (!merger) fprintf(fd_tt, "\t\ttr_2_src(%d, \"%s\", %d);\n", \ m, e->n->fn->name, e->n->ln); } -extern ProcList *rdy; -extern RunList *run; +extern ProcList *ready; +extern RunList *run_lst; +extern Lextok *runstmnts; extern Symbol *Fname, *oFname, *context; extern char *claimproc, *eventmap; extern int lineno, verbose, Npars, Mpars, nclaims; extern int m_loss, has_remote, has_remvar, merger, rvopt, separate; -extern int Ntimeouts, Etimeouts, deadvar, old_scope_rules; +extern int Ntimeouts, Etimeouts, deadvar, old_scope_rules, old_priority_rules; extern int u_sync, u_async, nrRdy, Unique; extern int GenCode, IsGuard, Level, TestOnly; +extern int globmin, globmax, ltl_mode, dont_simplify; + extern short has_stack; -extern char *NextLab[]; +extern char *NextLab[64]; /* must match value in dstep.c:18 */ -FILE *tc, *th, *tt, *tb; -static FILE *tm; +int buzzed; +FILE *fd_tc, *fd_th, *fd_tt, *fd_tb; +static FILE *fd_tm; int OkBreak = -1, has_hidden = 0; /* has_hidden set in sym.c and structs.c */ short nocast=0; /* to turn off casts in lvalues */ short terse=0; /* terse printing of varnames */ short no_arrays=0; short has_last=0; /* spec refers to _last */ +short has_priority=0; /* spec refers to _priority */ short has_badelse=0; /* spec contains else combined with chan refs */ short has_enabled=0; /* spec contains enabled() */ short has_pcvalue=0; /* spec contains pc_value() */ @@ -54,12 +56,13 @@ short has_unless=0; /* spec contains unless statements */ short has_provided=0; /* spec contains PROVIDED clauses on procs */ short has_code=0; /* spec contains c_code, c_expr, c_state */ -short evalindex=0; /* evaluate index of var names */ -int mst=0; /* max nr of state/process */ +short has_ltl=0; /* has inline ltl formulae */ +int mstp=0; /* max nr of state/process */ int claimnr = -1; /* claim process, if any */ int eventmapnr = -1; /* event trace, if any */ -int Pid; /* proc currently processed */ +int Pid_nr; /* proc currently processed */ int multi_oval; /* set in merges, used also in pangen4.c */ +int in_settr; /* avoid quotes inside quotes */ #define MAXMERGE 256 /* max nr of bups per merge sequence */ @@ -76,9 +79,14 @@ static short AllGlobal=0; /* set if process has provided clause */ static short withprocname=0; /* prefix local varnames with procname */ static short _isok=0; /* checks usage of predefined variable _ */ +static short evalindex=0; /* evaluate index of var names */ + +extern int has_global(Lextok *); +extern void check_mtypes(Lextok *, Lextok *); +extern void walk2_struct(char *, Symbol *); +extern int find_min(Sequence *); +extern int find_max(Sequence *); -int has_global(Lextok *); -void Fatal(char *, char *); static int getweight(Lextok *); static int scan_seq(Sequence *); static void genconditionals(void); @@ -89,11 +97,34 @@ static void Tpe(Lextok *); extern void spit_recvs(FILE *, FILE*); +static L_List *keep_track; + +void +keep_track_off(Lextok *n) +{ L_List *p; + + p = (L_List *) emalloc(sizeof(L_List)); + p->n = n; + p->nxt = keep_track; + keep_track = p; +} + +int +check_track(Lextok *n) +{ L_List *p; + + for (p = keep_track; p; p = p->nxt) + { if (p->n == n) + { return n->sym?n->sym->type:0; + } } + return 0; +} + static int fproc(char *s) { ProcList *p; - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) if (strcmp(p->n->name, s) == 0) return p->tn; @@ -102,10 +133,10 @@ } int -pid_is_claim(int p) /* Pid (p->tn) to type (p->b) */ +pid_is_claim(int p) /* Pid_nr (p->tn) to type (p->b) */ { ProcList *r; - for (r = rdy; r; r = r->nxt) + for (r = ready; r; r = r->nxt) { if (r->tn == p) return (r->b == N_CLAIM); } printf("spin: error, cannot find pid %d\n", p); @@ -117,56 +148,50 @@ { if (!q) return; reverse_procs(q->nxt); - fprintf(tc, " Addproc(%d);\n", q->tn); + fprintf(fd_tc, " Addproc(%d, %d);\n", + q->tn, q->priority < 1 ? 1 : q->priority); } static void forward_procs(RunList *q) { if (!q) return; - fprintf(tc, " Addproc(%d);\n", q->tn); + fprintf(fd_tc, " Addproc(%d, %d);\n", + q->tn, q->priority < 1 ? 1 : q->priority); forward_procs(q->nxt); } static void tm_predef_np(void) { - fprintf(th, "#define _T5 %d\n", uniq++); - fprintf(th, "#define _T2 %d\n", uniq++); - - if (Unique < (1 << (8*sizeof(unsigned char)) )) /* was uniq before */ - { fprintf(th, "#define T_ID unsigned char\n"); - } else if (Unique < (1 << (8*sizeof(unsigned short)) )) - { fprintf(th, "#define T_ID unsigned short\n"); - } else - { fprintf(th, "#define T_ID unsigned int\n"); - } + fprintf(fd_th, "#define _T5 %d\n", uniq++); + fprintf(fd_th, "#define _T2 %d\n", uniq++); - fprintf(tm, "\tcase _T5:\t/* np_ */\n"); + fprintf(fd_tm, "\tcase _T5:\t/* np_ */\n"); if (separate == 2) - fprintf(tm, "\t\tif (!((!(o_pm&4) && !(tau&128))))\n"); - else - fprintf(tm, "\t\tif (!((!(trpt->o_pm&4) && !(trpt->tau&128))))\n"); - - fprintf(tm, "\t\t\tcontinue;\n"); - fprintf(tm, "\t\t/* else fall through */\n"); - fprintf(tm, "\tcase _T2:\t/* true */\n"); - fprintf(tm, "\t\t_m = 3; goto P999;\n"); + { fprintf(fd_tm, "\t\tif (!((!(o_pm&4) && !(tau&128))))\n"); + } else + { fprintf(fd_tm, "\t\tif (!((!(trpt->o_pm&4) && !(trpt->tau&128))))\n"); + } + fprintf(fd_tm, "\t\t\tcontinue;\n"); + fprintf(fd_tm, "\t\t/* else fall through */\n"); + fprintf(fd_tm, "\tcase _T2:\t/* true */\n"); + fprintf(fd_tm, "\t\t_m = 3; goto P999;\n"); } static void tt_predef_np(void) { - fprintf(tt, "\t/* np_ demon: */\n"); - fprintf(tt, "\ttrans[_NP_] = "); - fprintf(tt, "(Trans **) emalloc(2*sizeof(Trans *));\n"); - fprintf(tt, "\tT = trans[_NP_][0] = "); - fprintf(tt, "settr(9997,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); - fprintf(tt, "\t T->nxt = "); - fprintf(tt, "settr(9998,0,0,_T2,0,\"(1)\", 0,2,0);\n"); - fprintf(tt, "\tT = trans[_NP_][1] = "); - fprintf(tt, "settr(9999,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); + fprintf(fd_tt, "\t/* np_ demon: */\n"); + fprintf(fd_tt, "\ttrans[_NP_] = "); + fprintf(fd_tt, "(Trans **) emalloc(3*sizeof(Trans *));\n"); + fprintf(fd_tt, "\tT = trans[_NP_][0] = "); + fprintf(fd_tt, "settr(9997,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); + fprintf(fd_tt, "\t T->nxt = "); + fprintf(fd_tt, "settr(9998,0,0,_T2,0,\"(1)\", 0,2,0);\n"); + fprintf(fd_tt, "\tT = trans[_NP_][1] = "); + fprintf(fd_tt, "settr(9999,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); } static struct { @@ -186,350 +211,460 @@ disambiguate(); /* avoid name-clashes between scopes */ - if (!(tc = fopen(Cfile[0].nm[separate], MFLAGS)) /* main routines */ - || !(th = fopen(Cfile[1].nm[separate], MFLAGS)) /* header file */ - || !(tt = fopen(Cfile[2].nm[separate], MFLAGS)) /* transition matrix */ - || !(tm = fopen(Cfile[3].nm[separate], MFLAGS)) /* forward moves */ - || !(tb = fopen(Cfile[4].nm[separate], MFLAGS))) /* backward moves */ + if (!(fd_tc = fopen(Cfile[0].nm[separate], MFLAGS)) /* main routines */ + || !(fd_th = fopen(Cfile[1].nm[separate], MFLAGS)) /* header file */ + || !(fd_tt = fopen(Cfile[2].nm[separate], MFLAGS)) /* transition matrix */ + || !(fd_tm = fopen(Cfile[3].nm[separate], MFLAGS)) /* forward moves */ + || !(fd_tb = fopen(Cfile[4].nm[separate], MFLAGS))) /* backward moves */ { printf("spin: cannot create pan.[chtmfb]\n"); alldone(1); } - fprintf(th, "#define SpinVersion \"%s\"\n", SpinVersion); - fprintf(th, "#define PanSource \""); + fprintf(fd_th, "#ifndef PAN_H\n"); + fprintf(fd_th, "#define PAN_H\n\n"); + + fprintf(fd_th, "#define SpinVersion \"%s\"\n", SpinVersion); + fprintf(fd_th, "#define PanSource \""); for (i = 0; oFname->name[i] != '\0'; i++) { char c = oFname->name[i]; - if (c == '\\' || c == ' ') /* Windows path */ - { fprintf(th, "\\"); + if (c == '\\') /* Windows path */ + { fprintf(fd_th, "\\"); } - fprintf(th, "%c", c); + fprintf(fd_th, "%c", c); } - fprintf(th, "\"\n\n"); - - fprintf(th, "#define G_long %d\n", (int) sizeof(long)); - fprintf(th, "#define G_int %d\n", (int) sizeof(int)); - - fprintf(th, "#ifdef WIN64\n"); - fprintf(th, " #define ONE_L ((unsigned long) 1)\n"); - fprintf(th, " #define long long long\n"); - fprintf(th, "#else\n"); - fprintf(th, " #define ONE_L (1L)\n"); - fprintf(th, "#endif\n"); + fprintf(fd_th, "\"\n\n"); - if (separate != 2) - { fprintf(th, "char *TrailFile = PanSource; /* default */\n"); - fprintf(th, "char *trailfilename;\n"); - } - - fprintf(th, "#if defined(BFS)\n"); - fprintf(th, " #ifndef SAFETY\n"); - fprintf(th, " #define SAFETY\n"); - fprintf(th, " #endif\n"); - fprintf(th, " #ifndef XUSAFE\n"); - fprintf(th, " #define XUSAFE\n"); - fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); - - fprintf(th, "#ifndef uchar\n"); - fprintf(th, " #define uchar unsigned char\n"); - fprintf(th, "#endif\n"); - fprintf(th, "#ifndef uint\n"); - fprintf(th, " #define uint unsigned int\n"); - fprintf(th, "#endif\n"); - - if (sizeof(void *) > 4) /* 64 bit machine */ - { fprintf(th, "#if !defined(HASH32) && !defined(HASH64)\n"); - fprintf(th, " #define HASH64\n"); - fprintf(th, "#endif\n"); - } + fprintf(fd_th, "#define G_long %d\n", (int) sizeof(long)); + fprintf(fd_th, "#define G_int %d\n\n", (int) sizeof(int)); + fprintf(fd_th, "#define ulong unsigned long\n"); + fprintf(fd_th, "#define ushort unsigned short\n"); + + fprintf(fd_th, "#ifdef WIN64\n"); + fprintf(fd_th, " #define ONE_L (1L)\n"); + fprintf(fd_th, "/* #define long long long */\n"); + fprintf(fd_th, "#else\n"); + fprintf(fd_th, " #define ONE_L (1L)\n"); + fprintf(fd_th, "#endif\n\n"); + + fprintf(fd_th, "#ifdef BFS_PAR\n"); + fprintf(fd_th, " #define NRUNS %d\n", (runstmnts)?1:0); + fprintf(fd_th, " #ifndef BFS\n"); + fprintf(fd_th, " #define BFS\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #ifndef PUTPID\n"); + fprintf(fd_th, " #define PUTPID\n"); + fprintf(fd_th, " #endif\n\n"); + fprintf(fd_th, " #if !defined(USE_TDH) && !defined(NO_TDH)\n"); + fprintf(fd_th, " #define USE_TDH\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #if defined(USE_TDH) && !defined(NO_HC)\n"); + fprintf(fd_th, " #define HC /* default for USE_TDH */\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #ifndef BFS_MAXPROCS\n"); + fprintf(fd_th, " #define BFS_MAXPROCS 64 /* max nr of cores to use */\n"); + fprintf(fd_th, " #endif\n"); + + fprintf(fd_th, " #define BFS_GLOB 0 /* global lock */\n"); + fprintf(fd_th, " #define BFS_ORD 1 /* used with -DCOLLAPSE */\n"); + fprintf(fd_th, " #define BFS_MEM 2 /* malloc from shared heap */\n"); + fprintf(fd_th, " #define BFS_PRINT 3 /* protect printfs */\n"); + fprintf(fd_th, " #define BFS_STATE 4 /* hashtable */\n\n"); + fprintf(fd_th, " #define BFS_INQ 2 /* state is in q */\n\n"); + + fprintf(fd_th, " #ifdef BFS_FIFO\n"); /* queue access */ + fprintf(fd_th, " #define BFS_ID(a,b) (BFS_STATE + (int) ((a)*BFS_MAXPROCS+(b)))\n"); + fprintf(fd_th, " #define BFS_MAXLOCKS (BFS_STATE + (BFS_MAXPROCS*BFS_MAXPROCS))\n"); + fprintf(fd_th, " #else\n"); /* h_store access (not needed for o_store) */ + fprintf(fd_th, " #ifndef BFS_W\n"); + fprintf(fd_th, " #define BFS_W 10\n"); /* 1<minel = -1; claimproc = n->name = "_:never_template:_"; - ready(n, ZN, s, 0, ZN, N_CLAIM); + mk_rdy(n, ZN, s, 0, ZN, N_CLAIM); } if (separate == 2) { if (has_remote) { printf("spin: warning, make sure that the S1 model\n"); printf(" includes the same remote references\n"); } - fprintf(th, "#ifndef NFAIR\n"); - fprintf(th, "#define NFAIR 2 /* must be >= 2 */\n"); - fprintf(th, "#endif\n"); + fprintf(fd_th, "#ifndef NFAIR\n"); + fprintf(fd_th, "#define NFAIR 2 /* must be >= 2 */\n"); + fprintf(fd_th, "#endif\n"); if (has_last) - fprintf(th, "#define HAS_LAST %d\n", has_last); + fprintf(fd_th, "#define HAS_LAST %d\n", has_last); + if (has_priority && !old_priority_rules) + fprintf(fd_th, "#define HAS_PRIORITY %d\n", has_priority); goto doless; } - fprintf(th, "#define DELTA %d\n", DELTA); - fprintf(th, "#ifdef MA\n"); - fprintf(th, " #if NCORE>1 && !defined(SEP_STATE)\n"); - fprintf(th, " #define SEP_STATE\n"); - fprintf(th, " #endif\n"); - fprintf(th, "#if MA==1\n"); /* user typed -DMA without size */ - fprintf(th, " #undef MA\n"); - fprintf(th, " #define MA 100\n"); - fprintf(th, "#endif\n#endif\n"); - fprintf(th, "#ifdef W_XPT\n"); - fprintf(th, " #if W_XPT==1\n"); /* user typed -DW_XPT without size */ - fprintf(th, " #undef W_XPT\n"); - fprintf(th, " #define W_XPT 1000000\n"); - fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); - fprintf(th, "#ifndef NFAIR\n"); - fprintf(th, " #define NFAIR 2 /* must be >= 2 */\n"); - fprintf(th, "#endif\n"); + fprintf(fd_th, "#define DELTA %d\n", DELTA); + fprintf(fd_th, "#ifdef MA\n"); + fprintf(fd_th, " #if NCORE>1 && !defined(SEP_STATE)\n"); + fprintf(fd_th, " #define SEP_STATE\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #if MA==1\n"); /* user typed -DMA without size */ + fprintf(fd_th, " #undef MA\n"); + fprintf(fd_th, " #define MA 100\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_th, "#ifdef W_XPT\n"); + fprintf(fd_th, " #if W_XPT==1\n"); /* user typed -DW_XPT without size */ + fprintf(fd_th, " #undef W_XPT\n"); + fprintf(fd_th, " #define W_XPT 1000000\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_th, "#ifndef NFAIR\n"); + fprintf(fd_th, " #define NFAIR 2 /* must be >= 2 */\n"); + fprintf(fd_th, "#endif\n"); if (Ntimeouts) - fprintf(th, "#define NTIM %d\n", Ntimeouts); + fprintf(fd_th, "#define NTIM %d\n", Ntimeouts); if (Etimeouts) - fprintf(th, "#define ETIM %d\n", Etimeouts); + fprintf(fd_th, "#define ETIM %d\n", Etimeouts); if (has_remvar) - fprintf(th, "#define REM_VARS 1\n"); + fprintf(fd_th, "#define REM_VARS 1\n"); if (has_remote) - fprintf(th, "#define REM_REFS %d\n", has_remote); /* not yet used */ + fprintf(fd_th, "#define REM_REFS %d\n", has_remote); /* not yet used */ if (has_hidden) - fprintf(th, "#define HAS_HIDDEN %d\n", has_hidden); + { fprintf(fd_th, "#define HAS_HIDDEN %d\n", has_hidden); + fprintf(fd_th, "#if defined(BFS_PAR) || defined(BFS)\n"); + fprintf(fd_th, " #error cannot use BFS on models with variables declared hidden\n"); + fprintf(fd_th, "#endif\n"); + } if (has_last) - fprintf(th, "#define HAS_LAST %d\n", has_last); + fprintf(fd_th, "#define HAS_LAST %d\n", has_last); + if (has_priority && !old_priority_rules) + fprintf(fd_th, "#define HAS_PRIORITY %d\n", has_priority); if (has_sorted) - fprintf(th, "#define HAS_SORTED %d\n", has_sorted); + fprintf(fd_th, "#define HAS_SORTED %d\n", has_sorted); if (m_loss) - fprintf(th, "#define M_LOSS\n"); + fprintf(fd_th, "#define M_LOSS\n"); if (has_random) - fprintf(th, "#define HAS_RANDOM %d\n", has_random); - fprintf(th, "#define HAS_CODE\n"); /* doesn't seem to cause measurable overhead */ - fprintf(th, "#if defined(RANDSTORE) && !defined(RANDSTOR)\n"); - fprintf(th, " #define RANDSTOR RANDSTORE\n"); /* xspin uses RANDSTORE... */ - fprintf(th, "#endif\n"); + fprintf(fd_th, "#define HAS_RANDOM %d\n", has_random); + if (has_ltl) + fprintf(fd_th, "#define HAS_LTL 1\n"); + fprintf(fd_th, "#define HAS_CODE 1\n"); /* could also be set to has_code */ + /* always defining it doesn't seem to cause measurable overhead though */ + /* and allows for pan -r etc to work for non-embedded code as well */ + fprintf(fd_th, "#if defined(RANDSTORE) && !defined(RANDSTOR)\n"); + fprintf(fd_th, " #define RANDSTOR RANDSTORE\n"); /* xspin uses RANDSTORE... */ + fprintf(fd_th, "#endif\n"); if (has_stack) - fprintf(th, "#define HAS_STACK %d\n", has_stack); - if (has_enabled) - fprintf(th, "#define HAS_ENABLED 1\n"); + fprintf(fd_th, "#define HAS_STACK %d\n", has_stack); + if (has_enabled || (has_priority && !old_priority_rules)) + fprintf(fd_th, "#define HAS_ENABLED 1\n"); if (has_unless) - fprintf(th, "#define HAS_UNLESS %d\n", has_unless); + fprintf(fd_th, "#define HAS_UNLESS %d\n", has_unless); if (has_provided) - fprintf(th, "#define HAS_PROVIDED %d\n", has_provided); + fprintf(fd_th, "#define HAS_PROVIDED %d\n", has_provided); if (has_pcvalue) - fprintf(th, "#define HAS_PCVALUE %d\n", has_pcvalue); + fprintf(fd_th, "#define HAS_PCVALUE %d\n", has_pcvalue); if (has_badelse) - fprintf(th, "#define HAS_BADELSE %d\n", has_badelse); + fprintf(fd_th, "#define HAS_BADELSE %d\n", has_badelse); if (has_enabled + || (has_priority && !old_priority_rules) || has_pcvalue || has_badelse || has_last) - { fprintf(th, "#ifndef NOREDUCE\n"); - fprintf(th, " #define NOREDUCE 1\n"); - fprintf(th, "#endif\n"); + { fprintf(fd_th, "#ifndef NOREDUCE\n"); + fprintf(fd_th, " #define NOREDUCE 1\n"); + fprintf(fd_th, "#endif\n"); } if (has_np) - fprintf(th, "#define HAS_NP %d\n", has_np); + fprintf(fd_th, "#define HAS_NP %d\n", has_np); if (merger) - fprintf(th, "#define MERGED 1\n"); + fprintf(fd_th, "#define MERGED 1\n"); doless: - fprintf(th, "#if !defined(HAS_LAST) && defined(BCS)\n"); - fprintf(th, " #define HAS_LAST 1 /* use it, but */\n"); - fprintf(th, " #ifndef STORE_LAST\n"); /* unless the user insists */ - fprintf(th, " #define NO_LAST 1 /* dont store it */\n"); - fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); - - fprintf(th, "#if defined(BCS) && defined(BITSTATE)\n"); - fprintf(th, " #ifndef NO_CTX\n"); - fprintf(th, " #define STORE_CTX 1\n"); - fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); + fprintf(fd_th, "#if !defined(HAS_LAST) && defined(BCS)\n"); + fprintf(fd_th, " #define HAS_LAST 1 /* use it, but */\n"); + fprintf(fd_th, " #ifndef STORE_LAST\n"); /* unless the user insists */ + fprintf(fd_th, " #define NO_LAST 1 /* don't store it */\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "#if defined(BCS) && defined(BITSTATE)\n"); + fprintf(fd_th, " #ifndef NO_CTX\n"); + fprintf(fd_th, " #define STORE_CTX 1\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); - fprintf(th, "#ifdef NP\n"); + fprintf(fd_th, "#ifdef NP\n"); if (!has_np) - fprintf(th, " #define HAS_NP 2\n"); - fprintf(th, " #define VERI %d /* np_ */\n", nrRdy); - fprintf(th, "#endif\n"); + fprintf(fd_th, " #define HAS_NP 2\n"); + fprintf(fd_th, " #define VERI %d /* np_ */\n", nrRdy); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "#if defined(NOCLAIM) && defined(NP)\n"); + fprintf(fd_th, " #undef NOCLAIM\n"); + fprintf(fd_th, "#endif\n"); if (claimproc) { claimnr = fproc(claimproc); /* the default claim */ - fprintf(th, "#ifndef NOCLAIM\n"); - fprintf(th, " #define NCLAIMS %d\n", nclaims); - fprintf(th, " #ifndef NP\n"); - fprintf(th, " #define VERI %d\n", claimnr); - fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); + fprintf(fd_th, "#ifndef NOCLAIM\n"); + fprintf(fd_th, " #define NCLAIMS %d\n", nclaims); + fprintf(fd_th, " #ifndef NP\n"); + fprintf(fd_th, " #define VERI %d\n", claimnr); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); } if (eventmap) { eventmapnr = fproc(eventmap); - fprintf(th, "#define EVENT_TRACE %d\n", eventmapnr); - fprintf(th, "#define endevent endstate%d\n", eventmapnr); + fprintf(fd_th, "#define EVENT_TRACE %d\n", eventmapnr); + fprintf(fd_th, "#define endevent _endstate%d\n", eventmapnr); if (eventmap[2] == 'o') /* ":notrace:" */ - fprintf(th, "#define NEGATED_TRACE 1\n"); + fprintf(fd_th, "#define NEGATED_TRACE 1\n"); } - fprintf(th, "typedef struct S_F_MAP {\n"); - fprintf(th, " char *fnm; int from; int upto;\n"); - fprintf(th, "} S_F_MAP;\n"); + fprintf(fd_th, "\ntypedef struct S_F_MAP {\n"); + fprintf(fd_th, " char *fnm;\n\tint from;\n\tint upto;\n"); + fprintf(fd_th, "} S_F_MAP;\n"); - fprintf(tc, "/*** Generated by %s ***/\n", SpinVersion); - fprintf(tc, "/*** From source: %s ***/\n\n", oFname->name); + fprintf(fd_tc, "/*** Generated by %s ***/\n", SpinVersion); + fprintf(fd_tc, "/*** From source: %s ***/\n\n", oFname->name); - ntimes(tc, 0, 1, Pre0); + ntimes(fd_tc, 0, 1, Pre0); - plunk_c_decls(tc); /* types can be refered to in State */ + plunk_c_decls(fd_tc); /* types can be refered to in State */ switch (separate) { - case 0: fprintf(tc, "#include \"pan.h\"\n"); break; - case 1: fprintf(tc, "#include \"pan_s.h\"\n"); break; - case 2: fprintf(tc, "#include \"pan_t.h\"\n"); break; + case 0: fprintf(fd_tc, "#include \"pan.h\"\n"); break; + case 1: fprintf(fd_tc, "#include \"pan_s.h\"\n"); break; + case 2: fprintf(fd_tc, "#include \"pan_t.h\"\n"); break; + } + + if (separate != 2) + { fprintf(fd_tc, "char *TrailFile = PanSource; /* default */\n"); + fprintf(fd_tc, "char *trailfilename;\n"); } - fprintf(tc, "#ifdef LOOPSTATE\n"); - fprintf(tc, "double cnt_loops;\n"); - fprintf(tc, "#endif\n"); - - fprintf(tc, "State A_Root; /* seed-state for cycles */\n"); - fprintf(tc, "State now; /* the full state-vector */\n"); - plunk_c_fcts(tc); /* State can be used in fcts */ + fprintf(fd_tc, "#ifdef LOOPSTATE\n"); + fprintf(fd_tc, "double cnt_loops;\n"); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_tc, "State A_Root; /* seed-state for cycles */\n"); + fprintf(fd_tc, "State now; /* the full state-vector */\n"); + fprintf(fd_tc, "#if NQS > 0\n"); + fprintf(fd_tc, "short q_flds[NQS+1];\n"); + fprintf(fd_tc, "short q_max[NQS+1];\n"); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_tc, "#ifndef XUSAFE\n"); + fprintf(fd_tc, " uchar q_claim[MAXQ+1];\n"); + fprintf(fd_tc, " char *q_name[MAXQ+1];\n"); + fprintf(fd_tc, " char *p_name[MAXPROC+1];\n"); + fprintf(fd_tc, "#endif\n"); + + plunk_c_fcts(fd_tc); /* State can be used in fcts */ if (separate != 2) - ntimes(tc, 0, 1, Preamble); - else - fprintf(tc, "extern int verbose; extern long depth;\n"); + { ntimes(fd_tc, 0, 1, Preamble); + ntimes(fd_tc, 0, 1, Separate); /* things that moved out of pan.h */ + } else + { fprintf(fd_tc, "extern int verbose;\n"); + fprintf(fd_tc, "extern long depth, depthfound;\n"); + } - fprintf(tc, "#ifndef NOBOUNDCHECK\n"); - fprintf(tc, " #define Index(x, y)\tBoundcheck(x, y, II, tt, t)\n"); - fprintf(tc, "#else\n"); - fprintf(tc, " #define Index(x, y)\tx\n"); - fprintf(tc, "#endif\n"); + fprintf(fd_tc, "#ifndef NOBOUNDCHECK\n"); + fprintf(fd_tc, " #define Index(x, y)\tBoundcheck(x, y, II, tt, t)\n"); + fprintf(fd_tc, "#else\n"); + fprintf(fd_tc, " #define Index(x, y)\tx\n"); + fprintf(fd_tc, "#endif\n"); c_preview(); /* sets hastrack */ - for (p = rdy; p; p = p->nxt) - mst = max(p->s->maxel, mst); + for (p = ready; p; p = p->nxt) + mstp = max(p->s->maxel, mstp); if (separate != 2) - { fprintf(tt, "#ifdef PEG\n"); - fprintf(tt, "struct T_SRC {\n"); - fprintf(tt, " char *fl; int ln;\n"); - fprintf(tt, "} T_SRC[NTRANS];\n\n"); - fprintf(tt, "void\ntr_2_src(int m, char *file, int ln)\n"); - fprintf(tt, "{ T_SRC[m].fl = file;\n"); - fprintf(tt, " T_SRC[m].ln = ln;\n"); - fprintf(tt, "}\n\n"); - fprintf(tt, "void\nputpeg(int n, int m)\n"); - fprintf(tt, "{ printf(\"%%5d\ttrans %%4d \", m, n);\n"); - fprintf(tt, " printf(\"%%s:%%d\\n\",\n"); - fprintf(tt, " T_SRC[n].fl, T_SRC[n].ln);\n"); - fprintf(tt, "}\n"); + { fprintf(fd_tt, "#ifdef PEG\n"); + fprintf(fd_tt, "struct T_SRC {\n"); + fprintf(fd_tt, " char *fl; int ln;\n"); + fprintf(fd_tt, "} T_SRC[NTRANS];\n\n"); + fprintf(fd_tt, "void\ntr_2_src(int m, char *file, int ln)\n"); + fprintf(fd_tt, "{ T_SRC[m].fl = file;\n"); + fprintf(fd_tt, " T_SRC[m].ln = ln;\n"); + fprintf(fd_tt, "}\n\n"); + fprintf(fd_tt, "void\nputpeg(int n, int m)\n"); + fprintf(fd_tt, "{ printf(\"%%5d\ttrans %%4d \", m, n);\n"); + fprintf(fd_tt, " printf(\"%%s:%%d\\n\",\n"); + fprintf(fd_tt, " T_SRC[n].fl, T_SRC[n].ln);\n"); + fprintf(fd_tt, "}\n"); if (!merger) - { fprintf(tt, "#else\n"); - fprintf(tt, "#define tr_2_src(m,f,l)\n"); + { fprintf(fd_tt, "#else\n"); + fprintf(fd_tt, "#define tr_2_src(m,f,l)\n"); } - fprintf(tt, "#endif\n\n"); - fprintf(tt, "void\nsettable(void)\n{\tTrans *T;\n"); - fprintf(tt, "\tTrans *settr(int, int, int, int, int,"); - fprintf(tt, " char *, int, int, int);\n\n"); - fprintf(tt, "\ttrans = (Trans ***) "); - fprintf(tt, "emalloc(%d*sizeof(Trans **));\n", nrRdy+1); + fprintf(fd_tt, "#endif\n\n"); + fprintf(fd_tt, "void\nsettable(void)\n{\tTrans *T;\n"); + fprintf(fd_tt, "\tTrans *settr(int, int, int, int, int,"); + fprintf(fd_tt, " char *, int, int, int);\n\n"); + fprintf(fd_tt, "\ttrans = (Trans ***) "); + fprintf(fd_tt, "emalloc(%d*sizeof(Trans **));\n", nrRdy+1); /* +1 for np_ automaton */ if (separate == 1) { - fprintf(tm, " if (II == 0)\n"); - fprintf(tm, " { _m = step_claim(trpt->o_pm, trpt->tau, tt, ot, t);\n"); - fprintf(tm, " if (_m) goto P999; else continue;\n"); - fprintf(tm, " } else\n"); - } - - fprintf(tm, "#define rand pan_rand\n"); - fprintf(tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); - fprintf(tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); - fprintf(tm, "#endif\n"); - fprintf(tm, " switch (t->forw) {\n"); + fprintf(fd_tm, " if (II == 0)\n"); + fprintf(fd_tm, " { _m = step_claim(trpt->o_pm, trpt->tau, tt, ot, t);\n"); + fprintf(fd_tm, " if (_m) goto P999; else continue;\n"); + fprintf(fd_tm, " } else\n"); + } + + fprintf(fd_tm, "#define rand pan_rand\n"); + fprintf(fd_tm, "#define pthread_equal(a,b) ((a)==(b))\n"); + fprintf(fd_tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); + fprintf(fd_tm, " #ifdef BFS_PAR\n"); + fprintf(fd_tm, " bfs_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(fd_tm, " #else\n"); + fprintf(fd_tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(fd_tm, " #endif\n"); + fprintf(fd_tm, "#endif\n"); + fprintf(fd_tm, " switch (t->forw) {\n"); } else - { fprintf(tt, "#ifndef PEG\n"); - fprintf(tt, " #define tr_2_src(m,f,l)\n"); - fprintf(tt, "#endif\n"); - fprintf(tt, "void\nset_claim(void)\n{\tTrans *T;\n"); - fprintf(tt, "\textern Trans ***trans;\n"); - fprintf(tt, "\textern Trans *settr(int, int, int, int, int,"); - fprintf(tt, " char *, int, int, int);\n\n"); - - fprintf(tm, "#define rand pan_rand\n"); - fprintf(tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); - fprintf(tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, forw);\n"); - fprintf(tm, "#endif\n"); - fprintf(tm, " switch (forw) {\n"); - } - - fprintf(tm, " default: Uerror(\"bad forward move\");\n"); - fprintf(tm, " case 0: /* if without executable clauses */\n"); - fprintf(tm, " continue;\n"); - fprintf(tm, " case 1: /* generic 'goto' or 'skip' */\n"); + { fprintf(fd_tt, "#ifndef PEG\n"); + fprintf(fd_tt, " #define tr_2_src(m,f,l)\n"); + fprintf(fd_tt, "#endif\n"); + fprintf(fd_tt, "void\nset_claim(void)\n{\tTrans *T;\n"); + fprintf(fd_tt, "\textern Trans ***trans;\n"); + fprintf(fd_tt, "\textern Trans *settr(int, int, int, int, int,"); + fprintf(fd_tt, " char *, int, int, int);\n\n"); + + fprintf(fd_tm, "#define rand pan_rand\n"); + fprintf(fd_tm, "#define pthread_equal(a,b) ((a)==(b))\n"); + fprintf(fd_tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); + fprintf(fd_tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, forw);\n"); + fprintf(fd_tm, "#endif\n"); + fprintf(fd_tm, " switch (forw) {\n"); + } + + fprintf(fd_tm, " default: Uerror(\"bad forward move\");\n"); + fprintf(fd_tm, " case 0: /* if without executable clauses */\n"); + fprintf(fd_tm, " continue;\n"); + fprintf(fd_tm, " case 1: /* generic 'goto' or 'skip' */\n"); if (separate != 2) - fprintf(tm, " IfNotBlocked\n"); - fprintf(tm, " _m = 3; goto P999;\n"); - fprintf(tm, " case 2: /* generic 'else' */\n"); + fprintf(fd_tm, " IfNotBlocked\n"); + fprintf(fd_tm, " _m = 3; goto P999;\n"); + fprintf(fd_tm, " case 2: /* generic 'else' */\n"); if (separate == 2) - fprintf(tm, " if (o_pm&1) continue;\n"); + fprintf(fd_tm, " if (o_pm&1) continue;\n"); else - { fprintf(tm, " IfNotBlocked\n"); - fprintf(tm, " if (trpt->o_pm&1) continue;\n"); + { fprintf(fd_tm, " IfNotBlocked\n"); + fprintf(fd_tm, " if (trpt->o_pm&1) continue;\n"); } - fprintf(tm, " _m = 3; goto P999;\n"); + fprintf(fd_tm, " _m = 3; goto P999;\n"); uniq = 3; if (separate == 1) - fprintf(tb, " if (II == 0) goto R999;\n"); + fprintf(fd_tb, " if (II == 0) goto R999;\n"); - fprintf(tb, " switch (t->back) {\n"); - fprintf(tb, " default: Uerror(\"bad return move\");\n"); - fprintf(tb, " case 0: goto R999; /* nothing to undo */\n"); + fprintf(fd_tb, " switch (t->back) {\n"); + fprintf(fd_tb, " default: Uerror(\"bad return move\");\n"); + fprintf(fd_tb, " case 0: goto R999; /* nothing to undo */\n"); - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { putproc(p); } if (separate != 2) - { - fprintf(th, "struct {\n"); - fprintf(th, " int tp; short *src;\n"); - fprintf(th, "} src_all[] = {\n"); - for (p = rdy; p; p = p->nxt) - fprintf(th, " { %d, &src_ln%d[0] },\n", + { fprintf(fd_th, "\n"); + for (p = ready; p; p = p->nxt) + fprintf(fd_th, "extern short src_ln%d[];\n", p->tn); + for (p = ready; p; p = p->nxt) + fprintf(fd_th, "extern S_F_MAP src_file%d[];\n", p->tn); + fprintf(fd_th, "\n"); + + fprintf(fd_tc, "uchar reached%d[3]; /* np_ */\n", nrRdy); + fprintf(fd_tc, "uchar *loopstate%d; /* np_ */\n", nrRdy); + + fprintf(fd_tc, "struct {\n"); + fprintf(fd_tc, " int tp; short *src;\n"); + fprintf(fd_tc, "} src_all[] = {\n"); + for (p = ready; p; p = p->nxt) + fprintf(fd_tc, " { %d, &src_ln%d[0] },\n", p->tn, p->tn); - fprintf(th, " { 0, (short *) 0 }\n"); - fprintf(th, "};\n"); + fprintf(fd_tc, " { 0, (short *) 0 }\n"); + fprintf(fd_tc, "};\n"); - fprintf(th, "S_F_MAP *flref[] = {\n"); /* 5.3.0 */ - for (p = rdy; p; p = p->nxt) - { fprintf(th, " src_file%d%c\n", p->tn, p->nxt?',':' '); + fprintf(fd_tc, "S_F_MAP *flref[] = {\n"); /* 5.3.0 */ + for (p = ready; p; p = p->nxt) + { fprintf(fd_tc, " src_file%d%c\n", p->tn, p->nxt?',':' '); } - fprintf(th, "};\n"); + fprintf(fd_tc, "};\n\n"); + } else + { fprintf(fd_tc, "extern uchar reached%d[3]; /* np_ */\n", nrRdy); } - gencodetable(th); + gencodetable(fd_tc); /* was th */ + + if (Unique < (1 << (8*sizeof(unsigned char)) )) /* was uniq before */ + { fprintf(fd_th, "#define T_ID unsigned char\n"); + } else if (Unique < (1 << (8*sizeof(unsigned short)) )) + { fprintf(fd_th, "#define T_ID unsigned short\n"); + } else + { fprintf(fd_th, "#define T_ID unsigned int\n"); + } if (separate != 1) { tm_predef_np(); tt_predef_np(); } - fprintf(tt, "}\n\n"); /* end of settable() */ + fprintf(fd_tt, "}\n\n"); /* end of settable() */ - fprintf(tm, "#undef rand\n"); - fprintf(tm, " }\n\n"); - fprintf(tb, " }\n\n"); + fprintf(fd_tm, "#undef rand\n"); + fprintf(fd_tm, " }\n\n"); + fprintf(fd_tb, " }\n\n"); if (separate != 2) - { ntimes(tt, 0, 1, Tail); + { ntimes(fd_tt, 0, 1, Tail); genheader(); if (separate == 1) - { fprintf(th, "#define FORWARD_MOVES\t\"pan_s.m\"\n"); - fprintf(th, "#define REVERSE_MOVES\t\"pan_s.b\"\n"); - fprintf(th, "#define SEPARATE\n"); - fprintf(th, "#define TRANSITIONS\t\"pan_s.t\"\n"); - fprintf(th, "extern void ini_claim(int, int);\n"); + { fprintf(fd_th, "#define FORWARD_MOVES\t\"pan_s.m\"\n"); + fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan_s.b\"\n"); + fprintf(fd_th, "#define SEPARATE\n"); + fprintf(fd_th, "#define TRANSITIONS\t\"pan_s.t\"\n"); + fprintf(fd_th, "extern void ini_claim(int, int);\n"); } else - { fprintf(th, "#define FORWARD_MOVES\t\"pan.m\"\n"); - fprintf(th, "#define REVERSE_MOVES\t\"pan.b\"\n"); - fprintf(th, "#define TRANSITIONS\t\"pan.t\"\n"); + { fprintf(fd_th, "#define FORWARD_MOVES\t\"pan.m\"\n"); + fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan.b\"\n"); + fprintf(fd_th, "#define TRANSITIONS\t\"pan.t\"\n"); } genaddproc(); genother(); @@ -537,76 +672,102 @@ genunio(); genconditionals(); gensvmap(); - if (!run) fatal("no runable process", (char *)0); - fprintf(tc, "void\n"); - fprintf(tc, "active_procs(void)\n{\n"); -#if 1 - fprintf(tc, " if (!permuted) {\n"); - reverse_procs(run); - fprintf(tc, " } else {\n"); - forward_procs(run); - fprintf(tc, " }\n"); -#else - reverse_procs(run); -#endif - fprintf(tc, "}\n"); - ntimes(tc, 0, 1, Dfa); - ntimes(tc, 0, 1, Xpt); - - fprintf(th, "#define NTRANS %d\n", uniq); - fprintf(th, "#ifdef PEG\n"); - fprintf(th, " long peg[NTRANS];\n"); - fprintf(th, "#endif\n"); - fprintf(th, "void select_claim(int);\n"); + if (!run_lst) fatal("no runable process", (char *)0); + fprintf(fd_tc, "void\n"); + fprintf(fd_tc, "active_procs(void)\n{\n"); + + fprintf(fd_tc, " if (reversing == 0) {\n"); + reverse_procs(run_lst); + fprintf(fd_tc, " } else {\n"); + forward_procs(run_lst); + fprintf(fd_tc, " }\n"); + + fprintf(fd_tc, "}\n"); + ntimes(fd_tc, 0, 1, Dfa); + ntimes(fd_tc, 0, 1, Xpt); + + fprintf(fd_th, "#define NTRANS %d\n", uniq); if (u_sync && !u_async) - { spit_recvs(th, tc); + { spit_recvs(fd_th, fd_tc); } } else { genheader(); - fprintf(th, "#define FORWARD_MOVES\t\"pan_t.m\"\n"); - fprintf(th, "#define REVERSE_MOVES\t\"pan_t.b\"\n"); - fprintf(th, "#define TRANSITIONS\t\"pan_t.t\"\n"); - fprintf(tc, "extern int Maxbody;\n"); - fprintf(tc, "#if VECTORSZ>32000\n"); - fprintf(tc, " extern int proc_offset[];\n"); - fprintf(tc, "#else\n"); - fprintf(tc, " extern short proc_offset[];\n"); - fprintf(tc, "#endif\n"); - fprintf(tc, "extern uchar proc_skip[];\n"); - fprintf(tc, "extern uchar *reached[];\n"); - fprintf(tc, "extern uchar *accpstate[];\n"); - fprintf(tc, "extern uchar *progstate[];\n"); - fprintf(tc, "extern uchar *stopstate[];\n"); - fprintf(tc, "extern uchar *visstate[];\n\n"); - fprintf(tc, "extern short *mapstate[];\n"); - - fprintf(tc, "void\nini_claim(int n, int h)\n{"); - fprintf(tc, "\textern State now;\n"); - fprintf(tc, "\textern void set_claim(void);\n\n"); - fprintf(tc, "#ifdef PROV\n"); - fprintf(tc, " #include PROV\n"); - fprintf(tc, "#endif\n"); - fprintf(tc, "\tset_claim();\n"); + fprintf(fd_th, "#define FORWARD_MOVES\t\"pan_t.m\"\n"); + fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan_t.b\"\n"); + fprintf(fd_th, "#define TRANSITIONS\t\"pan_t.t\"\n"); + fprintf(fd_tc, "extern int Maxbody;\n"); + fprintf(fd_tc, "#if VECTORSZ>32000\n"); + fprintf(fd_tc, " extern int *proc_offset;\n"); + fprintf(fd_tc, "#else\n"); + fprintf(fd_tc, " extern short *proc_offset;\n"); + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "extern uchar *proc_skip;\n"); + fprintf(fd_tc, "extern uchar *reached[];\n"); + fprintf(fd_tc, "extern uchar *accpstate[];\n"); + fprintf(fd_tc, "extern uchar *progstate[];\n"); + fprintf(fd_tc, "extern uchar *loopstate[];\n"); + fprintf(fd_tc, "extern uchar *stopstate[];\n"); + fprintf(fd_tc, "extern uchar *visstate[];\n\n"); + fprintf(fd_tc, "extern short *mapstate[];\n"); + + fprintf(fd_tc, "void\nini_claim(int n, int h)\n{"); + fprintf(fd_tc, "\textern State now;\n"); + fprintf(fd_tc, "\textern void set_claim(void);\n\n"); + fprintf(fd_tc, "#ifdef PROV\n"); + fprintf(fd_tc, " #include PROV\n"); + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\tset_claim();\n"); genother(); - fprintf(tc, "\n\tswitch (n) {\n"); + fprintf(fd_tc, "\n\tswitch (n) {\n"); genaddproc(); - fprintf(tc, "\t}\n"); - fprintf(tc, "\n}\n"); - fprintf(tc, "int\nstep_claim(int o_pm, int tau, int tt, int ot, Trans *t)\n"); - fprintf(tc, "{ int forw = t->forw; int _m = 0; extern char *noptr; int II=0;\n"); - fprintf(tc, " extern State now;\n"); - fprintf(tc, "#define continue return 0\n"); - fprintf(tc, "#include \"pan_t.m\"\n"); - fprintf(tc, "P999:\n\treturn _m;\n}\n"); - fprintf(tc, "#undef continue\n"); - fprintf(tc, "int\nrev_claim(int backw)\n{ return 0; }\n"); - fprintf(tc, "#include TRANSITIONS\n"); + fprintf(fd_tc, "\t}\n"); + fprintf(fd_tc, "\n}\n"); + fprintf(fd_tc, "int\nstep_claim(int o_pm, int tau, int tt, int ot, Trans *t)\n"); + fprintf(fd_tc, "{ int forw = t->forw; int _m = 0; extern char *noptr; int II=0;\n"); + fprintf(fd_tc, " extern State now;\n"); + fprintf(fd_tc, "#define continue return 0\n"); + fprintf(fd_tc, "#include \"pan_t.m\"\n"); + fprintf(fd_tc, "P999:\n\treturn _m;\n}\n"); + fprintf(fd_tc, "#undef continue\n"); + fprintf(fd_tc, "int\nrev_claim(int backw)\n{ return 0; }\n"); + fprintf(fd_tc, "#include TRANSITIONS\n"); } if (separate != 2) - { c_wrapper(tc); - c_chandump(tc); + { c_wrapper(fd_tc); + c_chandump(fd_tc); + } + + fprintf(fd_th, "#if defined(BFS_PAR) || NCORE>1\n"); + fprintf(fd_th, " void e_critical(int);\n"); + fprintf(fd_th, " void x_critical(int);\n"); + fprintf(fd_th, " #ifdef BFS_PAR\n"); + fprintf(fd_th, " void bfs_main(int, int);\n"); + fprintf(fd_th, " void bfs_report_mem(void);\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "\n\n/* end of PAN_H */\n#endif\n"); + fclose(fd_th); + fclose(fd_tt); + fclose(fd_tm); + fclose(fd_tb); + + if (!(fd_th = fopen("pan.p", MFLAGS))) + { printf("spin: cannot create pan.p for -DBFS_PAR\n"); + return; /* we're done anyway */ } + + ntimes(fd_th, 0, 1, pan_par); /* BFS_PAR */ + fclose(fd_th); + + fprintf(fd_tc, "\nTrans *t_id_lkup[%d];\n\n", globmax+1); + + if (separate != 2) + { fprintf(fd_tc, "\n#ifdef BFS_PAR\n\t#include \"pan.p\"\n#endif\n"); + } + fprintf(fd_tc, "\n/* end of pan.c */\n"); + fclose(fd_tc); } static int @@ -614,7 +775,7 @@ { ProcList *p; if (s) - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) if (s == p->n) return p->tn; return 0; @@ -624,17 +785,17 @@ dolen(Symbol *s, char *pre, int pid, int ai, int qln) { if (ai > 0) - fprintf(tc, "\n\t\t\t || "); - fprintf(tc, "%s(", pre); + fprintf(fd_tc, "\n\t\t\t || "); + fprintf(fd_tc, "%s(", pre); if (!(s->hidden&1)) { if (s->context) - fprintf(tc, "(int) ( ((P%d *)this)->", pid); + fprintf(fd_tc, "(int) ( ((P%d *)_this)->", pid); else - fprintf(tc, "(int) ( now."); + fprintf(fd_tc, "(int) ( now."); } - fprintf(tc, "%s", s->name); - if (qln > 1 || s->isarray) fprintf(tc, "[%d]", ai); - fprintf(tc, ") )"); + fprintf(fd_tc, "%s", s->name); + if (qln > 1 || s->isarray) fprintf(fd_tc, "[%d]", ai); + fprintf(fd_tc, ") )"); } struct AA { char TT[9]; char CC[8]; }; @@ -667,14 +828,14 @@ { if (which) { if (has_unless) - fprintf(tc, "%s", DD[j].CC); + fprintf(fd_tc, "%s", DD[j].CC); else - fprintf(tc, "%s", BB[j].CC); + fprintf(fd_tc, "%s", BB[j].CC); } else { if (has_unless) - fprintf(tc, "%s", DD[j].TT); + fprintf(fd_tc, "%s", DD[j].TT); else - fprintf(tc, "%s", BB[j].TT); + fprintf(fd_tc, "%s", BB[j].TT); } } @@ -684,38 +845,38 @@ int nid = z->Nid; int qln = z->nel; - fprintf(tc, "\t\tcase %d: if (", nid); + fprintf(fd_tc, "\t\tcase %d: if (", nid); for (j = 0; j < 4; j++) - { fprintf(tc, "\t(t->ty[i] == "); + { fprintf(fd_tc, "\t(t->ty[i] == "); bb_or_dd(j, 0); - fprintf(tc, " && ("); + fprintf(fd_tc, " && ("); for (k = 0; k < qln; k++) { if (k > 0) - fprintf(tc, "\n\t\t\t || "); + fprintf(fd_tc, "\n\t\t\t || "); bb_or_dd(j, 1); - fprintf(tc, "(%s%s", nm, z->name); + fprintf(fd_tc, "(%s%s", nm, z->name); if (qln > 1) - fprintf(tc, "[%d]", k); - fprintf(tc, ")"); + fprintf(fd_tc, "[%d]", k); + fprintf(fd_tc, ")"); } - fprintf(tc, "))\n\t\t\t "); + fprintf(fd_tc, "))\n\t\t\t "); if (j < 3) - fprintf(tc, "|| "); + fprintf(fd_tc, "|| "); else - fprintf(tc, " "); + fprintf(fd_tc, " "); } - fprintf(tc, ") return 0; break;\n"); + fprintf(fd_tc, ") return 0; break;\n"); } static void Docase(Symbol *s, int pid, int nid) { int i, j; - fprintf(tc, "\t\tcase %d: if (", nid); + fprintf(fd_tc, "\t\tcase %d: if (", nid); for (j = 0; j < 4; j++) - { fprintf(tc, "\t(t->ty[i] == "); + { fprintf(fd_tc, "\t(t->ty[i] == "); bb_or_dd(j, 0); - fprintf(tc, " && ("); + fprintf(fd_tc, " && ("); if (has_unless) { for (i = 0; i < s->nel; i++) dolen(s, DD[j].CC, pid, i, s->nel); @@ -723,13 +884,13 @@ { for (i = 0; i < s->nel; i++) dolen(s, BB[j].CC, pid, i, s->nel); } - fprintf(tc, "))\n\t\t\t "); + fprintf(fd_tc, "))\n\t\t\t "); if (j < 3) - fprintf(tc, "|| "); + fprintf(fd_tc, "|| "); else - fprintf(tc, " "); + fprintf(fd_tc, " "); } - fprintf(tc, ") return 0; break;\n"); + fprintf(fd_tc, ") return 0; break;\n"); } static void @@ -739,28 +900,28 @@ extern Ordered *all_names; Ordered *walk; - fprintf(th, "#define LOCAL 1\n"); - fprintf(th, "#define Q_FULL_F 2\n"); - fprintf(th, "#define Q_EMPT_F 3\n"); - fprintf(th, "#define Q_EMPT_T 4\n"); - fprintf(th, "#define Q_FULL_T 5\n"); - fprintf(th, "#define TIMEOUT_F 6\n"); - fprintf(th, "#define GLOBAL 7\n"); - fprintf(th, "#define BAD 8\n"); - fprintf(th, "#define ALPHA_F 9\n"); - - fprintf(tc, "int\n"); - fprintf(tc, "q_cond(short II, Trans *t)\n"); - fprintf(tc, "{ int i = 0;\n"); - fprintf(tc, " for (i = 0; i < 6; i++)\n"); - fprintf(tc, " { if (t->ty[i] == TIMEOUT_F) return %s;\n", + fprintf(fd_th, "#define LOCAL 1\n"); + fprintf(fd_th, "#define Q_FULL_F 2\n"); + fprintf(fd_th, "#define Q_EMPT_F 3\n"); + fprintf(fd_th, "#define Q_EMPT_T 4\n"); + fprintf(fd_th, "#define Q_FULL_T 5\n"); + fprintf(fd_th, "#define TIMEOUT_F 6\n"); + fprintf(fd_th, "#define GLOBAL 7\n"); + fprintf(fd_th, "#define BAD 8\n"); + fprintf(fd_th, "#define ALPHA_F 9\n"); + + fprintf(fd_tc, "int\n"); + fprintf(fd_tc, "q_cond(short II, Trans *t)\n"); + fprintf(fd_tc, "{ int i = 0;\n"); + fprintf(fd_tc, " for (i = 0; i < 6; i++)\n"); + fprintf(fd_tc, " { if (t->ty[i] == TIMEOUT_F) return %s;\n", (Etimeouts)?"(!(trpt->tau&1))":"1"); - fprintf(tc, " if (t->ty[i] == ALPHA_F)\n"); - fprintf(tc, "#ifdef GLOB_ALPHA\n"); - fprintf(tc, " return 0;\n"); - fprintf(tc, "#else\n\t\t\treturn "); - fprintf(tc, "(II+1 == (short) now._nr_pr && II+1 < MAXPROC);\n"); - fprintf(tc, "#endif\n"); + fprintf(fd_tc, " if (t->ty[i] == ALPHA_F)\n"); + fprintf(fd_tc, "#ifdef GLOB_ALPHA\n"); + fprintf(fd_tc, " return 0;\n"); + fprintf(fd_tc, "#else\n\t\t\treturn "); + fprintf(fd_tc, "(II+1 == (short) now._nr_pr && II+1 < MAXPROC);\n"); + fprintf(fd_tc, "#endif\n"); /* we switch on the chan name from the spec (as identified by * the corresponding Nid number) rather than the actual qid @@ -770,8 +931,8 @@ * but we do know which name is used. if it's a chan array, we * must check all elements of the array for compliance (bummer) */ - fprintf(tc, " switch (t->qu[i]) {\n"); - fprintf(tc, " case 0: break;\n"); + fprintf(fd_tc, " switch (t->qu[i]) {\n"); + fprintf(fd_tc, " case 0: break;\n"); for (walk = all_names; walk; walk = walk->next) { s = walk->entry; @@ -784,84 +945,89 @@ } else if (s->type == STRUCT) { /* struct may contain a chan */ char pregat[128]; - extern void walk2_struct(char *, Symbol *); strcpy(pregat, ""); if (!(s->hidden&1)) { if (s->context) - sprintf(pregat, "((P%d *)this)->",j); + sprintf(pregat, "((P%d *)_this)->",j); else sprintf(pregat, "now."); } walk2_struct(pregat, s); } } - fprintf(tc, " \tdefault: Uerror(\"unknown qid - q_cond\");\n"); - fprintf(tc, " \t\t\treturn 0;\n"); - fprintf(tc, " \t}\n"); - fprintf(tc, " }\n"); - fprintf(tc, " return 1;\n"); - fprintf(tc, "}\n"); + fprintf(fd_tc, " \tdefault: Uerror(\"unknown qid - q_cond\");\n"); + fprintf(fd_tc, " \t\t\treturn 0;\n"); + fprintf(fd_tc, " \t}\n"); + fprintf(fd_tc, " }\n"); + fprintf(fd_tc, " return 1;\n"); + fprintf(fd_tc, "}\n"); } static void putproc(ProcList *p) -{ Pid = p->tn; +{ Pid_nr = p->tn; Det = p->det; - if (pid_is_claim(Pid) + if (pid_is_claim(Pid_nr) && separate == 1) - { fprintf(th, "extern uchar reached%d[];\n", Pid); + { fprintf(fd_th, "extern uchar reached%d[];\n", Pid_nr); #if 0 - fprintf(th, "extern short nstates%d;\n", Pid); + fprintf(fd_th, "extern short _nstates%d;\n", Pid_nr); #else - fprintf(th, "\n#define nstates%d %d\t/* %s */\n", - Pid, p->s->maxel, p->n->name); + fprintf(fd_th, "\n#define _nstates%d %d\t/* %s */\n", + Pid_nr, p->s->maxel, p->n->name); #endif - fprintf(th, "extern short src_ln%d[];\n", Pid); - fprintf(th, "extern uchar *loopstate%d;\n", Pid); - fprintf(th, "extern S_F_MAP src_file%d[];\n", Pid); - fprintf(th, "#define endstate%d %d\n", - Pid, p->s->last?p->s->last->seqno:0); + fprintf(fd_th, "extern short src_ln%d[];\n", Pid_nr); + fprintf(fd_th, "extern uchar *loopstate%d;\n", Pid_nr); + fprintf(fd_th, "extern S_F_MAP src_file%d[];\n", Pid_nr); + fprintf(fd_th, "#define _endstate%d %d\n", + Pid_nr, p->s->last?p->s->last->seqno:0); return; } - if (!pid_is_claim(Pid) + if (!pid_is_claim(Pid_nr) && separate == 2) - { fprintf(th, "extern short src_ln%d[];\n", Pid); - fprintf(th, "extern uchar *loopstate%d;\n", Pid); + { fprintf(fd_th, "extern short src_ln%d[];\n", Pid_nr); + fprintf(fd_th, "extern uchar *loopstate%d;\n", Pid_nr); return; } AllGlobal = (p->prov)?1:0; /* process has provided clause */ - fprintf(th, "\n#define nstates%d %d\t/* %s */\n", - Pid, p->s->maxel, p->n->name); - if (Pid == eventmapnr) - fprintf(th, "#define nstates_event nstates%d\n", Pid); + fprintf(fd_th, "\n#define _nstates%d %d\t/* %s */\n", + Pid_nr, p->s->maxel, p->n->name); +/* new */ + fprintf(fd_th, "#define minseq%d %d\n", Pid_nr, find_min(p->s)); + fprintf(fd_th, "#define maxseq%d %d\n", Pid_nr, find_max(p->s)); + +/* end */ + + if (Pid_nr == eventmapnr) + fprintf(fd_th, "#define nstates_event _nstates%d\n", Pid_nr); - fprintf(th, "#define endstate%d %d\n", Pid, p->s->last?p->s->last->seqno:0); + fprintf(fd_th, "#define _endstate%d %d\n", Pid_nr, p->s->last?p->s->last->seqno:0); if (p->b == N_CLAIM || p->b == E_TRACE || p->b == N_TRACE) - { fprintf(tm, "\n /* CLAIM %s */\n", p->n->name); - fprintf(tb, "\n /* CLAIM %s */\n", p->n->name); + { fprintf(fd_tm, "\n /* CLAIM %s */\n", p->n->name); + fprintf(fd_tb, "\n /* CLAIM %s */\n", p->n->name); } else - { fprintf(tm, "\n /* PROC %s */\n", p->n->name); - fprintf(tb, "\n /* PROC %s */\n", p->n->name); + { fprintf(fd_tm, "\n /* PROC %s */\n", p->n->name); + fprintf(fd_tb, "\n /* PROC %s */\n", p->n->name); } - fprintf(tt, "\n /* proctype %d: %s */\n", Pid, p->n->name); - fprintf(tt, "\n trans[%d] = (Trans **)", Pid); - fprintf(tt, " emalloc(%d*sizeof(Trans *));\n\n", p->s->maxel); - - if (Pid == eventmapnr) - { fprintf(th, "\n#define in_s_scope(x_y3_) 0"); - fprintf(tc, "\n#define in_r_scope(x_y3_) 0"); + fprintf(fd_tt, "\n /* proctype %d: %s */\n", Pid_nr, p->n->name); + fprintf(fd_tt, "\n trans[%d] = (Trans **)", Pid_nr); + fprintf(fd_tt, " emalloc(%d*sizeof(Trans *));\n\n", p->s->maxel); + + if (Pid_nr == eventmapnr) + { fprintf(fd_th, "\n#define in_s_scope(x_y3_) 0"); + fprintf(fd_tc, "\n#define in_r_scope(x_y3_) 0"); } put_seq(p->s, 2, 0); - if (Pid == eventmapnr) - { fprintf(th, "\n\n"); - fprintf(tc, "\n\n"); + if (Pid_nr == eventmapnr) + { fprintf(fd_th, "\n\n"); + fprintf(fd_tc, "\n\n"); } - dumpsrc(p->s->maxel, Pid); + dumpsrc(p->s->maxel, Pid_nr); } static void @@ -1003,17 +1169,17 @@ if (e->esc /* && e->n->ntyp != GOTO */ && e->n->ntyp != '.') { for (x = e->esc, n = 0; x; x = x->nxt, n++) { int i = huntele(x->this->frst, e->status, -1)->seqno; - fprintf(tt, "\ttrans[%d][%d]->escp[%d] = %d;\n", - Pid, e->seqno, n, i); - fprintf(tt, "\treached%d[%d] = 1;\n", - Pid, i); + fprintf(fd_tt, "\ttrans[%d][%d]->escp[%d] = %d;\n", + Pid_nr, e->seqno, n, i); + fprintf(fd_tt, "\treached%d[%d] = 1;\n", + Pid_nr, i); } for (x = e->esc, n=0; x; x = x->nxt, n++) - { fprintf(tt, " /* escape #%d: %d */\n", n, + { fprintf(fd_tt, " /* escape #%d: %d */\n", n, huntele(x->this->frst, e->status, -1)->seqno); put_seq(x->this, 2, 0); /* args?? */ } - fprintf(tt, " /* end-escapes */\n"); + fprintf(fd_tt, " /* end-escapes */\n"); } } @@ -1040,11 +1206,11 @@ if (e->n->ntyp == D_STEP) { int inherit = (e->status&(ATOM|L_ATOM)); - fprintf(tm, "\tcase %d: ", uniq++); - fprintf(tm, "/* STATE %d - %s:%d - [", + fprintf(fd_tm, "\tcase %d: ", uniq++); + fprintf(fd_tm, "// STATE %d - %s:%d - [", e->seqno, e->n->fn->name, e->n->ln); - comment(tm, e->n, 0); - fprintf(tm, "] */\n\t\t"); + comment(fd_tm, e->n, 0); + fprintf(fd_tm, "]\n\t\t"); if (s->last->n->ntyp == BREAK) OkBreak = target(huntele(s->last->nxt, @@ -1052,59 +1218,65 @@ else OkBreak = -1; - if (!putcode(tm, s, e->nxt, 0, e->n->ln, e->seqno)) + if (!putcode(fd_tm, s, e->nxt, 0, e->n->ln, e->seqno)) { - fprintf(tm, "\n#if defined(C_States) && (HAS_TRACK==1)\n"); - fprintf(tm, "\t\tc_update((uchar *) &(now.c_state[0]));\n"); - fprintf(tm, "#endif\n"); + fprintf(fd_tm, "\n#if defined(C_States) && (HAS_TRACK==1)\n"); + fprintf(fd_tm, "\t\tc_update((uchar *) &(now.c_state[0]));\n"); + fprintf(fd_tm, "#endif\n"); - fprintf(tm, "\t\t_m = %d", getweight(s->frst->n)); + fprintf(fd_tm, "\t\t_m = %d", getweight(s->frst->n)); if (m_loss && s->frst->n->ntyp == 's') - fprintf(tm, "+delta_m; delta_m = 0"); - fprintf(tm, "; goto P999;\n\n"); + fprintf(fd_tm, "+delta_m; delta_m = 0"); + fprintf(fd_tm, "; goto P999;\n\n"); } - fprintf(tb, "\tcase %d: ", uniq-1); - fprintf(tb, "/* STATE %d */\n", e->seqno); - fprintf(tb, "\t\tsv_restor();\n"); - fprintf(tb, "\t\tgoto R999;\n"); + fprintf(fd_tb, "\tcase %d: ", uniq-1); + fprintf(fd_tb, "// STATE %d\n", e->seqno); + fprintf(fd_tb, "\t\tsv_restor();\n"); + fprintf(fd_tb, "\t\tgoto R999;\n"); if (e->nxt) a = huntele(e->nxt, e->status, -1)->seqno; else a = 0; tr_map(uniq-1, e); - fprintf(tt, "/*->*/\ttrans[%d][%d]\t= ", - Pid, e->seqno); - fprintf(tt, "settr(%d,%d,%d,%d,%d,\"", + fprintf(fd_tt, "/*->*/\ttrans[%d][%d]\t= ", + Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,%d,%d,%d,\"", e->Seqno, D_ATOM|inherit, a, uniq-1, uniq-1); - comment(tt, e->n, e->seqno); - fprintf(tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); - fprintf(tt, "%d, %d);\n", TPE[0], TPE[1]); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; + fprintf(fd_tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); + fprintf(fd_tt, "%d, %d);\n", TPE[0], TPE[1]); put_escp(e); } else { /* ATOMIC or NON_ATOMIC */ - fprintf(tt, "\tT = trans[ %d][%d] = ", Pid, e->seqno); - fprintf(tt, "settr(%d,%d,0,0,0,\"", + fprintf(fd_tt, "\tT = trans[ %d][%d] = ", Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,0,0,0,\"", e->Seqno, (e->n->ntyp == ATOMIC)?ATOM:0); - comment(tt, e->n, e->seqno); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; if ((e->status&CHECK2) || (g->status&CHECK2)) s->frst->status |= I_GLOB; - fprintf(tt, "\", %d, %d, %d);", + fprintf(fd_tt, "\", %d, %d, %d);", (s->frst->status&I_GLOB)?1:0, Tt0, Tt1); - blurb(tt, e); - fprintf(tt, "\tT->nxt\t= "); - fprintf(tt, "settr(%d,%d,%d,0,0,\"", + blurb(fd_tt, e); + fprintf(fd_tt, "\tT->nxt\t= "); + fprintf(fd_tt, "settr(%d,%d,%d,0,0,\"", e->Seqno, (e->n->ntyp == ATOMIC)?ATOM:0, a); - comment(tt, e->n, e->seqno); - fprintf(tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; + fprintf(fd_tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); if (e->n->ntyp == NON_ATOMIC) - { fprintf(tt, "%d, %d);", Tt0, Tt1); - blurb(tt, e); + { fprintf(fd_tt, "%d, %d);", Tt0, Tt1); + blurb(fd_tt, e); put_seq(s, Tt0, Tt1); } else - { fprintf(tt, "%d, %d);", TPE[0], TPE[1]); - blurb(tt, e); + { fprintf(fd_tt, "%d, %d);", TPE[0], TPE[1]); + blurb(fd_tt, e); put_seq(s, TPE[0], TPE[1]); } } @@ -1268,6 +1440,7 @@ switch (e->n->ntyp) { case ASGN: + if (check_track(e->n) == STRUCT) { break; } nr++; break; case 'r': @@ -1328,10 +1501,10 @@ } if (f && !f->merge && !f->merge_single && f->seqno != stopat) - { fprintf(tm, "\n\t\tbad hop %s:%d -- at %d, <", + { fprintf(fd_tm, "\n\t\t// bad 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", + comment(fd_tm, f->n, 0); + fprintf(fd_tm, "> looking for %d -- merge %d:%d:%d ", stopat, f->merge, f->merge_start, f->merge_single); break; } @@ -1344,7 +1517,7 @@ check_needed(void) { if (multi_needed) - { fprintf(tm, "(trpt+1)->bup.ovals = grab_ints(%d);\n\t\t", + { fprintf(fd_tm, "(trpt+1)->bup.ovals = grab_ints(%d);\n\t\t", multi_needed); multi_undo = multi_needed; multi_needed = 0; @@ -1363,7 +1536,9 @@ } if (deadvar && !has_code) for (u = e->dead; u; u = u->nxt) - { fprintf(tm_fd, ";\n\t\t/* dead %d: %s */ ", + { fprintf(tm_fd, ";\n\t\t"); + fprintf(tm_fd, "if (TstOnly) return 1; /* TT */\n"); + fprintf(tm_fd, "\t\t/* dead %d: %s */ ", u->special, u->var->name); switch (u->special) { @@ -1411,8 +1586,8 @@ } if (!didcase) - { fprintf(tb, "\n\tcase %d: ", casenr); - fprintf(tb, "/* STATE %d */\n\t\t", e->seqno); + { fprintf(fd_tb, "\n\tcase %d: ", casenr); + fprintf(fd_tb, "// STATE %d\n\t\t", e->seqno); didcase++; } @@ -1422,16 +1597,16 @@ 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"); + fprintf(fd_tb, ";\n\t/* %d */\t", YZmax); + putname(fd_tb, "", &YZ[YZmax], 0, " = trpt->bup.oval"); if (multi_oval > 0) { multi_oval--; - fprintf(tb, "s[%d]", multi_oval-1); + fprintf(fd_tb, "s[%d]", multi_oval-1); } } if (e->n->ntyp != '.') - { fprintf(tb, ";\n\t\t"); + { fprintf(fd_tb, ";\n\t\t"); undostmnt(e->n, e->seqno); } _isok--; @@ -1458,14 +1633,14 @@ return; lastfirst(stopat, f, casenr); #if 0 - fprintf(tb, "\n\t/* merge %d -- %d:%d %d:%d:%d (casenr %d) ", + fprintf(fd_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); + comment(fd_tb, f->n, 0); + fprintf(fd_tb, " */\n"); + fflush(fd_tb); #endif dobackward(f, casenr); } @@ -1516,12 +1691,14 @@ { /* 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"); + { fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); + fprintf(fd_tt, "settr(0,0,0,0,0,\""); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; + fprintf(fd_tt, "\",0,0,0);\n"); } else - { fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); + { fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); casenr = 1; /* mhs example */ j = a; goto haveit; /* pakula's example */ @@ -1530,20 +1707,20 @@ return -1; } - fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); + fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); if (ccache - && !pid_is_claim(Pid) - && Pid != eventmapnr - && (Cached = prev_case(e, Pid))) + && !pid_is_claim(Pid_nr) + && Pid_nr != eventmapnr + && (Cached = prev_case(e, Pid_nr))) { bupcase = Cached->b; casenr = Cached->m; fromcache = 1; - fprintf(tm, "/* STATE %d - %s:%d - [", + fprintf(fd_tm, "// STATE %d - %s:%d - [", e->seqno, e->n->fn->name, e->n->ln); - comment(tm, e->n, 0); - fprintf(tm, "] (%d:%d - %d) same as %d (%d:%d - %d) */\n", + comment(fd_tm, e->n, 0); + fprintf(fd_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); @@ -1551,18 +1728,18 @@ goto gotit; } - fprintf(tm, "\tcase %d: /* STATE %d - %s:%d - [", + fprintf(fd_tm, "\tcase %d: // STATE %d - %s:%d - [", uniq++, e->seqno, e->n->fn->name, e->n->ln); - comment(tm, e->n, 0); + comment(fd_tm, e->n, 0); nrbups = (e->merge || e->merge_start) ? nrhops(e) : nr_bup(e); - fprintf(tm, "] (%d:%d:%d - %d) */\n\t\t", + fprintf(fd_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_is_claim(Pid) && Pid != eventmapnr) - fprintf(tm, "IfNotBlocked\n\t\t"); + if (e->n->ntyp != 'r' && !pid_is_claim(Pid_nr) && Pid_nr != eventmapnr) + fprintf(fd_tm, "IfNotBlocked\n\t\t"); if (multi_needed != 0 || multi_undo != 0) fatal("cannot happen, case_cache", (char *) 0); @@ -1577,36 +1754,36 @@ YZmax = YZcnt = 0; /* new 4.2.6, revised 6.0.0 */ - if (pid_is_claim(Pid)) - { fprintf(tm, "\n#if defined(VERI) && !defined(NP)\n"); -fprintf(tm, "#if NCLAIMS>1\n"); - fprintf(tm, "\t\t{ static int reported%d = 0;\n", e->seqno); - fprintf(tm, "\t\t int nn = (int) ((Pclaim *)this)->_n;\n\t\t"); - fprintf(tm, " if (verbose && !reported%d)\n\t\t", e->seqno); - fprintf(tm, " {\tprintf(\"depth %%ld: Claim %%s (%%d), state %%d (line %%d)\\n\",\n\t\t"); - fprintf(tm, " \t\tdepth, procname[spin_c_typ[nn]], nn, "); - fprintf(tm, "(int) ((Pclaim *)this)->_p, src_claim[ (int) ((Pclaim *)this)->_p ]);\n\t\t"); - fprintf(tm, " reported%d = 1;\n\t\t", e->seqno); - fprintf(tm, " fflush(stdout);\n\t\t"); - fprintf(tm, "} }\n"); -fprintf(tm, "#else\n"); - fprintf(tm, "{ static int reported%d = 0;\n\t\t", e->seqno); - fprintf(tm, " if (verbose && !reported%d)\n\t\t", e->seqno); - fprintf(tm, " { printf(\"depth %%d: Claim, state %%d (line %%d)\\n\",\n\t\t"); - fprintf(tm, " (int) depth, (int) ((Pclaim *)this)->_p, "); - fprintf(tm, "src_claim[ (int) ((Pclaim *)this)->_p ]);\n\t\t"); - fprintf(tm, " reported%d = 1;\n\t\t", e->seqno); - fprintf(tm, " fflush(stdout);\n\t\t"); - fprintf(tm, "} }\n"); -fprintf(tm, "#endif\n"); - fprintf(tm, "#endif\n\t\t"); + if (pid_is_claim(Pid_nr)) + { fprintf(fd_tm, "\n#if defined(VERI) && !defined(NP)\n"); + fprintf(fd_tm, "#if NCLAIMS>1\n\t\t"); + fprintf(fd_tm, "{ static int reported%d = 0;\n\t\t", e->seqno); + fprintf(fd_tm, " if (verbose && !reported%d)\n\t\t", e->seqno); + fprintf(fd_tm, " { int nn = (int) ((Pclaim *)pptr(0))->_n;\n\t\t"); + fprintf(fd_tm, " printf(\"depth %%ld: Claim %%s (%%d), state %%d (line %%d)\\n\",\n\t\t"); + fprintf(fd_tm, " depth, procname[spin_c_typ[nn]], nn, "); + fprintf(fd_tm, "(int) ((Pclaim *)pptr(0))->_p, src_claim[ (int) ((Pclaim *)pptr(0))->_p ]);\n\t\t"); + fprintf(fd_tm, " reported%d = 1;\n\t\t", e->seqno); + fprintf(fd_tm, " fflush(stdout);\n\t\t"); + fprintf(fd_tm, "} }\n"); + fprintf(fd_tm, "#else\n\t\t"); + fprintf(fd_tm, "{ static int reported%d = 0;\n\t\t", e->seqno); + fprintf(fd_tm, " if (verbose && !reported%d)\n\t\t", e->seqno); + fprintf(fd_tm, " { printf(\"depth %%d: Claim, state %%d (line %%d)\\n\",\n\t\t"); + fprintf(fd_tm, " (int) depth, (int) ((Pclaim *)pptr(0))->_p, "); + fprintf(fd_tm, "src_claim[ (int) ((Pclaim *)pptr(0))->_p ]);\n\t\t"); + fprintf(fd_tm, " reported%d = 1;\n\t\t", e->seqno); + fprintf(fd_tm, " fflush(stdout);\n\t\t"); + fprintf(fd_tm, "} }\n"); + fprintf(fd_tm, "#endif\n"); + fprintf(fd_tm, "#endif\n\t\t"); } /* end */ /* the src xrefs have the numbers in e->seqno builtin */ - fprintf(tm, "reached[%d][%d] = 1;\n\t\t", Pid, e->seqno); + fprintf(fd_tm, "reached[%d][%d] = 1;\n\t\t", Pid_nr, e->seqno); - doforward(tm, e); + doforward(fd_tm, e); if (e->merge_start) ntarget = e->merge_start; @@ -1628,26 +1805,26 @@ if (f && f->seqno != ntarget) { if (!f->merge && !f->merge_single) - { fprintf(tm, "/* stop at bad hop %d, %d */\n\t\t", + { fprintf(fd_tm, "/* stop at bad hop %d, %d */\n\t\t", f->seqno, ntarget); goto out; } - fprintf(tm, "/* merge: "); - comment(tm, f->n, 0); - fprintf(tm, "(%d, %d, %d) */\n\t\t", f->merge, f->seqno, ntarget); - fprintf(tm, "reached[%d][%d] = 1;\n\t\t", Pid, f->seqno); + fprintf(fd_tm, "/* merge: "); + comment(fd_tm, f->n, 0); + fprintf(fd_tm, "(%d, %d, %d) */\n\t\t", f->merge, f->seqno, ntarget); + fprintf(fd_tm, "reached[%d][%d] = 1;\n\t\t", Pid_nr, f->seqno); YZcnt++; lab_transfer(e, f); mark = f->status&(ATOM|L_ATOM); /* last step wins */ - doforward(tm, f); + doforward(fd_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); + fprintf(fd_tm, "_m = %d", getweight(e->n)); + if (m_loss && e->n->ntyp == 's') fprintf(fd_tm, "+delta_m; delta_m = 0"); + fprintf(fd_tm, "; goto P999; /* %d */\n", YZcnt); multi_needed = 0; didcase = 0; @@ -1657,31 +1834,31 @@ dobackward(e, casenr); /* the original step */ - fprintf(tb, ";\n\t\t"); + fprintf(fd_tb, ";\n\t\t"); if (e->merge || e->merge_start) { if (!didcase) - { fprintf(tb, "\n\tcase %d: ", casenr); - fprintf(tb, "/* STATE %d */", e->seqno); + { fprintf(fd_tb, "\n\tcase %d: ", casenr); + fprintf(fd_tb, "// STATE %d", e->seqno); didcase++; } else - fprintf(tb, ";"); + fprintf(fd_tb, ";"); } else - fprintf(tb, ";"); - fprintf(tb, "\n\t\t"); + fprintf(fd_tb, ";"); + fprintf(fd_tb, "\n\t\t"); if (multi_undo) - { fprintf(tb, "ungrab_ints(trpt->bup.ovals, %d);\n\t\t", + { fprintf(fd_tb, "ungrab_ints(trpt->bup.ovals, %d);\n\t\t", multi_undo); multi_undo = 0; } if (didcase) - { fprintf(tb, "goto R999;\n"); + { fprintf(fd_tb, "goto R999;\n"); bupcase = casenr; } if (!e->merge && !e->merge_start) - new_case(e, casenr, bupcase, Pid); + new_case(e, casenr, bupcase, Pid_nr); gotit: j = a; @@ -1690,7 +1867,7 @@ else if (e->merge) j = e->merge; haveit: - fprintf(tt, "%ssettr(%d,%d,%d,%d,%d,\"", fromcache?"/* c */ ":"", + fprintf(fd_tt, "%ssettr(%d,%d,%d,%d,%d,\"", fromcache?"/* c */ ":"", e->Seqno, mark, j, casenr, bupcase); return (fromcache)?0:casenr; @@ -1712,8 +1889,8 @@ } else a = 0; if (g - && (g->status&CHECK2 /* entering remotely ref'd state */ - || e->status&CHECK2)) /* leaving remotely ref'd state */ + && ((g->status&CHECK2) /* entering remotely ref'd state */ + || (e->status&CHECK2))) /* leaving remotely ref'd state */ e->status |= I_GLOB; /* don't remove dead edges in here, to preserve structure of fsm */ @@ -1732,8 +1909,8 @@ case BREAK: putskip(e->seqno); casenr = 1; /* standard goto */ -generic_case: fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); - fprintf(tt, "settr(%d,%d,%d,%d,0,\"", +generic_case: fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,%d,%d,0,\"", e->Seqno, e->status&ATOM, a, casenr); break; #ifndef PRINTF @@ -1759,22 +1936,24 @@ } /* tailend of settr(...); */ Global_ref = (e->status&I_GLOB)?1:has_global(e->n); - comment(tt, e->n, e->seqno); - fprintf(tt, "\", %d, ", Global_ref); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; + fprintf(fd_tt, "\", %d, ", Global_ref); if (Tt0 != 2) - { fprintf(tt, "%d, %d);", Tt0, Tt1); + { fprintf(fd_tt, "%d, %d);", Tt0, Tt1); } else { Tpe(e->n); /* sets EPT */ - fprintf(tt, "%d, %d);", EPT[0], EPT[1]); + fprintf(fd_tt, "%d, %d);", EPT[0], EPT[1]); } if ((e->merge_start && e->merge_start != a) || (e->merge && e->merge != a)) - { fprintf(tt, " /* m: %d -> %d,%d */\n", + { fprintf(fd_tt, " /* m: %d -> %d,%d */\n", a, e->merge_start, e->merge); - fprintf(tt, " reached%d[%d] = 1;", - Pid, a); /* Sheinman's example */ + fprintf(fd_tt, " reached%d[%d] = 1;", + Pid_nr, a); /* Sheinman's example */ } - fprintf(tt, "\n"); + fprintf(fd_tt, "\n"); if (casenr > 2) tr_map(casenr, e); @@ -1839,16 +2018,18 @@ } else if (e->sub) { if (0) printf(" has sub\n"); - fprintf(tt, "\tT = trans[%d][%d] = ", - Pid, e->seqno); - fprintf(tt, "settr(%d,%d,0,0,0,\"", + fprintf(fd_tt, "\tT = trans[%d][%d] = ", + Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,0,0,0,\"", e->Seqno, e->status&ATOM); - comment(tt, e->n, e->seqno); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; if (e->status&CHECK2) e->status |= I_GLOB; - fprintf(tt, "\", %d, %d, %d);", + fprintf(fd_tt, "\", %d, %d, %d);", (e->status&I_GLOB)?1:0, Tt0, Tt1); - blurb(tt, e); + blurb(fd_tt, e); for (h = e->sub; h; h = h->nxt) { putskip(h->this->frst->seqno); g = huntstart(h->this->frst); @@ -1860,29 +2041,31 @@ && g->n->lft->ntyp == CONST && g->n->lft->val == 0 /* 0 or false */ && !g->esc) - { fprintf(tt, "#if 0\n\t/* dead link: */\n"); + { fprintf(fd_tt, "#if 0\n\t/* dead link: */\n"); deadlink = 1; if (verbose&32) - printf("spin: warning, %s:%d: condition is always false\n", + printf("spin: %s:%d, warning, condition is always false\n", g->n->fn?g->n->fn->name:"", g->n->ln); } else deadlink = 0; if (0) printf(" settr %d %d\n", a, 0); if (h->nxt) - fprintf(tt, "\tT = T->nxt\t= "); + fprintf(fd_tt, "\tT = T->nxt\t= "); else - fprintf(tt, "\t T->nxt\t= "); - fprintf(tt, "settr(%d,%d,%d,0,0,\"", + fprintf(fd_tt, "\t T->nxt\t= "); + fprintf(fd_tt, "settr(%d,%d,%d,0,0,\"", e->Seqno, e->status&ATOM, a); - comment(tt, e->n, e->seqno); +in_settr++; + comment(fd_tt, e->n, e->seqno); +in_settr--; if (g->status&CHECK2) h->this->frst->status |= I_GLOB; - fprintf(tt, "\", %d, %d, %d);", + fprintf(fd_tt, "\", %d, %d, %d);", (h->this->frst->status&I_GLOB)?1:0, Tt0, Tt1); - blurb(tt, e); + blurb(fd_tt, e); if (deadlink) - fprintf(tt, "#endif\n"); + fprintf(fd_tt, "#endif\n"); } for (h = e->sub; h; h = h->nxt) put_seq(h->this, Tt0, Tt1); @@ -2036,7 +2219,7 @@ && !(f->status & L_ATOM) && !(g->status & (ATOM|L_ATOM))) #endif - { fprintf(tt, "\t/* mark-down line %d status %d = %d */\n", f->n->ln, f->status, (f->status & D_ATOM)); + { fprintf(fd_tt, "\t/* mark-down line %d status %d = %d */\n", f->n->ln, f->status, (f->status & D_ATOM)); return 1; /* assume worst case */ } } for (h = f->sub; h; h = h->nxt) @@ -2070,7 +2253,7 @@ /* not safe unless no local var inits are used */ /* note that a local variable init could refer to a global */ - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { if (strcmp(n->sym->name, p->n->name) == 0) { /* printf("proc %s safety: %d\n", p->n->name, p->unsafe); */ return (p->unsafe != 0); @@ -2083,6 +2266,7 @@ int has_global(Lextok *n) { Lextok *v; + static Symbol *n_seen = (Symbol *) 0; if (!n) return 0; if (AllGlobal) return 1; /* global provided clause */ @@ -2111,6 +2295,14 @@ case LEN: return (((n->sym->xu)&(XR|XS|XX)) != (XR|XS)); case NAME: + if (strcmp(n->sym->name, "_priority") == 0) + { if (old_priority_rules) + { if (n_seen != n->sym) + fatal("cannot refer to _priority with -o6", (char *) 0); + n_seen = n->sym; + } + return 0; + } if (n->sym->context || (n->sym->hidden&64) || strcmp(n->sym->name, "_pid") == 0 @@ -2125,8 +2317,8 @@ return glob_inline(n->sym->name); case ENABLED: case PC_VAL: case NONPROGRESS: - case 'p': case 'q': - case TIMEOUT: + case 'p': case 'q': + case TIMEOUT: case SET_P: case GET_P: return 1; /* @ was 1 (global) since 2.8.5 @@ -2161,11 +2353,12 @@ Bailout(FILE *fd, char *str) { if (!GenCode) - fprintf(fd, "continue%s", str); - else if (IsGuard) - fprintf(fd, "%s%s", NextLab[Level], str); - else - fprintf(fd, "Uerror(\"block in d_step seq\")%s", str); + { fprintf(fd, "continue%s", str); + } else if (IsGuard) + { fprintf(fd, "%s%s", NextLab[Level], str); + } else + { fprintf(fd, "Uerror(\"block in d_step seq\")%s", str); + } } #define cat0(x) putstmnt(fd,now->lft,m); fprintf(fd, x); \ @@ -2173,6 +2366,24 @@ #define cat1(x) fprintf(fd,"("); cat0(x); fprintf(fd,")") #define cat2(x,y) fprintf(fd,x); putstmnt(fd,y,m) #define cat3(x,y,z) fprintf(fd,x); putstmnt(fd,y,m); fprintf(fd,z) +#define cat30(x,y,z) fprintf(fd,x,0); putstmnt(fd,y,m); fprintf(fd,z) + +extern void explain(int); +void +dump_tree(const char *s, Lextok *p) +{ char z[64]; + + if (!p) return; + + printf("\n%s:\t%2d:\t%3d (", s, p->ln, p->ntyp); + explain(p->ntyp); + if (p->ntyp == 315) printf(": %s", p->sym->name); + if (p->ntyp == 312) printf(": %d", p->val); + printf(")"); + + if (p->lft) { sprintf(z, "%sL", s); dump_tree(z, p->lft); } + if (p->rgt) { sprintf(z, "%sR", s); dump_tree(z, p->rgt); } +} void putstmnt(FILE *fd, Lextok *now, int m) @@ -2214,14 +2425,14 @@ else fprintf(fd, "((trpt->tau)&1)"); if (GenCode) - printf("spin: warning, %s:%d, 'timeout' in d_step sequence\n", + printf("spin: %s:%d, warning, 'timeout' in d_step sequence\n", Fname->name, lineno); /* is okay as a guard */ break; case RUN: if (now->sym == NULL) - Fatal("internal error pangen2.c", (char *) 0); + fatal("internal error pangen2.c", (char *) 0); if (claimproc && strcmp(now->sym->name, claimproc) == 0) fatal("claim %s, (not runnable)", claimproc); @@ -2230,10 +2441,11 @@ fatal("eventmap %s, (not runnable)", eventmap); if (GenCode) - fatal("'run' in d_step sequence (use atomic)", - (char *)0); + fatal("'run' in d_step sequence (use atomic)", (char *)0); - fprintf(fd,"addproc(II, %d", fproc(now->sym->name)); + fprintf(fd,"addproc(II, %d, %d", + (now->val > 0 && !old_priority_rules) ? now->val : 1, + fproc(now->sym->name)); for (v = now->lft, i = 0; v; v = v->rgt, i++) { cat2(", ", v->lft); } @@ -2246,12 +2458,41 @@ for ( ; i < Npars; i++) fprintf(fd, ", 0"); fprintf(fd, ")"); + check_mtypes(now, now->lft); +#if 0 + /* process now->sym->name has run priority now->val */ + if (now->val > 0 && now->val < 256 && !old_priority_rules) + { fprintf(fd, " && (((P0 *)pptr(now._nr_pr - 1))->_priority = %d)", now->val); + } +#endif + if (now->val < 0 || now->val > 255) /* 0 itself is allowed */ + { fatal("bad process in run %s, valid range: 1..255", now->sym->name); + } break; case ENABLED: cat3("enabled(II, ", now->lft, ")"); break; + case GET_P: + if (old_priority_rules) + { fprintf(fd, "1"); + } else + { cat3("get_priority(", now->lft, ")"); + } + break; + + case SET_P: + if (!old_priority_rules) + { fprintf(fd, "if (TstOnly) return 1; /* T30 */\n\t\t"); + fprintf(fd, "set_priority("); + putstmnt(fd, now->lft->lft, m); + fprintf(fd, ", "); + putstmnt(fd, now->lft->rgt, m); + fprintf(fd, ")"); + } + break; + case NONPROGRESS: /* o_pm&4=progress, tau&128=claim stutter */ if (separate == 2) @@ -2324,7 +2565,7 @@ break; case 's': - if (Pid == eventmapnr) + if (Pid_nr == eventmapnr) { fprintf(fd, "if ((II == -EVENT_TRACE && _tp != 's') "); putname(fd, "|| _qid+1 != ", now->lft, m, ""); for (v = now->rgt, i=0; v; v = v->rgt, i++) @@ -2342,7 +2583,7 @@ } fprintf(fd, ")\n"); fprintf(fd, "\t\t continue"); - putname(th, " || (x_y3_ == ", now->lft, m, ")"); + putname(fd_th, " || (x_y3_ == ", now->lft, m, ")"); break; } if (TestOnly) @@ -2369,21 +2610,21 @@ putname(fd, "(", now->lft, m, "))\n"); if (m_loss) - fprintf(fd, "\t\t{ nlost++; delta_m = 1; } else {"); - else + { fprintf(fd, "\t\t{ nlost++; delta_m = 1; } else {"); + } else { fprintf(fd, "\t\t\t"); Bailout(fd, ";"); } - if (has_enabled) - fprintf(fd, "\n\t\tif (TstOnly) return 1;"); + if (has_enabled || has_priority) + fprintf(fd, "\n\t\tif (TstOnly) return 1; /* T1 */"); if (u_sync && !u_async && rvopt) fprintf(fd, "\n\n\t\tif (no_recvs(II)) continue;\n"); fprintf(fd, "\n#ifdef HAS_CODE\n"); fprintf(fd, "\t\tif (readtrail && gui) {\n"); - fprintf(fd, "\t\t\tchar simtmp[32];\n"); + fprintf(fd, "\t\t\tchar simtmp[64];\n"); putname(fd, "\t\t\tsprintf(simvals, \"%%d!\", ", now->lft, m, ");\n"); _isok++; for (v = now->rgt, i = 0; v; v = v->rgt, i++) @@ -2408,23 +2649,27 @@ fatal("too many pars in send", ""); } for (j = i; i < Mpars; i++) - fprintf(fd, ", 0"); + { fprintf(fd, ", 0"); + } fprintf(fd, ", %d)", j); if (u_sync) { fprintf(fd, ";\n\t\t"); if (u_async) - putname(fd, "if (q_zero(", now->lft, m, ")) "); + { putname(fd, "if (q_zero(", now->lft, m, ")) "); + } putname(fd, "{ boq = ", now->lft, m, ""); if (GenCode) - fprintf(fd, "; Uerror(\"rv-attempt in d_step\")"); + { fprintf(fd, "; Uerror(\"rv-attempt in d_step\")"); + } fprintf(fd, "; }"); } if (m_loss) - fprintf(fd, ";\n\t\t}\n\t\t"); /* end of m_loss else */ + { fprintf(fd, ";\n\t\t}\n\t\t"); /* end of m_loss else */ + } break; case 'r': - if (Pid == eventmapnr) + if (Pid_nr == eventmapnr) { fprintf(fd, "if ((II == -EVENT_TRACE && _tp != 'r') "); putname(fd, "|| _qid+1 != ", now->lft, m, ""); for (v = now->rgt, i=0; v; v = v->rgt, i++) @@ -2442,7 +2687,7 @@ fprintf(fd, ")\n"); fprintf(fd, "\t\t continue"); - putname(tc, " || (x_y3_ == ", now->lft, m, ")"); + putname(fd_tc, " || (x_y3_ == ", now->lft, m, ")"); break; } @@ -2480,13 +2725,24 @@ { fprintf(fd, ", 1, "); putstmnt(fd, v->lft, m); } else if (v->lft->ntyp == EVAL) - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft->lft, m); + { if (v->lft->lft->ntyp == ',') /* usertype1 */ + { if (0) { dump_tree("1", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + fprintf(fd, ", 1, "); + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft->lft, m); + } } else { fprintf(fd, ", 0, 0"); } } for ( ; i < Mpars; i++) - fprintf(fd, ", 0, 0"); + { fprintf(fd, ", 0, 0"); + } fprintf(fd, ")"); } fprintf(fd, ")"); @@ -2534,8 +2790,9 @@ for (v = now->rgt, j=0; v; v = v->rgt) { if (v->lft->ntyp != CONST && v->lft->ntyp != EVAL) - j++; /* count settables */ - } + { j++; /* count settables */ + } } + fprintf(fd, ";\n\n\t\tXX=1"); /* test */ if (now->val == 0 || now->val == 2) { for (v = now->rgt, i=0; v; v = v->rgt, i++) @@ -2552,6 +2809,8 @@ fprintf(fd, "0, %d, 0)) ", i); Bailout(fd, ""); } } + if (has_enabled || has_priority) + fprintf(fd, ";\n\t\tif (TstOnly) return 1 /* T2 */"); } else /* random receive: val 1 or 3 */ { fprintf(fd, ";\n\t\tif (!(XX = Q_has("); putname(fd, "", now->lft, m, ""); @@ -2560,30 +2819,42 @@ { fprintf(fd, ", 1, "); putstmnt(fd, v->lft, m); } else if (v->lft->ntyp == EVAL) - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft->lft, m); + { if (v->lft->lft->ntyp == ',') /* usertype2 */ + { if (0) { dump_tree("2", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + fprintf(fd, ", 1, "); + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft->lft, m); + } } else { fprintf(fd, ", 0, 0"); } } for ( ; i < Mpars; i++) - fprintf(fd, ", 0, 0"); + { fprintf(fd, ", 0, 0"); + } fprintf(fd, "))) "); Bailout(fd, ""); - if (!GenCode) { - fprintf(fd, ";\n\t\t"); - if (multi_oval) - { check_needed(); - fprintf(fd, "(trpt+1)->bup.ovals[%d] = ", - multi_oval-1); - multi_oval++; - } else - fprintf(fd, "(trpt+1)->bup.oval = "); - fprintf(fd, "XX"); - } - } - if (has_enabled) - fprintf(fd, ";\n\t\tif (TstOnly) return 1"); + if (has_enabled || has_priority) + { fprintf(fd, ";\n\t\tif (TstOnly) return 1 /* T2 */"); + } + if (!GenCode) + { fprintf(fd, ";\n\t\t"); + if (multi_oval) + { check_needed(); + fprintf(fd, "(trpt+1)->bup.ovals[%d] = ", + multi_oval-1); + multi_oval++; + } else + { fprintf(fd, "(trpt+1)->bup.oval = "); + } + fprintf(fd, "XX"); + } } if (j == 0 && now->val >= 2) { fprintf(fd, ";\n\t\t"); @@ -2595,16 +2866,20 @@ fprintf(fd, ";\n\t\t"); /* no variables modified */ if (j == 0 && now->val == 0) - { fprintf(fd, "if (q_flds[((Q0 *)qptr("); + { fprintf(fd, "\n#ifndef BFS_PAR\n\t\t"); + /* q_flds values are not shared among cores */ + fprintf(fd, "if (q_flds[((Q0 *)qptr("); putname(fd, "", now->lft, m, "-1))->_t]"); - fprintf(fd, " != %d)\n\t", i); - fprintf(fd, "\t\tUerror(\"wrong nr of msg fields in rcv\");\n\t\t"); + fprintf(fd, " != %d)\n\t\t\t", i); + fprintf(fd, "Uerror(\"wrong nr of msg fields in rcv\");\n"); + fprintf(fd, "#endif\n\t\t"); } for (v = now->rgt; v; v = v->rgt) - if ((v->lft->ntyp != CONST + { if ((v->lft->ntyp != CONST && v->lft->ntyp != EVAL)) - jj++; /* nr of vars needing bup */ + { jj++; /* nr of vars needing bup */ + } } if (jj) for (v = now->rgt, i = 0; v; v = v->rgt, i++) @@ -2623,12 +2898,12 @@ sprintf(tempbuf, "(trpt+1)->bup.oval = "); if (v->lft->sym && !strcmp(v->lft->sym->name, "_")) - { fprintf(fd, tempbuf); + { fprintf(fd, tempbuf, (char *) 0); putname(fd, "qrecv(", now->lft, m, ""); fprintf(fd, ", XX-1, %d, 0);\n\t\t", i); } else { _isok++; - cat3(tempbuf, v->lft, ";\n\t\t"); + cat30(tempbuf, v->lft, ";\n\t\t"); _isok--; } } @@ -2650,9 +2925,25 @@ } } } } /* set */ for (v = now->rgt, i = 0; v; v = v->rgt, i++) - { if ((v->lft->ntyp == CONST - || v->lft->ntyp == EVAL) && v->rgt) - continue; + { + if (v->lft->ntyp == CONST && v->rgt) + { continue; + } + + if (v->lft->ntyp == EVAL) + { Lextok *fix = v->lft->lft; + int old_i = i; + while (fix && fix->ntyp == ',') /* usertype9 */ + { i++; + fix = fix->rgt; + } + if (i > old_i) + { i--; /* next increment handles it */ + } + if (v->rgt) + { continue; + } + } fprintf(fd, ";\n\t\t"); if (v->lft->ntyp != CONST @@ -2666,6 +2957,7 @@ nocast=0; fprintf(fd, " = "); } + putname(fd, "qrecv(", now->lft, m, ", "); fprintf(fd, "XX-1, %d, ", i); fprintf(fd, "%d)", (v->rgt || now->val >= 2)?0:1); @@ -2698,15 +2990,23 @@ _isok++; for (v = now->rgt, i = 0; v; v = v->rgt, i++) { if (v->lft->ntyp != EVAL) - { cat3("\t\tsprintf(simtmp, \"%%d\", ", v->lft, "); strcat(simvals, simtmp);"); + { cat3("\t\t\tsprintf(simtmp, \"%%d\", ", v->lft, "); strcat(simvals, simtmp);"); } else - { cat3("\t\tsprintf(simtmp, \"%%d\", ", v->lft->lft, "); strcat(simvals, simtmp);"); - } + { if (v->lft->lft->ntyp == ',') /* usertype4 */ + { if (0) { dump_tree("4", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + cat3("\n\t\t\tsprintf(simtmp, \"%%d,\", ", fix->lft, "); strcat(simvals, simtmp);"); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { cat3("\n\t\t\tsprintf(simtmp, \"%%d\", ", v->lft->lft, "); strcat(simvals, simtmp);"); + } } if (v->rgt) - fprintf(fd, "\t\tstrcat(simvals, \",\");\n"); - } + { fprintf(fd, "\n\t\t\tstrcat(simvals, \",\");\n"); + } } _isok--; - fprintf(fd, "\t\t}\n"); + fprintf(fd, "\n\t\t}\n"); fprintf(fd, "#endif\n\t\t"); if (u_sync) @@ -2724,7 +3024,7 @@ fprintf(fd, "\t\t\t now._cnt[now._a_t&1] = 1;\n"); fprintf(fd, "#endif\n"); fprintf(fd, "#ifdef DEBUG\n"); - fprintf(fd, "\t\t\tprintf(\"%%3d: proc %%d fairness \", depth, II);\n"); + fprintf(fd, "\t\t\tprintf(\"%%3ld: proc %%d fairness \", depth, II);\n"); fprintf(fd, "\t\t\tprintf(\"Rule 2: --cnt to %%d (%%d)\\n\",\n"); fprintf(fd, "\t\t\t now._cnt[now._a_t&1], now._a_t);\n"); fprintf(fd, "#endif\n"); @@ -2764,9 +3064,19 @@ putname(fd, "", now->lft, m, ", "); fprintf(fd, "0, %d, 0) == ", i); if (v->lft->ntyp == CONST) - putstmnt(fd, v->lft, m); - else /* EVAL */ - putstmnt(fd, v->lft->lft, m); + { putstmnt(fd, v->lft, m); + } else /* EVAL */ + { if (v->lft->lft->ntyp == ',') /* usertype2 */ + { if (0) { dump_tree("8", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { putstmnt(fd, v->lft->lft, m); + } + } } fprintf(fd, ")"); } else @@ -2776,13 +3086,24 @@ { fprintf(fd, ", 1, "); putstmnt(fd, v->lft, m); } else if (v->lft->ntyp == EVAL) - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft->lft, m); + { if (v->lft->lft->ntyp == ',') /* usertype3 */ + { if (0) { dump_tree("3", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + fprintf(fd, ", 1, "); + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft->lft, m); + } } else fprintf(fd, ", 0, 0"); } for ( ; i < Mpars; i++) - fprintf(fd, ", 0, 0"); + { fprintf(fd, ", 0, 0"); + } fprintf(fd, ")"); } break; @@ -2816,8 +3137,10 @@ break; case ASGN: - if (has_enabled) - fprintf(fd, "if (TstOnly) return 1;\n\t\t"); + if (check_track(now) == STRUCT) { break; } + + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T3 */\n\t\t"); _isok++; if (!GenCode) @@ -2827,14 +3150,27 @@ sprintf(tempbuf, "(trpt+1)->bup.ovals[%d] = ", multi_oval-1); multi_oval++; - cat3(tempbuf, now->lft, ";\n\t\t"); + cat30(tempbuf, now->lft, ";\n\t\t"); } else { cat3("(trpt+1)->bup.oval = ", now->lft, ";\n\t\t"); } } + if (now->lft->sym + && now->lft->sym->type == PREDEF + && strcmp(now->lft->sym->name, "_") != 0 + && strcmp(now->lft->sym->name, "_priority") != 0) + { fatal("invalid assignment to %s", now->lft->sym->name); + } + nocast = 1; putstmnt(fd,now->lft,m); nocast = 0; fprintf(fd," = "); _isok--; - putstmnt(fd,now->rgt,m); + if (now->lft->sym->isarray + && now->rgt->ntyp == ',') /* array initializer */ + { putstmnt(fd, now->rgt->lft, m); + non_fatal("cannot use an array list initializer here", (char *) 0); + } else + { putstmnt(fd, now->rgt, m); + } if (now->sym->type != CHAN || verbose > 0) @@ -2853,8 +3189,8 @@ break; case PRINT: - if (has_enabled) - fprintf(fd, "if (TstOnly) return 1;\n\t\t"); + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T4 */\n\t\t"); #ifdef PRINTF fprintf(fd, "printf(%s", now->sym->name); #else @@ -2867,14 +3203,29 @@ break; case PRINTM: - if (has_enabled) - fprintf(fd, "if (TstOnly) return 1;\n\t\t"); - fprintf(fd, "printm("); - if (now->lft && now->lft->ismtyp) - fprintf(fd, "%d", now->lft->val); - else - putstmnt(fd, now->lft, m); - fprintf(fd, ")"); + { char *s = 0; + if (now->lft->sym + && now->lft->sym->mtype_name) + { s = now->lft->sym->mtype_name->name; + } + + if (has_enabled || has_priority) + { fprintf(fd, "if (TstOnly) return 1; /* T5 */\n\t\t"); + } + fprintf(fd, "/* YY */ printm("); + if (now->lft + && now->lft->ismtyp) + { fprintf(fd, "%d", now->lft->val); + } else + { putstmnt(fd, now->lft, m); + } + if (s) + { fprintf(fd, ", \"%s\"", s); + } else + { fprintf(fd, ", 0"); + } + fprintf(fd, ")"); + } break; case NAME: @@ -2890,7 +3241,7 @@ case 'q': if (terse) - fprintf(fd, "%s", now->sym->name); + fprintf(fd, "%s", now->sym?now->sym->name:"?"); else fprintf(fd, "%d", remotelab(now)); break; @@ -2908,13 +3259,13 @@ case C_CODE: if (now->sym) fprintf(fd, "/* %s */\n\t\t", now->sym->name); - if (has_enabled) - fprintf(fd, "if (TstOnly) return 1;\n\t\t"); + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T6 */\n\t\t"); if (now->sym) plunk_inline(fd, now->sym->name, 1, GenCode); else - Fatal("internal error pangen2.c", (char *) 0); + fatal("internal error pangen2.c", (char *) 0); if (!GenCode) { fprintf(fd, "\n"); /* state changed, capture it */ @@ -2925,8 +3276,8 @@ break; case ASSERT: - if (has_enabled) - fprintf(fd, "if (TstOnly) return 1;\n\t\t"); + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T7 */\n\t\t"); cat3("spin_assert(", now->lft, ", "); terse = nocast = 1; @@ -2937,18 +3288,18 @@ case '.': case BREAK: case GOTO: - if (Pid == eventmapnr) + if (Pid_nr == eventmapnr) fprintf(fd, "Uerror(\"cannot get here\")"); putskip(m); break; case '@': - if (Pid == eventmapnr) + if (Pid_nr == eventmapnr) { fprintf(fd, "return 0"); break; } - if (has_enabled) + if (has_enabled || has_priority) { fprintf(fd, "if (TstOnly)\n\t\t\t"); fprintf(fd, "return (II+1 == now._nr_pr);\n\t\t"); } @@ -2959,7 +3310,7 @@ default: printf("spin: error, %s:%d, bad node type %d (.m)\n", now->fn->name, now->ln, now->ntyp); - fflush(tm); + fflush(fd); alldone(1); } } @@ -2993,6 +3344,7 @@ { fprintf(fd, "%s%s%s", pre, n->sym->name, suff); return; } + if (!s->type) /* not a local name */ s = lookup(s->name); /* must be a global */ @@ -3005,23 +3357,34 @@ if (s->type == PROCTYPE) fatal("proctype-name '%s' used as array-name", s->name); - fprintf(fd, pre); + fprintf(fd, pre, 0); if (!terse && !s->owner && evalindex != 1) - { if (s->context - || strcmp(s->name, "_p") == 0 - || strcmp(s->name, "_pid") == 0) - { fprintf(fd, "((P%d *)this)->", Pid); + { if (old_priority_rules + && strcmp(s->name, "_priority") == 0) + { fprintf(fd, "1"); + goto shortcut; } else - { int x = strcmp(s->name, "_"); - if (!(s->hidden&1) && x != 0) - fprintf(fd, "now."); - if (x == 0 && _isok == 0) - fatal("attempt to read value of '_'", 0); - } } + { if (s->context + || strcmp(s->name, "_p") == 0 + || strcmp(s->name, "_pid") == 0 + || strcmp(s->name, "_priority") == 0) + { fprintf(fd, "((P%d *)_this)->", Pid_nr); + } else + { int x = strcmp(s->name, "_"); + if (!(s->hidden&1) && x != 0) + fprintf(fd, "now."); + if (x == 0 && _isok == 0) + fatal("attempt to read value of '_'", 0); + } } } + + if (terse && buzzed == 1) + { fprintf(fd, "B_state.%s", (s->context)?"local[B_pid].":""); + } ptr = s->name; - if (s->type != PREDEF) /* new 6.0.2 */ + if (!dont_simplify /* new 6.4.3 */ + && s->type != PREDEF) /* new 6.0.2 */ { if (withprocname && s->context && strcmp(pre, ".")) @@ -3069,7 +3432,7 @@ { /* attempt to catch arrays that are indexed with an array element in the same array * this causes trouble in the verifier in the backtracking * e.g., restoring a[?] in the assignment: a [a[1]] = x where a[1] == 1 - * but it is hard when the array is inside a structure, so the names dont match + * but it is hard when the array is inside a structure, so the names don't match */ #if 0 if (n->lft->ntyp == NAME) @@ -3090,7 +3453,8 @@ if (s->type == STRUCT && n->rgt && n->rgt->lft) { putname(fd, ".", n->rgt->lft, m, ""); } - fprintf(fd, suff); +shortcut: + fprintf(fd, suff, 0); } void @@ -3105,7 +3469,11 @@ putstmnt(fd, n->lft->lft, m); /* pid */ fprintf(fd, "]"); } - fprintf(fd, ".%s", n->sym->name); + if (ltl_mode) + { fprintf(fd, ":%s", n->sym->name); + } else + { fprintf(fd, ".%s", n->sym->name); + } } else { if (Sym_typ(n) < SHORT) { promoted = 1; diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen2.h /sys/src/cmd/spin/pangen2.h --- /n/sources/plan9/sys/src/cmd/spin/pangen2.h Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen2.h Mon Feb 22 00:00:00 2021 @@ -1,19 +1,15 @@ /***** spin: pangen2.h *****/ -/* Copyright (c) 1989-2007 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ -/* (c) 2007: small additions for V5.0 to support multi-core verifications */ - -static char *Pre0[] = { -"#ifdef SC", - "#define _FILE_OFFSET_BITS 64", /* to allow file sizes greater than 2Gb */ -"#endif", +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ + +static const char *Pre0[] = { + "#ifdef SC", + " #define _FILE_OFFSET_BITS 64", /* allows file sizes greater than 2Gb */ + "#endif", "#include ", "#include ", "#include ", @@ -29,9 +25,10 @@ "#endif", "#include ", /* defines off_t */ "#include ", + "#include ", "#include ", - "#define Offsetof(X, Y) ((unsigned long)(&(((X *)0)->Y)))", + "#define Offsetof(X, Y) ((ulong)(&(((X *)0)->Y)))", "#ifndef max", "#define max(a,b) (((a)<(b)) ? (b) : (a))", "#endif", @@ -41,8 +38,55 @@ 0, }; -static char *Preamble[] = { +static const char *Separate[] = { + "#ifdef COLLAPSE", + " #if (NCORE>1 && !defined(SEP_STATE)) || defined(BFS_PAR)", + " volatile ulong *ncomps; /* in shared memory */", + " #else", + " ulong ncomps[256+2];", + " #endif", + "#endif", + "Trans ***trans; /* 1 ptr per state per proctype */\n", + "", + "#if VECTORSZ>32000", + " int P_o[MAXPROC], P_o_tmp[MAXPROC+1];", + " int Q_o[MAXQ], Q_o_tmp[MAXPROC+1];", + "", + " int *proc_offset = (int *) P_o;", + " int *q_offset = (int *) Q_o;", + "#else", + " short P_o[MAXPROC], P_o_tmp[MAXPROC+1];", + " short Q_o[MAXQ], Q_o_tmp[MAXPROC+1];", + "", + " short *proc_offset = (short *) P_o;", + " short *q_offset = (short *) Q_o;", + "#endif", + "uchar P_s[MAXPROC+1], P_s_tmp[MAXPROC+1];", + "uchar Q_s[MAXQ+1], Q_s_tmp[MAXQ+1];", + "uchar *proc_skip = (uchar *) P_s;", + "uchar *q_skip = (uchar *) Q_s;", + "", + "#ifdef TRIX", + " TRIX_v6 *freebodies;", + " TRIX_v6 *processes[MAXPROC+1];", + " TRIX_v6 *channels[MAXQ+1];", + " long _p_count[MAXPROC];", + " long _c_count[MAXPROC];", + "#endif\n", + "ulong vsize; /* vector size in bytes */", + "#ifdef SVDUMP", + " int vprefix=0, svfd; /* runtime option -pN */", + "#endif", + "char *tprefix = \"trail\"; /* runtime option -tsuffix */", + "short boq = -1; /* blocked_on_queue status */", + "int _; /* predefined write-only variable */", + "#ifdef PEG", + " long peg[NTRANS];", + "#endif", + 0, +}; +static const char *Preamble[] = { "#ifdef RANDOMIZE", " #define T_RAND RANDOMIZE", "#endif", @@ -73,7 +117,7 @@ "#undef onstack_put", "#undef onstack_zap", "#define onstack_put() ;", - "#define onstack_zap() gstore((char *) &now, vsize, 4)", + "#define onstack_zap() g_store((char *) &now, vsize, 4)", "#else", "#if defined(FULLSTACK) && !defined(BITSTATE)", "#define onstack_put() trpt->ostate = Lstate", @@ -84,148 +128,13 @@ " }", "#endif", "#endif", - - "#ifndef NO_V_PROVISO", - "#define V_PROVISO", - "#endif", - "#if !defined(NO_RESIZE) && !defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(SPACE) && NCORE==1", - " #define AUTO_RESIZE", - "#endif", - "", - "struct H_el {", - " struct H_el *nxt;", - "#ifdef FULLSTACK", - " unsigned int tagged;", - " #if defined(BITSTATE) && !defined(NOREDUCE) && !defined(SAFETY)", - " unsigned int proviso;", /* uses just 1 bit 0/1 */ - " #endif", - "#endif", - "#if defined(CHECK) || (defined(COLLAPSE) && !defined(FULLSTACK))", - " unsigned long st_id;", - "#endif", - "#if !defined(SAFETY) || defined(REACH)", - " unsigned int D;", - "#endif", - "#ifdef BCS", - " #ifndef CONSERVATIVE", - " #define CONSERVATIVE 1 /* good for up to 8 processes */", - " #endif", - " #ifdef CONSERVATIVE", - " #if CONSERVATIVE <= 0 || CONSERVATIVE>32", - " #error sensible values for CONSERVATIVE are 1..32 (256/8 = 32)", - " #endif", - " uchar ctx_pid[CONSERVATIVE];", /* pids setting lowest value */ - " #endif", - " uchar ctx_low;", /* lowest nr of context switches seen so far */ - "#endif", - "#if NCORE>1", - " /* could cost 1 extra word: 4 bytes if 32-bit and 8 bytes if 64-bit */", - " #ifdef V_PROVISO", - " uchar cpu_id; /* id of cpu that created the state */", - " #endif", - "#endif", - "#ifdef COLLAPSE", - " #if VECTORSZ<65536", - " unsigned short ln;", /* length of vector */ - " #else", - " unsigned long ln;", /* length of vector */ - " #endif", - "#endif", - "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", - " unsigned long m_K1;", - "#endif", - " unsigned long state;", - "} **H_tab, **S_Tab;\n", - - "typedef struct Trail {", - " int st; /* current state */", - " int o_tt;", - " uchar pr; /* process id */", - " uchar tau; /* 8 bit-flags */", - " uchar o_pm; /* 8 more bit-flags */", - "#if 0", - " Meaning of bit-flags:", - " tau&1 -> timeout enabled", - " tau&2 -> request to enable timeout 1 level up (in claim)", - " tau&4 -> current transition is a claim move", - " tau&8 -> current transition is an atomic move", - " tau&16 -> last move was truncated on stack", - " tau&32 -> current transition is a preselected move", - " tau&64 -> at least one next state is not on the stack", - " tau&128 -> current transition is a stutter move", - - " o_pm&1 -> the current pid moved -- implements else", - " o_pm&2 -> this is an acceptance state", - " o_pm&4 -> this is a progress state", - " o_pm&8 -> fairness alg rule 1 undo mark", - " o_pm&16 -> fairness alg rule 3 undo mark", - " o_pm&32 -> fairness alg rule 2 undo mark", - " o_pm&64 -> the current proc applied rule2", - " o_pm&128 -> a fairness, dummy move - all procs blocked", - "#endif", - "#ifdef NSUCC", - " uchar n_succ; /* nr of successor states */", - "#endif", - "#if defined(FULLSTACK) && defined(MA) && !defined(BFS)", - " uchar proviso;", - "#endif", - "#ifndef BFS", - " uchar o_n, o_ot; /* to save locals */", - "#endif", - " uchar o_m;", - "#ifdef EVENT_TRACE", - " #if nstates_event<256", - " uchar o_event;", - " #else", - " unsigned short o_event;", - " #endif", - "#endif", - "#ifndef BFS", - " short o_To;", - " #ifdef T_RAND", - " short oo_i;", - " #endif", - "#endif", - "#if defined(HAS_UNLESS) && !defined(BFS)", - " int e_state; /* if escape trans - state of origin */", - "#endif", - "#if (defined(FULLSTACK) && !defined(MA)) || defined(BFS) || (NCORE>1)", - " struct H_el *ostate; /* pointer to stored state */", - "#endif", - /* CNTRSTACK when !NOREDUCE && BITSTATE && SAFETY, uses LL[] */ - "#if defined(CNTRSTACK) && !defined(BFS)", - " long j6, j7;", - "#endif", - " Trans *o_t;", /* transition fct, next state */ - - "#if !defined(BFS) && !defined(TRIX_ORIG)", - " char *p_bup;", - " char *q_bup;", - "#endif", - - "#ifdef BCS", - " unsigned short sched_limit;", - " unsigned char bcs; /* phase 1 or 2, or forced 4 */", - " unsigned char b_pno; /* preferred pid */", - "#endif", - - "#ifdef P_RAND", /* process scheduling randomization */ - " unsigned char p_left; /* nr of procs left to explore */", - " short p_skip; /* to find starting point in list */", - "#endif", - - "#ifdef HAS_SORTED", - " short ipt;", /* insertion slot in q */ - "#endif", - " union {", - " int oval;", /* single backup value of variable */ - " int *ovals;", /* ptr to multiple values */ - " } bup;", - "} Trail;", + "H_el **H_tab, **S_Tab;", + "/* #ifndef BFS_PAR */", + " H_el *Lstate;", + "/* #endif */", "Trail *trail, *trpt;", - "FILE *efd;", - "uchar *this;", + "uchar *_this;", "long maxdepth=10000;", "long omaxdepth=10000;", "#ifdef BCS", @@ -235,19 +144,17 @@ " #define B_FORCED 4", "int sched_max = 0;", "#endif", - "#ifdef PERMUTED", - " uchar permuted = 1;", - "#else", - " uchar permuted = 0;", - "#endif", + "", "double quota; /* time limit */", "#if NCORE>1", - "long z_handoff = -1;", + " long z_handoff = -1;", "#endif", "#ifdef SC", /* stack cycling */ - "char *stackfile;", + " char *stackfile;", "#endif", "uchar *SS, *LL;", + "", + "uchar reversing = 0;", "uchar HASH_NR = 0;", "", "double memcnt = (double) 0;", @@ -260,10 +167,138 @@ "static char *have;", "static long left = 0L;", "static double fragment = (double) 0;", - "static unsigned long grow;", + "static ulong grow;", "", #if 1 "unsigned int HASH_CONST[] = {", + " /* generated by hashgen 421 -- assumes 4 bytes per int */", + " 0x100d4e63, 0x0fc22f87, 0xa7155c77, 0x78f2c3b9,", + " 0xde32d207, 0xc27d305b, 0x1bb3fb2b, 0x2798c7a5,", + " 0x9c675ffd, 0x777d9081, 0x07aef2f1, 0xae08922f,", + " 0x5bd365b7, 0xed51c47b, 0x9b5aeea1, 0xbcc9d431,", + " 0x396d8fff, 0xa2fd1367, 0x08616521, 0x5e84991f,", + " 0x87495bc5, 0x2930039b, 0xceb6a593, 0xfe522d63,", + " 0x7ff60baf, 0xf89b1fbf, 0x74c01755, 0xe0c559bf,", + " 0x3669fc47, 0x8756d3bf, 0x14f78445, 0x24c41779,", + " 0x0af7b129, 0xde22368d, 0x3e1c01e3, 0xaf773e49,", + " 0x5b762459, 0x86d12911, 0x0953a3af, 0xb66dc23d,", + " 0x96b3bd4f, 0x19b1dd51, 0xd886fbc3, 0xa7f3a025,", + " 0xccb48e63, 0x87d8f027, 0x2bea270d, 0xdb0e9379,", + " 0x78c09f21, 0x0cbbfe07, 0xea4bc7c3, 0x5bfbc3c9,", + " 0x3c6e53fd, 0xab320cdd, 0x31041409, 0x416e7485,", + " 0xe41d75fd, 0xc3c5060f, 0x201a9dc1, 0x93dee72b,", + " 0x6461305f, 0xc571dec5, 0xa1fd21c5, 0xfb421ce1,", + " 0x7f024b05, 0xfa518819, 0x6c9777fb, 0x0d4d9351,", + " 0x08b33861, 0xccb9d0f3, 0x34112791, 0xe962d7c9,", + " 0x8d742211, 0xcd9c47a1, 0x64437b69, 0x5fe40feb,", + " 0x806113cb, 0x10e1d593, 0x821851b3, 0x057a1ff3,", + " 0x8ededc0b, 0x90dd5b31, 0x635ff359, 0x68dbcd35,", + " 0x1050ff4f, 0xdbb07257, 0x486336db, 0x83af1e75,", + " 0x432f1799, 0xc1d0e7e7, 0x21f4eb5b, 0x881ec2c1,", + " 0x23f3b539, 0x6cdfb80d, 0x71d474cf, 0x97d5d4a9,", + " 0xf721d2e5, 0xb5ff3711, 0x3f2e58cd, 0x4e06e3d9,", + " 0x7d711739, 0x927887df, 0x7d57ad71, 0x232eb767,", + " 0xe3f5cc51, 0x6576b443, 0xed17bf1f, 0x8828b637,", + " 0xc940f6ab, 0xc7b830ef, 0x11ed8a13, 0xaff20949,", + " 0xf28a8465, 0x0da10cf9, 0xb512497d, 0x44accae1,", + " 0x95e0929f, 0xe08c8901, 0xfd22d6c9, 0xb6a5c029,", + " 0xaadb428d, 0x6e8a453d, 0x3d5c0195, 0x8bf4ae39,", + " 0xbf83ab19, 0x3e9dac33, 0xc4df075d, 0x39472d71,", + " 0xb8647725, 0x1a6d4887, 0x78a03577, 0xafd76ef7,", + " 0xc1a1d6b3, 0x1afb33c5, 0x87896299, 0x5cc992ef,", + " 0x7f805d0d, 0x089a039b, 0xa353cc27, 0x57b296b3,", + " 0x52badec9, 0xc916e431, 0x09171957, 0x14996d51,", + " 0xe87e32c7, 0xb4fdbb5d, 0xdd216a03, 0x4ddd3fff,", + " 0x767d5c57, 0x79c97509, 0xab70543b, 0xc5feca4f,", + " 0x8eb37b89, 0x20a2cefd, 0xf4b00b91, 0xf166593d,", + " 0x7bf50f65, 0x753e6c8b, 0xfb5b81dd, 0xf2d45ef5,", + " 0x9741c04f, 0x300da48d, 0x01dc4121, 0xa112cd47,", + " 0x0223b24b, 0xa89fbce7, 0x681e1f7b, 0xe7c6aedf,", + " 0x1fd3d523, 0x561ba723, 0xf54042fb, 0x1a516751,", + " 0xcd085bd5, 0xe74246d5, 0x8b170b5d, 0x249985e9,", + " 0x5b4d9cf7, 0xe9912323, 0x5fc0f339, 0x41f8f051,", + " 0x8a296fb1, 0x62909f51, 0x2c05d695, 0x095efccb,", + " 0xa91574f1, 0x0f5cc6c3, 0x23a2ca2b, 0xc6053ec1,", + " 0xeb19e081, 0x3d1b3997, 0xb0c5f3cd, 0xe5d85b35,", + " 0x1cb1bdf1, 0x0c8f278f, 0x518249c3, 0x9f61b68d,", + " 0xade0919d, 0x779e29c3, 0xdbac9485, 0x2ce149a9,", + " 0x254c2409, 0x205b34fb, 0xc8ab1a89, 0x6b4a2585,", + " 0x2303d94b, 0x8fa186b9, 0x49826da5, 0xd23a37ad,", + " 0x680b18c9, 0xa46fbd7f, 0xe42c2cf9, 0xf7cfcb5f,", + " 0xb4842b8b, 0xe483780d, 0x66cf756b, 0x3eb73781,", + " 0x41ca17a5, 0x59f91b0f, 0x92fb67d9, 0x0a5c330f,", + " 0x46013fdb, 0x3b0634af, 0x9024f533, 0x96a001a7,", + " 0x15bcd793, 0x3a311fb1, 0x78913b8b, 0x9d4a5ddf,", + " 0x33189b31, 0xa99e8283, 0xf7cb29e9, 0x12d64a27,", + " 0xeda770ff, 0xa7320297, 0xbd3c14a5, 0x96d0156f,", + " 0x0115db95, 0x7f79f52b, 0xa6d52521, 0xa063d4bd,", + " 0x9cb5e039, 0x42cf8195, 0xcb716835, 0x1bc21273,", + " 0x5a67ad27, 0x4b3b0545, 0x162cda67, 0x0489166b,", + " 0x85fd06a9, 0x562b037d, 0x995bc1f3, 0xe144e78b,", + " 0x1e749f69, 0xa36df057, 0xcfee1667, 0x8c4116b7,", + " 0x94647fe3, 0xe6899df7, 0x6d218981, 0xf1069079,", + " 0xd1851a33, 0xf424fc83, 0x24467005, 0xad8caf59,", + " 0x1ae5da13, 0x497612f9, 0x10f6d1ef, 0xeaf4ff05,", + " 0x405f030b, 0x693b041d, 0x2065a645, 0x9fec71b3,", + " 0xc3bd1b0f, 0xf29217a3, 0x0f25e15d, 0xd48c2b97,", + " 0xce8acf2d, 0x0629489b, 0x1a5b0e01, 0x32d0c059,", + " 0x2d3664bf, 0xc45f3833, 0xd57f551b, 0xbdd991c5,", + " 0x9f97da9f, 0xa029c2a9, 0x5dd0cbdf, 0xe237ba41,", + " 0x62bb0b59, 0x93e7d037, 0x7e495619, 0x51b8282f,", + " 0x853e8ef3, 0x9b8abbeb, 0x055f66f9, 0x2736f7e5,", + " 0x8d7e6353, 0x143abb65, 0x4e2bb5b3, 0x872e1adf,", + " 0x8fcac853, 0xb7cf6e57, 0x12177f3d, 0x1d2da641,", + " 0x07856425, 0xc0ed53dd, 0x252271d9, 0x79874843,", + " 0x0aa8c9b5, 0x7e804f93, 0x2d080e09, 0x3929ddfd,", + " 0x36433dbd, 0xd6568c17, 0xe624e939, 0xb33189ef,", + " 0x29e68bff, 0x8aae2433, 0xe6335499, 0xc5facd9d,", + " 0xbd5afc65, 0x7a584fa7, 0xab191435, 0x64bbdeef,", + " 0x9f5cd8e1, 0xb3a1be05, 0xbd0c1753, 0xb00e2c7f,", + " 0x6a96e315, 0x96a31589, 0x660af5af, 0xc0438d43,", + " 0x17637373, 0x6460e8df, 0x7d458de9, 0xd76b923f,", + " 0x316f045f, 0x3ccbd035, 0x63f64d81, 0xd990d969,", + " 0x7c860a93, 0x99269ff7, 0x6fbcac8f, 0xd8cc562b,", + " 0x67141071, 0x09f85ea3, 0x1298f2dd, 0x41fa86e5,", + " 0xce1d7cf5, 0x6b232c9d, 0x8f093d4b, 0x3203ad4b,", + " 0x07d70d5f, 0x38c44c75, 0x0887c9ef, 0x1833acf5,", + " 0xa3607f85, 0x7d367573, 0x0ea4ffc3, 0xad2d09c1,", + " 0x7a1e664f, 0xef41dff5, 0x03563491, 0x67f30a1f,", + " 0x5ce5f9ef, 0xa2487a27, 0xe5077957, 0x9beb36fd,", + " 0x16e41251, 0x216799ef, 0x07181f8d, 0xc191c3cf,", + " 0xba21cab5, 0x73944eb7, 0xdf9eb69d, 0x5fef6cfd,", + " 0xd750a6f5, 0x04f3fa43, 0x7cb2d063, 0xd3bdb369,", + " 0x35f35981, 0x9f294633, 0x5e293517, 0x70e51d05,", + " 0xf8db618d, 0x66ee05db, 0x835eaa77, 0x166a02c3,", + " 0xb516f283, 0x94102293, 0x1ace50a5, 0x64072651,", + " 0x66df7b75, 0x02e1b261, 0x8e6a73b9, 0x19dddfe7,", + " 0xd551cf39, 0x391c17cb, 0xf4304de5, 0xcd67b8d1,", + " 0x25873e8d, 0x115b4c71, 0x36e062f3, 0xaec0c7c9,", + " 0xd929f79d, 0x935a661b, 0xda762b47, 0x170bd76b,", + " 0x1a955cb5, 0x341fb0ef, 0x7f366cef, 0xc98f60c7,", + " 0xa4181af3, 0xa94a8837, 0x5fa3bc43, 0x11c638c1,", + " 0x4e66fabb, 0x30ab85cf, 0x250704ef, 0x8bf3bc07,", + " 0x6d2cd5ab, 0x613ef9c3, 0xb8e62149, 0x0404fd91,", + " 0xa04fd9b1, 0xa5e389eb, 0x9543bd23, 0xad6ca1f9,", + " 0x210c49ab, 0xf8e9532b, 0x854fba89, 0xdc7fc6bb,", + " 0x48a051a7, 0x6b2f383b, 0x61a4b433, 0xd3af231b,", + " 0xc5023fc7, 0xa5aa85df, 0xa0cd1157, 0x4206f64d,", + " 0x3fea31c3, 0x62d510a1, 0x13988957, 0x6a11a033,", + " 0x46f2a3b7, 0x2784ef85, 0x229eb9eb, 0x9c0c3053,", + " 0x5b7ead39, 0x82ae9afb, 0xf99e9fb3, 0x914b6459,", + " 0xaf05edd7, 0xc82710dd, 0x8fc1ea1f, 0x7e0d7a8d,", + " 0x7c7592e9, 0x65321017, 0xea57553f, 0x4aeb49ff,", + " 0x5239ae4d, 0x4b4b4585, 0x94091c21, 0x7eaaf4cb,", + " 0x6b489d6f, 0xecb9c0c3, 0x29a7af63, 0xaf117a0d,", + " 0x969ea6cd, 0x7658a34d, 0x5fc0bba9, 0x26e99b7f,", + " 0x7a6f260f, 0xe37c34f1, 0x1a1569bb, 0xc3bc7371,", + " 0x8567543d, 0xad0c46a9, 0xa1264fd9, 0x16f10b29,", + " 0x5e00dd3b, 0xf85b6bcd, 0xa2d32d8b, 0x4a3c8d43,", + " 0x6b33b959, 0x4fd1e6c9, 0x7938b8a9, 0x1ec795c7,", + " 0xe2ef3409, 0x83c16b9d, 0x0d3fd9eb, 0xeb461ad7,", + " 0xb09c831d, 0xaf052001, 0x7911164d, 0x1a9dc191,", + " 0xb52a0815, 0x0f732157, 0xc68c4831, 0x12cf3cbb };", +#else + "unsigned int HASH_CONST[] = {", " /* asuming 4 bytes per int */", " 0x100d4e63, 0x0fc22f87,", " 0x3ff0c3ff, 0x38e84cd7,", @@ -314,52 +349,41 @@ " 0xdd62408b, 0x02ec0bcb,", " 0x5469b785, 0x2f4f50bb,", " 0x20f19395, 0xf96ba085,", - " 0x2381f937, 0x768e2a11,", - " 0", - "};", -#else - "unsigned int HASH_CONST[] = {", - " /* asuming 4 bytes per int */", - " 0x88888EEF, 0x00400007,", - " 0x04c11db7, 0x100d4e63,", - " 0x0fc22f87, 0x3ff0c3ff,", - " 0x38e84cd7, 0x02b148e9,", - " 0x98b2e49d, 0xb616d379,", - " 0xa5247fd9, 0xbae92a15,", - " 0xb91c8bc5, 0x8e5880f3,", - " 0xacd7c069, 0xb4c44bb3,", - " 0x2ead1fb7, 0x8e428171,", - " 0xdbebd459, 0x828ae611,", - " 0x6cb25933, 0x86cdd651,", - " 0x9e8f5f21, 0xd5f8d8e7,", - " 0x9c4e956f, 0xb5cf2c71,", - " 0x2e805a6d, 0x33fc3a55,", - " 0xaf203ed1, 0xe31f5909,", - " 0x5276db35, 0x0c565ef7,", - " 0x273d1aa5, 0x8923b1dd,", - " 0", - "};", + " 0x2381f937, 0x768e2a11 };", #endif + "", "#if NCORE>1", "extern int core_id;", "#endif", "long mreached=0;", - "int done=0, errors=0, Nrun=1;", + "ulong errors=0;", + "int done=0, Nrun=1;", "int c_init_done=0;", "char *c_stack_start = (char *) 0;", "double nstates=0, nlinks=0, truncs=0, truncs2=0;", "double nlost=0, nShadow=0, hcmp=0, ngrabs=0;", + "#ifdef BFS_PAR", + "extern ulong bfs_punt;", + "#endif", "#ifdef PUTPID", "char *progname;", "#endif", "#if defined(ZAPH) && defined(BITSTATE)", "double zstates = 0;", "#endif", - "int c_init_run;", + "/* int c_init_run; */", + "#ifdef REVERSE", + " #define P_REVERSE", + "#endif", + "#ifdef T_REVERSE", + " int t_reverse = 1;", /* can be modified with a parameter */ + "#else", + " int t_reverse = 0;", + "#endif", "#ifdef BFS", "double midrv=0, failedrv=0, revrv=0;", "#endif", - "unsigned long nr_states=0; /* nodes in DFA */", + "ulong nr_states=0; /* nodes in DFA */", "long Fa=0, Fh=0, Zh=0, Zn=0;", "long PUT=0, PROBE=0, ZAPS=0;", "long Ccheck=0, Cholds=0;", @@ -370,15 +394,15 @@ "char *claimname;", "#endif", "int state_tables=0, fairness=0, no_rck=0, Nr_Trails=0, dodot=0;", - "char simvals[128];", + "char simvals[256];", "#ifndef INLINE", "int TstOnly=0;", "#endif", - "unsigned long mask, nmask;", + "ulong mask, nmask;", "#ifdef BITSTATE", - "int ssize=23; /* 1 Mb */", + "int ssize=27; /* 16 Mb */", "#else", - "int ssize=19; /* 512K slots */", + "int ssize=24; /* 16M slots */", "#endif", "int hmax=0, svmax=0, smax=0;", "int Maxbody=0, XX;", @@ -391,7 +415,7 @@ "#ifdef MA", "#define INLINE_REV", "extern void dfa_init(unsigned short);", - "extern int dfa_member(unsigned long);", + "extern int dfa_member(ulong);", "extern int dfa_store(uchar *);", "unsigned int maxgs = 0;", "#endif", @@ -404,36 +428,41 @@ " State comp_now; /* compressed state vector */", "#endif", "", - "State comp_msk;", - "uchar *Mask = (uchar *) &comp_msk;", + "#ifndef HC", + " #ifdef BFS_PAR", + " State tmp_msk;", + " #endif", + " State comp_msk;", + " uchar *Mask = (uchar *) &comp_msk;", + "#endif", "#ifdef COLLAPSE", - "State comp_tmp;", - "static char *scratch = (char *) &comp_tmp;", + " State comp_tmp;", + " static char *scratch = (char *) &comp_tmp;", "#endif", - + "", "_Stack *stack; /* for queues, processes */", "Svtack *svtack; /* for old state vectors */", "#ifdef BITSTATE", "static unsigned int hfns = 3; /* new default */", "#endif", - "static unsigned long j1_spin; /* 5.2.1: avoid nameclash with math.h */", - "static unsigned long K1, K2;", - "static unsigned long j2, j3, j4;", + "static ulong j1_spin, j2_spin; /* 5.2.1: avoid nameclash with math.h */", + "static ulong j3_spin, j4_spin;", + "ulong K1, K2;", "#ifdef BITSTATE", - "static long udmem;", + "long udmem;", "#endif", + "#ifndef BFS_PAR", "static long A_depth = 0;", + "#endif", "long depth = 0;", + "long depthfound = -1; /* loop detection */", /* depth: not static to support -S2, but possible clash with embedded code */ "#if NCORE>1", "long nr_handoffs = 0;", "#endif", - "static uchar warned = 0, iterative = 0, exclusive = 0, like_java = 0, every_error = 0;", - "static uchar noasserts = 0, noends = 0, bounded = 0;", - - "#if defined(T_RAND) || defined(P_RAND) || defined(RANDSTOR)", - "unsigned int s_rand = 123; /* default seed */", - "#endif", + "uchar warned = 0, iterative = 0, exclusive = 0, like_java = 0, every_error = 0;", + "uchar noasserts = 0, noends = 0, bounded = 0;", + "uint s_rand = 12345; /* default seed */", "#if SYNC>0 && ASYNC==0", "void set_recvs(void);", @@ -447,10 +476,27 @@ "#define UnBlock /* don't bother */", "#endif\n", "#ifdef BITSTATE", - "int (*bstore)(char *, int);", + "int (*b_store)(char *, int);", "int bstore_reg(char *, int);", "int bstore_mod(char *, int);", "#endif", + "", + "void dfs_uerror(char *);", + "void dfs_Uerror(char *);", + "#ifdef BFS_PAR", + "void bfs_uerror(char *);", + "void bfs_Uerror(char *);", + "#endif", + "void (*uerror)(char *);", + "void (*Uerror)(char *);", + "void (*hasher)(uchar *, int);", + "void (*o_hash)(uchar *, int, int);", + "void d_hash(uchar *, int);", + "void m_hash(uchar *, int);", + "void d_sfh(uchar *, int);", + "void o_hash32(uchar *, int, int);", + "void o_hash64(uchar *, int, int);", + "", "void active_procs(void);", "void cleanup(void);", "void do_the_search(void);", @@ -463,7 +509,7 @@ 0, }; -static char *Tail[] = { +static const char *Tail[] = { "Trans *", "settr( int t_id, int a, int b, int c, int d,", " char *t, int g, int tpe0, int tpe1)", @@ -568,10 +614,14 @@ "}", "#endif", "void", - "retrans(int n, int m, int is, short srcln[], uchar reach[], uchar lstate[])", + "retrans(int n, int m, int is, short srcln[], uchar reach[], uchar lpstate[])", " /* process n, with m states, is=initial state */", - "{ Trans *T0, *T1, *T2, *T3, *T4, *T5;", - " int i, k;", + "{ Trans *T0, *T1, *T2, *T3;", + " Trans *T4, *T5; /* t_reverse or has_unless */", + " int i;", + "#if defined(HAS_UNLESS) || !defined(NOREDUCE)", + " int k;", + "#endif", "#ifndef NOREDUCE", " int g, h, j, aa;", "#endif", @@ -832,6 +882,7 @@ " }", " printf(\"size=\\\"8,10\\\";\\n\");", " printf(\" GT [shape=box,style=dotted,label=\\\"%%s\\\"];\\n\", buf);", + " printf(\" GT -> S%%d;\\n\", is);", " } else", " { switch (Btypes[n]) {", " case I_PROC: printf(\"init\\n\"); break;", @@ -871,11 +922,14 @@ " printf(\" 'else' stmnts\\n\");", " pan_exit(1);", " } }", - "#ifndef LOOPSTATE", + "#if !defined(LOOPSTATE) && !defined(BFS_PAR)", " if (state_tables)", "#endif", - " do_dfs(n, m, is, srcln, reach, lstate);", - "#ifdef T_REVERSE", + " do_dfs(n, m, is, srcln, reach, lpstate);", + "", + " if (!t_reverse)", + " { return;", + " }", " /* process n, with m states, is=initial state -- reverse list */", " if (!state_tables && Btypes[n] != N_CLAIM)", " { for (i = 1; i < m; i++)", /* for each state */ @@ -887,12 +941,12 @@ "", " /* find unless-escapes, they should go first */", " T4 = T5 = T0 = trans[n][i];", - "#ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " while (T4 && T4->e_trans) /* escapes are first in orig list */", " { T5 = T4; /* remember predecessor */", " T4 = T4->nxt;", " }", - "#endif", + " #endif", " /* T4 points to first non-escape, T5 to its parent, T0 to original list */", " if (T4 != T0) /* there was at least one escape */", " { T3 = T5->nxt; /* start of non-escapes */", @@ -907,12 +961,12 @@ " T3 = (Trans *) 0;", /* remember a possible 'else' */ " for (T5 = T0; T5; T5 = T4)", " { T4 = T5->nxt;", - "#ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " if (T5->e_trans)", " { printf(\"error: cannot happen!\\n\");", " continue;", " }", - "#endif", + " #endif", " if (strcmp(T5->tp, \"else\") == 0)", " { T3 = T5;", " T5->nxt = (Trans *) 0;", @@ -924,7 +978,15 @@ " /* T3 points to a possible else, which is removed from the list */", " /* T1 points to the reversed list so far (without escapes) */", " /* T2 points to the tail element -- where the else should go */", - " if (T2 && T3) { T2->nxt = T3; } /* add else */", + " if (T2 && T3)", + " { T2->nxt = T3; /* add else */", + " } else", + " { if (T3) /* there was an else, but there's no tail */", + " { if (!T1) /* and no reversed list */", + " { T1 = T3; /* odd, but possible */", + " } else /* even stranger */", + " { T1->nxt = T3;", + " } } }", "", " /* add in the escapes, to that they appear at the front */", " if (Tx && Ty) { Ty->nxt = T1; T1 = Tx; }", @@ -939,7 +1001,6 @@ " for (T0 = trans[n][i]; T0; T0 = T0->nxt)", " crack(n, i, T0, srcln);", " }", - "#endif", "}", "void", "imed(Trans *T, int v, int n, int j) /* set intermediate state */", @@ -978,14 +1039,17 @@ "#endif", " }", "}", + "", + "extern Trans *t_id_lkup[];", /* needed by BFS_PAR */ + "", "void", - "dfs_table(int n, int m, int is, short srcln[], uchar reach[], uchar lstate[])", + "dfs_table(int n, int m, int is, short srcln[], uchar reach[], uchar lpstate[])", "{ Trans *z;\n", " if (is >= m || is <= 0 || !trans[n][is])", " return;", " if ((reach[is] & (4|8|16)) != 0)", " { if ((reach[is] & (8|16)) == 16) /* on stack, not yet recorded */", - " { lstate[is] = 1;", + " { lpstate[is] = 1;", " reach[is] |= 8; /* recorded */", " if (state_tables && verbose)", " { printf(\"state %%d line %%d is a loopstate\\n\", is, srcln[is]);", @@ -994,25 +1058,25 @@ " }", " reach[is] |= (4|16); /* visited | onstack */", " for (z = trans[n][is]; z; z = z->nxt)", - " {", + " { t_id_lkup[z->t_id] = z;", /* needed by BFS_PAR */ "#ifdef HAS_UNLESS", " int i, j;", "#endif", - " dfs_table(n, m, z->st, srcln, reach, lstate);", + " dfs_table(n, m, z->st, srcln, reach, lpstate);", "#ifdef HAS_UNLESS", " for (i = 0; i < HAS_UNLESS; i++)", " { j = trans[n][is]->escp[i];", " if (!j) break;", - " dfs_table(n, m, j, srcln, reach, lstate);", + " dfs_table(n, m, j, srcln, reach, lpstate);", " }", "#endif", " }", " reach[is] &= ~16; /* no longer on stack */", "}", "void", - "do_dfs(int n, int m, int is, short srcln[], uchar reach[], uchar lstate[])", + "do_dfs(int n, int m, int is, short srcln[], uchar reach[], uchar lpstate[])", "{ int i;", - " dfs_table(n, m, is, srcln, reach, lstate);", + " dfs_table(n, m, is, srcln, reach, lpstate);", " for (i = 0; i < m; i++)", " reach[i] &= ~(4|8|16);", "}", diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen3.c /sys/src/cmd/spin/pangen3.c --- /n/sources/plan9/sys/src/cmd/spin/pangen3.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen3.c Mon Feb 22 00:00:00 2021 @@ -1,19 +1,17 @@ /***** spin: pangen3.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" +#include -extern FILE *th; -extern int eventmapnr; +extern FILE *fd_th, *fd_tc; +extern int eventmapnr, old_priority_rules, in_settr; typedef struct SRC { int ln, st; /* linenr, statenr */ @@ -30,16 +28,17 @@ extern int ltl_mode; -extern void sr_mesg(FILE *, int, int); +extern void sr_mesg(FILE *, int, int, const char *); +extern Lextok **find_mtype_list(const char *); static void putnr(int n) { if (col++ == 8) - { fprintf(th, "\n\t"); + { fprintf(fd_tc, "\n\t"); /* was th */ col = 1; } - fprintf(th, "%3d, ", n); + fprintf(fd_tc, "%3d, ", n); /* was th */ } static void @@ -49,7 +48,7 @@ return; if (lastfnm) - fprintf(th, "{ \"%s\", %d, %d },\n\t", + fprintf(fd_tc, "{ \"%s\", %d, %d },\n\t", /* was th */ lastfnm->name, lastfrom, j-1); @@ -61,73 +60,118 @@ putfnm_flush(int j) { if (lastfnm) - fprintf(th, "{ \"%s\", %d, %d }\n", + fprintf(fd_tc, "{ \"%s\", %d, %d }\n", /* was th */ lastfnm->name, lastfrom, j); } -void -putskip(int m) /* states that need not be reached */ +static SRC * +newsrc(int m, SRC *n) { SRC *tmp; - - for (tmp = skip; tmp; tmp = tmp->nxt) - if (tmp->st == m) - return; tmp = (SRC *) emalloc(sizeof(SRC)); tmp->st = m; - tmp->nxt = skip; - skip = tmp; + tmp->nxt = n; + return tmp; +} + +void +putskip(int m) /* states that need not be reached */ +{ SRC *tmp, *lst = (SRC *)0; + /* 6.4.0: now an ordered list */ + for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == m) + { return; + } + if (tmp->st > m) /* insert before */ + { if (tmp == skip) + { tmp = newsrc(m, skip); + skip = tmp; + } else + { assert(lst); + tmp = newsrc(m, lst->nxt); + lst->nxt = tmp; + } + return; + } } + /* insert at the end */ + if (lst) + { lst->nxt = newsrc(m, 0); + } else /* empty list */ + { skip = newsrc(m, 0); + } } void unskip(int m) /* a state that needs to be reached after all */ -{ SRC *tmp, *lst=(SRC *)0; +{ SRC *tmp, *lst = (SRC *)0; for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) - if (tmp->st == m) + { if (tmp->st == m) { if (tmp == skip) skip = skip->nxt; else if (lst) /* always true, but helps coverity */ lst->nxt = tmp->nxt; break; } + if (tmp->st > m) + { break; /* m is not in list */ + } } } void putsrc(Element *e) /* match states to source lines */ -{ SRC *tmp; +{ SRC *tmp, *lst = (SRC *)0; int n, m; if (!e || !e->n) return; n = e->n->ln; m = e->seqno; - - for (tmp = frst; tmp; tmp = tmp->nxt) - if (tmp->st == m) + /* 6.4.0: now an ordered list */ + for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == m) { if (tmp->ln != n || tmp->fn != e->n->fn) printf("putsrc mismatch seqno %d, line %d - %d, file %s\n", m, n, tmp->ln, tmp->fn->name); return; } - tmp = (SRC *) emalloc(sizeof(SRC)); + if (tmp->st > m) /* insert before */ + { if (tmp == frst) + { tmp = newsrc(m, frst); + frst = tmp; + } else + { assert(lst); + tmp = newsrc(m, lst->nxt); + lst->nxt = tmp; + } + tmp->ln = n; + tmp->fn = e->n->fn; + return; + } } + /* insert at the end */ + tmp = newsrc(m, lst?lst->nxt:0); tmp->ln = n; - tmp->st = m; tmp->fn = e->n->fn; - tmp->nxt = frst; - frst = tmp; + if (lst) + { lst->nxt = tmp; + } else + { frst = tmp; + } } static void dumpskip(int n, int m) { SRC *tmp, *lst; + FILE *tz = fd_tc; /* was fd_th */ int j; - fprintf(th, "uchar reached%d [] = {\n\t", m); + fprintf(tz, "uchar reached%d [] = {\n\t", m); + tmp = skip; + lst = (SRC *) 0; for (j = 0, col = 0; j <= n; j++) - { lst = (SRC *) 0; - for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) - if (tmp->st == j) + { /* find j in the sorted list */ + for ( ; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == j) { putnr(1); if (lst) lst->nxt = tmp->nxt; @@ -135,15 +179,19 @@ skip = tmp->nxt; break; } - if (!tmp) - putnr(0); - } - fprintf(th, "};\n"); + if (tmp->st > j) + { putnr(0); + break; /* j is not in the list */ + } } - fprintf(th, "uchar *loopstate%d;\n", m); + if (!tmp) + { putnr(0); + } } + fprintf(tz, "};\n"); + fprintf(tz, "uchar *loopstate%d;\n", m); if (m == eventmapnr) - fprintf(th, "#define reached_event reached%d\n", m); + fprintf(fd_th, "#define reached_event reached%d\n", m); skip = (SRC *) 0; } @@ -153,27 +201,33 @@ { SRC *tmp, *lst; int j; static int did_claim = 0; + FILE *tz = fd_tc; /* was fd_th */ - fprintf(th, "short src_ln%d [] = {\n\t", m); + fprintf(tz, "\nshort src_ln%d [] = {\n\t", m); + tmp = frst; for (j = 0, col = 0; j <= n; j++) - { lst = (SRC *) 0; - for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) - if (tmp->st == j) + { for ( ; tmp; tmp = tmp->nxt) + { if (tmp->st == j) { putnr(tmp->ln); break; } + if (tmp->st > j) + { putnr(0); + break; + } } if (!tmp) - putnr(0); - } - fprintf(th, "};\n"); + { putnr(0); + } } + fprintf(tz, "};\n"); lastfnm = (Symbol *) 0; lastdef.name = "-"; - fprintf(th, "S_F_MAP src_file%d [] = {\n\t", m); + fprintf(tz, "S_F_MAP src_file%d [] = {\n\t", m); + tmp = frst; + lst = (SRC *) 0; for (j = 0, col = 0; j <= n; j++) - { lst = (SRC *) 0; - for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) - if (tmp->st == j) + { for ( ; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == j) { putfnm(j, tmp->fn); if (lst) lst->nxt = tmp->nxt; @@ -181,18 +235,22 @@ frst = tmp->nxt; break; } + if (tmp->st > j) + { putfnm(j, &lastdef); + break; + } } if (!tmp) - putfnm(j, &lastdef); - } + { putfnm(j, &lastdef); + } } putfnm_flush(j); - fprintf(th, "};\n"); + fprintf(tz, "};\n"); if (pid_is_claim(m) && !did_claim) - { fprintf(th, "short *src_claim;\n"); + { fprintf(tz, "short *src_claim;\n"); did_claim++; } if (m == eventmapnr) - fprintf(th, "#define src_event src_ln%d\n", m); + fprintf(fd_th, "#define src_event src_ln%d\n", m); frst = (SRC *) 0; dumpskip(n, m); @@ -206,26 +264,40 @@ static int symbolic(FILE *fd, Lextok *tv) -{ Lextok *n; extern Lextok *Mtype; +{ Lextok *n, *Mtype; int cnt = 1; if (tv->ismtyp) - for (n = Mtype; n; n = n->rgt, cnt++) - if (cnt == tv->val) - { fprintf(fd, "%s", n->lft->sym->name); - return 1; + { char *s = "_unnamed_"; + if (tv->sym && tv->sym->mtype_name) + { s = tv->sym->mtype_name->name; } + Mtype = *find_mtype_list(s); + for (n = Mtype; n; n = n->rgt, cnt++) + { if (cnt == tv->val) + { fprintf(fd, "%s", n->lft->sym->name); + return 1; + } } } + return 0; } static void comwork(FILE *fd, Lextok *now, int m) { Lextok *v; + char *s = 0; int i, j; if (!now) { fprintf(fd, "0"); return; } switch (now->ntyp) { - case CONST: sr_mesg(fd, now->val, now->ismtyp); break; + case CONST: if (now->ismtyp + && now->sym + && now->sym->mtype_name) + { s = now->sym->mtype_name->name; + } + sr_mesg(fd, now->val, now->ismtyp, s); + break; + case '!': Cat3("!(", now->lft, ")"); break; case UMIN: Cat3("-(", now->lft, ")"); break; case '~': Cat3("~(", now->lft, ")"); break; @@ -324,7 +396,27 @@ case ENABLED: Cat3("enabled(", now->lft, ")"); break; - case EVAL: Cat3("eval(", now->lft, ")"); + case GET_P: if (old_priority_rules) + { fprintf(fd, "1"); + } else + { Cat3("get_priority(", now->lft, ")"); + } + break; + + case SET_P: if (!old_priority_rules) + { fprintf(fd, "set_priority("); + comwork(fd, now->lft->lft, m); + fprintf(fd, ", "); + comwork(fd, now->lft->rgt, m); + fprintf(fd, ")"); + } + break; + + case EVAL: if (now->lft->ntyp == ',') + { Cat3("eval(", now->lft->lft, ")"); + } else + { Cat3("eval(", now->lft, ")"); + } break; case NONPROGRESS: @@ -346,12 +438,14 @@ } break; - case ASGN: comwork(fd,now->lft,m); + case ASGN: + if (check_track(now) == STRUCT) { break; } + comwork(fd,now->lft,m); fprintf(fd," = "); comwork(fd,now->rgt,m); break; - case PRINT: { char c, buf[512]; + case PRINT: { char c, buf[1024]; strncpy(buf, now->sym->name, 510); for (i = j = 0; i < 510; i++, j++) { c = now->sym->name[i]; @@ -372,14 +466,35 @@ fprintf(fd, ")"); break; case PRINTM: fprintf(fd, "printm("); - comwork(fd, now->lft, m); - fprintf(fd, ")"); + { char *s = 0; + if (now->lft->sym + && now->lft->sym->mtype_name) + { s = now->lft->sym->mtype_name->name; + } + + if (now->lft && now->lft->ismtyp) + { fprintf(fd, "%d", now->lft->val); + } else + { comwork(fd, now->lft, m); + } + + if (s) + { if (in_settr) + { fprintf(fd, ", '%s')", s); + } else + { fprintf(fd, ", \"%s\")", s); + } + } else + { fprintf(fd, ", 0)"); + } + } break; case NAME: putname(fd, "", now, m, ""); break; - case 'p': if (ltl_mode) + case 'p': + if (ltl_mode) { fprintf(fd, "%s", now->lft->sym->name); /* proctype */ if (now->lft->lft) { fprintf(fd, "["); @@ -405,7 +520,7 @@ case ELSE: fprintf(fd, "else"); break; case '@': fprintf(fd, "-end-"); break; - case D_STEP: fprintf(fd, "D_STEP"); break; + case D_STEP: fprintf(fd, "D_STEP%d", now->ln); break; case ATOMIC: fprintf(fd, "ATOMIC"); break; case NON_ATOMIC: fprintf(fd, "sub-sequence"); break; case IF: fprintf(fd, "IF"); break; diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen3.h /sys/src/cmd/spin/pangen3.h --- /n/sources/plan9/sys/src/cmd/spin/pangen3.h Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen3.h Mon Feb 22 00:00:00 2021 @@ -1,16 +1,12 @@ /***** spin: pangen3.h *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ -/* (c) 2007: small additions for V5.0 to support multi-core verifications */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ -static char *Head0[] = { +static const char *Head0[] = { "#if defined(BFS) && defined(REACH)", " #undef REACH", /* redundant with bfs */ "#endif", @@ -66,10 +62,13 @@ " #define VECTORSZ 1024 /* sv size in bytes */", " #endif", "#endif\n", + "#define MAXQ 255", + "#define MAXPROC 255", + "", 0, }; -static char *Header[] = { +static const char *Header[] = { "#ifdef VERBOSE", " #ifndef CHECK", " #define CHECK", @@ -83,22 +82,32 @@ " #define NOFAIR", " #endif", "#endif", +#if 0 + NOREDUCE BITSTATE SAFETY MA WS>4 + CNTRSTACK: - + + d - + FULLSTACK: + d - - d + - + d d d + - + + d + + - - d d d + Neither: + d + d d + + d d + d +#endif "#ifdef NOREDUCE", " #ifndef XUSAFE", " #define XUSAFE", " #endif", " #if !defined(SAFETY) && !defined(MA)", - " #define FULLSTACK", + " #define FULLSTACK", /* => NOREDUCE && !SAFETY && !MA */ " #endif", "#else", " #ifdef BITSTATE", - " #if defined(SAFETY) && !defined(HASH64)", - " #define CNTRSTACK", + " #if defined(SAFETY) && WS<=4", + " #define CNTRSTACK", /* => !NOREDUCE && BITSTATE && SAFETY && WS<=4 */ " #else", - " #define FULLSTACK", + " #define FULLSTACK", /* => !NOREDUCE && BITSTATE && (!SAFETY || WS>4) */ " #endif", " #else", - " #define FULLSTACK", + " #define FULLSTACK", /* => !NOREDUCE && !BITSTATE */ " #endif", "#endif", "#ifdef BITSTATE", @@ -117,31 +126,9 @@ " #undef HC", " #define HC4", "#endif", - "#ifdef HC0", /* 32 bits */ - " #define HC 0", - "#endif", - "#ifdef HC1", /* 32+8 bits */ - " #define HC 1", - "#endif", - "#ifdef HC2", /* 32+16 bits */ - " #define HC 2", - "#endif", - "#ifdef HC3", /* 32+24 bits */ - " #define HC 3", - "#endif", - "#ifdef HC4", /* 32+32 bits - combine with -DMA=8 */ - " #define HC 4", - "#endif", - "#ifdef COLLAPSE", - " #if NCORE>1 && !defined(SEP_STATE)", - " unsigned long *ncomps; /* in shared memory */", - " #else", - " unsigned long ncomps[256+2];", - " #endif", - "#endif", - - "#define MAXQ 255", - "#define MAXPROC 255", + "#if defined(HC0) || defined(HC1) || defined(HC2) || defined(HC3) || defined(HC4)", + " #define HC 4", /* 2x32 bits */ + "#endif", /* really only one hashcompact mode, not 5 */ "", "typedef struct _Stack { /* for queues and processes */", "#if VECTORSZ>32000", @@ -186,37 +173,15 @@ 0, }; -static char *Header0[] = { +static const char *Header0[] = { " char *body;", " struct Svtack *nxt;", " struct Svtack *lst;", "} Svtack;\n", - "Trans ***trans; /* 1 ptr per state per proctype */\n", - "struct H_el *Lstate;", - "int depthfound = -1; /* loop detection */", - - "#ifndef TRIX", - " #if VECTORSZ>32000", - " int proc_offset[MAXPROC];", - " int q_offset[MAXQ];", - " #else", - " short proc_offset[MAXPROC];", - " short q_offset[MAXQ];", - " #endif", - " uchar proc_skip[MAXPROC];", - " uchar q_skip[MAXQ];", - "#endif", - - "unsigned long vsize; /* vector size in bytes */", - "#ifdef SVDUMP", - " int vprefix=0, svfd; /* runtime option -pN */", - "#endif", - "char *tprefix = \"trail\"; /* runtime option -tsuffix */", - "short boq = -1; /* blocked_on_queue status */", 0, }; -static char *Head1[] = { +static const char *Head1[] = { "typedef struct State {", " uchar _nr_pr;", " uchar _nr_qs;", @@ -242,18 +207,21 @@ #endif " unsigned short _vsz;", "#else", - " unsigned long _vsz;", + " ulong _vsz;", "#endif", "#endif", - "#ifdef HAS_LAST", /* cannot go before _cnt - see hstore() */ + "#ifdef HAS_LAST", /* cannot go before _cnt - see h_store() */ " uchar _last; /* pid executed in last step */", "#endif", "#if defined(BITSTATE) && defined(BCS) && defined(STORE_CTX)", " uchar _ctx; /* nr of context switches so far */", "#endif", - + "#if defined(BFS_PAR) && defined(L_BOUND)", + " uchar _l_bnd; /* bounded liveness */", + " uchar *_l_sds; /* seed state */", + "#endif", "#ifdef EVENT_TRACE", " #if nstates_event<256", " uchar _event;", @@ -264,13 +232,13 @@ 0, }; -static char *Addp0[] = { +static const char *Addp0[] = { /* addproc(....parlist... */ ")", - "{ int j, h = now._nr_pr;", + "{ int j = 0, h = now._nr_pr;", "#ifndef NOCOMP", " int k;", "#endif", - " uchar *o_this = this;\n", + " uchar *o_this = _this;\n", "#ifndef INLINE", " if (TstOnly) return (h < MAXPROC);", "#endif", @@ -289,18 +257,21 @@ 0, }; -static char *Addp1[] = { +static const char *Addp1[] = { " default: Uerror(\"bad proc - addproc\");", " }", + " #ifdef BFS_PAR", + " bfs_prepmask(1); /* addproc */", + " #endif", "#ifdef TRIX", - " vsize += sizeof(struct H_el *);", + " vsize += sizeof(H_el *);", "#else", " if (vsize%%WS)", " proc_skip[h] = WS-(vsize%%WS);", " else", " proc_skip[h] = 0;", - " #ifndef NOCOMP", + " #if !defined(NOCOMP) && !defined(HC)", " for (k = vsize + (int) proc_skip[h]; k > vsize; k--)", " Mask[k-1] = 1; /* align */", " #endif", @@ -360,11 +331,14 @@ " processes[h]->parent_pid = calling_pid;", " processes[h]->nxt = (TRIX_v6 *) 0;", "#else", - " #ifndef NOCOMP", + " #if !defined(NOCOMP) && !defined(HC)", " for (k = 1; k <= Air[n]; k++)", " Mask[vsize - k] = 1; /* pad */", " Mask[vsize-j] = 1; /* _pid */", " #endif", + " #ifdef BFS_PAR", + " bfs_fixmask(1); /* addproc */", + " #endif", " if (vsize >= VECTORSZ)", " { printf(\"pan: error, VECTORSZ too small, recompile pan.c\");", " printf(\" with -DVECTORSZ=N with N>%%d\\n\", (int) vsize);", @@ -373,16 +347,18 @@ "#endif", " memset((char *)pptr(h), 0, j);", - " this = pptr(h);", + " _this = pptr(h);", " if (BASE > 0 && h > 0)", - " ((P0 *)this)->_pid = h-BASE;", - " else", - " ((P0 *)this)->_pid = h;", + " { ((P0 *)_this)->_pid = h-BASE;", + " } else", + " { ((P0 *)_this)->_pid = h;", + " }", " switch (n) {", 0, }; -static char *Addq0[] = { +static const char *Addq0[] = { + "", "int", "addqueue(int calling_pid, int n, int is_rv)", "{ int j=0, i = now._nr_qs;", @@ -398,18 +374,21 @@ 0, }; -static char *Addq1[] = { +static const char *Addq1[] = { " default: Uerror(\"bad queue - addqueue\");", " }", + " #ifdef BFS_PAR", + " bfs_prepmask(2); /* addqueue */", + " #endif", "#ifdef TRIX", - " vsize += sizeof(struct H_el *);", + " vsize += sizeof(H_el *);", "#else", " if (vsize%%WS)", " q_skip[i] = WS-(vsize%%WS);", " else", " q_skip[i] = 0;", - " #ifndef NOCOMP", + " #if !defined(NOCOMP) && !defined(HC)", " k = vsize;", " #ifndef BFS", " if (is_rv) k += j;", @@ -420,6 +399,9 @@ " vsize += (int) q_skip[i];", " q_offset[i] = vsize;", " vsize += j;", + " #ifdef BFS_PAR", + " bfs_fixmask(2); /* addqueue */", + " #endif", "#endif", " now._nr_qs += 1;", @@ -456,7 +438,7 @@ 0, }; -static char *Addq11[] = { +static const char *Addq11[] = { "{ int j; uchar *z;\n", "#ifdef HAS_SORTED", " int k;", @@ -484,7 +466,7 @@ 0, }; -static char *Addq2[] = { +static const char *Addq2[] = { " case 0: printf(\"queue %%d was deleted\\n\", into+1);", " default: Uerror(\"bad queue - qsend\");", " }", @@ -505,7 +487,7 @@ 0, }; -static char *Addq3[] = { +static const char *Addq3[] = { " case 0: printf(\"queue %%d was deleted\\n\", from+1);", " }", " Uerror(\"bad queue q-zero\");", @@ -565,7 +547,11 @@ "short q_recver[MAXQ+1];", "int", "q_R_check(int x, int who)", - "{ if (!q_recver[x])", + "{", + "#ifdef VERBOSE", + " printf(\"q_R_check x=%%d who=%%d\\n\", x, who);", + "#endif", + " if (!q_recver[x])", " { q_recver[x] = who+1;", "#if SYNC", " if (q_zero(x))", @@ -605,7 +591,7 @@ 0, }; -static char *Addq4[] = { +static const char *Addq4[] = { " case 0: printf(\"queue %%d was deleted\\n\", from+1);", " }", " Uerror(\"bad queue - q_full\");", @@ -649,7 +635,7 @@ 0, }; -static char *Addq5[] = { +static const char *Addq5[] = { " case 0: printf(\"queue %%d was deleted\\n\", from+1);", " default: Uerror(\"bad queue - qrecv\");", " }", @@ -657,7 +643,7 @@ "}", "#endif\n", "#ifndef BITSTATE", - "#ifdef COLLAPSE", + " #ifdef COLLAPSE", "long", "col_q(int i, char *z)", "{ int j=0, k;", @@ -667,19 +653,56 @@ 0, }; -static char *Code0[] = { +static const char *Code0[] = { + "#ifdef INIT_STATE", + "void", /* Bocchino */ + "init_state(State state)" + "{ state._nr_pr = 0;", + " state._nr_qs = 0;", + " state._a_t = 0;", + "#ifndef NOFAIR", + " memset(&state._cnt, 0, sizeof(state._cnt));", + "#endif", + "#ifndef NOVSZ", + " state._vsz = 0;", + "#endif", + "#ifdef HAS_LAST", + " state._last = 0;", + "#endif", + "#if defined(BITSTATE) && defined(BCS) && defined(STORE_CTX)", + " state._ctx = 0;", + "#endif", + "#if defined(BFS_PAR) && defined(L_BOUND)", + " state._l_bnd = 0;", + " state._l_sds = 0;", + "#endif", + "#ifdef EVENT_TRACE", + " state_event = 0;", + "#endif", + "#ifdef TRIX", + " memset(&state._ids_, 0, sizeof(state._ids_));", + "#else", + " memset(&state.sv, 0, sizeof(state.sv));", + "#endif", + "}", + "#endif", + "", "void", "run(void)", "{ /* int i; */", + "#ifdef INIT_STATE", + " init_state(now);", + "#else", " memset((char *)&now, 0, sizeof(State));", - " vsize = (unsigned long) (sizeof(State) - VECTORSZ);", + "#endif", + " vsize = (ulong) (sizeof(State) - VECTORSZ);", "#ifndef NOVSZ", " now._vsz = vsize;", "#endif", "#ifdef TRIX", " if (VECTORSZ != sizeof(now._ids_))", " { printf(\"VECTORSZ is %%d, but should be %%d in this mode\\n\",", - " VECTORSZ, sizeof(now._ids_));", + " VECTORSZ, (int) sizeof(now._ids_));", " Uerror(\"VECTORSZ set incorrectly, recompile Spin (not pan.c)\");", " }", "#endif", @@ -692,28 +715,30 @@ 0, }; -static char *R0[] = { +static const char *R0[] = { " Maxbody = max(Maxbody, ((int) sizeof(P%d)));", " reached[%d] = reached%d;", - " accpstate[%d] = (uchar *) emalloc(nstates%d);", - " progstate[%d] = (uchar *) emalloc(nstates%d);", - " loopstate%d = loopstate[%d] = (uchar *) emalloc(nstates%d);", - " stopstate[%d] = (uchar *) emalloc(nstates%d);", - " visstate[%d] = (uchar *) emalloc(nstates%d);", - " mapstate[%d] = (short *) emalloc(nstates%d * sizeof(short));", - "#ifdef HAS_CODE", - " NrStates[%d] = nstates%d;", - "#endif", - " stopstate[%d][endstate%d] = 1;", + " accpstate[%d] = (uchar *) emalloc(_nstates%d);", + " progstate[%d] = (uchar *) emalloc(_nstates%d);", + " loopstate%d = loopstate[%d] = (uchar *) emalloc(_nstates%d);", + " stopstate[%d] = (uchar *) emalloc(_nstates%d);", + " visstate[%d] = (uchar *) emalloc(_nstates%d);", + " mapstate[%d] = (short *) emalloc(_nstates%d * sizeof(short));", + " stopstate[%d][_endstate%d] = 1;", 0, }; -static char *R0a[] = { - " retrans(%d, nstates%d, start%d, src_ln%d, reached%d, loopstate%d);", +static const char *R00[] = { + " NrStates[%d] = _nstates%d;", 0, }; -static char *Code1[] = { +static const char *R0a[] = { + " retrans(%d, _nstates%d, _start%d, src_ln%d, reached%d, loopstate%d);", + 0, +}; + +static const char *Code1[] = { "#ifdef NP", " #define ACCEPT_LAB 1 /* at least 1 in np_ */", "#else", @@ -749,12 +774,12 @@ 0, }; -static char *Code3[] = { +static const char *Code3[] = { "#define PROG_LAB %d /* progress labels */", 0, }; -static char *R2[] = { +static const char *R2[] = { "uchar *accpstate[%d];", "uchar *progstate[%d];", "uchar *loopstate[%d];", @@ -767,21 +792,21 @@ "#endif", 0, }; -static char *R3[] = { +static const char *R3[] = { " Maxbody = max(Maxbody, ((int) sizeof(Q%d)));", 0, }; -static char *R4[] = { - " r_ck(reached%d, nstates%d, %d, src_ln%d, src_file%d);", +static const char *R4[] = { + " r_ck(reached%d, _nstates%d, %d, src_ln%d, src_file%d);", 0, }; -static char *R5[] = { +static const char *R5[] = { " case %d: j = sizeof(P%d); break;", 0, }; -static char *R6[] = { +static const char *R6[] = { " }", - " this = o_this;", + " _this = o_this;", "#ifdef TRIX", " re_mark_all(1); /* addproc */", "#endif", @@ -800,22 +825,157 @@ " #ifdef COLLAPSE", "long", "col_p(int i, char *z)", - "{ int j, k; unsigned long ordinal(char *, long, short);", + "{ int j, k; ulong ordinal(char *, long, short);", " char *x, *y;", " P0 *ptr = (P0 *) pptr(i);", " switch (ptr->_t) {", " case 0: j = sizeof(P0); break;", 0, }; -static char *R8a[] = { +static const char *R7a[] = { + "void\nre_mark_all(int whichway)", + "{ int j;", + " #ifdef V_TRIX", + " printf(\"%%d: re_mark_all channels %%d\\n\", depth, whichway);", + " #endif", + " #ifndef BFS", + " for (j = 0; j < now._nr_qs; j++)", + " channels[j]->modified = 1; /* channel index moved */", + " #endif", + " #ifndef TRIX_ORIG", + " if (whichway > 0)", + " { for (j = now._nr_pr + now._nr_qs - 1; j >= now._nr_pr; j--)", + " now._ids_[j] = now._ids_[j-1];", + " } else", + " { for (j = now._nr_pr; j < now._nr_pr + now._nr_qs; j++)", + " now._ids_[j] = now._ids_[j+1];", + " }", + " #endif", + "}", + 0, +}; + +static const char *R7b[] = { + "#ifdef BFS_PAR", + "void", + "bfs_prepmask(int caller)", + "{", + "#if !defined(NOCOMP) && !defined(HC)", + " memcpy((char *) &tmp_msk, (const char *) Mask, sizeof(State));", + " Mask = (uchar *) &tmp_msk;", + "#endif", + " switch (caller) {", + " case 1: /* addproc */", + "#if VECTORSZ>32000", + " memcpy((char *) P_o_tmp, (const char *) proc_offset, MAXPROC*sizeof(int));", + "#else", + " memcpy((char *) P_o_tmp, (const char *) proc_offset, MAXPROC*sizeof(short));", + "#endif", + " memcpy((char *) P_s_tmp, (const char *) proc_skip, MAXPROC*sizeof(uchar));", + " proc_offset = P_o_tmp;", + " proc_skip = (uchar *) &P_s_tmp[0];", + " break;", + " case 2: /* addqueue */", + "#if VECTORSZ>32000", + " memcpy((char *) Q_o_tmp, (const char *) q_offset, MAXQ*sizeof(int));", + "#else", + " memcpy((char *) Q_o_tmp, (const char *) q_offset, MAXQ*sizeof(short));", + "#endif", + " memcpy((char *) Q_s_tmp, (const char *) q_skip, MAXQ*sizeof(uchar));", + " q_offset = Q_o_tmp;", + " q_skip = (uchar *) &Q_s_tmp[0];", + " break;", + " case 3: /* no nothing */", + " break;", + " default: /* cannot happen */", + " Uerror(\"no good\");", + " break;", + " }", + "}", + "", + "typedef struct BFS_saves BFS_saves;", + "struct BFS_saves {", + " char *m;", + " BFS_saves *nxt;", + "} *bfs_save_po,", + " *bfs_save_ps,", + "#if !defined(NOCOMP) && !defined(HC)", + " *bfs_save_mask,", + "#endif", + " *bfs_save_qo,", + " *bfs_save_qs;", + "", + "extern volatile uchar *sh_malloc(ulong);", + "static int bfs_runs; /* 0 before local heaps are initialized */", + "", + "void", + "bfs_swoosh(BFS_saves **where, char **what, int howmuch)", + "{ BFS_saves *m;", + " for (m = *where; m; m = m->nxt)", + " { if (memcmp(m->m, *what, howmuch) == 0)", + " { *what = m->m;", + " return;", + " } }", + " m = (BFS_saves *) emalloc(sizeof(BFS_saves));", + " if (bfs_runs)", + " { m->m = (char *) sh_malloc(howmuch);", + " } else", + " { m->m = (char *) sh_pre_malloc(howmuch);", + " }", + " memcpy(m->m, *what, howmuch);", + " m->nxt = *where;", + " *where = m;", + " *what = m->m;", + "}", + "", + "void", + "bfs_fixmask(int caller)", /* 1=addproc, 2=addqueue */ + "{", + "#if !defined(NOCOMP) && !defined(HC)", + " bfs_swoosh(&bfs_save_mask, (char **) &Mask, sizeof(State));", + "#endif", + "#ifndef TRIX", + " switch (caller) {", + " case 1: /* addproc */", + " #if VECTORSZ>32000", + " bfs_swoosh(&bfs_save_po, (char **) &proc_offset, MAXPROC*sizeof(int));", + " #else", + " bfs_swoosh(&bfs_save_po, (char **) &proc_offset, MAXPROC*sizeof(short));", + " #endif", + " bfs_swoosh(&bfs_save_ps, (char **) &proc_skip, MAXPROC*sizeof(uchar));", + " break;", + " case 2: /* addqueue */", + " #if VECTORSZ>32000", + " bfs_swoosh(&bfs_save_qo, (char **) &q_offset, MAXQ*sizeof(int));", + " #else", + " bfs_swoosh(&bfs_save_qo, (char **) &q_offset, MAXQ*sizeof(short));", + " #endif", + " bfs_swoosh(&bfs_save_qs, (char **) &q_skip, MAXQ*sizeof(uchar));", + " break;", + " case 3: /* do nothing */", + " break;", + " default:", + " Uerror(\"double plus ungood\");", + " break;", + " }", + "#endif", + "}", + "#endif", + 0, +}; +static const char *R8a[] = { " default: Uerror(\"bad proctype - collapse\");", " }", " if (z) x = z; else x = scratch;", " y = (char *) ptr; k = proc_offset[i];", - + "", + "#if !defined(NOCOMP) && !defined(HC)", " for ( ; j > 0; j--, y++)", " if (!Mask[k++]) *x++ = *y;", - + "#else", + " memcpy(x, y, j);", + " x += j;", + "#endif", " for (j = 0; j < WS-1; j++)", " *x++ = 0;", " x -= j;", @@ -826,18 +986,24 @@ "#endif", 0, }; -static char *R8b[] = { +static const char *R8b[] = { " default: Uerror(\"bad qtype - collapse\");", " }", " if (z) x = z; else x = scratch;", " y = (char *) ptr; k = q_offset[i];", + "#if NQS > 0", " /* no need to store the empty slots at the end */", " j -= (q_max[ptr->_t] - ptr->Qlen) * ((j - 2)/q_max[ptr->_t]);", - + "#endif", + "", + "#if !defined(NOCOMP) && !defined(HC)", " for ( ; j > 0; j--, y++)", " if (!Mask[k++]) *x++ = *y;", - + "#else", + " memcpy(x, y, j);", + " x += j;", + "#endif", " for (j = 0; j < WS-1; j++)", " *x++ = 0;", " x -= j;", @@ -849,11 +1015,12 @@ 0, }; -static char *R12[] = { +static const char *R12[] = { "\t\tcase %d: r = ((Q%d *)z)->contents[slot].fld%d; break;", 0, }; -char *R13[] = { + +const char *R13_[] = { "int ", "unsend(int into)", "{ int _m=0, j; uchar *z;\n", @@ -882,7 +1049,7 @@ " switch (((Q0 *)qptr(into))->_t) {", 0, }; -char *R14[] = { +const char *R14_[] = { " default: Uerror(\"bad queue - unsend\");", " }", " return _m;", @@ -912,17 +1079,17 @@ " switch (((Q0 *)qptr(from))->_t) {", 0, }; -char *R15[] = { +const char *R15_[] = { " default: Uerror(\"bad queue - qrecv\");", " }", "}", 0, }; -static char *Proto[] = { +static const char *Proto[] = { "", "/** function prototypes **/", - "char *emalloc(unsigned long);", - "char *Malloc(unsigned long);", + "char *emalloc(ulong);", + "char *Malloc(ulong);", "int Boundcheck(int, int, int, int, Trans *);", "int addqueue(int, int, int);", "/* int atoi(char *); */", @@ -936,10 +1103,9 @@ #endif "int delproc(int, int);", "int endstate(void);", - "int hstore(char *, int);", -"#ifdef MA", - "int gstore(char *, int, uchar);", -"#endif", + "int find_claim(char *);", + "int h_store(char *, int);", + "int pan_rand(void);", "int q_cond(short, Trans *);", "int q_full(int);", "int q_len(int);", @@ -947,24 +1113,33 @@ "int qrecv(int, int, int, int);", "int unsend(int);", "/* void *sbrk(int); */", - "void Uerror(char *);", "void spin_assert(int, char *, int, int, Trans *);", + "#ifdef BFS_PAR", + "void bfs_printf(const char *, ...);", + "volatile uchar *sh_pre_malloc(ulong);", + "#endif", "void c_chandump(int);", "void c_globals(void);", "void c_locals(int, int);", "void checkcycles(void);", "void crack(int, int, Trans *, short *);", - "void d_sfh(const char *, int);", - "void sfh(const char *, int);", + "void d_sfh(uchar *, int);", "void d_hash(uchar *, int);", + "void m_hash(uchar *, int);", "void s_hash(uchar *, int);", - "void r_hash(uchar *, int);", "void delq(int);", "void dot_crack(int, int, Trans *);", "void do_reach(void);", "void pan_exit(int);", "void exit(int);", - "void hinit(void);", + "#ifdef BFS_PAR", + " void bfs_setup_mem(void);", + "#endif", + "#ifdef BITSTATE", + " void sinit(void);", + "#else", + " void hinit(void);", + "#endif", "void imed(Trans *, int, int, int);", "void new_state(void);", "void p_restor(int);", @@ -972,16 +1147,19 @@ "void putrail(void);", "void q_restor(void);", "void retrans(int, int, int, short *, uchar *, uchar *);", + "void select_claim(int);", "void settable(void);", "void setq_claim(int, int, char *, int, char *);", "void sv_restor(void);", "void sv_save(void);", "void tagtable(int, int, int, short *, uchar *);", "void do_dfs(int, int, int, short *, uchar *, uchar *);", - "void uerror(char *);", "void unrecv(int, int, int, int, int);", "void usage(FILE *);", - "void wrap_stats(void);", + "void wrap_stats(void);\n", + "#ifdef MA", + " int g_store(char *, int, uchar);", + "#endif", "#if defined(FULLSTACK) && defined(BITSTATE)", " int onstack_now(void);", " void onstack_init(void);", @@ -991,27 +1169,270 @@ "#ifndef XUSAFE", " int q_S_check(int, int);", " int q_R_check(int, int);", - " uchar q_claim[MAXQ+1];", - " char *q_name[MAXQ+1];", - " char *p_name[MAXPROC+1];", + " extern uchar q_claim[MAXQ+1];", + " extern char *q_name[MAXQ+1];", + " extern char *p_name[MAXPROC+1];", + "#endif", + "", + "#ifndef NO_V_PROVISO", + " #define V_PROVISO", + "#endif", + "#if !defined(NO_RESIZE) && !defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(SPACE) && !defined(USE_TDH) && NCORE==1", + " #define AUTO_RESIZE", + "#endif", + "", + "typedef struct Trail Trail;", + "typedef struct H_el H_el;", + "", + "struct H_el {", + " H_el *nxt;", + " #ifdef FULLSTACK", + " unsigned int tagged;", + " #if defined(BITSTATE) && !defined(NOREDUCE) && !defined(SAFETY)", + " unsigned int proviso;", /* uses just 1 bit 0/1 */ + " #endif", + " #endif", + " #if defined(CHECK) || (defined(COLLAPSE) && !defined(FULLSTACK))", + " ulong st_id;", + " #endif", + " #if !defined(SAFETY) || defined(REACH)", + " uint D;", + " #endif", + " #ifdef BCS", + " #ifndef CONSERVATIVE", + " #define CONSERVATIVE 1 /* good for up to 8 processes */", + " #endif", + " #ifdef CONSERVATIVE", + " #if CONSERVATIVE <= 0 || CONSERVATIVE>32", + " #error sensible values for CONSERVATIVE are 1..32 (256/8 = 32)", + " #endif", + " uchar ctx_pid[CONSERVATIVE];", /* pids setting lowest value */ + " #endif", + " uchar ctx_low;", /* lowest nr of context switches seen so far */ + " #endif", + " #if NCORE>1", + " /* could cost 1 extra word: 4 bytes if 32-bit and 8 bytes if 64-bit */", + " #ifdef V_PROVISO", + " uchar cpu_id; /* id of cpu that created the state */", + " #endif", + " #endif", + " #ifdef COLLAPSE", + " #if VECTORSZ<65536", + " ushort ln;", /* length of vector */ + " #else", + " ulong ln;", /* length of vector */ + " #endif", + " #endif", + " #if defined(AUTO_RESIZE) && !defined(BITSTATE)", + " ulong m_K1;", + " #endif", + " ulong state;", + "};", + "", + "#ifdef BFS_PAR", + "typedef struct BFS_Trail BFS_Trail;", + "struct BFS_Trail {", + " H_el *ostate;", + " int st;", + " int o_tt;", + " T_ID t_id;", /* could be uint, ushort, or uchar */ + " uchar pr;", + " uchar o_pm;", + " uchar tau;", + "};", + " #if SYNC>0", + " #undef BFS_NOTRAIL", /* just in case it was used */ + " #endif", + "#endif", + "", + "#ifdef RHASH", + " #ifndef PERMUTED", + " #define PERMUTED", + " #endif", + "#endif", + "", + "struct Trail {", + " int st; /* current state */", + " int o_tt;", + "#ifdef PERMUTED", + " uint seed;", + " uchar oII;", + "#endif", + " uchar pr; /* process id */", + " uchar tau; /* 8 bit-flags */", + " uchar o_pm; /* 8 more bit-flags */", + "", + " #if 0", + " Meaning of bit-flags on tau and o_pm:", + " tau&1 -> timeout enabled", + " tau&2 -> request to enable timeout 1 level up (in claim)", + " tau&4 -> current transition is a claim move", + " tau&8 -> current transition is an atomic move", + " tau&16 -> last move was truncated on stack", + " tau&32 -> current transition is a preselected move", + " tau&64 -> at least one next state is not on the stack", + " tau&128 -> current transition is a stutter move", + + " o_pm&1 -> the current pid moved -- implements else", + " o_pm&2 -> this is an acceptance state", + " o_pm&4 -> this is a progress state", + " o_pm&8 -> fairness alg rule 1 undo mark", + " o_pm&16 -> fairness alg rule 3 undo mark", + " o_pm&32 -> fairness alg rule 2 undo mark", + " o_pm&64 -> the current proc applied rule2", + " o_pm&128 -> a fairness, dummy move - all procs blocked", + " #endif", + "", + " #ifdef NSUCC", + " uchar n_succ; /* nr of successor states */", + " #endif", + " #if defined(FULLSTACK) && defined(MA) && !defined(BFS)", + " uchar proviso;", + " #endif", + " #ifndef BFS", + " uchar o_n, o_ot; /* to save locals */", + " #endif", + " uchar o_m;", + " #ifdef EVENT_TRACE", + " #if nstates_event<256", + " uchar o_event;", + " #else", + " unsigned short o_event;", + " #endif", + " #endif", + " #ifndef BFS", + " short o_To;", + " #if defined(T_RAND) || defined(RANDOMIZE)", + " short oo_i;", + " #endif", + " #endif", + " #if defined(HAS_UNLESS) && !defined(BFS)", + " int e_state; /* if escape trans - state of origin */", + " #endif", + " #if (defined(FULLSTACK) && !defined(MA)) || defined(BFS) || (NCORE>1)", + " H_el *ostate; /* pointer to stored state */", + " #endif", + /* CNTRSTACK when !NOREDUCE && BITSTATE && SAFETY && WS<=4, uses LL[] */ + " #if defined(CNTRSTACK) && !defined(BFS)", + " long j6, j7;", + " #endif", + " Trans *o_t;", /* transition fct, next state */ + + " #if !defined(BFS) && !defined(TRIX_ORIG)", + " char *p_bup;", + " char *q_bup;", + " #endif", + + " #ifdef BCS", + " unsigned short sched_limit;", + " unsigned char bcs; /* phase 1 or 2, or forced 4 */", + " unsigned char b_pno; /* preferred pid */", + " #endif", + + " #ifdef P_RAND", /* process scheduling randomization */ + " unsigned char p_left; /* nr of procs left to explore */", + " short p_skip; /* to find starting point in list */", + " #endif", + + " #ifdef HAS_SORTED", + " short ipt;", /* insertion slot in q */ + " #endif", + " #ifdef HAS_PRIORITY", + " short o_priority;", + " #endif", + " union {", + " int oval;", /* single backup value of variable */ + " int *ovals;", /* ptr to multiple values */ + " } bup;", + "}; /* end of struct Trail */", + "", + "#ifdef BFS", /* breadth-first search */ + " #define Q_PROVISO", + " #ifndef INLINE_REV", + " #define INLINE_REV", + " #endif", + "", + "typedef struct SV_Hold {", + " State *sv;", + " #ifndef BFS_PAR", + " int sz;", + " #endif", + " struct SV_Hold *nxt;", + "} SV_Hold;", + "#if !defined(BFS_PAR) || NRUNS>0", + " typedef struct EV_Hold {", + " #if !defined(BFS_PAR) || (!defined(NOCOMP) && !defined(HC) && NRUNS>0)", + " char *sv; /* Mask */", + " #endif", + " #if VECTORSZ<65536", + " ushort sz; /* vsize */", + " #else", + " ulong sz;", + " #endif", + " #ifdef BFS_PAR", + " uchar owner;", + " #endif", + " uchar nrpr;", + " uchar nrqs;", + " #if !defined(BFS_PAR) || (!defined(TRIX) && NRUNS>0)", + " char *po, *qo;", + " char *ps, *qs;", + " #endif", + " struct EV_Hold *nxt;", + " } EV_Hold;", "#endif", + "typedef struct BFS_State {", + " #ifdef BFS_PAR", + " BFS_Trail *t_info;", + " State *osv;", + " #else", + " Trail *frame;", + " SV_Hold *onow;", + " #endif", + " #if !defined(BFS_PAR) || NRUNS>0", + " EV_Hold *omask;", + " #endif", + " #if defined(Q_PROVISO) && !defined(NOREDUCE)", + " H_el *lstate;", + " #endif", + " #if !defined(BFS_PAR) || SYNC>0", + " short boq;", + " #endif", + " #ifdef VERBOSE", + " ulong nr;", + " #endif", + " #ifndef BFS_PAR", /* new 6.2.4, 3 dec 2012 */ + " struct BFS_State *nxt;", + " #endif", + "} BFS_State;", + "#endif\n", 0, }; -static char *SvMap[] = { +static const char *SvMap[] = { "void", "to_compile(void)", - "{ char ctd[1024], carg[64];", + "{ char ctd[2048], carg[128];", "#ifdef BITSTATE", " strcpy(ctd, \"-DBITSTATE \");", "#else", " strcpy(ctd, \"\");", "#endif", + "#ifdef BFS_PAR", + " strcat(ctd, \"-DBFS_PAR \");", + "#endif", "#ifdef NOVSZ", " strcat(ctd, \"-DNOVSZ \");", "#endif", - "#ifdef REVERSE", - " strcat(ctd, \"-DREVERSE \");", + "#ifdef RHASH", + " strcat(ctd, \"-DRHASH \");", + "#else", + " #ifdef PERMUTED", + " strcat(ctd, \"-DPERMUTED \");", + " #endif", + "#endif", + "#ifdef P_REVERSE", + " strcat(ctd, \"-DP_REVERSE \");", "#endif", "#ifdef T_REVERSE", " strcat(ctd, \"-DT_REVERSE \");", @@ -1081,20 +1502,8 @@ "#ifdef VAR_RANGES", " strcat(ctd, \"-DVAR_RANGES \");", "#endif", - "#ifdef HC0", - " strcat(ctd, \"-DHC0 \");", - "#endif", - "#ifdef HC1", - " strcat(ctd, \"-DHC1 \");", - "#endif", - "#ifdef HC2", - " strcat(ctd, \"-DHC2 \");", - "#endif", - "#ifdef HC3", - " strcat(ctd, \"-DHC3 \");", - "#endif", - "#ifdef HC4", - " strcat(ctd, \"-DHC4 \");", + "#ifdef HC", + " strcat(ctd, \"-DHC \");", "#endif", "#ifdef CHECK", " strcat(ctd, \"-DCHECK \");", @@ -1120,9 +1529,6 @@ "#ifdef PRINTF", " strcat(ctd, \"-DPRINTF \");", "#endif", - "#ifdef OTIM", - " strcat(ctd, \"-DOTIM \");", - "#endif", "#ifdef COLLAPSE", " strcat(ctd, \"-DCOLLAPSE \");", "#endif", @@ -1150,10 +1556,6 @@ "#endif", "#if NCORE>1", " sprintf(carg, \"-DNCORE=%%d \", NCORE);", - " strcat(ctd, carg);", - "#endif", - "#ifdef SFH", - " sprintf(carg, \"-DSFH \");", " strcat(ctd, carg);", "#endif", "#ifdef VMAX", diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen4.c /sys/src/cmd/spin/pangen4.c --- /n/sources/plan9/sys/src/cmd/spin/pangen4.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen4.c Mon Feb 22 00:00:00 2021 @@ -1,23 +1,20 @@ /***** spin: pangen4.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" -extern FILE *tc, *tb; +extern FILE *fd_tc, *fd_tb; extern Queue *qtab; extern Symbol *Fname; -extern int lineno, m_loss, Pid, eventmapnr, multi_oval; +extern int lineno, m_loss, Pid_nr, eventmapnr, multi_oval; extern short nocast, has_provided, has_sorted; -extern char *R13[], *R14[], *R15[]; +extern const char *R13_[], *R14_[], *R15_[]; static void check_proc(Lextok *, int); @@ -27,7 +24,7 @@ int i, j; if (!now) - { fprintf(tb, "0"); + { fprintf(fd_tb, "0"); return; } lineno = now->ln; @@ -44,25 +41,25 @@ case FULL: case EMPTY: case 'R': case NFULL: case NEMPTY: case ENABLED: case '?': case PC_VAL: case '^': - case C_EXPR: + case C_EXPR: case GET_P: case NONPROGRESS: - putstmnt(tb, now, m); + putstmnt(fd_tb, now, m); break; case RUN: - fprintf(tb, "delproc(0, now._nr_pr-1)"); + fprintf(fd_tb, "delproc(0, now._nr_pr-1)"); break; case 's': - if (Pid == eventmapnr) break; + if (Pid_nr == eventmapnr) break; if (m_loss) - fprintf(tb, "if (_m == 2) "); - putname(tb, "_m = unsend(", now->lft, m, ")"); + fprintf(fd_tb, "if (_m == 2) "); + putname(fd_tb, "_m = unsend(", now->lft, m, ")"); break; case 'r': - if (Pid == eventmapnr) break; + if (Pid_nr == eventmapnr) break; for (v = now->rgt, i=j=0; v; v = v->rgt, i++) if (v->lft->ntyp != CONST @@ -80,14 +77,14 @@ if (now->val == 1) { ii++; jj = multi_oval - ii - 1; - fprintf(tb, "XX = trpt->bup.oval"); + fprintf(fd_tb, "XX = trpt->bup.oval"); if (multi_oval > 0) - { fprintf(tb, "s[%d]", jj); + { fprintf(fd_tb, "s[%d]", jj); jj++; } - fprintf(tb, ";\n\t\t"); + fprintf(fd_tb, ";\n\t\t"); } else - { fprintf(tb, "XX = 1;\n\t\t"); + { fprintf(fd_tb, "XX = 1;\n\t\t"); jj = multi_oval - ii - 1; } @@ -96,28 +93,33 @@ { switch(v->lft->ntyp) { case CONST: case EVAL: - fprintf(tb, "unrecv"); - putname(tb, "(", now->lft, m, ", XX-1, "); - fprintf(tb, "%d, ", i); + fprintf(fd_tb, "unrecv"); + putname(fd_tb, "(", now->lft, m, ", XX-1, "); + fprintf(fd_tb, "%d, ", i); if (v->lft->ntyp == EVAL) - undostmnt(v->lft->lft, m); - else - undostmnt(v->lft, m); - fprintf(tb, ", %d);\n\t\t", (i==0)?1:0); + { if (v->lft->lft->ntyp == ',') + { undostmnt(v->lft->lft->lft, m); + } else + { undostmnt(v->lft->lft, m); + } + } else + { undostmnt(v->lft, m); + } + fprintf(fd_tb, ", %d);\n\t\t", (i==0)?1:0); break; default: - fprintf(tb, "unrecv"); - putname(tb, "(", now->lft, m, ", XX-1, "); - fprintf(tb, "%d, ", i); + fprintf(fd_tb, "unrecv"); + putname(fd_tb, "(", now->lft, m, ", XX-1, "); + fprintf(fd_tb, "%d, ", i); if (v->lft->sym && !strcmp(v->lft->sym->name, "_")) - { fprintf(tb, "trpt->bup.oval"); + { fprintf(fd_tb, "trpt->bup.oval"); if (multi_oval > 0) - fprintf(tb, "s[%d]", jj); + fprintf(fd_tb, "s[%d]", jj); } else - putstmnt(tb, v->lft, m); + putstmnt(fd_tb, v->lft, m); - fprintf(tb, ", %d);\n\t\t", (i==0)?1:0); + fprintf(fd_tb, ", %d);\n\t\t", (i==0)?1:0); if (multi_oval > 0) jj++; break; @@ -135,11 +137,11 @@ default: if (!v->lft->sym || strcmp(v->lft->sym->name, "_") != 0) - { nocast=1; putstmnt(tb,v->lft,m); - nocast=0; fprintf(tb, " = trpt->bup.oval"); + { nocast=1; putstmnt(fd_tb, v->lft, m); + nocast=0; fprintf(fd_tb, " = trpt->bup.oval"); if (multi_oval > 0) - fprintf(tb, "s[%d]", jj); - fprintf(tb, ";\n\t\t"); + fprintf(fd_tb, "s[%d]", jj); + fprintf(fd_tb, ";\n\t\t"); } if (multi_oval > 0) jj++; @@ -150,15 +152,22 @@ break; case '@': - fprintf(tb, "p_restor(II);\n\t\t"); + fprintf(fd_tb, "p_restor(II);\n\t\t"); + break; + + case SET_P: + fprintf(fd_tb, "((P0 *)pptr((trpt->o_priority >> 8)))"); + fprintf(fd_tb, "->_priority = trpt->o_priority & 255"); break; case ASGN: - nocast=1; putstmnt(tb,now->lft,m); - nocast=0; fprintf(tb, " = trpt->bup.oval"); + if (check_track(now) == STRUCT) { break; } + + nocast=1; putstmnt(fd_tb, now->lft, m); + nocast=0; fprintf(fd_tb, " = trpt->bup.oval"); if (multi_oval > 0) { multi_oval--; - fprintf(tb, "s[%d]", multi_oval-1); + fprintf(fd_tb, "s[%d]", multi_oval-1); } check_proc(now->rgt, m); break; @@ -174,7 +183,7 @@ break; case C_CODE: - fprintf(tb, "sv_restor();\n"); + fprintf(fd_tb, "sv_restor();\n"); break; case ASSERT: @@ -184,6 +193,11 @@ case PRINTM: break; + case ',': + if (now->lft) /* eval usertype5 */ + { undostmnt(now->lft, m); + break; + } /* else fall thru */ default: printf("spin: bad node type %d (.b)\n", now->ntyp); alldone(1); @@ -223,7 +237,7 @@ if (!now) return; if (now->ntyp == '@' || now->ntyp == RUN) - { fprintf(tb, ";\n\t\t"); + { fprintf(fd_tb, ";\n\t\t"); undostmnt(now, m); } check_proc(now->lft, m); @@ -235,76 +249,76 @@ { char buf1[256]; Queue *q; int i; - ntimes(tc, 0, 1, R13); + ntimes(fd_tc, 0, 1, R13_); for (q = qtab; q; q = q->nxt) - { fprintf(tc, "\tcase %d:\n", q->qid); + { fprintf(fd_tc, "\tcase %d:\n", q->qid); if (has_sorted) { sprintf(buf1, "((Q%d *)z)->contents", q->qid); - fprintf(tc, "#ifdef HAS_SORTED\n"); - fprintf(tc, "\t\tj = trpt->ipt;\n"); /* ipt was bup.oval */ - fprintf(tc, "#endif\n"); - fprintf(tc, "\t\tfor (k = j; k < ((Q%d *)z)->Qlen; k++)\n", + fprintf(fd_tc, "#ifdef HAS_SORTED\n"); + fprintf(fd_tc, "\t\tj = trpt->ipt;\n"); /* ipt was bup.oval */ + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\t\tfor (k = j; k < ((Q%d *)z)->Qlen; k++)\n", q->qid); - fprintf(tc, "\t\t{\n"); + fprintf(fd_tc, "\t\t{\n"); for (i = 0; i < q->nflds; i++) - fprintf(tc, "\t\t\t%s[k].fld%d = %s[k+1].fld%d;\n", + fprintf(fd_tc, "\t\t\t%s[k].fld%d = %s[k+1].fld%d;\n", buf1, i, buf1, i); - fprintf(tc, "\t\t}\n"); - fprintf(tc, "\t\tj = ((Q0 *)z)->Qlen;\n"); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tj = ((Q0 *)z)->Qlen;\n"); } sprintf(buf1, "((Q%d *)z)->contents[j].fld", q->qid); for (i = 0; i < q->nflds; i++) - fprintf(tc, "\t\t%s%d = 0;\n", buf1, i); + fprintf(fd_tc, "\t\t%s%d = 0;\n", buf1, i); if (q->nslots==0) { /* check if rendezvous succeeded, 1 level down */ - fprintf(tc, "\t\t_m = (trpt+1)->o_m;\n"); - fprintf(tc, "\t\tif (_m) (trpt-1)->o_pm |= 1;\n"); - fprintf(tc, "\t\tUnBlock;\n"); + fprintf(fd_tc, "\t\t_m = (trpt+1)->o_m;\n"); + fprintf(fd_tc, "\t\tif (_m) (trpt-1)->o_pm |= 1;\n"); + fprintf(fd_tc, "\t\tUnBlock;\n"); } else - fprintf(tc, "\t\t_m = trpt->o_m;\n"); + fprintf(fd_tc, "\t\t_m = trpt->o_m;\n"); - fprintf(tc, "\t\tbreak;\n"); + fprintf(fd_tc, "\t\tbreak;\n"); } - ntimes(tc, 0, 1, R14); + ntimes(fd_tc, 0, 1, R14_); for (q = qtab; q; q = q->nxt) { sprintf(buf1, "((Q%d *)z)->contents", q->qid); - fprintf(tc, " case %d:\n", q->qid); + fprintf(fd_tc, " case %d:\n", q->qid); if (q->nslots == 0) - fprintf(tc, "\t\tif (strt) boq = from+1;\n"); + fprintf(fd_tc, "\t\tif (strt) boq = from+1;\n"); else if (q->nslots > 1) /* shift */ - { fprintf(tc, "\t\tif (strt && slot<%d)\n", + { fprintf(fd_tc, "\t\tif (strt && slot<%d)\n", q->nslots-1); - fprintf(tc, "\t\t{\tfor (j--; j>=slot; j--)\n"); - fprintf(tc, "\t\t\t{"); + fprintf(fd_tc, "\t\t{\tfor (j--; j>=slot; j--)\n"); + fprintf(fd_tc, "\t\t\t{"); for (i = 0; i < q->nflds; i++) - { fprintf(tc, "\t%s[j+1].fld%d =\n\t\t\t", + { fprintf(fd_tc, "\t%s[j+1].fld%d =\n\t\t\t", buf1, i); - fprintf(tc, "\t%s[j].fld%d;\n\t\t\t", + fprintf(fd_tc, "\t%s[j].fld%d;\n\t\t\t", buf1, i); } - fprintf(tc, "}\n\t\t}\n"); + fprintf(fd_tc, "}\n\t\t}\n"); } strcat(buf1, "[slot].fld"); - fprintf(tc, "\t\tif (strt) {\n"); + fprintf(fd_tc, "\t\tif (strt) {\n"); for (i = 0; i < q->nflds; i++) - fprintf(tc, "\t\t\t%s%d = 0;\n", buf1, i); - fprintf(tc, "\t\t}\n"); + fprintf(fd_tc, "\t\t\t%s%d = 0;\n", buf1, i); + fprintf(fd_tc, "\t\t}\n"); if (q->nflds == 1) /* set */ - fprintf(tc, "\t\tif (fld == 0) %s0 = fldvar;\n", + fprintf(fd_tc, "\t\tif (fld == 0) %s0 = fldvar;\n", buf1); else - { fprintf(tc, "\t\tswitch (fld) {\n"); + { fprintf(fd_tc, "\t\tswitch (fld) {\n"); for (i = 0; i < q->nflds; i++) - { fprintf(tc, "\t\tcase %d:\t%s", i, buf1); - fprintf(tc, "%d = fldvar; break;\n", i); + { fprintf(fd_tc, "\t\tcase %d:\t%s", i, buf1); + fprintf(fd_tc, "%d = fldvar; break;\n", i); } - fprintf(tc, "\t\t}\n"); + fprintf(fd_tc, "\t\t}\n"); } - fprintf(tc, "\t\tbreak;\n"); + fprintf(fd_tc, "\t\tbreak;\n"); } - ntimes(tc, 0, 1, R15); + ntimes(fd_tc, 0, 1, R15_); } extern void explain(int); @@ -319,7 +333,8 @@ case LEN: case 'R': case NAME: has_provided = 1; - if (strcmp(n->sym->name, "_pid") == 0) + if (strcmp(n->sym->name, "_pid") == 0 + || strcmp(n->sym->name, "_priority") == 0) return 1; return (!(n->sym->context)); @@ -330,6 +345,7 @@ return 1; case ENABLED: case PC_VAL: + case GET_P: /* not SET_P */ return proper_enabler(n->lft); case '!': case UMIN: case '~': @@ -339,8 +355,9 @@ case '%': case LT: case GT: case '&': case '^': case '|': case LE: case GE: case NE: case '?': case EQ: case OR: case AND: case LSHIFT: - case RSHIFT: case 'c': + case RSHIFT: case 'c': /* case ',': */ return proper_enabler(n->lft) && proper_enabler(n->rgt); + default: break; } diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen4.h /sys/src/cmd/spin/pangen4.h --- /n/sources/plan9/sys/src/cmd/spin/pangen4.h Tue Aug 7 22:31:57 2007 +++ /sys/src/cmd/spin/pangen4.h Mon Feb 22 00:00:00 2021 @@ -1,24 +1,21 @@ /***** spin: pangen4.h *****/ -/* Copyright (c) 1997-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * The DFA code below was written by Anuj Puri and Gerard J. Holzmann in + * May 1997, and was inspired by earlier work on data compression using + * sharing tree data structures and graph-encoded sets by J-Ch. Gregoire + * (INRS Telecom, Quebec, Canada) and D.Zampunieris (Univ.Namur, Belgium) + * The splay routine code included here is based on the public domain + * version written by D. Sleator in 1992. + */ -/* The DFA code below was written by Anuj Puri and Gerard J. Holzmann in */ -/* May 1997, and was inspired by earlier work on data compression using */ -/* sharing tree data structures and graph-encoded sets by J-Ch. Gregoire */ -/* (INRS Telecom, Quebec, Canada) and D.Zampunieris (Univ.Namur, Belgium) */ - -/* The splay routine code included here is based on the public domain */ -/* version written by D. Sleator in 1992. */ - -static char *Dfa[] = { +static const char *Dfa[] = { "#ifdef MA", +#if 0 "/*", "#include ", "#define uchar unsigned char", @@ -26,6 +23,7 @@ "#define ulong unsigned long", "#define ushort unsigned short", "", +#endif "#define TWIDTH 256", "#define HASH(y,n) (n)*(((long)y))", "#define INRANGE(e,h) ((h>=e->From && h<=e->To)||(e->s==1 && e->S==h))", @@ -466,7 +464,7 @@ " for (j = 0; j < TWIDTH; j++)", " for (i = 0; i < dfa_depth+1; i++)", " cnt += tree_stats(layers[i*TWIDTH+j]);", - " printf(\"Minimized Automaton:\t%%6d nodes and %%6g edges\\n\",", + " printf(\"Minimized Automaton:\t%%6lu nodes and %%6g edges\\n\",", " nr_states, cnt);", "}", "", diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen5.c /sys/src/cmd/spin/pangen5.c --- /n/sources/plan9/sys/src/cmd/spin/pangen5.c Mon Dec 12 01:03:05 2011 +++ /sys/src/cmd/spin/pangen5.c Mon Feb 22 00:00:00 2021 @@ -1,13 +1,10 @@ /***** spin: pangen5.c *****/ -/* Copyright (c) 1999-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" @@ -17,7 +14,7 @@ struct BuildStack *nxt; } BuildStack; -extern ProcList *rdy; +extern ProcList *ready; extern int verbose, eventmapnr, claimnr, rvopt, export_ast, u_sync; extern Element *Al_El; @@ -27,7 +24,7 @@ static int max_st_id; static int cur_st_id; int o_max; -FSM_state *fsm; +FSM_state *fsmx; FSM_state **fsm_tbl; FSM_use *use_free; @@ -52,7 +49,7 @@ cur_st_id = max_st_id; max_st_id = 0; - for (f = fsm; f; f = f->nxt) + for (f = fsmx; f; f = f->nxt) fsm_tbl[f->from] = f; } @@ -140,6 +137,7 @@ || lt->ntyp == C_CODE || lt->ntyp == C_EXPR || has_lab(el, 0) /* any label at all */ + || lt->ntyp == SET_P /* to prevent multiple set_p merges */ || lt->ntyp == DO || lt->ntyp == UNLESS @@ -265,7 +263,7 @@ FSM_trans *t; Lextok *lt; - for (f = fsm; f; f = f->nxt) /* all states */ + for (f = fsmx; f; f = f->nxt) /* all states */ for (t = f->t; t; t = t->nxt) /* all edges */ { if (!t->step) continue; /* happens with 'unless' */ @@ -316,7 +314,7 @@ /* 2nd scan -- find possible merge_starts */ - for (f = fsm; f; f = f->nxt) /* all states */ + for (f = fsmx; f; f = f->nxt) /* all states */ for (t = f->t; t; t = t->nxt) /* all edges */ { if (!t->step || t->step->merge) continue; @@ -324,14 +322,17 @@ lt = t->step->n; #if 0 4.1.3: - an rv send operation inside an atomic, *loses* atomicity - when executed - and should therefore never be merged with a subsequent + an rv send operation ('s') inside an atomic, *loses* atomicity + when executed, and should therefore never be merged with a subsequent statement within the atomic sequence - the same is not true for non-rv send operations + the same is not true for non-rv send operations; + 6.2.2: + RUN statements can start a new process at a higher priority level + which interferes with statement merging, so it too is not a suitable + merge target #endif - if (lt->ntyp == 'c' /* potentially blocking stmnts */ + if ((lt->ntyp == 'c' && !any_oper(lt->lft, RUN)) /* 2nd clause 6.2.2 */ || lt->ntyp == 'r' || (lt->ntyp == 's' && u_sync == 0)) /* added !u_sync in 4.1.3 */ { if (!canfill_in(t)) /* atomic, non-global, etc. */ @@ -367,7 +368,7 @@ FSM_use *u, *v, *w; int n; - for (f = fsm; f; f = f->nxt) /* all states */ + for (f = fsmx; f; f = f->nxt) /* all states */ for (t = f->t; t; t = t->nxt) /* all edges */ for (n = 0; n < 2; n++) /* reads and writes */ for (u = t->Val[n]; u; u = u->nxt) @@ -381,7 +382,7 @@ } if (!export_ast) - for (f = fsm; f; f = f->nxt) + for (f = fsmx; f; f = f->nxt) for (t = f->t; t; t = t->nxt) for (n = 0; n < 2; n++) for (u = t->Val[n], w = (FSM_use *) 0; u; ) @@ -451,8 +452,8 @@ static void FSM_DEL(void) { - rel_state(fsm); - fsm = (FSM_state *) 0; + rel_state(fsmx); + fsmx = (FSM_state *) 0; } static FSM_state * @@ -460,7 +461,7 @@ { FSM_state *f; /* fsm_tbl isn't allocated yet */ - for (f = fsm; f; f = f->nxt) + for (f = fsmx; f; f = f->nxt) if (f->from == s) break; if (!f) @@ -472,8 +473,8 @@ f = (FSM_state *) emalloc(sizeof(FSM_state)); f->from = s; f->t = (FSM_trans *) 0; - f->nxt = fsm; - fsm = f; + f->nxt = fsmx; + fsmx = f; if (s > max_st_id) max_st_id = s; } @@ -518,7 +519,8 @@ } if (t->step) - ana_stmnt(t, t->step->n, 0); + { ana_stmnt(t, t->step->n, 0); + } } #define LVAL 1 @@ -534,6 +536,7 @@ if (now->sym->name[0] == '_' && (strcmp(now->sym->name, "_") == 0 || strcmp(now->sym->name, "_pid") == 0 + || strcmp(now->sym->name, "_priority") == 0 || strcmp(now->sym->name, "_last") == 0)) return; @@ -590,10 +593,17 @@ case C_EXPR: break; + case ',': /* reached with SET_P and array initializers */ + if (now->lft && now->lft->rgt) + { ana_stmnt(t, now->lft->rgt, RVAL); + } + break; + case '!': case UMIN: case '~': case ENABLED: + case GET_P: case PC_VAL: case LEN: case FULL: @@ -605,6 +615,11 @@ ana_stmnt(t, now->lft, RVAL); break; + case SET_P: + ana_stmnt(t, now->lft, RVAL); /* ',' */ + ana_stmnt(t, now->lft->rgt, RVAL); + break; + case '/': case '*': case '-': @@ -628,8 +643,11 @@ break; case ASGN: + if (check_track(now) == STRUCT) { break; } + ana_stmnt(t, now->lft, LVAL); - ana_stmnt(t, now->rgt, RVAL); + if (now->rgt->ntyp) + ana_stmnt(t, now->rgt, RVAL); break; case PRINT: @@ -654,12 +672,16 @@ ana_stmnt(t, now->lft, RVAL); for (v = now->rgt; v; v = v->rgt) { if (v->lft->ntyp == EVAL) - ana_stmnt(t, v->lft->lft, RVAL); - else - if (v->lft->ntyp != CONST - && now->ntyp != 'R') /* was v->lft->ntyp */ - ana_stmnt(t, v->lft, LVAL); - } + { if (v->lft->lft->ntyp == ',') + { ana_stmnt(t, v->lft->lft->lft, RVAL); + } else + { ana_stmnt(t, v->lft->lft, RVAL); + } + } else + { if (v->lft->ntyp != CONST + && now->ntyp != 'R') /* was v->lft->ntyp */ + { ana_stmnt(t, v->lft, LVAL); + } } } break; case '?': @@ -681,9 +703,9 @@ break; default: - printf("spin: %s:%d, bad node type %d (ana_stmnt)\n", - now->fn->name, now->ln, now->ntyp); - fatal("aborting", (char *) 0); + if (0) printf("spin: %s:%d, bad node type %d usage %d (ana_stmnt)\n", + now->fn->name, now->ln, now->ntyp, usage); + fatal("aborting (ana_stmnt)", (char *) 0); } } @@ -694,7 +716,7 @@ #if 0 int counter = 1; #endif - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { ana_seq(p->s); fsm_table(); @@ -830,9 +852,15 @@ { if (e->n->ntyp == GOTO) { g = get_lab(e->n, 1); g = huntele(g, e->status, -1); + if (!g) + { fatal("unexpected error 2", (char *) 0); + } To = g->seqno; } else if (e->nxt) { g = huntele(e->nxt, e->status, -1); + if (!g) + { fatal("unexpected error 3", (char *) 0); + } To = g->seqno; } else To = 0; diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen5.h /sys/src/cmd/spin/pangen5.h --- /n/sources/plan9/sys/src/cmd/spin/pangen5.h Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/pangen5.h Mon Feb 22 00:00:00 2021 @@ -1,15 +1,12 @@ /***** spin: pangen5.h *****/ -/* Copyright (c) 1997-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ -static char *Xpt[] = { +static const char *Xpt[] = { "#if defined(MA) && (defined(W_XPT) || defined(R_XPT))", "static Vertex **temptree;", "static char wbuf[4096];", @@ -30,7 +27,7 @@ "}", "", "static void", - "wclose(fd)", + "wclose(int fd)", "{", " if (wcnt > 0)", " write(fd, wbuf, wcnt);", @@ -136,7 +133,7 @@ " stacker[dfa_depth-1] = 0; r = dfa_store(stacker);", " stacker[dfa_depth-1] = 4; j = dfa_member(dfa_depth-1);", " if (r != 1 || j != 0)", - " { printf(\"%%d: \", stackcnt);", + " { printf(\"%%lu: \", stackcnt);", " for (i = 0; i < dfa_depth; i++)", " printf(\"%%d,\", stacker[i]);", " printf(\" -- not a stackstate \\n\", r, j);", @@ -416,7 +413,7 @@ " x_cleanup(d);", " close(fd);", "", - " printf(\"pan: removed %%d stackstates\\n\", stackcnt);", + " printf(\"pan: removed %%lu stackstates\\n\", stackcnt);", " nstates -= (double) stackcnt;", "}", "#endif", diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen6.c /sys/src/cmd/spin/pangen6.c --- /n/sources/plan9/sys/src/cmd/spin/pangen6.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/pangen6.c Mon Feb 22 00:00:00 2021 @@ -1,20 +1,10 @@ /***** spin: pangen6.c *****/ -/* Copyright (c) 2000-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Abstract syntax tree analysis / slicing (spin option -A) */ -/* AST_store stores the fsms's for each proctype */ -/* AST_track keeps track of variables used in properties */ -/* AST_slice starts the slicing algorithm */ -/* it first collects more info and then calls */ -/* AST_criteria to process the slice criteria */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" @@ -22,7 +12,7 @@ extern Ordered *all_names; extern FSM_use *use_free; extern FSM_state **fsm_tbl; -extern FSM_state *fsm; +extern FSM_state *fsmx; extern int verbose, o_max; static FSM_trans *cur_t; @@ -201,11 +191,20 @@ case '~': case 'c': case ENABLED: + case SET_P: + case GET_P: case ASSERT: - case EVAL: def_use(now->lft, USE|code); break; + case EVAL: + if (now->lft->ntyp == ',') + { def_use(now->lft->lft, USE|code); + } else + { def_use(now->lft, USE|code); + } + break; + case LEN: case FULL: case EMPTY: @@ -265,18 +264,25 @@ def_use(now->lft, DEREF_DEF|DEREF_USE|USE|code); for (v = now->rgt; v; v = v->rgt) { if (v->lft->ntyp == EVAL) - def_use(v->lft, code); /* will add USE */ - else if (v->lft->ntyp != CONST) - def_use(v->lft, DEF|code); - } + { if (v->lft->ntyp == ',') + { def_use(v->lft->lft, code); /* will add USE */ + } else + { def_use(v->lft, code); /* will add USE */ + } + } else if (v->lft->ntyp != CONST) + { def_use(v->lft, DEF|code); + } } break; case 'R': def_use(now->lft, DEREF_USE|USE|code); for (v = now->rgt; v; v = v->rgt) { if (v->lft->ntyp == EVAL) - def_use(v->lft, code); /* will add USE */ - } + { if (v->lft->ntyp == ',') + { def_use(v->lft->lft, code); /* will add USE */ + } else + { def_use(v->lft, code); /* will add USE */ + } } } break; case '?': @@ -1011,7 +1017,8 @@ printf(" -- %d\n", code); #endif if (in_recv && (code&DEF) && (code&USE)) - { printf("spin: error: DEF and USE of same var in rcv stmnt: "); + { printf("spin: %s:%d, error: DEF and USE of same var in rcv stmnt: ", + n->fn->name, n->ln); AST_var(n, n->sym, 1); printf(" -- %d\n", code); nr_errs++; @@ -1060,18 +1067,24 @@ case '~': case 'c': case ENABLED: + case SET_P: + case GET_P: case ASSERT: AST_track(now->lft, USE|code); break; case EVAL: - AST_track(now->lft, USE|(code&(~DEF))); + if (now->lft->ntyp == ',') + { AST_track(now->lft->lft, USE|(code&(~DEF))); + } else + { AST_track(now->lft, USE|(code&(~DEF))); + } break; case NAME: name_AST_track(now, code); if (now->sym->nel > 1 || now->sym->isarray) - AST_track(now->lft, USE|code); /* index */ + AST_track(now->lft, USE); /* index, was USE|code */ break; case 'R': @@ -1728,11 +1741,11 @@ n_ast->p = p; n_ast->i_st = start_state; n_ast->relevant = 0; - n_ast->fsm = fsm; + n_ast->fsm = fsmx; n_ast->nxt = ast; ast = n_ast; } - fsm = (FSM_state *) 0; /* hide it from FSM_DEL */ + fsmx = (FSM_state *) 0; /* hide it from FSM_DEL */ } static void @@ -1983,7 +1996,7 @@ h = fsm_tbl[out]; i = f->from / BPW; - j = f->from % BPW; + j = f->from % BPW; /* assert(j <= 32); else lshift undefined? */ g = h->mod; if (verbose&32) @@ -2011,28 +2024,30 @@ d. the dominator is reachable, and not equal to this node #endif for (t = f->p, i = 0; t; t = t->nxt) - i += fsm_tbl[t->to]->seen; - if (i <= 1) continue; /* a. */ - + { i += fsm_tbl[t->to]->seen; + } + if (i <= 1) + { continue; /* a. */ + } for (cnt = 1; cnt < a->nstates; cnt++) /* 0 is endstate */ { if (cnt == f->from || !fsm_tbl[cnt]->seen) - continue; /* c. */ - + { continue; /* c. */ + } i = cnt / BPW; - j = cnt % BPW; + j = cnt % BPW; /* assert(j <= 32); */ if (!(f->dom[i]&(1<t, i = 0; t; t = t->nxt) - i += fsm_tbl[t->to]->seen; + { i += fsm_tbl[t->to]->seen; + } if (i <= 1) - continue; /* b. */ - + { continue; /* b. */ + } if (f->mod) /* final check in 2nd phase */ - subgraph(a, f, cnt); /* possible entry-exit pair */ - } - } + { subgraph(a, f, cnt); /* possible entry-exit pair */ + } } } } static void @@ -2166,27 +2181,26 @@ for (f = a->fsm; f; f = f->nxt) { if (!f->seen) continue; - f->dom = (ulong *) - emalloc(a->nwords * sizeof(ulong)); + f->dom = (ulong *) emalloc(a->nwords * sizeof(ulong)); if (f->from == a->i_st) { i = a->i_st / BPW; - j = a->i_st % BPW; + j = a->i_st % BPW; /* assert(j <= 32); */ f->dom[i] = (1<nwords; i++) - f->dom[i] = (ulong) ~0; /* all 1's */ - + { f->dom[i] = (ulong) ~0; /* all 1's */ + } if (a->nstates % BPW) for (i = (a->nstates % BPW); i < (int) BPW; i++) - f->dom[a->nwords-1] &= ~(1<dom[a->nwords-1] &= ~(1<< ((ulong) i)); /* clear tail */ + } for (cnt = 0; cnt < a->nstates; cnt++) - if (!fsm_tbl[cnt]->seen) + { if (!fsm_tbl[cnt]->seen) { i = cnt / BPW; - j = cnt % BPW; - f->dom[i] &= ~(1<dom[i] &= ~(1<< ((ulong) j)); + } } } } } static int @@ -2214,7 +2228,7 @@ } i = f->from / BPW; - j = f->from % BPW; + j = f->from % BPW; /* assert(j <= 32); */ ndom[i] |= (1<nwords; i++) diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen6.h /sys/src/cmd/spin/pangen6.h --- /n/sources/plan9/sys/src/cmd/spin/pangen6.h Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/pangen6.h Mon Feb 22 00:00:00 2021 @@ -1,20 +1,98 @@ /***** spin: pangen6.h *****/ -/* Copyright (c) 2006-2007 by the California Institute of Technology. */ -/* ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged */ -/* Supporting routines for a multi-core extension of the SPIN software */ -/* Developed as part of Reliable Software Engineering Project ESAS/6G */ -/* Like all SPIN Software this software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Any commercial use must be negotiated with the Office of Technology */ -/* Transfer at the California Institute of Technology. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Bug-reports and/or questions can be send to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ -static char *Code2c[] = { /* multi-core option - Spin 5.0 and later */ +static const char *Code2e[] = { + "#if (NCORE>1 || defined(BFS_PAR)) && !defined(WIN32) && !defined(WIN64)", + " /* Test and Set assembly code */", + " #if defined(i386) || defined(__i386__) || defined(__x86_64__)", + " int", + " tas(volatile int *s) /* tested */", + " { int r;", + " __asm__ __volatile__(", + " \"xchgl %%0, %%1 \\n\\t\"", + " : \"=r\"(r), \"=m\"(*s)", + " : \"0\"(1), \"m\"(*s)", + " : \"memory\");", + " ", + " return r;", + " }", + " #elif defined(__arm__)", + " int", + " tas(volatile int *s) /* not tested */", + " { int r = 1;", + " __asm__ __volatile__(", + " \"swpb %%0, %%0, [%%3] \\n\"", + " : \"=r\"(r), \"=m\"(*s)", + " : \"0\"(r), \"r\"(s));", + "", + " return r;", + " }", + " #elif defined(sparc) || defined(__sparc__)", + " int", + " tas(volatile int *s) /* not tested */", + " { int r = 1;", + " __asm__ __volatile__(", + " \" ldstub [%%2], %%0 \\n\"", + " : \"=r\"(r), \"=m\"(*s)", + " : \"r\"(s));", + "", + " return r;", + " }", + " #elif defined(ia64) || defined(__ia64__)", + " /* Intel Itanium */", + " int", + " tas(volatile int *s) /* tested */", + " { long int r;", + " __asm__ __volatile__(", + " \" xchg4 %%0=%%1,%%2 \\n\"", + " : \"=r\"(r), \"+m\"(*s)", + " : \"r\"(1)", + " : \"memory\");", + " return (int) r;", + " }", + " #elif defined(__powerpc64__)", + " int", + " tas(volatile int *s) /* courtesy srirajpaul */", + " { int r;", + " #if 1", + " r = __sync_lock_test_and_set();", + " #else", + " /* xlc compiler only */", + " r = __fetch_and_or(s, 1);", + " __isync();", + " #endif", + " return r;", + " }", + " #else", + " #error missing definition of test and set operation for this platform", + " #endif", + "", + " #ifndef NO_CAS", /* linux, windows */ + " #define cas(a,b,c) __sync_bool_compare_and_swap(a,b,c)", + " #else", + " int", /* workaround if the above is not available */ + " cas(volatile uint32_t *a, uint32_t b, uint32_t c)", + " { static volatile int cas_lock;", + " while (tas(&cas_lock) != 0) { ; }", + " if (*a == b)", + " { *a = c;", + " cas_lock = 0;", + " return 1;", + " }", + " cas_lock = 0;", + " return 0;", + " }", + " #endif", + "#endif", + 0, +}; + +static const char *Code2c[] = { /* multi-core option - Spin 5.0 and later */ "#if NCORE>1", "#if defined(WIN32) || defined(WIN64)", " #ifndef _CONSOLE", @@ -24,9 +102,11 @@ " #undef long", " #endif", " #include ", + "/*", " #ifdef WIN64", " #define long long long", " #endif", + "*/", "#else", " #include ", " #include ", @@ -66,7 +146,7 @@ "#endif", "", "#ifdef SET_SEG_SIZE", - " /* no longer usefule -- being recomputed for local heap size anyway */", + " /* no longer useful -- being recomputed for local heap size anyway */", " double SEG_SIZE = (((double) SET_SEG_SIZE) * 1048576.);", "#else", " double SEG_SIZE = (1048576.*1024.); /* 1GB default shared memory pool segments */", @@ -122,7 +202,9 @@ " volatile uchar m_o_pm;", " volatile int nr_handoffs; /* to compute real_depth */", " volatile char m_now [VMAX];", - " volatile char m_Mask [(VMAX + 7)/8];", + "#if !defined(NOCOMP) && !defined(HC)", + " volatile char m_mask [(VMAX + 7)/8];", + "#endif", " volatile OFFT m_p_offset[PMAX];", " volatile OFFT m_q_offset[QMAX];", " volatile uchar m_p_skip [PMAX];", @@ -137,7 +219,6 @@ "int store_proxy_pid;", "short remote_party;", "int proxy_pid_snd; /* id of proxy if nonzero -- send half */", - "char o_cmdline[512]; /* to pass options to children */", "", "int iamin[CS_NR+NCORE]; /* non-shared */", "", @@ -256,10 +337,6 @@ "void mem_put_acc(void); /* liveness mode */", "void mem_get(void); /* get state from work queue */", "void sudden_stop(char *);", - "#if 0", - "void enter_critical(int);", - "void leave_critical(int);", - "#endif", "", "void", "record_info(SM_results *r)", @@ -296,7 +373,7 @@ " r->m_svmax = svmax;", " r->m_smax = smax;", " r->m_mreached = mreached;", - " r->m_errors = errors;", + " r->m_errors = (int) errors;", " r->m_VMAX = vmax_seen;", " r->m_PMAX = (short) pmax_seen;", " r->m_QMAX = (short) qmax_seen;", @@ -348,7 +425,7 @@ " nlost += r->m_nlost;", " hcmp += r->m_hcmp;", " /* frame_wait += r->m_frame_wait; */", - " errors += r->m_errors;", + " errors += (unsigned long int) r->m_errors;", "", " if (hmax < r->m_hmax) hmax = r->m_hmax;", " if (svmax < r->m_svmax) svmax = r->m_svmax;", @@ -380,7 +457,7 @@ " volatile sh_Allocater *nxt_pool;", " /*", " * mark all shared memory segments for removal ", - " * the actual removes wont happen intil last process dies or detaches", + " * the actual removes won't happen intil last process dies or detaches", " * the shmctl calls can return -1 if not all procs have detached yet", " */", " for (m = 0; m < NR_QS; m++) /* +1 for global q */", @@ -420,7 +497,7 @@ " { if (*search_terminated != 0)", " { if (verbose)", " { printf(\"cpu%%d: termination initiated (%%d)\\n\",", - " core_id, *search_terminated);", + " core_id, (int) *search_terminated);", " }", " } else", " { if (verbose)", @@ -440,7 +517,7 @@ "", " if (core_id == 0) /* local root process */", " { for (i = 1; i < NCORE; i++) /* not for 0 of course */", - " {", + " { int ignore;", "#if defined(WIN32) || defined(WIN64)", " DWORD dwExitCode = 0;", " GetExitCodeProcess(worker_handles[i], &dwExitCode);", @@ -448,10 +525,10 @@ " { TerminateProcess(worker_handles[i], 0);", " }", " printf(\"cpu0: terminate %%d %%d\\n\",", - " worker_pids[i], (dwExitCode == STILL_ACTIVE));", + " (int) worker_pids[i], (dwExitCode == STILL_ACTIVE));", "#else", - " sprintf(b, \"kill -%%d %%d\", SIGKILL, worker_pids[i]);", - " system(b); /* if this is a proxy: receive half */", + " sprintf(b, \"kill -%%d %%d\", (int) SIGKILL, (int) worker_pids[i]);", + " ignore = system(b); /* if this is a proxy: receive half */", " printf(\"cpu0: %%s\\n\", b);", "#endif", " }", @@ -459,8 +536,9 @@ " } else", " { /* on WIN32/WIN64 -- these merely kills the root process... */", " if (was_interrupted == 0)", /* 2=SIGINT to root to trigger stop */ - " { sprintf(b, \"kill -%%d %%d\", SIGINT, worker_pids[0]);", - " system(b); /* warn the root process */", + " { int ignore;", + " sprintf(b, \"kill -%%d %%d\", (int) SIGINT, (int) worker_pids[0]);", + " ignore = system(b); /* warn the root process */", " printf(\"cpu%%d: %%s\\n\", core_id, b);", " issued_kill++;", " } }", @@ -596,7 +674,7 @@ " volatile struct Stack_Tree *prv; /* backward link towards root */", "} Stack_Tree;", "", - "struct H_el *grab_shared(int);", + "H_el *grab_shared(int);", "volatile Stack_Tree **stack_last; /* in shared memory */", "char *stack_cache = NULL; /* local */", "int nr_cached = 0; /* local */", @@ -637,7 +715,7 @@ " if (cf)", " { stack_last[core_id] = cf->prv;", " } else if (nr_handoffs * z_handoff + depth > 0)", - " { printf(\"cpu%%d: error pop_stack_tree (depth %%d)\\n\",", + " { printf(\"cpu%%d: error pop_stack_tree (depth %%ld)\\n\",", " core_id, depth);", " }", "}", @@ -706,6 +784,13 @@ "", " if (sh_lock != NULL)", " { iamin[which] = 0;", + "#if defined(__powerpc64__)", + " #if 1", + " __sync_synchronize(); /* srirajpaul */", + " #else", + " __lwsync(); /* xlc compiler only */", + " #endif", + "#endif", " sh_lock[which] = 0; /* unlock */", " }", "}", @@ -1002,7 +1087,7 @@ " #endif", "", " #ifndef BITSTATE", - " H_tab = (struct H_el **) emalloc(n);", + " H_tab = (H_el **) emalloc(n);", " #endif", "#else", " #ifndef MEMLIM", @@ -1016,7 +1101,7 @@ " (memlim - memcnt - (double) n - (NCORE * LWQ_SIZE + GWQ_SIZE))/(1048576.));", " }", " #ifndef BITSTATE", - " H_tab = (struct H_el **) prep_shmid_S((size_t) n); /* hash_table */", + " H_tab = (H_el **) prep_shmid_S((size_t) n); /* hash_table */", " #endif", " need_mem = memlim - memcnt - ((double) NCORE * LWQ_SIZE) - GWQ_SIZE;", " if (need_mem <= 0.)", @@ -1060,7 +1145,7 @@ " }", " SEG_SIZE /= 2.;", " if (verbose)", - " { printf(\"pan: lowered segsize to %f\\n\", SEG_SIZE);", + " { printf(\"pan: lowered segsize to %%f\\n\", SEG_SIZE);", " }", " if (SEG_SIZE >= 1024.)", " { goto shm_more;", /* always terminates */ @@ -1150,58 +1235,6 @@ "#endif", /* !SEP_STATE */ "}", "", - " /* Test and Set assembly code */", - "", - " #if defined(i386) || defined(__i386__) || defined(__x86_64__)", - " int", - " tas(volatile int *s) /* tested */", - " { int r;", - " __asm__ __volatile__(", - " \"xchgl %%0, %%1 \\n\\t\"", - " : \"=r\"(r), \"=m\"(*s)", - " : \"0\"(1), \"m\"(*s)", - " : \"memory\");", - " ", - " return r;", - " }", - " #elif defined(__arm__)", - " int", - " tas(volatile int *s) /* not tested */", - " { int r = 1;", - " __asm__ __volatile__(", - " \"swpb %%0, %%0, [%%3] \\n\"", - " : \"=r\"(r), \"=m\"(*s)", - " : \"0\"(r), \"r\"(s));", - "", - " return r;", - " }", - " #elif defined(sparc) || defined(__sparc__)", - " int", - " tas(volatile int *s) /* not tested */", - " { int r = 1;", - " __asm__ __volatile__(", - " \" ldstub [%%2], %%0 \\n\"", - " : \"=r\"(r), \"=m\"(*s)", - " : \"r\"(s));", - "", - " return r;", - " }", - " #elif defined(ia64) || defined(__ia64__)", - " /* Intel Itanium */", - " int", - " tas(volatile int *s) /* tested */", - " { long int r;", - " __asm__ __volatile__(", - " \" xchg4 %%0=%%1,%%2 \\n\"", - " : \"=r\"(r), \"+m\"(*s)", - " : \"r\"(1)", - " : \"memory\");", - " return (int) r;", - " }", - " #else", - " #error missing definition of test and set operation for this platform", - " #endif", - "", "void", "cleanup_shm(int val)", "{ volatile sh_Allocater *nxt_pool;", @@ -1275,7 +1308,7 @@ " #error MA without SEP_STATE is not supported with multi-core", "#endif", "#ifdef BFS", - " #error BFS is not supported with multi-core", + " #error instead of -DNCORE -DBFS use -DBFS_PAR", "#endif", "#ifdef SC", " #error SC is not supported with multi-core", @@ -1391,7 +1424,7 @@ "int unpack_state(SM_frame *, int);", "#endif", "", - "struct H_el *", + "H_el *", "grab_shared(int n)", "{", "#ifndef SEP_STATE", @@ -1399,7 +1432,7 @@ "", " if (n == 0)", " { printf(\"cpu%%d: grab shared zero\\n\", core_id); fflush(stdout);", - " return (struct H_el *) rval;", + " return (H_el *) rval;", " } else if (n&(sizeof(void *)-1))", " { n += sizeof(void *)-(n&(sizeof(void *)-1)); /* alignment */", " }", @@ -1464,9 +1497,9 @@ " memset(rval, 0, n);", " memcnt += (double) n;", "", - " return (struct H_el *) rval;", + " return (H_el *) rval;", "#else", - " return (struct H_el *) emalloc(n);", + " return (H_el *) emalloc(n);", "#endif", "}", "", @@ -1565,7 +1598,7 @@ " { if (m_workq[NCORE][*grfree].m_vsize != 0)", " { /* can happen if reader is slow emptying slot */", " *gr_readmiss++;", - " goto out; /* dont wait: release lock and return */", + " goto out; /* don't wait: release lock and return */", " }", " lrfree = *grfree; /* Get_Free_Frame use lrfree in this mode */", " *grfree = (*grfree + 1) %% GN_FRAMES;", /* next process looks at next slot */ @@ -1574,7 +1607,7 @@ " leave_critical(GQ_WR); /* for short lock duration */", " gq_hasroom++;", " mem_put(NCORE); /* copy state into reserved slot */", - " rval = 1; /* successfull handoff */", + " rval = 1; /* successful handoff */", " } else", " { gq_hasnoroom++;", "out: leave_critical(GQ_WR);", /* should be rare */ @@ -1586,7 +1619,7 @@ "int", "unpack_state(SM_frame *f, int from_q)", "{ int i, j;", - " static struct H_el D_State;", + " static H_el D_State;", "", " if (f->m_vsize > 0)", " { boq = f->m_boq;", @@ -1597,9 +1630,11 @@ " vsize = f->m_vsize;", "correct:", " memcpy((uchar *) &now, (uchar *) f->m_now, vsize);", + " #if !defined(NOCOMP) && !defined(HC)", " for (i = j = 0; i < VMAX; i++, j = (j+1)%%8)", - " { Mask[i] = (f->m_Mask[i/8] & (1<m_mask[i/8] & (1< 0)", " { memcpy((uchar *) proc_offset, (uchar *) f->m_p_offset, now._nr_pr * sizeof(OFFT));", " memcpy((uchar *) proc_skip, (uchar *) f->m_p_skip, now._nr_pr * sizeof(uchar));", @@ -2080,12 +2115,13 @@ " if (VVERBOSE) cpu_printf(\"putting state into q%%d\\n\", q);", "", " memcpy((uchar *) f->m_now, (uchar *) &now, vsize);", - " memset((uchar *) f->m_Mask, 0, (VMAX+7)/8 * sizeof(char));", + "#if !defined(NOCOMP) && !defined(HC)", + " memset((uchar *) f->m_mask, 0, (VMAX+7)/8 * sizeof(char));", " for (i = j = 0; i < VMAX; i++, j = (j+1)%%8)", " { if (Mask[i])", - " { f->m_Mask[i/8] |= (1<m_mask[i/8] |= (1< 0)", " { memcpy((uchar *) f->m_p_offset, (uchar *) proc_offset, now._nr_pr * sizeof(OFFT));", " memcpy((uchar *) f->m_p_skip, (uchar *) proc_skip, now._nr_pr * sizeof(uchar));", @@ -2201,12 +2237,13 @@ " if (VVERBOSE) cpu_printf(\"filing state for q%%d\\n\", q);", "", " memcpy((uchar *) f.m_now, (uchar *) &now, vsize);", - " memset((uchar *) f.m_Mask, 0, (VMAX+7)/8 * sizeof(char));", + "#if !defined(NOCOMP) && !defined(HC)", + " memset((uchar *) f.m_mask, 0, (VMAX+7)/8 * sizeof(char));", " for (i = j = 0; i < VMAX; i++, j = (j+1)%%8)", " { if (Mask[i])", - " { f.m_Mask[i/8] |= (1< 0)", " { memcpy((uchar *)f.m_p_offset, (uchar *)proc_offset, now._nr_pr*sizeof(OFFT));", " memcpy((uchar *)f.m_p_skip, (uchar *)proc_skip, now._nr_pr*sizeof(uchar));", @@ -2581,7 +2618,7 @@ " #endif", "", " #ifndef BITSTATE", - " H_tab = (struct H_el **) emalloc(n);", + " H_tab = (H_el **) emalloc(n);", " #endif", "#else", " #ifndef MEMLIM", @@ -2594,7 +2631,7 @@ " MEMLIM, ((double)n/(1048576.)), ((double) NCORE * LWQ_SIZE + GWQ_SIZE)/(1048576.),", " (memlim - memcnt - (double) n - ((double) NCORE * LWQ_SIZE + GWQ_SIZE))/(1048576.));", " #ifndef BITSTATE", - " H_tab = (struct H_el **) prep_shmid_S((size_t) n); /* hash_table */", + " H_tab = (H_el **) prep_shmid_S((size_t) n); /* hash_table */", " #endif", " get_mem = memlim - memcnt - ((double) NCORE) * LWQ_SIZE - GWQ_SIZE;", " if (get_mem <= 0)", @@ -2737,7 +2774,7 @@ " #error MA requires SEP_STATE in multi-core mode", "#endif", "#ifdef BFS", - " #error BFS is not supported in multi-core mode", + " #error instead of -DNCORE -DBFS use -DBFS_PAR", "#endif", "#ifdef SC", " #error SC is not supported in multi-core mode", diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen7.c /sys/src/cmd/spin/pangen7.c --- /n/sources/plan9/sys/src/cmd/spin/pangen7.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/pangen7.c Mon Feb 22 00:00:00 2021 @@ -1,28 +1,24 @@ /***** spin: pangen7.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ -/* pangen7.c: Version 5.3.0 2010, synchronous product of never claims */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include +#include #include "spin.h" #include "y.tab.h" #include -#ifdef PC -extern int unlink(const char *); -#else +#ifndef PC #include #endif -extern ProcList *rdy; +extern ProcList *ready; extern Element *Al_El; extern int nclaims, verbose, Strict; +extern short has_accept; typedef struct Succ_List Succ_List; typedef struct SQueue SQueue; @@ -55,21 +51,21 @@ Guard *nxt; }; -SQueue *sq, *sd, *render; /* states move from sq to sd to render to holding */ -SQueue *holding, *lasthold; -State_Stack *dsts; - -int nst; /* max nr of states in claims */ -int *Ist; /* initial states */ -int *Nacc; /* number of accept states in claim */ -int *Nst; /* next states */ -int **reached; /* n claims x states */ -int unfolding; /* to make sure all accept states are reached */ -int is_accept; /* remember if the current state is accepting in any claim */ -int not_printing; /* set during explore_product */ +static SQueue *sq, *sd, *render; /* states move from sq to sd to render to holding */ +static SQueue *holding, *lasthold; +static State_Stack *dsts; + +static int nst; /* max nr of states in claims */ +static int *Ist; /* initial states */ +static int *Nacc; /* number of accept states in claim */ +static int *Nst; /* next states */ +static int **reached; /* n claims x states */ +static int unfolding; /* to make sure all accept states are reached */ +static int is_accept; /* remember if the current state is accepting in any claim */ +static int not_printing; /* set during explore_product */ -Element ****matrix; /* n x two-dimensional arrays state x state */ -Element **Selfs; /* self-loop states at end of claims */ +static Element ****matrix; /* n x two-dimensional arrays state x state */ +static Element **Selfs; /* self-loop states at end of claims */ static void get_seq(int, Sequence *); static void set_el(int n, Element *e); @@ -151,9 +147,9 @@ static void wrap_text(char *pre, Lextok *t, char *post) { - printf(pre); + printf(pre, (char *) 0); comment(stdout, t, 0); - printf(post); + printf(post, (char *) 0); } static State_Stack * @@ -185,7 +181,7 @@ static void pop_dsts(void) { - assert(dsts); + assert(dsts != NULL); dsts = dsts->nxt; } @@ -249,7 +245,7 @@ y = push_dsts(s->combo); if (!y) { if (once++ == 0) - { assert(s->succ); + { assert(s->succ != NULL); state_body(s, guard); } pop_dsts(); @@ -272,7 +268,7 @@ } } } -static struct X { +static struct X_tbl { char *s; int n; } spl[] = { {"end", 3 }, @@ -288,7 +284,7 @@ { ProcList *p; int i; - for (p = rdy, i = 0; p; p = p->nxt, i++) /* find claim name */ + for (p = ready, i = 0; p; p = p->nxt, i++) /* find claim name */ { if (i == n) { break; } } @@ -353,13 +349,14 @@ l->c = (Symbol *) emalloc(sizeof(Symbol)); l->uiid = 0; /* this is not in an inline */ - for (p = rdy, i = 0; p; p = p->nxt, i++) /* find claim name */ + for (p = ready, i = 0; p; p = p->nxt, i++) /* find claim name */ { if (i == n) { l->c->name = p->n->name; break; } } assert(p && p->b == N_CLAIM); Nacc[n] = 1; + has_accept = 1; l->e = e; l->nxt = labtab; @@ -380,7 +377,7 @@ is_accept = 0; for (j = 0; spl[j].n; j++) /* 2 special label prefixes */ { nmatches = 0; - for (p = rdy, i = 0; p; p = p->nxt, i++) /* check each claim */ + for (p = ready, i = 0; p; p = p->nxt, i++) /* check each claim */ { if (p->b != N_CLAIM) { continue; } @@ -404,7 +401,8 @@ is_accepting: if (strchr(p->n->name, ':')) { sprintf(buf, "N%d", i); } else - { strcpy(buf, p->n->name); + { assert(strlen(p->n->name) < sizeof(buf)); + strcpy(buf, p->n->name); } if (unfolding == 0 && i == 0) { if (!not_printing) @@ -499,7 +497,7 @@ if (unfolding == 0) { printf("never Product {\n"); /* name expected by iSpin */ q = find_state(Ist); /* should find it in the holding q */ - assert(q); + assert(q != NULL); q->nxt = holding; /* put it at the front */ holding = q; } @@ -597,7 +595,7 @@ Selfs = (Element **) emalloc(sizeof(Element *) * nclaims); matrix = (Element ****) emalloc(sizeof(Element ***) * nclaims); /* claims */ - for (p = rdy, i = 0; p; p = p->nxt, i++) + for (p = ready, i = 0; p; p = p->nxt, i++) { if (p->b == N_CLAIM) { nst = max(p->s->maxel, nst); Nacc[i] = claim_has_accept(p); @@ -614,7 +612,7 @@ { e->status &= ~DONE; } - for (p = rdy, n=0; p; p = p->nxt, n++) + for (p = ready, n=0; p; p = p->nxt, n++) { if (p->b == N_CLAIM) { /* fill in matrix[n] */ e = p->s->frst; @@ -729,7 +727,7 @@ { if (last) { last->nxt = nq->nxt; } else - { sd = nq; + { sd = nq->nxt; /* 6.4.0: was sd = nq */ } return nq; /* found */ } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/pangen7.h /sys/src/cmd/spin/pangen7.h --- /n/sources/plan9/sys/src/cmd/spin/pangen7.h Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/spin/pangen7.h Mon Feb 22 00:00:00 2021 @@ -0,0 +1,2413 @@ +/***** spin: pangen7.h *****/ + +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ + +static const char *pan_par[] = { /* generates pan.p */ + "#include ", + "#include ", + "#include ", /* for nanosleep */ + "#include ", + "#include ", + "#ifdef BFS_DISK", + "#include ", /* for rmdir */ + "#include ", /* for mkdir */ + "#include ", + "#include ", /* for open */ + "#endif", + "", + "#define Max(a,b) (((a)>(b))?(a):(b))", + "#ifndef WAIT_MAX", + " #define WAIT_MAX 2 /* seconds */", + "#endif", + "#define BFS_GEN 2 /* current and next generation */", + "", + "typedef struct BFS_Slot BFS_Slot;", + "typedef struct BFS_shared BFS_shared;", + "typedef struct BFS_data BFS_data;", + "", + "struct BFS_Slot {", + " #ifdef BFS_FIFO", + " enum bfs_types type; /* message type */", + " #endif", + " BFS_State *s_data; /* state data */", + " #ifndef BFS_QSZ", + " BFS_Slot *nxt; /* linked list */", + " #endif", + "};", + "", + "struct BFS_data {", + " double memcnt;", + " double nstates;", + " double nlinks;", + " double truncs;", + " ulong mreached;", + " ulong vsize;", + " ulong memory_left;", + " ulong punted;", + " ulong errors;", + " int override; /* after crash, if another proc clears locks */", + "};", + "", + "struct BFS_shared { /* about 13K for BFS_MAXPROCS=16 and BFS_MAXLOCKS=1028 */", + " volatile ulong quit; /* set to signal termination -- one word */", + " volatile ulong started;", + "", + " volatile uchar sh_owner[BFS_MAXLOCKS]; /* optional */", + "#ifdef BFS_CHECK", + " volatile uchar in_count[BFS_MAXLOCKS]; /* optional */", + "#endif", + " volatile int sh_locks[BFS_MAXLOCKS];", + " volatile ulong wait_count[BFS_MAXLOCKS]; /* optional */", + "", + " volatile BFS_data bfs_data[BFS_MAXPROCS];", + " volatile uchar bfs_flag[BFS_MAXPROCS]; /* running 0, normal exit 1, abnormal 2 */", + " volatile uchar bfs_idle[BFS_MAXPROCS]; /* set when all input queues are empty */", + "#ifdef BFS_DISK", + " volatile uchar bfs_out_cnt[BFS_MAXPROCS]; /* set when core writes a state */", + "#endif", + "", + "#ifdef BFS_QSZ", + " #define BFS_NORECYCLE", + " #if BFS_QSZ<=0", + " #error BFS_QSZ must be positive", + " #endif", + " #ifdef BFS_FIFO", + " #error BFS_QSZ cannot be combined with BFS_FIFO", + " #endif", + " #ifdef BFS_DISK", + " #error BFS_QSZ cannot be combined with BFS_DISK", + " #endif", + " volatile BFS_Slot bfsq[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS][BFS_QSZ];", + " volatile uint bfs_ix[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];", + "#else", + " volatile BFS_Slot *head[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];", + "#endif", + "", + "#ifdef BFS_FIFO", + " volatile BFS_Slot *tail[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];", + " volatile BFS_Slot *dels[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];", + "#endif", + "#ifdef BFS_LOGMEM", + " volatile ulong logmem[1024];", + "#endif", + " volatile ulong mem_left;", + " volatile uchar *allocator; /* start of shared heap, must be last */", + "};", + "", + "enum bfs_types { EMPTY = 0, STATE, DELETED };", + "", + "extern volatile uchar *bfs_get_shared_mem(key_t, size_t);", + "extern BFS_Slot * bfs_new_slot(BFS_Trail *);", + "extern BFS_Slot * bfs_prep_slot(BFS_Trail *, BFS_Slot *);", + "extern BFS_Slot * bfs_next(void);", + "extern BFS_Slot * bfs_pack_state(Trail *, BFS_Trail *, int, BFS_Slot *);", + "extern SV_Hold * bfs_new_sv(int);", + "#if NRUNS>0", + "extern EV_Hold * bfs_new_sv_mask(int);", + "#endif", + "extern BFS_Trail * bfs_grab_trail(void);", + "extern BFS_Trail * bfs_unpack_state(BFS_Slot *);", + "extern int bfs_all_empty(void);", + "extern int bfs_all_idle(void);", + "extern int bfs_all_running(void);", + "extern int bfs_idle_and_empty(void);", + "extern size_t bfs_find_largest(key_t);", + "", + "extern void bfs_clear_locks(void);", + "extern void bfs_drop_shared_memory(void);", + "extern void bfs_explore_state(BFS_Slot *);", + "extern void bfs_initial_state(void);", + "extern void bfs_mark_done(int);", + "extern void bfs_printf(const char *fmt, ...);", + "extern void bfs_push_state(Trail *, BFS_Trail *, int);", + "extern void bfs_recycle(BFS_Slot *);", + "extern void bfs_release_trail(BFS_Trail *);", + "extern void bfs_run(void);", + "extern void bfs_setup_mem(void);", + "extern void bfs_setup(void);", + "extern void bfs_shutdown(const char *);", + "extern void bfs_statistics(void);", + "extern void bfs_store_state(Trail *, short);", + "extern void bfs_set_toggle(void);", + "extern void bfs_update(void);", + "", + "#ifdef MA", + " #error cannot combine -DMA with -DBFS_PAR", + " /* would require us to parallelize g_store */", + "#endif", + "#ifdef BCS", + " #error cannot combine -DBCS with -DBFS_PAR", + "#endif", + "#ifdef BFS_DISK", + " #ifdef BFS_FIFO", + " #error cannot combine BFS_DISK and BFS_FIFO", + " #endif", + " extern void bfs_disk_start(void);", + " extern void bfs_disk_stop(void);", + " extern void bfs_disk_out(void);", + " extern void bfs_disk_inp(void);", + " extern void bfs_disk_iclose(void);", + " extern void bfs_disk_oclose(void);", + " int bfs_out_fd[BFS_MAXPROCS];", + " int bfs_inp_fd[BFS_MAXPROCS];", + "#endif", + "", + "static BFS_shared *shared_memory;", + "#ifndef BFS_QSZ", + "static BFS_Slot *bfs_free_slot; /* local free list */", + "#endif", + "static BFS_Slot bfs_null;", + "static SV_Hold *bfs_svfree[VECTORSZ];", + "static uchar *bfs_heap; /* local pointer into heap */", + "static ulong bfs_left; /* local part of shared heap */", + "#if NRUNS>0", + "static void bfs_keep(EV_Hold *);", + "#endif", + "static long bfs_sent; /* nr msgs sent -- local to each process */", + "static long bfs_rcvd; /* nr msgs rcvd */", + "static long bfs_sleep_cnt; /* stats */", + "static long bfs_wcount;", + "static long bfs_gcount;", + "static ulong bfs_total_shared;", + "#ifdef BFS_STAGGER", + " static int bfs_stage_cnt = 0;", + " static void bfs_stagger_flush(void);", + "#endif", + "static int bfs_toggle; /* local variable, 0 or 1 */", + "static int bfs_qscan; /* scan input queues in order */", + "static ulong bfs_snapped;", + "static int shared_mem_id;", + "#ifndef NOREDUCE", + "static int bfs_nps; /* no preselection */", + "#endif", + "ulong bfs_punt; /* states dropped for lack of memory */", + "#if defined(VERBOSE) || defined(BFS_CHECK)", + "static const char *bfs_sname[] = {", + " \"EMPTY\", /* 0 */", + " \"STATE\", /* 1 */", + " \"STATE\", /* 2 = DELETED */", + " 0", + "};", + "#endif", + "static const char *bfs_lname[] = { /* match values defined in pangen2.c */", + " \"global lock\", /* BFS_GLOB */", + " \"ordinal\", /* BFS_ORD */", + " \"shared memory\", /* BFS_MEM */", + " \"print to stdout\", /* BFS_PRINT */", + " \"hashtable\", /* BFS_STATE */", + " 0", + "};", + "", + "static ulong bfs_count[DELETED+1]; /* indexed with bfs_types: EMPTY=0, STATE=1, DELETED=2 */", + "", + "static int bfs_keep_state;", + "", + "int Cores = 1;", + "int who_am_i = 0; /* root */", + "", + "#ifdef L_BOUND", + " int L_bound = L_BOUND;", + "#endif", + "", + "#ifdef BFS_CHECK", + "void", + "bfs_dump_now(char *s)", + "{ int i; char *p = (char *) &now;", + "", + " e_critical(BFS_PRINT);", + " printf(\"%%s\\t\", s);", + " printf(\"%%3lu: \", vsize);", + " for (i = 0; i < vsize; i++)", + " { printf(\"%%3d \", *p++);", + " }", + " printf(\" %%s\\noffsets:\\t\", s);", + " for (i = 0; i < now._nr_pr; i++)", + " { printf(\"%%3d \", proc_offset[i]);", + " }", + " printf(\"\\n\");", + " x_critical(BFS_PRINT);", + "}", + "", + "void", + "view_state(char *s) /* debugging */", + "{ int i;", + " char *p;", + " e_critical(BFS_PRINT);", + " printf(\"cpu%%02d %%s: \", who_am_i, s);", + " p = (char *)&now;", + " for (i = 0; i < vsize; i++)", + " printf(\"%%3d, \", *p++);", + " printf(\"\\n\"); fflush(stdout);", + " x_critical(BFS_PRINT);", + "}", + "#endif", + "", + "void", + "bfs_main(int ncores, int cycles)", + "{", + " if (cycles)", + " { fprintf(stderr, \"pan: cycle detection is not supported in this mode\\n\");", + " exit(1);", + " }", + "", + " if (ncores == 0) /* i.e., find out */", + " { FILE *fd;", + " char buf[512];", + " if ((fd = fopen(\"/proc/cpuinfo\", \"r\")) == NULL)", + " { /* cannot tell */", + " ncores = Cores; /* use the default */", + " } else", + " { while (fgets(buf, sizeof(buf), fd))", + " { if (strncmp(buf, \"processor\", strlen(\"processor\")) == 0)", + " { ncores++;", + " } }", + " fclose(fd);", + " ncores--;", + " if (verbose)", + " { printf(\"pan: %%d available cores\\n\", ncores+1);", + " } } }", + " if (ncores >= BFS_MAXPROCS)", + " { Cores = BFS_MAXPROCS-1; /* why -1? */", + " } else if (ncores < 1)", + " { Cores = 1;", + " } else", + " { Cores = ncores;", + " }", + " printf(\"pan: using %%d core%%s\\n\", Cores, (Cores>1)?\"s\":\"\");", + " fflush(stdout);", + "#ifdef BFS_DISK", + " bfs_disk_start();", /* create .spin */ + "#endif", + " bfs_setup(); /* shared memory segments and fork */", + " bfs_run();", + " if (who_am_i == 0)", + " { stop_timer(0);", + " }", + " bfs_statistics();", + " bfs_mark_done(1);", + " if (who_am_i == 0)", + " { report_time();", + "#ifdef BFS_DISK", + " bfs_disk_stop();", + "#endif", + " }", + "#ifdef C_EXIT", + " C_EXIT; /* trust that it defines a fct */", + "#endif", + " bfs_drop_shared_memory();", + " exit(0);", + "}", + "", + "void", + "bfs_setup_mem(void)", + "{ size_t n;", + " key_t key;", + "#ifdef BFS_FIFO", + " bfs_null.type = EMPTY;", + "#endif", + " ntrpt = (Trail *) emalloc(sizeof(Trail));", /* just once */ + "", + " if ((key = ftok(\".\", (int) 'L')) == -1)", + " { perror(\"ftok shared memory\");", + " exit(1);", + " }", + " n = bfs_find_largest(key);", + " bfs_total_shared = (ulong) n;", + "", + " shared_memory = (BFS_shared *) bfs_get_shared_mem(key, n); /* root */", + " shared_memory->allocator = (uchar *) shared_memory + sizeof(BFS_shared);", + " shared_memory->mem_left = (ulong) (n - sizeof(BFS_shared));", + "}", + "", + "ulong bfs_LowLim;", + "#ifndef BFS_RESERVE", + " #define BFS_RESERVE 5", + /* keep memory on global heap in reserve for first few cores */ + /* that run out of their local allocation of shared mem */ + /* 1~50 percent, 2~30 percent, 5~20 percent, >Cores=none */ + "#else", + " #if BFS_RESERVE<1", + " #error BFS_RESERVE must be at least 1", + " #endif", + "#endif", + "", + "void", + "bfs_setup(void) /* executed by root */", + "{ int i, j;", + " ulong n; /* share of shared memory allocated to each core */", + "", + " n = shared_memory->mem_left / (Cores + Cores/(BFS_RESERVE)); /* keep some reserve */", + "", + " if ((n%%sizeof(void *)) != 0)", + " { n -= (n%%sizeof(void *)); /* align, without exceeding total */", + " }", + " for (i = 0; i < Cores-1; i++)", + " { j = fork();", + " if (j == -1)", + " { bfs_printf(\"fork failed\\n\");", + " exit(1);", + " }", + " if (j == 0)", + " { who_am_i = i+1; /* 1..Cores-1 */", + " break;", + " } }", + "", + " e_critical(BFS_MEM);", + " bfs_heap = (uchar *) shared_memory->allocator;", + " shared_memory->allocator += n;", + " shared_memory->mem_left -= n;", + " x_critical(BFS_MEM);", + "", + " bfs_left = n;", + " bfs_runs = 1;", + " bfs_LowLim = n / (2 * (ulong) Cores);", /* 50% */ + "}", + "", + "void", + "bfs_run(void)", + "{ BFS_Slot *v;", + "", + "#ifdef BFS_DISK", + " bfs_disk_out();", /* create outqs */ + "#endif", + " if (who_am_i == 0)", + " { bfs_initial_state();", + " }", + "#ifdef BFS_DISK", + " #ifdef BFS_STAGGER", + " bfs_stagger_flush();", + " #endif", + " bfs_disk_oclose();", /* sync and close outqs */ + "#endif", + "#ifdef BFS_FIFO", + " static int i_count;", + "#endif", + "", + " srand(s_rand+HASH_NR);", + " bfs_qscan = 0;", + " bfs_toggle = 1 - bfs_toggle; /* after initial state */", + " e_critical(BFS_GLOB);", + " shared_memory->started++;", + " x_critical(BFS_GLOB);", + "", + " while (shared_memory->started != Cores) /* wait for all cores to connect */", + " { usleep(1);", + " }", + "", + "#ifdef BFS_DISK", + " bfs_disk_out();", + " bfs_disk_inp();", + "#endif", + "", + " start_timer();", + " while (shared_memory->quit == 0)", + " { v = bfs_next(); /* get next message from current generation */", + " if (v->s_data) /* v->type == STATE || v->type == DELETED */", + " { bfs_count[STATE]++;", + "#ifdef VERBOSE", + " bfs_printf(\"GOT STATE (depth %%d, nr %%u)\\n\",", + " v->s_data->t_info->o_tt, v->s_data->nr);", + "#endif", + " /* last resort: start dropping states when out of memory */", + " if (bfs_left > 1024 || shared_memory->mem_left > 1024)", + " { bfs_explore_state(v);", + " } else", + " { static int warned_loss = 0;", + " if (warned_loss == 0 && who_am_i == 0)", + " { warned_loss++;", + " bfs_printf(\"out of shared memory - losing states\\n\");", + " }", + " bfs_punt++;", + " }", + "#if !defined(BFS_FIFO) && !defined(BFS_NORECYCLE)", + " bfs_recycle(v);", + "#endif", + "#ifdef BFS_FIFO", + " i_count = 0;", + "#endif", + " } else", + " { bfs_count[EMPTY]++;", + "#if defined(BFS_FIFO) && defined(BFS_CHECK)", + " assert(v->type == EMPTY);", + "#endif", + "#ifdef BFS_FIFO", + " if (who_am_i == 0)", + " { if (bfs_idle_and_empty())", + " { if (i_count++ > 10)", + " { shared_memory->quit = 1;", + " }", + " else usleep(1);", + " }", + " } else if (!bfs_all_running())", + " { bfs_shutdown(\"early termination\");", + " }", + "#else", + " if (who_am_i == 0)", + " { if (bfs_all_idle()) /* wait for it */", + " { if (!bfs_all_empty()) /* more states to process */", + " { bfs_set_toggle();", + " goto do_toggle;", + " } else /* done */", + " { shared_memory->quit = 1; /* step 4 */", + " }", + " } else", + " { bfs_sleep_cnt++;", + " }", + " } else", + " { /* wait for quit or idle bit to be reset by root */", + " while (shared_memory->bfs_idle[who_am_i] == 1", + " && shared_memory->quit == 0)", + " { if (bfs_all_running())", + " { bfs_sleep_cnt++;", + " usleep(10); /* new 6.2.3 */", + " } else", + " { bfs_shutdown(\"early termination\");", + " /* no return */", + " } }", + "do_toggle: bfs_qscan = 0;", + "#ifdef BFS_DISK", + " bfs_disk_iclose();", + " bfs_disk_oclose();", + "#endif", + " bfs_toggle = 1 - bfs_toggle;", + "#ifdef BFS_DISK", + " bfs_disk_out();", + " bfs_disk_inp();", + "#endif", + " #ifdef BFS_CHECK", + " bfs_printf(\"toggle: recv from %%d, send to %%d\\n\",", + " bfs_toggle, 1 - bfs_toggle);", + " #endif", + " }", + "#endif", + " } }", + "#ifdef BFS_CHECK", + " bfs_printf(\"done, sent %%5ld recvd %%5ld punt %%5lu sleep: %%ld\\n\",", + " bfs_sent, bfs_rcvd, bfs_punt, bfs_sleep_cnt);", + "#endif", + "}", + "", + "void", + "bfs_report_mem(void) /* called from within wrapup() */", + "{", + " printf(\"%%9.3f total shared memory usage\\n\\n\",", + " ((double) bfs_total_shared - (double) bfs_left)/(1024.*1024.));", + "}", + "", + "void", + "bfs_statistics(void)", + "{", + " #ifdef VERBOSE", + " enum bfs_types i;", + " #endif", + " if (verbose)", + " bfs_printf(\"states sent %%7ld recvd %%7ld stored %%8g sleeps: %%4ld, %%4ld, %%ld\\n\",", + " bfs_sent, bfs_rcvd, nstates, bfs_wcount, bfs_gcount, bfs_sleep_cnt);", + " if (0) bfs_printf(\"states punted %%7lu\\n\", bfs_punt);", + " #ifdef VERBOSE", + " for (i = EMPTY; i <= DELETED; i++)", + " { if (bfs_count[i] > 0)", + " { bfs_printf(\"%%6s %%8lu\\n\",", + " bfs_sname[i], bfs_count[i]);", + " } }", + " #endif", + " bfs_update();", + "", + " if (who_am_i == 0 && shared_memory)", + " { int i; ulong count = 0L;", + " done = 1;", + "", + " e_critical(BFS_PRINT);", + " wrapup();", + " if (verbose)", + " { printf(\"\\nlock-wait counts:\\n\");", + " for (i = 0; i < BFS_STATE; i++)", + " printf(\"%%16s %%9lu\\n\",", + " bfs_lname[i], shared_memory->wait_count[i]);", + "#ifndef BITSTATE", + " for (i = BFS_STATE; i < BFS_MAXLOCKS; i++)", + " { if (0)", + " printf(\" [%%6d] %%9lu\\n\",", + " i, shared_memory->wait_count[i]);", + " count += shared_memory->wait_count[i];", + " }", + " printf(\"%%16s %%9lu (avg per region)\\n\",", + " bfs_lname[BFS_STATE], count/(BFS_MAXLOCKS - BFS_STATE));", + "#endif", + " }", + " fflush(stdout);", + " x_critical(BFS_PRINT);", + " }", + "}", + "", + "void", + "bfs_snapshot(void)", + "{ clock_t stop_time;", + " double delta_time;", + " struct tms stop_tm;", + " volatile BFS_data *s;", + "", + " e_critical(BFS_PRINT);", + " printf(\"cpu%%02d Depth= %%7lu States= %%8.3g Transitions= %%8.3g \",", + " who_am_i, mreached, nstates, nstates+truncs);", + " printf(\"Memory= %%9.3f\\t\", memcnt/1048576.);", + " printf(\"SharedMLeft= %%4lu \", bfs_left/1048576);", + " stop_time = times(&stop_tm);", + " delta_time = ((double) (stop_time - start_time))/((double) sysconf(_SC_CLK_TCK));", + " if (delta_time > 0.01)", + " { printf(\"t= %%6.3g R= %%6.0g\\n\", delta_time, nstates/delta_time);", + " } else", + " { printf(\"t= %%6.3g R= %%6.0g\\n\", 0., 0.);", + " }", + " fflush(stdout);", + " x_critical(BFS_PRINT);", + "", + " s = &shared_memory->bfs_data[who_am_i];", + " s->mreached = (ulong) mreached;", + " s->vsize = (ulong) vsize;", + " s->errors = (int) errors;", + " s->memcnt = (double) memcnt;", + " s->nstates = (double) nstates;", + " s->nlinks = (double) nlinks;", + " s->truncs = (double) truncs;", + " s->memory_left = (ulong) bfs_left;", + " s->punted = (ulong) bfs_punt;", + " bfs_snapped++; /* for bfs_best */", + "}", + "", + "void", + "bfs_shutdown(const char *s)", + "{", + " bfs_clear_locks(); /* in case we interrupted at a bad point */", + " if (!strstr(s, \"early \") || verbose)", + " { bfs_printf(\"stop (%%s)\\n\", s);", + " }", + " bfs_update();", + " if (who_am_i == 0)", + " { wrapup();", + "#ifdef BFS_DISK", + " bfs_disk_stop();", + "#endif", + " }", + " bfs_mark_done(2);", + " pan_exit(2);", + "}", + "", + "SV_Hold *bfs_free_hold;", + "", + "SV_Hold *", + "bfs_get_hold(void)", + "{ SV_Hold *x;", + " if (bfs_free_hold)", + " { x = bfs_free_hold;", + " bfs_free_hold = bfs_free_hold->nxt;", + " } else", + " { x = (SV_Hold *) sh_malloc((ulong) sizeof(SV_Hold));", + " }", + " return x;", + "}", + "", + "BFS_Trail *", + "bfs_unpack_state(BFS_Slot *n) /* called in bfs_explore_state */", + "{ BFS_Trail *otrpt;", + " BFS_State *bfs_t;", + " int vecsz;", + "", + " if (!n || !n->s_data || !n->s_data->t_info)", + " { bfs_Uerror(\"internal error\");", + " }", + " otrpt = (BFS_Trail *) ((BFS_State *) n->s_data)->t_info;", + "", + " trpt->ostate = otrpt->ostate;", + " trpt->st = otrpt->st;", + " trpt->o_tt = otrpt->o_tt;", + " trpt->pr = otrpt->pr;", + " trpt->tau = otrpt->tau;", + " trpt->o_pm = otrpt->o_pm;", + " if (trpt->ostate)", + " trpt->o_t = t_id_lkup[otrpt->t_id];", + "#if defined(C_States) && (HAS_TRACK==1)", + " c_revert((uchar *) &(now.c_state[0]));", + "#endif", + " if (trpt->o_pm & 4) /* rv succeeded */", + " { return (BFS_Trail *) 0; /* revisit not needed */", + " }", + "#ifndef NOREDUCE", + " bfs_nps = 0;", + "#endif", + " if (trpt->o_pm & 8) /* rv attempt failed */", + " { revrv++;", + " if (trpt->tau&8)", + " { trpt->tau &= ~8; /* break atomic */", + "#ifndef NOREDUCE", + " } else if (trpt->tau&32) /* void preselection */", + " { trpt->tau &= ~32;", + " bfs_nps = 1; /* no preselection in repeat */", + "#endif", + " } }", + " trpt->o_pm &= ~(4|8);", + " if (trpt->o_tt > mreached)", + " { static ulong nr = 0L, nc;", + " mreached = trpt->o_tt;", + " nc = (long) nstates/FREQ;", + " if (nc > nr)", + " { nr = nc;", + " bfs_snapshot();", + " } }", + " depth = trpt->o_tt;", + " if (depth >= maxdepth)", + " {", + "#if SYNC", + " if (boq != -1)", + " { BFS_Trail *x = (BFS_Trail *) trpt->ostate;", + " if (x) x->o_pm |= 4; /* rv not failing */", + " }", + "#endif", + " truncs++;", + " if (!warned)", + " { warned = 1;", + " bfs_printf(\"error: max search depth too small\\n\");", + " }", + " if (bounded)", + " { bfs_uerror(\"depth limit reached\");", + " }", + " return (BFS_Trail *) 0;", + " }", + "", + " bfs_t = n->s_data;", + "#if NRUNS>0", + " vsize = bfs_t->omask->sz;", + "#else", + " vsize = ((State *) (bfs_t->osv))->_vsz;", + "#endif", + "#if SYNC", + " boq = bfs_t->boq;", + "#endif", + "", + "#if defined(Q_PROVISO) && !defined(BITSTATE) && defined(FULLSTACK)", + " #ifdef USE_TDH", + " if (((uchar *)(bfs_t->lstate))) /* if BFS_INQ is set */", + " { *((uchar *) bfs_t->lstate) = 0; /* turn it off */", + " }", + " #else", + " if (bfs_t->lstate) /* bfs_par */", + " { bfs_t->lstate->tagged = 0; /* bfs_par state removed from q */", + " }", + " #endif", + "#endif", + " memcpy((char *) &now, (uchar *) bfs_t->osv, vsize);", + "#if !defined(NOCOMP) && !defined(HC) && NRUNS>0", + " Mask = (uchar *) bfs_t->omask->sv; /* in shared memory */", + "#endif", + "#ifdef BFS_CHECK", + " if (0) bfs_dump_now(\"got1\");", + "#endif", + "#ifdef TRIX", + " re_populate();", + "#else", + " #if NRUNS>0", + " if (now._nr_pr > 0)", + " {", + " #if VECTORSZ>32000", + " proc_offset = (int *) bfs_t->omask->po;", + " #else", + " proc_offset = (short *) bfs_t->omask->po;", + " #endif", + " proc_skip = (uchar *) bfs_t->omask->ps;", + " }", + " if (now._nr_qs > 0)", + " {", + " #if VECTORSZ>32000", + " q_offset = (int *) bfs_t->omask->qo;", + " #else", + " q_offset = (short *) bfs_t->omask->qo;", + " #endif", + " q_skip = (uchar *) bfs_t->omask->qs;", + " }", + " #endif", + "#endif", + " vecsz = ((State *) bfs_t->osv)->_vsz;", + "#ifdef BFS_CHECK", + " assert(vecsz > 0 && vecsz < VECTORSZ);", + "#endif", + " { SV_Hold *x = bfs_get_hold();", + " x->sv = bfs_t->osv;", + " x->nxt = bfs_svfree[vecsz];", + " bfs_svfree[vecsz] = x;", + " bfs_t->osv = (State *) 0;", + " }", + "#if NRUNS>0", + " bfs_keep(bfs_t->omask);", + "#endif", + "", + "#ifdef BFS_CHECK", + " if (0) bfs_dump_now(\"got2\");", + " if (0) view_state(\"after\");", + "#endif", + " return (BFS_Trail *) bfs_t->t_info;", + "}", + "void", + "bfs_initial_state(void)", + "{", + "#ifdef BFS_CHECK", + " assert(trpt != NULL);", + "#endif", + " trpt->ostate = (H_el *) 0;", + " trpt->o_tt = -1;", + " trpt->tau = 0;", + "#ifdef VERI", + " trpt->tau |= 4; /* claim moves first */", + "#endif", + " bfs_store_state(trpt, boq); /* initial state : bfs_lib.c */", + "}", + "", + "#ifdef BITSTATE", + " #define bfs_do_store(v, n) b_store(v, n)", + "#else", + " #ifdef USE_TDH", + " #define bfs_do_store(v, n) o_store(v, n)", + " #else", + " #define bfs_do_store(v, n) h_store(v, n)", + " #endif", + "#endif", + "", + "#ifdef BFS_SEP_HASH", + "int", + "bfs_seen_before(void)", + "{ /* cannot set trpt->tau |= 64 to mark successors outside stack */", + " /* since the check is done remotely and the trpt value is gone */", + " #ifdef VERI", + " if (!trpt->ostate /* initial state */", + " || ((trpt->tau&4) /* starting claim moves(s) */", + " && !(((BFS_Trail *)trpt->ostate)->tau&4))) /* prev move: prog */", + " { return 0; /* claim move: mid-state not stored */", + " } /* else */", + " #endif", + " if (!bfs_do_store((char *)&now, vsize)) /* sep_hash */", + " { nstates++; /* local count */", + " return 0; /* new state */", + " }", + " #ifdef BFS_CHECK", + " bfs_printf(\"seen before\\n\");", + " #endif", + " truncs++;", + " return 1; /* old state */", + "}", + "#endif", + "", + "void", + "bfs_explore_state(BFS_Slot *v) /* generate all successors of v */", + "{ BFS_Trail *otrpt;", + " Trans *t;", + "#ifdef HAS_UNLESS", + " int E_state;", + "#endif", + " int tt;", + " short II, To = BASE, From = (short) (now._nr_pr-1);", + " short oboq = boq;", + " uchar _n, _m, ot;", + "", + " memset(ntrpt, 0, sizeof(Trail));", + " otrpt = bfs_unpack_state(v); /* BFS_Trail */", + "", + " if (!otrpt) { return; } /* e.g., depth limit reached */", + "#ifdef L_BOUND", + " #if defined(VERBOSE)", + " bfs_printf(\"Unpacked state with l_bound %%d -- sds %%p\\n\",", + " now._l_bnd, now._l_sds);", + " #endif", + "#endif", + "", + "#if defined(C_States) && (HAS_TRACK==1)", + " c_revert((uchar *) &(now.c_state[0]));", + "#endif", + "", + "#ifdef BFS_SEP_HASH", + " if (bfs_seen_before()) return;", + "#endif", + "", + "#ifdef VERI", /* could move to just before store_state */ + " if (now._nr_pr == 0 /* claim terminated */", + " || stopstate[((Pclaim *)pptr(0))->_t][((Pclaim *)pptr(0))->_p])", + " { bfs_uerror(\"end state in claim reached\");", + " }", + "#endif", + " trpt->tau &= ~1; /* timeout off */", + "#ifdef VERI", + " if (trpt->tau&4) /* claim move */", + " { trpt->tau |= (otrpt->tau)&1; /* inherit from prog move */", + " From = To = 0; /* claim */", + " goto Repeat_two;", + " }", + "#endif", + "#ifndef NOREDUCE", + " if (boq == -1 && !(trpt->tau&8) && bfs_nps == 0)", + " for (II = now._nr_pr-1; II >= BASE; II -= 1)", + " {", + "Pickup: _this = pptr(II);", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", + " if (trans[ot][tt]->atom & 8)", + " { t = trans[ot][tt];", + " if (t->qu[0] != 0)", + " { if (!q_cond(II, t))", + " continue;", + " }", + " From = To = II;", + " trpt->tau |= 32; /* preselect marker */", + " #ifdef VERBOSE", + " bfs_printf(\"%%3ld: proc %%d PreSelected (tau=%%d)\\n\", ", + " depth, II, trpt->tau);", + " #endif", + " goto Repeat_two;", + " } }", + " trpt->tau &= ~32;", + "#endif", + "", + "Repeat_one:", + " if (trpt->tau&8)", + " { From = To = (short ) trpt->pr; /* atomic */", + " } else", + " { From = now._nr_pr-1;", + " To = BASE;", + " }", + "#if defined(VERI) || !defined(NOREDUCE) || defined(ETIM)", + "Repeat_two: /* MainLoop */", + "#endif", + " _n = _m = 0;", + " for (II = From; II >= To; II -= 1) /* all processes */", + " {", + "#ifdef BFS_CHECK", + " bfs_printf(\"proc %%d (%%d - %%d)\\n\", II, From, To);", + "#endif", + "#if SYNC ", + " if (boq != -1 && trpt->pr == II)", + " { continue; /* no rendezvous with same proc */", + " }", + "#endif", + " _this = pptr(II);", + " tt = (int) ((P0 *)_this)->_p;", + " ot = (uchar) ((P0 *)_this)->_t;", + " ntrpt->pr = (uchar) II;", + " ntrpt->st = tt; ", + " trpt->o_pm &= ~1; /* no move yet */", + "#ifdef EVENT_TRACE", + " trpt->o_event = now._event;", + "#endif", + "#ifdef HAS_PRIORITY", + " if (!highest_priority(((P0 *)_this)->_pid, II, t))", + " { continue;", + " }", + "#else", + " #ifdef HAS_PROVIDED", + " if (!provided(II, ot, tt, t))", + " { continue;", + " }", + " #endif", + "#endif", + "#ifdef HAS_UNLESS", + " E_state = 0;", + "#endif", + " for (t = trans[ot][tt]; t; t = t->nxt) /* all process transitions */", + " {", + "#ifdef BFS_CHECK", + " assert(t_id_lkup[t->t_id] == t); /* for reverse lookup in bfs_unpack_state */", + "#endif", + "#ifdef VERBOSE", + " if (0) bfs_printf(\"\\tproc %%d tr %%d\\n\", II, t->forw);", + "#endif", + "#ifdef HAS_UNLESS", + " if (E_state > 0", + " && E_state != t->e_trans)", + " break;", + "#endif", + " /* trpt->o_t = */ ntrpt->o_t = t;", + " oboq = boq;", + "", + " if (!(_m = do_transit(t, II)))", + " continue;", + "", + " trpt->o_pm |= 1; /* we moved */", + " (trpt+1)->o_m = _m; /* for unsend */", + "#ifdef PEG", + " peg[t->forw]++;", + "#endif", + "#ifdef VERBOSE", + " e_critical(BFS_PRINT);", + " printf(\"%%3ld: proc %%d exec %%d, \",", + " depth, II, t->forw);", + " printf(\"%%d to %%d, %%s %%s %%s\",", + " tt, t->st, t->tp,", + " (t->atom&2)?\"atomic\":\"\",", + " (boq != -1)?\"rendez-vous\":\"\");", + " #ifdef HAS_UNLESS", + " if (t->e_trans)", + " printf(\" (escapes to state %%d)\", t->st);", + " #endif", + " printf(\" %%saccepting [tau=%%d]\\n\",", + " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);", + " x_critical(BFS_PRINT);", + "#endif", + "#ifdef HAS_UNLESS", + " E_state = t->e_trans;", + " #if SYNC>0", + " if (t->e_trans > 0 && boq != -1)", + " { fprintf(efd, \"error: rendezvous stmnt in the escape clause\\n\");", + " fprintf(efd, \" of unless stmnt not compatible with -DBFS\\n\");", + " pan_exit(1);", + " }", + " #endif", + "#endif", + " if (t->st > 0)", + " { ((P0 *)_this)->_p = t->st;", + " }", + " /* use the ostate ptr, with type *H_el, to temporarily store *BFS_Trail */", + "#ifdef BFS_NOTRAIL", + " ntrpt->ostate = (H_el *) 0; /* no error-traces in this mode */", + "#else", + " ntrpt->ostate = (H_el *) otrpt; /* parent stackframe */", + "#endif", + " /* ntrpt->st = tt; * was already set above */", + "", + " if (boq == -1 && (t->atom&2)) /* atomic */", + " { ntrpt->tau = 8; /* record for next move */", + " } else", + " { ntrpt->tau = 0; /* no timeout or preselect etc */", + " }", + "#ifdef VERI", + " ntrpt->tau |= trpt->tau&4; /* if claim, inherit */", + " if (boq == -1 && !(ntrpt->tau&8)) /* unless rv or atomic */", + " { if (ntrpt->tau&4) /* claim */", + " { ntrpt->tau &= ~4; /* switch to prog */", + " } else", + " { ntrpt->tau |= 4; /* switch to claim */", + " } }", + "#endif", + "#ifdef L_BOUND", + " { uchar obnd = now._l_bnd;", + " uchar *os = now._l_sds;", + " #ifdef VERBOSE", + " bfs_printf(\"saving bound %%d -- sds %%p\\n\", obnd, (void *) os);", + " #endif", + "#endif", + "", + " bfs_store_state(ntrpt, oboq);", + "#ifdef EVENT_TRACE", + " now._event = trpt->o_event;", + "#endif", + " /* undo move and generate other successor states */", + " trpt++; /* this is where ovals and ipt are set */", + " do_reverse(t, II, _m); /* restore now. */", + "#ifdef L_BOUND", + " #ifdef VERBOSE", + " bfs_printf(\"restoring bound %%d -- sds %%p\\n\", obnd, (void *) os);", + " #endif", + " now._l_bnd = obnd;", + " now._l_sds = os;", + " }", + "#endif", + " trpt--;", + "#ifdef VERBOSE", + " e_critical(BFS_PRINT);", + " printf(\"%%3ld: proc %%d \", depth, II);", + " printf(\"reverses %%d, %%d to %%d,\", t->forw, tt, t->st);", + " printf(\" %%s [abit=%%d,adepth=%%d,\", t->tp, now._a_t, 0);", + " printf(\"tau=%%d,%%d]\\n\", trpt->tau, (trpt-1)->tau);", + " x_critical(BFS_PRINT);", + "#endif", + " reached[ot][t->st] = 1;", + " reached[ot][tt] = 1;", + "", + " ((P0 *)_this)->_p = tt;", + " _n |= _m;", + " } }", + "#ifdef VERBOSE", + " bfs_printf(\"done _n = %%d\\n\", _n);", + "#endif", + "", + "#ifndef NOREDUCE", + " /* preselected - no succ definitely outside stack */", + " if ((trpt->tau&32) && !(trpt->tau&64))", + " { From = now._nr_pr-1; To = BASE;", + " #ifdef VERBOSE", + " bfs_printf(\"%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", + " depth, II+1, (int) _n, trpt->tau);", + " #endif", + " _n = 0; trpt->tau &= ~32;", + " if (II >= BASE)", + " { goto Pickup;", + " }", + " goto Repeat_two;", + " }", + " trpt->tau &= ~(32|64);", + "#endif", + " if (_n == 0", + "#ifdef VERI", + " && !(trpt->tau&4)", + "#endif", + " )", + " { /* no successor states generated */", + " if (boq != -1) /* was rv move */", + " { BFS_Trail *x = (BFS_Trail *) trpt->ostate; /* pre-rv state */", + " if (x && ((x->tau&8) || (x->tau&32))) /* break atomic or preselect */", + " { x->o_pm |= 8; /* mark failure */", + " _this = pptr(otrpt->pr);", + " ((P0 *) _this)->_p = otrpt->st; /* reset state */", + " unsend(boq); /* retract rv offer */", + " boq = -1;", + "#ifdef VERBOSE", + " printf(\"repush state\\n\");", + "#endif", + " bfs_push_state(NULL, x, x->o_tt); /* repush rv fail */", + " } /* else the rv need not be retried */", + " } else if (now._nr_pr > BASE) /* possible deadlock */", + " { if ((trpt->tau&8)) /* atomic step blocked */", + " { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */", + " goto Repeat_one;", + " }", + "#ifdef ETIM", + " /* if timeouts were used in the model */", + " if (!(trpt->tau&1))", + " { trpt->tau |= 1; /* enable timeout */", + " goto Repeat_two;", + " }", + "#endif", + " if (!noends && !endstate())", + " { bfs_uerror(\"invalid end state.\");", + " }", + " }", + "#ifdef VERI", + " else /* boq == -1 && now._nr_pr == BASE && trpt->tau != 4 */", + " { trpt->tau |= 4; /* switch to claim for stutter moves */", + " #ifdef VERBOSE", + " printf(\"%%3ld: proc -1 exec -1, (stutter move)\\n\", depth, II);", + " #endif", + " bfs_store_state(trpt, boq);", /* doesn't store it but queues it */ + " #ifdef VERBOSE", + " printf(\"%%3ld: proc -1 reverses -1, (stutter move)\\n\", depth, II);", + " #endif", + " trpt->tau &= ~4; /* undo, probably not needed */", + " }", + "#endif", + " }", + "#ifdef BFS_NOTRAIL", + " bfs_release_trail(otrpt);", + "#endif", + "}", + "#if !defined(BFS_FIFO) && !defined(BFS_NORECYCLE)", + "void", + "bfs_recycle(BFS_Slot *n)", + "{", + " #ifdef BFS_CHECK", + " assert(n != &bfs_null);", + " #endif", + " n->nxt = bfs_free_slot;", + " bfs_free_slot = n;", + "", + " #ifdef BFS_CHECK", + " bfs_printf(\"recycles %%s -- %%p\\n\",", + " n->s_data?\"STATE\":\"EMPTY\", (void *) n);", + " #endif", + "}", + "#endif", + "#ifdef BFS_FIFO", + "int", + "bfs_empty(int p)", /* return Cores if all empty or index of first non-empty q of p */ + "{ int i;", + " const int dst = 0;", + " for (i = 0; i < Cores; i++)", + " { if (shared_memory->head[dst][p][i] != (BFS_Slot *) 0)", + " {", + " volatile BFS_Slot *x = shared_memory->head[dst][p][i];", + " while (x && x->type == DELETED)", + " { x = x->nxt;", + " }", + " if (!x)", + " { continue;", + " }", + " if (p == who_am_i)", + " { shared_memory->head[dst][p][i] = x;", + " }", + " #ifdef BFS_CHECK", + " bfs_printf(\"input q [%%d][%%d][%%d] !empty\\n\",", + " dst, p, i);", + " #endif", + " return i;", + " } }", + " #ifdef BFS_CHECK", + " bfs_printf(\"all input qs [%%d][%%d][0..max] empty\\n\",", + " dst, p);", + " #endif ", + " return Cores;", + "}", + "#endif", + "#ifdef BFS_DISK", + "void", + "bfs_ewrite(int fd, const void *p, size_t count)", + "{", + " if (write(fd, p, count) != count)", + " { perror(\"diskwrite\");", + " Uerror(\"aborting\");", + " }", + "}", + "", + "void", + "bfs_eread(int fd, void *p, size_t count)", + "{", + " if (read(fd, p, count) != count)", + " { perror(\"diskread\");", + " Uerror(\"aborting\");", + " }", + "}", + "", + "void", + "bfs_sink_disk(int who_are_you, BFS_Slot *n)", + "{ SV_Hold *x;", + "#ifdef VERBOSE", + " bfs_printf(\"sink_disk -> %%d\\n\", who_are_you);", + "#endif", + " bfs_ewrite(bfs_out_fd[who_are_you], (const void *) n->s_data->t_info, sizeof(BFS_Trail));", + " bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &vsize, sizeof(ulong));", + " bfs_ewrite(bfs_out_fd[who_are_you], &now, vsize);", + "", + " bfs_release_trail(n->s_data->t_info);", + " n->s_data->t_info = (BFS_Trail *) 0;", + "", + "#if NRUNS>0", + " bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->omask), sizeof(EV_Hold *));", + "#endif", + "#ifdef Q_PROVISO", + " bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->lstate), sizeof(H_el *));", + "#endif", + "#if SYNC>0", + " bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->boq), sizeof(short));", + "#endif", + "#if VERBOSE", + " bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->nr), sizeof(ulong));", + "#endif", + " shared_memory->bfs_out_cnt[who_am_i] = 1;", /* wrote at least one state */ + "}", + "void", + "bfs_source_disk(int fd, volatile BFS_Slot *n)", + "{ ulong nb; /* local temporary */", + " SV_Hold *x;", + "#ifdef VERBOSE", + " bfs_printf(\"source_disk <- %%d\\n\", who_am_i);", + "#endif", + " n->s_data->t_info = bfs_grab_trail();", + " bfs_eread(fd, (void *) n->s_data->t_info, sizeof(BFS_Trail));", + " bfs_eread(fd, (void *) &nb, sizeof(ulong));", + "", + " x = bfs_new_sv(nb); /* space for osv isn't already allocated */", + " n->s_data->osv = x->sv;", + " x->sv = (State *) 0;", + " x->nxt = bfs_free_hold;", + " bfs_free_hold = x;", + "", + " bfs_eread(fd, (void *) n->s_data->osv, (size_t) nb);", + "#if NRUNS>0", + " bfs_eread(fd, (void *) &(n->s_data->omask), sizeof(EV_Hold *));", + "#endif", + "#ifdef Q_PROVISO", + " bfs_eread(fd, (void *) &(n->s_data->lstate), sizeof(H_el *));", + "#endif", + "#if SYNC>0", + " bfs_eread(fd, (void *) &(n->s_data->boq), sizeof(short));", + "#endif", + "#if VERBOSE", + " bfs_eread(fd, (void *) &(n->s_data->nr), sizeof(ulong));", + "#endif", + "}", + "#endif", + "", + "#ifndef BFS_QSZ", + " #ifdef BFS_STAGGER", + "static BFS_Slot *bfs_stage[BFS_STAGGER];", + "", + "static void", + "bfs_stagger_flush(void)", + "{ int i, who_are_you;", + " int dst = 1 - bfs_toggle;", + " BFS_Slot *n;", + " who_are_you = (rand()%%Cores);", /* important: all to the same cpu, but reversed */ + " for (i = bfs_stage_cnt-1; i >= 0; i--)", + " { n = bfs_stage[i];", + " #ifdef BFS_DISK", + " bfs_sink_disk(who_are_you, n);", + " bfs_stage[i] = (BFS_Slot *) 0;", + " #endif", + " n->nxt = (BFS_Slot *) shared_memory->head[dst][who_are_you][who_am_i];", + " shared_memory->head[dst][who_are_you][who_am_i] = n;", + " /* bfs_sent++; */", + " }", + " #ifdef VERBOSE", + " bfs_printf(\"stagger flush %%d states to %%d\\n\",", + " bfs_stage_cnt, who_are_you);", + " #endif", + " bfs_stage_cnt = 0;", + "}", + "", + "void", + "bfs_stagger_add(BFS_Slot *n)", + "{", + " if (bfs_stage_cnt == BFS_STAGGER)", + " { bfs_stagger_flush();", + " }", + " bfs_stage[bfs_stage_cnt++] = n;", + "}", + " #endif", + "#endif", + "", + "void", + "bfs_push_state(Trail *x, BFS_Trail *y, int tt)", + "{ int who_are_you;", + "#ifdef BFS_FIFO", + " const int dst = 0;", + "#else", + " int dst = 1 - bfs_toggle;", + "#endif", + "#ifdef BFS_QSZ", + " uint z;", + " if (bfs_keep_state > 0)", + " { who_are_you = bfs_keep_state - 1;", + " } else", + " { who_are_you = (rand()%%Cores);", + " }", + " z = shared_memory->bfs_ix[dst][who_are_you][who_am_i];", + " if (z >= BFS_QSZ)", + " { static int warned_qloss = 0;", + " if (warned_qloss == 0 && who_am_i == 0)", + " { warned_qloss++;", + " bfs_printf(\"BFS_QSZ too small - losing states\\n\");", + " }", + " bfs_punt++;", + " return;", + " }", + " shared_memory->bfs_ix[dst][who_are_you][who_am_i] = z+1;", + " BFS_Slot *n = bfs_pack_state(x, y, tt, bfs_prep_slot(y, ", + " (BFS_Slot *) &(shared_memory->bfsq[dst][who_are_you][who_am_i][z])));", + "#else", + " BFS_Slot *n = bfs_pack_state(x, y, tt, bfs_new_slot(y));", + "", + " #ifdef BFS_GREEDY", + " who_are_you = who_am_i; /* for testing only */", + " #else", + " if (bfs_keep_state > 0)", + " { who_are_you = bfs_keep_state - 1;", + " } else", + " {", + " #ifdef BFS_STAGGER", + " who_are_you = -1;", + " bfs_stagger_add(n);", + " goto done;", + " #else", + " who_are_you = (rand()%%Cores);", + " #endif", + " }", + " #endif", + " #ifdef BFS_FIFO", + " if (!shared_memory->tail[dst][who_are_you][who_am_i])", + " { shared_memory->dels[dst][who_are_you][who_am_i] =", + " shared_memory->tail[dst][who_are_you][who_am_i] =", + " shared_memory->head[dst][who_are_you][who_am_i] = n;", + " } else", + " { shared_memory->tail[dst][who_are_you][who_am_i]->nxt = n;", + " shared_memory->tail[dst][who_are_you][who_am_i] = n;", + " }", + " shared_memory->bfs_idle[who_are_you] = 0;", + " #else", + " #ifdef BFS_DISK", + " bfs_sink_disk(who_are_you, n);", + " #endif", + " n->nxt = (BFS_Slot *) shared_memory->head[dst][who_are_you][who_am_i];", + " shared_memory->head[dst][who_are_you][who_am_i] = n;", + " #endif", + " #ifdef BFS_STAGGER", + "done:", + " #endif", + "#endif", /* BFS_QSZ */ + "#ifdef VERBOSE", + " bfs_printf(\"PUT STATE (depth %%ld, nr %%u) to %%d -- s_data: %%p\\n\",", + " tt, n->s_data->nr, who_are_you, n->s_data);", + "#endif", + " bfs_sent++;", + "}", + "", + "BFS_Slot *", + "bfs_next(void)", + "{ volatile BFS_Slot *n = &bfs_null;", + " #ifdef BFS_FIFO", + " const int src = 0;", + " bfs_qscan = bfs_empty(who_am_i);", + " #else", + " const int src = bfs_toggle;", + " #ifdef BFS_QSZ", + " while (bfs_qscan < Cores", + " && shared_memory->bfs_ix[src][who_am_i][bfs_qscan] == 0)", + " { bfs_qscan++;", + " }", + " #else", + " while (bfs_qscan < Cores", + " && shared_memory->head[src][who_am_i][bfs_qscan] == (BFS_Slot *) 0)", + " { bfs_qscan++;", + " }", + " #endif", + " #endif", + " if (bfs_qscan < Cores)", + " {", + " #ifdef BFS_FIFO", /* no wait for toggles */ + " shared_memory->bfs_idle[who_am_i] = 0;", + " for (n = shared_memory->head[src][who_am_i][bfs_qscan]; n; n = n->nxt)", + " { if (n->type != DELETED)", + " { break;", + " } }", + " #ifdef BFS_CHECK", + " assert(n && n->type == STATE); /* q cannot be empty */", + " #endif", + " if (n->nxt)", + " { shared_memory->head[src][who_am_i][bfs_qscan] = n->nxt;", + " }", /* else, do not remove it - yet - avoid empty queues */ + " n->type = DELETED;", + " #else", + " #ifdef BFS_QSZ", + " uint x = --shared_memory->bfs_ix[src][who_am_i][bfs_qscan];", + " n = &(shared_memory->bfsq[src][who_am_i][bfs_qscan][x]);", + " #else", + " n = shared_memory->head[src][who_am_i][bfs_qscan];", + " shared_memory->head[src][who_am_i][bfs_qscan] = n->nxt;", + " #if defined(BFS_FIFO) && defined(BFS_CHECK)", + " assert(n->type == STATE);", + " #endif", + " n->nxt = (BFS_Slot *) 0;", + " #endif", + " #ifdef BFS_DISK", + " /* the states actually show up in reverse order (FIFO iso LIFO) here */", + " /* but that doesn't really matter as long as the count is right */", + " bfs_source_disk(bfs_inp_fd[bfs_qscan], n); /* get the data */", + " #endif", + + " #endif", + " #ifdef BFS_CHECK", + " bfs_printf(\"rcv STATE from [%%d][%%d][%%d]\\n\",", + " src, who_am_i, bfs_qscan);", + " #endif", + " bfs_rcvd++;", + " } else", + " {", + " #if defined(BFS_STAGGER) && !defined(BFS_QSZ)", + " if (bfs_stage_cnt > 0)", + " { bfs_stagger_flush();", + " }", + " #endif", + " shared_memory->bfs_idle[who_am_i] = 1;", + " #if defined(BFS_FIFO) && defined(BFS_CHECK)", + " assert(n->type == EMPTY);", + " #endif", + " }", + " return (BFS_Slot *) n;", + "}", + "", + "int", + "bfs_all_empty(void)", + "{ int i;", + "#ifdef BFS_DISK", + " for (i = 0; i < Cores; i++)", + " { if (shared_memory->bfs_out_cnt[i] != 0)", + " {", + " #ifdef VERBOSE", + " bfs_printf(\"bfs_all_empty %%d not empty\\n\", i);", + " #endif", + " return 0;", + " } }", + "#else", + " int p;", + " #ifdef BFS_FIFO", + " const int dst = 0;", + " #else", + " int dst = 1 - bfs_toggle; /* next generation */", + " #endif", + " for (p = 0; p < Cores; p++)", + " for (i = 0; i < Cores; i++)", + " #ifdef BFS_QSZ", + " { if (shared_memory->bfs_ix[dst][p][i] > 0)", + " #else", + " { if (shared_memory->head[dst][p][i] != (BFS_Slot *) 0)", + " #endif", + " { return 0;", + " } }", + "#endif", + "#ifdef VERBOSE", + " bfs_printf(\"bfs_all_empty\\n\");", + "#endif", + " return 1;", + "}", + "", + "#ifdef BFS_FIFO", + "BFS_Slot *", + "bfs_sweep(void)", + "{ BFS_Slot *n;", + " int i;", + " for (i = 0; i < Cores; i++)", + " for (n = (BFS_Slot *) shared_memory->dels[0][who_am_i][i];", + " n && n != shared_memory->head[0][who_am_i][i];", + " n = n->nxt)", + " { if (n->type == DELETED && n->nxt)", + " { shared_memory->dels[0][who_am_i][i] = n->nxt;", + " n->nxt = (BFS_Slot *) 0;", + " return n;", + " } }", + " return (BFS_Slot *) sh_malloc((ulong) sizeof(BFS_Slot));", + "}", + "#endif", + "", + "typedef struct BFS_T_Hold BFS_T_Hold;", + "struct BFS_T_Hold {", + " volatile BFS_Trail *t;", + " BFS_T_Hold *nxt;", + "};", + "BFS_T_Hold *bfs_t_held, *bfs_t_free;", + "", + "BFS_Trail *", + "bfs_grab_trail(void)", /* call in bfs_source_disk and bfs_new_slot */ + "{ BFS_Trail *t;", + " BFS_T_Hold *h;", + "", + "#ifdef VERBOSE", + " bfs_printf(\"grab trail - bfs_t_held %%p\\n\", (void *) bfs_t_held);", + "#endif", + " if (bfs_t_held)", + " { h = bfs_t_held;", + " bfs_t_held = bfs_t_held->nxt;", + " t = (BFS_Trail *) h->t;", + " h->t = (BFS_Trail *) 0; /* make sure it cannot be reused */", + " h->nxt = bfs_t_free;", + " bfs_t_free = h;", + "", + " } else", + " { t = (BFS_Trail *) sh_malloc((ulong) sizeof(BFS_Trail));", + " }", + "#ifdef BFS_CHECK", + " assert(t);", + "#endif", + " t->ostate = (H_el *) 0;", + "#ifdef VERBOSE", + " bfs_printf(\"grab trail %%p\\n\", (void *) t);", + "#endif", + " return t;", + "}", + "", + "#if defined(BFS_DISK) || defined(BFS_NOTRAIL)", + "void", + "bfs_release_trail(BFS_Trail *t)", /* call in bfs_sink_disk (not bfs_recycle) */ + "{ BFS_T_Hold *h;", + " #ifdef BFS_CHECK", + " assert(t);", + " #endif", + " #ifdef VERBOSE", + " bfs_printf(\"release trail %%p\\n\", (void *) t);", + " #endif", + " if (bfs_t_free)", + " { h = bfs_t_free;", + " bfs_t_free = bfs_t_free->nxt;", + " } else", + " { h = (BFS_T_Hold *) emalloc(sizeof(BFS_T_Hold));", + " }", + " h->t = t;", + " h->nxt = bfs_t_held;", + " bfs_t_held = h;", + " #ifdef VERBOSE", + " bfs_printf(\"release trail - bfs_t_held %%p\\n\", (void *) bfs_t_held);", + " #endif", + "}", + "#endif", + "", + "#ifndef BFS_QSZ", + "BFS_Slot *", + "bfs_new_slot(BFS_Trail *f)", + "{ BFS_Slot *t;", + "", + "#ifdef BFS_FIFO", + " t = bfs_sweep();", + "#else", + " if (bfs_free_slot) /* local */", + " { t = bfs_free_slot;", + " bfs_free_slot = bfs_free_slot->nxt;", + " t->nxt = (BFS_Slot *) 0;", + " } else", + " { t = (BFS_Slot *) sh_malloc((ulong) sizeof(BFS_Slot));", + " }", + "#endif", + " if (t->s_data)", + " { memset(t->s_data, 0, sizeof(BFS_State));", + " } else", + " { t->s_data = (BFS_State *) sh_malloc((ulong) sizeof(BFS_State));", + " }", + "", + " /* we keep a ptr to the frame of parent states, which is */", + " /* used for reconstructing path and recovering failed rvs etc */", + " /* we should not overwrite the data at this address with a memset */", + "", + " if (f)", + " { t->s_data->t_info = f;", + " } else", + " { t->s_data->t_info = bfs_grab_trail();", + " }", + " return t;", + "}", + "#else", + "BFS_Slot *", + "bfs_prep_slot(BFS_Trail *f, BFS_Slot *t)", + "{", + " if (t->s_data)", + " { memset(t->s_data, 0, sizeof(BFS_State));", + " } else", + " { t->s_data = (BFS_State *) sh_malloc((ulong) sizeof(BFS_State));", + " }", + " if (f)", + " { t->s_data->t_info = f;", + " } else", + " { t->s_data->t_info = bfs_grab_trail();", + " }", + " return t;", + "}", + "#endif", + "", + "SV_Hold *", + "bfs_new_sv(int n)", + "{ SV_Hold *h;", + "", + " if (bfs_svfree[n])", + " { h = bfs_svfree[n];", + " bfs_svfree[n] = h->nxt;", + " h->nxt = (SV_Hold *) 0;", + " } else", + " { h = (SV_Hold *) sh_malloc((ulong) sizeof(SV_Hold));", + "#if 0", + " h->sz = n;", + "#endif", + " h->sv = (State *) sh_malloc((ulong)(sizeof(State) - VECTORSZ + n));", + " }", + " memcpy((char *)h->sv, (char *)&now, n);", + " return h;", + "}", + "#if NRUNS>0", + "static EV_Hold *kept[VECTORSZ]; /* local */", + "", + "static void", + "bfs_keep(EV_Hold *v)", + "{ EV_Hold *h;", + "", + " for (h = kept[v->sz]; h; h = h->nxt) /* check local list */", + " { if (v->nrpr == h->nrpr", + " && v->nrqs == h->nrqs", + "#if !defined(NOCOMP) && !defined(HC)", + " && (v->sv == h->sv || memcmp((char *) v->sv, (char *) h->sv, v->sz) == 0)", + "#endif", + "#ifdef TRIX", + " )", + "#else", + " #if NRUNS>0", + " #if VECTORSZ>32000", + " && (memcmp((char *) v->po, (char *) h->po, v->nrpr * sizeof(int)) == 0)", + " && (memcmp((char *) v->qo, (char *) h->qo, v->nrqs * sizeof(int)) == 0)", + " #else", + " && (memcmp((char *) v->po, (char *) h->po, v->nrpr * sizeof(short)) == 0)", + " && (memcmp((char *) v->qo, (char *) h->qo, v->nrqs * sizeof(short)) == 0)", + " #endif", + " && (memcmp((char *) v->ps, (char *) h->ps, v->nrpr * sizeof(uchar)) == 0)", + " && (memcmp((char *) v->qs, (char *) h->qs, v->nrqs * sizeof(uchar)) == 0))", + " #else", + " )", + " #endif", + "#endif", + " { break;", + " } }", + "", + " if (!h) /* we don't have one like it yet */", + " { v->nxt = kept[v->sz]; /* keep the original owner field */", + " kept[v->sz] = v;", + " /* all ptrs inside are to shared memory, but nxt is local */", + " }", + "}", + "", + "EV_Hold *", + "bfs_new_sv_mask(int n)", + "{ EV_Hold *h;", + "", + " for (h = kept[n]; h; h = h->nxt)", + " { if ((now._nr_pr == h->nrpr)", + " && (now._nr_qs == h->nrqs)", + "#if !defined(NOCOMP) && !defined(HC) && NRUNS>0", + " && ((char *) Mask == h->sv || (memcmp((char *) Mask, h->sv, n) == 0))", + "#endif", + "#ifdef TRIX", + " )", + "#else", + " #if NRUNS>0", + " #if VECTORSZ>32000", + " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(int)) == 0)", + " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(int)) == 0)", + " #else", + " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(short)) == 0)", + " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(short)) == 0)", + " #endif", + " && (memcmp((char *) proc_skip, (char *) h->ps, now._nr_pr * sizeof(uchar)) == 0)", + " && (memcmp((char *) q_skip, (char *) h->qs, now._nr_qs * sizeof(uchar)) == 0))", + " #else", + " )", + " #endif", + "#endif", + " { break;", + " } }", + "", + " if (!h)", + " { /* once created, the contents are never modified */", + " h = (EV_Hold *) sh_malloc((ulong)sizeof(EV_Hold));", + " h->owner = who_am_i;", + " h->sz = n;", + " h->nrpr = now._nr_pr;", + " h->nrqs = now._nr_qs;", + "#if !defined(NOCOMP) && !defined(HC) && NRUNS>0", + " h->sv = (char *) Mask; /* in shared memory, and never modified */", + "#endif", + "#if NRUNS>0 && !defined(TRIX)", + " if (now._nr_pr > 0)", + " { h->ps = (char *) proc_skip;", + " h->po = (char *) proc_offset;", + " }", + " if (now._nr_qs > 0)", + " { h->qs = (char *) q_skip;", + " h->qo = (char *) q_offset;", + " }", + "#endif", + " h->nxt = kept[n];", + " kept[n] = h;", + " }", + " return h;", + "}", + "#endif", /* NRUNS>0 */ + "BFS_Slot *", + "bfs_pack_state(Trail *f, BFS_Trail *g, int search_depth, BFS_Slot *t)", + "{", + "#ifdef BFS_CHECK", + " assert(t->s_data != NULL);", + " assert(t->s_data->t_info != NULL);", + " assert(f || g);", + "#endif", + " if (!g)", + " { t->s_data->t_info->ostate = f->ostate;", + " t->s_data->t_info->st = f->st;", + " t->s_data->t_info->o_tt = search_depth;", + " t->s_data->t_info->pr = f->pr;", + " t->s_data->t_info->tau = f->tau;", + " t->s_data->t_info->o_pm = f->o_pm;", + " if (f->o_t)", + " { t->s_data->t_info->t_id = f->o_t->t_id;", + " } else", + " { t->s_data->t_info->t_id = -1;", + " t->s_data->t_info->ostate = NULL;", + " }", + " } /* else t->s_data->t_info == g */", + "#if SYNC", + " t->s_data->boq = boq;", + "#endif", + "#ifdef VERBOSE", + " { static ulong u_cnt;", + " t->s_data->nr = u_cnt++;", + " }", + "#endif", + "#ifdef TRIX", + " sv_populate(); /* make sure now is up to date */", + "#endif", + "#ifndef BFS_DISK", + " { SV_Hold *x = bfs_new_sv(vsize);", + " t->s_data->osv = x->sv;", + " x->sv = (State *) 0;", + " x->nxt = bfs_free_hold;", + " bfs_free_hold = x;", + " }", + "#endif", + "#if NRUNS>0", + " t->s_data->omask = bfs_new_sv_mask(vsize);", + "#endif", + "", + "#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)", + " t->s_data->lstate = Lstate; /* Lstate is set in o_store or h_store */", + "#endif", + "#ifdef BFS_FIFO", + " t->type = STATE;", + "#endif", + " return t;", + "}", + "", + "void", + "bfs_store_state(Trail *t, short oboq)", + "{", + "#ifdef TRIX", + " sv_populate();", + "#endif", + "#if defined(VERI) && defined(Q_PROVISO) && !defined(BITSTATE) && defined(FULLSTACK)", + " if (!(t->tau&4)", /* prog move */ + " && t->ostate)", /* not initial state */ + " { t->tau |= ((BFS_Trail *) t->ostate)->tau&64;", + " } /* lift 64 across claim moves */", + "#endif", + "", + "#ifdef BFS_SEP_HASH", + " #if SYNC", + " if (boq == -1 && oboq != -1) /* post-rv */", + " { BFS_Trail *x = (BFS_Trail *) trpt->ostate; /* pre-rv state */", + " if (x)", + " { x->o_pm |= 4; /* rv complete */", + " } }", + " #endif", + " d_sfh((uchar *)&now, (int) vsize); /* sep-hash -- sets K1 -- overkill */", + " bfs_keep_state = K1%%Cores + 1;", + " bfs_push_state(t, NULL, trpt->o_tt+1); /* bfs_store_state - sep_hash */", + " bfs_keep_state = 0;", + "#else", + " #ifdef VERI", +#if 0 + in VERI mode store the state when + (!t->ostate || (t->tau&4)) in initial state and after each program move + + i.e., dont store when !(!t->ostate || (t->tau&4)) = (t->ostate && !(t->tau&4)) + the *first* time that the tau flag is not set: + possibly after a series of claim moves in an atomic sequence +#endif + " if (!(t->tau&4) && t->ostate && (((BFS_Trail *)t->ostate)->tau&4))", + " { /* do not store intermediate state */", + " #if defined(VERBOSE) && defined(L_BOUND)", + " bfs_printf(\"Un-Stored state bnd %%d -- sds %%p\\n\",", + " now._l_bnd, now._l_sds);", + " #endif", + " bfs_push_state(t, NULL, trpt->o_tt+1); /* claim move */", + " } else", + " #endif", + " if (!bfs_do_store((char *)&now, vsize)) /* includes bfs_visited */", + " { nstates++; /* local count */", + " trpt->tau |= 64; /* bfs: succ outside stack */", + " #if SYNC", + " if (boq == -1 && oboq != -1) /* post-rv */", + " { BFS_Trail *x = ", + " (BFS_Trail *) trpt->ostate; /* pre-rv state */", + " if (x)", + " { x->o_pm |= 4; /* rv complete */", + " } }", + " #endif", + " bfs_push_state(t, NULL, trpt->o_tt+1); /* successor */", + " } else", + " { truncs++;", + " #ifdef BFS_CHECK", + " bfs_printf(\"seen before\\n\");", + " #endif", + " #if defined(Q_PROVISO) && !defined(BITSTATE) && defined(FULLSTACK)", + " #ifdef USE_TDH", + " if (Lstate)", /* if BFS_INQ is set */ + " { trpt->tau |= 64;", + " }", + " #else", + " if (Lstate && Lstate->tagged) /* bfs_store_state */", + " { trpt->tau |= 64;", + " }", + " #endif", + " #endif", + " }", + "#endif", + "}", + "", + "/*** support routines ***/", + "", + "void", + "bfs_clear_locks(void)", + "{ int i;", + "", + " /* clear any locks held by this process only */", + " if (shared_memory)", + " for (i = 0; i < BFS_MAXLOCKS; i++)", + " { if (shared_memory->sh_owner[i] == who_am_i + 1)", + " { shared_memory->sh_locks[i] = 0;", + "#ifdef BFS_CHECK", + " shared_memory->in_count[i] = 0;", + "#endif", + " shared_memory->sh_owner[i] = 0;", + " } }", + "}", + "", + "void", + "e_critical(int which)", + "{ int w;", + "#ifdef BFS_CHECK", + " assert(which >= 0 && which < BFS_MAXLOCKS);", + "#endif", + " if (shared_memory == NULL) return;", + " while (tas(&(shared_memory->sh_locks[which])) != 0)", + " { w = shared_memory->sh_owner[which]; /* sh_locks[which] could be 0 by now */", + " assert(w >= 0 && w <= BFS_MAXPROCS);", + " if (w > 0 && shared_memory->bfs_flag[w-1] == 2)", + " { /* multiple processes can get here; only one should do this: */", + " if (tas(&(shared_memory->bfs_data[w - 1].override)) == 0)", + " { fprintf(stderr, \"cpu%%02d: override lock %%d - held by %%d\\n\",", + " who_am_i, which, shared_memory->sh_owner[which]);", + "#ifdef BFS_CHECK", + " shared_memory->in_count[which] = 0;", + "#endif", + " shared_memory->sh_locks[which] = 0;", + " shared_memory->sh_owner[which] = 0;", + " } }", + " shared_memory->wait_count[which]++; /* not atomic of course */", + " }", + "#ifdef BFS_CHECK", + " if (shared_memory->in_count[which] != 0)", + " { fprintf(stderr, \"cpu%%02d: cannot happen lock %%d count %%d\\n\", who_am_i,", + " which, shared_memory->in_count[which]);", + " }", + " shared_memory->in_count[which]++;", + "#endif", + " shared_memory->sh_owner[which] = who_am_i+1;", + "}", + "", + "void", + "x_critical(int which)", + "{", + " if (shared_memory == NULL) return;", + "#ifdef BFS_CHECK", + " assert(shared_memory->in_count[which] == 1);", + " shared_memory->in_count[which] = 0;", + "#endif", + " shared_memory->sh_locks[which] = 0;", + " shared_memory->sh_owner[which] = 0;", + "}", + "", + "void", + "bfs_printf(const char *fmt, ...)", + "{ va_list args;", + "", + " e_critical(BFS_PRINT);", + "#ifdef BFS_CHECK", + " if (1) { int i=who_am_i; while (i-- > 0) printf(\" \"); }", + "#endif", + " printf(\"cpu%%02d: \", who_am_i);", + " va_start(args, fmt);", + " vprintf(fmt, args);", + " va_end(args);", + " fflush(stdout);", + " x_critical(BFS_PRINT);", + "}", + "", + "int", + "bfs_all_idle(void)", + "{ int i;", + "", + " if (shared_memory)", + " for (i = 0; i < Cores; i++)", + " { if (shared_memory->bfs_flag[i] == 0", + " && shared_memory->bfs_idle[i] == 0)", + " { return 0;", + " } }", + " return 1;", + "}", + "", + "#ifdef BFS_FIFO", + "int", + "bfs_idle_and_empty(void)", + "{ int p; /* read-only */", + " for (p = 0; p < Cores; p++)", + " { if (shared_memory->bfs_flag[p] == 0", + " && shared_memory->bfs_idle[p] == 0)", + " { return 0;", + " } }", + " for (p = 0; p < Cores; p++)", + " { if (bfs_empty(p) < Cores)", + " { return 0;", + " } }", + " return 1;", + "}", + "#endif", + "", + "void", + "bfs_set_toggle(void) /* executed by root */", + "{ int i;", + "", + " if (shared_memory)", + " for (i = 0; i < Cores; i++)", + " { shared_memory->bfs_idle[i] = 0;", + " }", + "}", + "", + "int", + "bfs_all_running(void) /* crash detection */", + "{ int i;", + " for (i = 0; i < Cores; i++)", + " { if (!shared_memory || shared_memory->bfs_flag[i] > 1)", + " { return 0;", + " } }", + " return 1;", + "}", + "", + "void", + "bfs_mark_done(int code)", + "{", + " if (shared_memory)", + " { shared_memory->bfs_flag[who_am_i] = (int) code;", + " shared_memory->quit = 1;", + " }", + "}", + "", + "static uchar *", + "bfs_offset(int c)", + "{ int p, N;", + "#ifdef COLLAPSE", + " uchar *q = (uchar *) ncomps; /* it is the first object allocated */", + " q += (256+2) * sizeof(ulong); /* preserve contents of ncomps */", + "#else", + " uchar *q = (uchar *) &(shared_memory->allocator);", + "#endif", + " /* _NP_+1 proctypes, reachability info:", + " * reached[x : 0 .. _NP_+1][ 0 .. NrStates[x] ]", + " */", + " for (p = N = 0; p <= _NP_; p++)", + " { N += NrStates[p]; /* sum for all proctypes */", + " }", + "", + " /* space needed per proctype: N bytes */", + " /* rounded up to a multiple of the word size */", + " if ((N%%sizeof(void *)) != 0) /* aligned */", + " { N += sizeof(void *) - (N%%sizeof(void *));", + " }", + "", + " q += ((c - 1) * (_NP_ + 1) * N);", + " return q;", + "}", + "", + "static void", + "bfs_putreached(void)", + "{ uchar *q;", + " int p;", + "", + " assert(who_am_i > 0);", + "", + " q = bfs_offset(who_am_i);", + " for (p = 0; p <= _NP_; p++)", + " { memcpy((void *) q, (const void *) reached[p], (size_t) NrStates[p]);", + " q += NrStates[p];", + " }", + "}", + "", + "static void", + "bfs_getreached(int c)", + "{ uchar *q;", + " int p, i;", + "", + " assert(who_am_i == 0 && c >= 1 && c < Cores);", + "", + " q = (uchar *) bfs_offset(c);", + " for (p = 0; p <= _NP_; p++)", + " for (i = 0; i < NrStates[p]; i++)", + " { reached[p][i] += *q++; /* update local copy */", + " }", + "}", + "", + "void", + "bfs_update(void)", + "{ int i;", + " volatile BFS_data *s;", + "", + " if (!shared_memory) return;", + "", + " s = &shared_memory->bfs_data[who_am_i];", + " if (who_am_i == 0)", + " { shared_memory->bfs_flag[who_am_i] = 3; /* or else others don't stop */", + " bfs_gcount = 0;", + " for (i = 1; i < Cores; i++) /* start at 1 not 0 */", + " { while (shared_memory->bfs_flag[i] == 0)", + " { sleep(1);", + " if (bfs_gcount++ > WAIT_MAX) /* excessively long wait */", + " { printf(\"cpu00: give up waiting for cpu%%2d (%%d cores)\\n\", i, Cores);", + " bfs_gcount = 0;", + " break;", + " } }", + " s = &shared_memory->bfs_data[i];", + " mreached = Max(mreached, s->mreached);", + " hmax = vsize = Max(vsize, s->vsize);", + " errors += s->errors;", + " memcnt += s->memcnt;", + " nstates += s->nstates;", + " nlinks += s->nlinks;", + " truncs += s->truncs;", + " bfs_left += s->memory_left;", + " bfs_punt += s->punted;", + " bfs_getreached(i);", + " }", + " } else", + " { s->mreached = (ulong) mreached;", + " s->vsize = (ulong) vsize;", + " s->errors = (int) errors;", + " s->memcnt = (double) memcnt;", + " s->nstates = (double) nstates;", + " s->nlinks = (double) nlinks;", + " s->truncs = (double) truncs;", + " s->memory_left = (ulong) bfs_left;", + " s->punted = (ulong) bfs_punt;", + " bfs_putreached();", + " }", + "}", + "", + "volatile uchar *", + "sh_pre_malloc(ulong n) /* used before the local heaps are populated */", + "{ volatile uchar *ptr = NULL;", + "", + " assert(!bfs_runs);", + " if ((n%%sizeof(void *)) != 0)", + " { n += sizeof(void *) - (n%%sizeof(void *));", + " assert((n%%sizeof(void *)) == 0);", + " }", + "", + " e_critical(BFS_MEM); /* needed? */", + " if (shared_memory->mem_left < n + 7)", /* 7 for possible alignment */ + " { x_critical(BFS_MEM);", + " bfs_printf(\"want %%lu, have %%lu\\n\",", + " n, shared_memory->mem_left);", + " bfs_shutdown(\"out of shared memory\");", + " assert(0); /* should be unreachable */", + " }", + " ptr = shared_memory->allocator;", + "#if WS>4", /* align to 8 byte boundary */ + " { int b = (int) ((uint64_t) ptr)&7;", + " if (b != 0)", + " { ptr += (8-b);", + " shared_memory->allocator = ptr;", + " } }", + "#endif", + " shared_memory->allocator += n;", + " shared_memory->mem_left -= n;", + " x_critical(BFS_MEM);", + "", + " bfs_pre_allocated += n;", + "", + " return ptr;", + "}", + "", + "volatile uchar *", + "sh_malloc(ulong n)", + "{ volatile uchar *ptr = NULL;", + "#ifdef BFS_CHECK", + " assert(bfs_runs);", + "#endif", + " if ((n%%sizeof(void *)) != 0)", + " { n += sizeof(void *) - (n%%sizeof(void *));", + "#ifdef BFS_CHECK", + " assert((n%%sizeof(void *)) == 0);", + "#endif", + " }", + "", + " /* local heap -- no locks needed */", + " if (bfs_left < n)", + " { e_critical(BFS_MEM);", + " if (shared_memory->mem_left >= n)", + " { ptr = (uchar *) shared_memory->allocator;", + " shared_memory->allocator += n;", + " shared_memory->mem_left -= n;", + " x_critical(BFS_MEM);", + " return ptr;", + " }", + " x_critical(BFS_MEM);", + "#ifdef BFS_LOGMEM", + " int i;", + " e_critical(BFS_MEM);", + " for (i = 0; i < 1024; i++)", + " { if (shared_memory->logmem[i] > 0)", + " { bfs_printf(\"\tlog[%%d]\t%%d\\n\", i, shared_memory->logmem[i]);", + " } }", + " x_critical(BFS_MEM);", + "#endif", + " bfs_shutdown(\"out of shared memory\"); /* no return */", + " }", + "#ifdef BFS_LOGMEM", + " e_critical(BFS_MEM);", + " if (n < 1023)", + " { shared_memory->logmem[n]++;", + " } else", + " { shared_memory->logmem[1023]++;", + " }", + " x_critical(BFS_MEM);", + "#endif", + " ptr = (uchar *) bfs_heap;", + " bfs_heap += n;", + " bfs_left -= n;", + "", + " if (0) printf(\"sh_malloc %%ld\\n\", n);", + " return ptr;", + "}", + "", + "volatile uchar *", + "bfs_get_shared_mem(key_t key, size_t n)", + "{ char *rval;", + "", + " assert(who_am_i == 0);", + "", + " shared_mem_id = shmget(key, n, 0600 | IPC_CREAT | IPC_EXCL); /* create */", + " if (shared_mem_id == -1)", + " { fprintf(stderr, \"cpu%%02d: tried to get %%d MB of shared memory\\n\",", + " who_am_i, (int) n/(1024*1024));", + " perror(\"shmget\");", + " exit(1);", + " }", + " if ((rval = (char *) shmat(shared_mem_id, (void *) 0, 0)) == (char *) -1) /* attach */", + " { perror(\"shmat\");", + " exit(1);", + " }", + " return (uchar *) rval;", + "}", + "", + "void", + "bfs_drop_shared_memory(void)", + "{", + " if (who_am_i == 0)", + " { printf(\"pan: releasing shared memory...\");", + " fflush(stdout);", + " }", + " if (shared_memory)", + " { shmdt(shared_memory); /* detach */", + " if (who_am_i == 0)", + " { shmctl(shared_mem_id, IPC_RMID, (void *) 0); /* remove */", + " } }", + " if (who_am_i == 0)", + " { printf(\"done\\n\");", + " fflush(stdout);", + " }", + "}", + "", + "size_t", + "bfs_find_largest(key_t key)", + "{ size_t n;", + " const size_t delta = 32*1024*1024;", + " int temp_id = -1;", + " int atleastonce = 0;", + "", + " for (n = delta; ; n += delta)", + " { if (WS <= 4 && n >= 1024*1024*1024)", /* was n >= INT_MAX */ + " { n = 1024*1024*1024;", + " break;", + " }", + "#ifdef MEMLIM", + " if ((double) n > memlim)", + " { n = (size_t) memlim;", + " break;", + " }", + "#endif", + " temp_id = shmget(key, n, 0600); /* check for stale copy */", + " if (temp_id != -1)", + " { if (shmctl(temp_id, IPC_RMID, ((void *) 0)) < 0) /* remove */", + " { perror(\"remove_segment_fails 2\");", + " exit(1);", + " } }", + "", + " temp_id = shmget(key, n, 0600 | IPC_CREAT | IPC_EXCL); /* create new */", + " if (temp_id == -1)", + " { n -= delta;", + " break;", + " } else", + " { atleastonce++;", + " if (shmctl(temp_id, IPC_RMID, ((void *) 0)) < 0)", + " { perror(\"remove_segment_fails 0\");", + " exit(1);", + " } } }", + "", + " if (!atleastonce)", + " { printf(\"cpu%%02d: no shared memory n=%%d\\n\", who_am_i, (int) n);", + " exit(1);", + " }", + "", + " printf(\"cpu%%02d: largest shared memory segment: %%lu MB\\n\",", + " who_am_i, (ulong) n/(1024*1024));", + "#if 0", + " #ifdef BFS_SEP_HASH", + " n /= 2; /* not n /= Cores because the queues take most memory */", + " printf(\"cpu%%02d: using %%lu MB\\n\", who_am_i, (ulong) n/(1024*1024));", + " #endif", + "#endif", + " fflush(stdout);", + "", + " if ((n/(1024*1024)) == 32)", + " { if (sizeof(void *) == 4) /* a 32 bit machine */", + " { fprintf(stderr, \"\\t32MB is the default; increase it to 1 GB with:\\n\");", + " fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmmax=%%d\\n\", (1<<30));", + " fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmall=%%d\\n\", (1<<30)/8192);", + " } else if (sizeof(void *) == 8) /* a 64 bit machine */", + " { fprintf(stderr, \"\\t32MB is the default; increase it to 30 GB with:\\n\");", + " fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmmax=32212254720\\n\");", + " fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmall=7864320\\n\");", + " fprintf(stderr, \"\\tor for 60 GB:\\n\");", + " fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmmax=60000000000\\n\");", + " fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmall=30000000\\n\");", + " } else", + " { fprintf(stderr, \"\\tweird wordsize %%d\\n\", (int) sizeof(void *));", + " } }", + "", + " return n;", + "}", + "#ifdef BFS_DISK", + "void", + "bfs_disk_start(void)", /* setup .spin*/ + "{ int unused = system(\"rm -fr .spin\");", + " if (mkdir(\".spin\", 0777) != 0)", + " { perror(\"mkdir\");", + " Uerror(\"aborting\");", + " }", + "}", + "void", + "bfs_disk_stop(void)", /* remove .spin */ + "{", + " if (system(\"rm -fr .spin\") < 0)", + " { perror(\"rm -fr .spin/\");", + " }", + "}", + "void", + "bfs_disk_inp(void)", /* this core only */ + "{ int i; char fnm[16];", + "#ifdef VERBOSE", + " bfs_printf(\"inp %%d %%d 0..%%d\\n\", bfs_toggle, who_am_i, Cores);", + "#endif", + " for (i = 0; i < Cores; i++)", + " { sprintf(fnm, \".spin/q%%d_%%d_%%d\", bfs_toggle, who_am_i, i);", + " if ((bfs_inp_fd[i] = open(fnm, 0444)) < 0)", + " { perror(\"open\");", + " Uerror(fnm);", + " } }", + "}", + "void", + "bfs_disk_out(void)", /* this core only */ + "{ int i; char fnm[16];", + "#ifdef VERBOSE", + " bfs_printf(\"out %%d 0..%%d %%d\\n\", 1-bfs_toggle, Cores, who_am_i);", + "#endif", + " shared_memory->bfs_out_cnt[who_am_i] = 0;", + " for (i = 0; i < Cores; i++)", + " { sprintf(fnm, \".spin/q%%d_%%d_%%d\", 1-bfs_toggle, i, who_am_i);", + " if ((bfs_out_fd[i] = creat(fnm, 0666)) < 0)", + " { perror(\"creat\");", + " Uerror(fnm);", + " } }", + "}", + "void", + "bfs_disk_iclose(void)", + "{ int i;", + "#ifdef VERBOSE", + " bfs_printf(\"close_inp\\n\");", + "#endif", + " for (i = 0; i < Cores; i++)", + " { if (close(bfs_inp_fd[i]) < 0)", + " { perror(\"iclose\");", + " } }", + "}", + "void", + "bfs_disk_oclose(void)", + "{ int i;", + "#ifdef VERBOSE", + " bfs_printf(\"close_out\\n\");", + "#endif", + " for (i = 0; i < Cores; i++)", + " { if (fsync(bfs_out_fd[i]) < 0)", + " { perror(\"fsync\");", + " }", + " if (close(bfs_out_fd[i]) < 0)", + " { perror(\"oclose\");", + " } }", + "}", + "#endif", + "void", + "bfs_write_snap(int fd)", + "{ if (write(fd, snap, strlen(snap)) != strlen(snap))", + " { printf(\"pan: error writing %%s\\n\", fnm);", + " bfs_shutdown(\"file system error\");", + " }", + "}", + "", + "void", + "bfs_one_step(BFS_Trail *t, int fd)", + "{ if (t && t->t_id != (T_ID) -1)", + " { sprintf(snap, \"%%d:%%d:%%d\\n\",", + " trcnt++, t->pr, t->t_id);", + " bfs_write_snap(fd);", + " }", + "}", + "", + "void", + "bfs_putter(BFS_Trail *t, int fd)", + "{ if (t && t != (BFS_Trail *) t->ostate)", + " bfs_putter((BFS_Trail *) t->ostate, fd);", + "#ifdef L_BOUND", + " if (depthfound == trcnt)", + " { strcpy(snap, \"-1:-1:-1\\n\");", + " bfs_write_snap(fd);", + " depthfound = -1;", + " }", + "#endif", + " bfs_one_step(t, fd);", + "}", + "", + "void", + "bfs_nuerror(char *str)", + "{ int fd = make_trail();", + "", + " if (fd < 0) return;", + "#ifdef VERI", + " sprintf(snap, \"-2:%%d:-2\\n\", (uchar) ((P0 *)pptr(0))->_t);", + " bfs_write_snap(fd);", + "#endif", + "#ifdef MERGED", + " sprintf(snap, \"-4:-4:-4\\n\");", + " bfs_write_snap(fd);", + "#endif", + " trcnt = 1;", + " if (strstr(str, \"invalid\"))", + " { bfs_putter((BFS_Trail *) trpt->ostate, fd);", + " } else", + " { BFS_Trail x;", + " memset((char *) &x, 0, sizeof(BFS_Trail));", + " x.pr = trpt->pr;", + " x.t_id = (trpt->o_t)?trpt->o_t->t_id:0;", + " x.ostate = trpt->ostate;", + " bfs_putter(&x, fd);", + " }", + " close(fd);", + " if (errors >= upto && upto != 0)", + " { bfs_shutdown(str);", + " }", + "}", + "", + "void", + "bfs_uerror(char *str)", + "{ static char laststr[256];", + "", + " errors++;", + " if (strncmp(str, laststr, 254) != 0)", + " { bfs_printf(\"pan:%%lu: %%s (at depth %%ld)\\n\",", + " errors, str, ((depthfound == -1)?depth:depthfound));", + " strncpy(laststr, str, 254);", + " }", + "#ifdef HAS_CODE", + " if (readtrail) { wrap_trail(); return; }", + "#endif", + " if (every_error != 0 || errors == upto)", + " { bfs_nuerror(str);", + " }", + " if (errors >= upto && upto != 0)", + " { bfs_shutdown(\"bfs_uerror\");", + " }", + " depthfound = -1;", + "}\n", + "void", + "bfs_Uerror(char *str)", + "{ /* bfs_uerror(str); */", + " bfs_printf(\"pan:%%lu: %%s (at depth %%ld)\\n\", ++errors, str,", + " ((depthfound == -1)?depth:depthfound));", + " bfs_shutdown(\"bfs_Uerror\");", + "}", + 0, +}; diff -Nru /n/sources/plan9/sys/src/cmd/spin/pc_zpp.c /sys/src/cmd/spin/pc_zpp.c --- /n/sources/plan9/sys/src/cmd/spin/pc_zpp.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/pc_zpp.c Thu Jan 1 00:00:00 1970 @@ -1,452 +0,0 @@ -/***** spin: pc_zpp.c *****/ - -/* Copyright (c) 1997-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* pc_zpp.c is only used in the PC version of Spin */ -/* it is included to avoid too great a reliance on an external cpp */ - -#include -#include -#include -#include -#include "spin.h" - -#ifdef PC -enum cstate { PLAIN, IN_STRING, IN_QUOTE, S_COMM, COMMENT, E_COMM }; - -#define MAXNEST 32 -#define MAXDEF 128 -#define MAXLINE 2048 -#define GENEROUS 8192 - -#define debug(x,y) if (verbose) printf(x,y) - -static FILE *outpp /* = stdout */; - -static int if_truth[MAXNEST]; -static int printing[MAXNEST]; -static int if_depth, nr_defs, verbose = 0; -static enum cstate state = PLAIN; -static char Out1[GENEROUS], Out2[GENEROUS]; - -static struct Defines { - int exists; - char *src, *trg; -} d[MAXDEF]; - -static int process(char *, int, char *); -static int zpp_do(char *); - -extern char *emalloc(size_t); /* main.c */ - -static int -do_define(char *p) -{ char *q, *r, *s; - - for (q = p+strlen(p)-1; q > p; q--) - if (*q == '\n' || *q == '\t' || *q == ' ') - *q = '\0'; - else - break; - - q = p + strspn(p, " \t"); - if (!(r = strchr(q, '\t'))) - r = strchr(q, ' '); - if (!r) { s = ""; goto adddef; } - s = r + strspn(r, " \t"); - *r = '\0'; - if (strchr(q, '(')) - { debug("zpp: #define with arguments %s\n", q); - return 0; - } - for (r = q+strlen(q)-1; r > q; r--) - if (*r == ' ' || *r == '\t') - *r = '\0'; - else - break; - if (nr_defs >= MAXDEF) - { debug("zpp: too many #defines (max %d)\n", nr_defs); - return 0; - } - if (strcmp(q, s) != 0) - { int j; -adddef: for (j = 0; j < nr_defs; j++) - if (!strcmp(d[j].src, q)) - d[j].exists = 0; - d[nr_defs].src = emalloc(strlen(q)+1); - d[nr_defs].trg = emalloc(strlen(s)+1); - strcpy(d[nr_defs].src, q); - strcpy(d[nr_defs].trg, s); - d[nr_defs++].exists = 1; - } - return 1; -} - -static int -isvalid(int c) -{ - return (isalnum(c) || c == '_'); -} - -static char * -apply(char *p0) -{ char *out, *in1, *in2, *startat; - int i, j; - - startat = in1 = Out2; strcpy(Out2, p0); - out = Out1; *out = '\0'; - - for (i = nr_defs-1; i >= 0; i--) - { if (!d[i].exists) continue; - j = (int) strlen(d[i].src); -more: in2 = strstr(startat, d[i].src); - if (!in2) /* no more matches */ - { startat = in1; - continue; - } - if ((in2 == in1 || !isvalid(*(in2-1))) - && (in2+j == '\0' || !isvalid(*(in2+j)))) - { *in2 = '\0'; - - if (strlen(in1)+strlen(d[i].trg)+strlen(in2+j) >= GENEROUS) - { - printf("spin: macro expansion overflow %s -> %s ?\n", - d[i].src, d[i].trg); - return in1; - } - strcat(out, in1); - strcat(out, d[i].trg); - strcat(out, in2+j); - if (in1 == Out2) - { startat = in1 = Out1; - out = Out2; - } else - { startat = in1 = Out2; - out = Out1; - } - *out = '\0'; - } else - { startat = in2+1; /* +1 not +j.. */ - } - goto more; /* recursive defines */ - } - return in1; -} - -static char * -do_common(char *p) -{ char *q, *s; - - q = p + strspn(p, " \t"); - for (s = (q + strlen(q) - 1); s > q; s--) - if (*s == ' ' || *s == '\t' || *s == '\n') - *s = '\0'; - else - break; - return q; -} - -static int -do_undefine(char *p) -{ int i; char *q = do_common(p); - - for (i = 0; i < nr_defs; i++) - if (!strcmp(d[i].src, q)) - d[i].exists = 0; - return 1; -} - -static char * -check_ifdef(char *p) -{ int i; char *q = do_common(p); - - for (i = 0; i < nr_defs; i++) - if (d[i].exists - && !strcmp(d[i].src, q)) - return d[i].trg; - return (char *) 0; -} - -static int -do_ifdef(char *p) -{ - if (++if_depth >= MAXNEST) - { debug("zpp: too deeply nested (max %d)\n", MAXNEST); - return 0; - } - if_truth[if_depth] = (check_ifdef(p) != (char *)0); - printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth]; - - return 1; -} - -static int -do_ifndef(char *p) -{ - if (++if_depth >= MAXNEST) - { debug("zpp: too deeply nested (max %d)\n", MAXNEST); - return 0; - } - if_truth[if_depth] = (check_ifdef(p) == (char *)0); - printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth]; - - return 1; -} - -static int -is_simple(char *q) -{ - if (!q) return 0; - if (strcmp(q, "0") == 0) - if_truth[if_depth] = 0; - else if (strcmp(q, "1") == 0) - if_truth[if_depth] = 1; - else - return 0; - return 1; -} - -static int -do_if(char *p) -{ char *q = do_common(p); - if (++if_depth >= MAXNEST) - { debug("zpp: too deeply nested (max %d)\n", MAXNEST); - return 0; - } - if (!is_simple(q) - && !is_simple(check_ifdef(q))) - { debug("zpp: cannot handle #if %s\n", q); - return 0; - } - printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth]; - - return 1; -} - -static int -do_else(char *p) -{ - debug("zpp: do_else %s", p); - if_truth[if_depth] = 1-if_truth[if_depth]; - printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth]; - - return 1; -} - -static int -do_endif(char *p) -{ - if (--if_depth < 0) - { debug("zpp: unbalanced #endif %s\n", p); - return 0; - } - return 1; -} - -static int -do_include(char *p) -{ char *r, *q; - - q = strchr(p, '<'); - r = strrchr(p, '>'); - if (!q || !r) - { q = strchr (p, '\"'); - r = strrchr(p, '\"'); - if (!q || !r || q == r) - { debug("zpp: malformed #include %s", p); - return 0; - } } - *r = '\0'; - return zpp_do(++q); -} - -static int -in_comment(char *p) -{ char *q = p; - - for (q = p; *q != '\n' && *q != '\0'; q++) - switch (state) { - case PLAIN: - switch (*q) { - case '"': state = IN_STRING; break; - case '\'': state = IN_QUOTE; break; - case '/': state = S_COMM; break; - case '\\': q++; break; - } - break; - case IN_STRING: - if (*q == '"') state = PLAIN; - else if (*q == '\\') q++; - break; - case IN_QUOTE: - if (*q == '\'') state = PLAIN; - else if (*q == '\\') q++; - break; - case S_COMM: - if (*q == '*') - { *(q-1) = *q = ' '; - state = COMMENT; - } else if (*q != '/') - state = PLAIN; - break; - case COMMENT: - state = (*q == '*') ? E_COMM: COMMENT; - *q = ' '; - break; - case E_COMM: - if (*q == '/') - state = PLAIN; - else if (*q != '*') - state = COMMENT; - *q = ' '; - break; - } - if (state == S_COMM) state = PLAIN; - else if (state == E_COMM) state = COMMENT; - return (state == COMMENT); -} - -static int -strip_cpp_comments(char *p) -{ char *q; - - q = strstr(p, "//"); - if (q) - { if (q > p && *(q-1) == '\\') - { return strip_cpp_comments(q+1); - } - *q = '\n'; - *(q+1) = '\0'; - return 1; - } - return 0; -} - -static int -zpp_do(char *fnm) -{ char buf[2048], buf2[MAXLINE], *p; int n, on; - FILE *inp; int lno = 0, nw_lno = 0; - - if ((inp = fopen(fnm, "r")) == NULL) - { fprintf(stdout, "spin: error: No file '%s'\n", fnm); - exit(1); /* 4.1.2 was stderr */ - } - printing[0] = if_truth[0] = 1; - fprintf(outpp, "#line %d \"%s\"\n", lno+1, fnm); - while (fgets(buf, MAXLINE, inp)) - { lno++; n = (int) strlen(buf); - on = 0; nw_lno = 0; - while (n > 2 && buf[n-2] == '\\') - { buf[n-2] = '\0'; -feedme: - if (!fgets(buf2, MAXLINE, inp)) - { debug("zpp: unexpected EOF ln %d\n", lno); - return 0; /* switch to cpp */ - } - lno++; - if (n + (int) strlen(buf2) >= 2048) - { debug("zpp: line %d too long\n", lno); - return 0; - } - strcat(buf, buf2); - n = (int) strlen(buf); - } - - if (strip_cpp_comments(&buf[on])) - n = (int) strlen(buf); - - if (in_comment(&buf[on])) - { buf[n-1] = '\0'; /* eat newline */ - on = n-1; nw_lno = 1; - goto feedme; - } - p = buf + strspn(buf, " \t"); - if (nw_lno && *p != '#') - fprintf(outpp, "#line %d \"%s\"\n", lno, fnm); - if (*p == '#') - { if (!process(p+1, lno+1, fnm)) - return 0; - } else if (printing[if_depth]) - fprintf(outpp, "%s", apply(buf)); - } - fclose(inp); - return 1; -} - -int -try_zpp(char *fnm, char *onm) -{ int r; - if ((outpp = fopen(onm, MFLAGS)) == NULL) - return 0; - r = zpp_do(fnm); - fclose(outpp); - return r; /* 1 = ok; 0 = use cpp */ -} - -static struct Directives { - int len; - char *directive; - int (*handler)(char *); - int interp; -} s[] = { - { 6, "define", do_define, 1 }, - { 4, "else", do_else, 0 }, - { 5, "endif", do_endif, 0 }, - { 5, "ifdef", do_ifdef, 0 }, - { 6, "ifndef", do_ifndef, 0 }, - { 2, "if", do_if, 0 }, - { 7, "include", do_include, 1 }, - { 8, "undefine", do_undefine, 1 }, -}; - -static int -process(char *q, int lno, char *fnm) -{ char *p; int i, r; - - for (p = q; *p; p++) - if (*p != ' ' && *p != '\t') - break; - - if (strncmp(p, "line", 4) == 0) - { p += 4; - while (*p == ' ' || *p == '\t') - { p++; - } - lno = atoi(p); - return 1; /* line directive */ - } - if (isdigit((int) *p)) - { lno = atoi(p); - return 1; - } - if (strncmp(p, "error", 5) == 0) - { printf("spin: %s", p); - exit(1); - } - if (strncmp(p, "warning", 7) == 0) - { printf("spin: %s", p); - return 1; - } - for (i = 0; i < (int) (sizeof(s)/sizeof(struct Directives)); i++) - if (!strncmp(s[i].directive, p, s[i].len)) - { if (s[i].interp - && !printing[if_depth]) - return 1; - fprintf(outpp, "#line %d \"%s\"\n", lno, fnm); - r = s[i].handler(p + s[i].len); - if (i == 6) /* include */ - fprintf(outpp, "#line %d \"%s\"\n", lno, fnm); - return r; - } - - debug("zpp: unrecognized directive: %s", p); - return 0; -} -#endif diff -Nru /n/sources/plan9/sys/src/cmd/spin/ps_msc.c /sys/src/cmd/spin/ps_msc.c --- /n/sources/plan9/sys/src/cmd/spin/ps_msc.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/ps_msc.c Thu Jan 1 00:00:00 1970 @@ -1,446 +0,0 @@ -/***** spin: ps_msc.c *****/ - -/* Copyright (c) 1997-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* The Postscript generation code below was written by Gerard J. Holzmann */ -/* in June 1997. Parts of the prolog template are based on similar boiler */ -/* plate in the Tcl/Tk distribution. This code is used to support Spin's */ -/* option -M for generating a Postscript file from a simulation run. */ - -#include "spin.h" -#include "version.h" - -/* extern void free(void *); */ - -static char *PsPre[] = { - "%%%%Pages: (atend)", - "%%%%PageOrder: Ascend", - "%%%%DocumentData: Clean7Bit", - "%%%%Orientation: Portrait", - "%%%%DocumentNeededResources: font Courier-Bold", - "%%%%EndComments", - "", - "%%%%BeginProlog", - "50 dict begin", - "", - "/baseline 0 def", - "/height 0 def", - "/justify 0 def", - "/lineLength 0 def", - "/spacing 0 def", - "/stipple 0 def", - "/strings 0 def", - "/xoffset 0 def", - "/yoffset 0 def", - "", - "/ISOEncode {", - " dup length dict begin", - " {1 index /FID ne {def} {pop pop} ifelse} forall", - " /Encoding ISOLatin1Encoding def", - " currentdict", - " end", - " /Temporary exch definefont", - "} bind def", - "", - "/AdjustColor {", - " CL 2 lt {", - " currentgray", - " CL 0 eq {", - " .5 lt {0} {1} ifelse", - " } if", - " setgray", - " } if", - "} bind def", - "", - "/DrawText {", - " /stipple exch def", - " /justify exch def", - " /yoffset exch def", - " /xoffset exch def", - " /spacing exch def", - " /strings exch def", - " /lineLength 0 def", - " strings {", - " stringwidth pop", - " dup lineLength gt {/lineLength exch def} {pop} ifelse", - " newpath", - " } forall", - " 0 0 moveto (TXygqPZ) false charpath", - " pathbbox dup /baseline exch def", - " exch pop exch sub /height exch def pop", - " newpath", - " translate", - " lineLength xoffset mul", - " strings length 1 sub spacing mul height add yoffset mul translate", - " justify lineLength mul baseline neg translate", - " strings {", - " dup stringwidth pop", - " justify neg mul 0 moveto", - " stipple {", - " gsave", - " /char (X) def", - " {", - " char 0 3 -1 roll put", - " currentpoint", - " gsave", - " char true charpath clip StippleText", - " grestore", - " char stringwidth translate", - " moveto", - " } forall", - " grestore", - " } {show} ifelse", - " 0 spacing neg translate", - " } forall", - "} bind def", - "%%%%EndProlog", - "%%%%BeginSetup", - "/CL 2 def", - "%%%%IncludeResource: font Courier-Bold", - "%%%%EndSetup", - 0, -}; - -static int MH = 600; /* page height - can be scaled */ -static int oMH = 600; /* page height - not scaled */ -#define MW 500 /* page width */ -#define LH 100 /* bottom margin */ -#define RH 100 /* right margin */ -#define WW 50 /* distance between process lines */ -#define HH 8 /* vertical distance between steps */ -#define PH 14 /* height of process-tag headers */ - -static FILE *pfd; -static char **I; /* initial procs */ -static int *D,*R; /* maps between depth and ldepth */ -static short *M; /* x location of each box at index y */ -static short *T; /* y index of match for each box at index y */ -static char **L; /* text labels */ -static char *ProcLine; /* active processes */ -static int pspno = 0; /* postscript page */ -static int ldepth = 1; -static int maxx, TotSteps = 2*4096; /* max nr of steps, about 40 pages */ -static float Scaler = (float) 1.0; - -extern int ntrail, s_trail, pno, depth; -extern Symbol *oFname; -extern void exit(int); -void putpages(void); -void spitbox(int, int, int, char *); - -void -putlegend(void) -{ - fprintf(pfd, "gsave\n"); - fprintf(pfd, "/Courier-Bold findfont 8 scalefont "); - fprintf(pfd, "ISOEncode setfont\n"); - fprintf(pfd, "0.000 0.000 0.000 setrgbcolor AdjustColor\n"); - fprintf(pfd, "%d %d [\n", MW/2, LH+oMH+ 5*HH); - fprintf(pfd, " (%s -- %s -- MSC -- %d)\n] 10 -0.5 0.5 0 ", - SpinVersion, oFname?oFname->name:"", pspno); - fprintf(pfd, "false DrawText\ngrestore\n"); -} - -void -startpage(void) -{ int i; - - pspno++; - fprintf(pfd, "%%%%Page: %d %d\n", pspno, pspno); - putlegend(); - - for (i = TotSteps-1; i >= 0; i--) - { if (!I[i]) continue; - spitbox(i, RH, -PH, I[i]); - } - - fprintf(pfd, "save\n"); - fprintf(pfd, "10 %d moveto\n", LH+oMH+5); - fprintf(pfd, "%d %d lineto\n", RH+MW, LH+oMH+5); - fprintf(pfd, "%d %d lineto\n", RH+MW, LH); - fprintf(pfd, "10 %d lineto\n", LH); - fprintf(pfd, "closepath clip newpath\n"); - fprintf(pfd, "%f %f translate\n", - (float) RH, (float) LH); - memset(ProcLine, 0, 256*sizeof(char)); - if (Scaler != 1.0) - fprintf(pfd, "%f %f scale\n", Scaler, Scaler); -} - -void -putprelude(void) -{ char snap[256]; FILE *fd; - - sprintf(snap, "%s.ps", oFname?oFname->name:"msc"); - if (!(pfd = fopen(snap, MFLAGS))) - fatal("cannot create file '%s'", snap); - - fprintf(pfd, "%%!PS-Adobe-2.0\n"); - fprintf(pfd, "%%%%Creator: %s\n", SpinVersion); - fprintf(pfd, "%%%%Title: MSC %s\n", oFname?oFname->name:"--"); - fprintf(pfd, "%%%%BoundingBox: 119 154 494 638\n"); - ntimes(pfd, 0, 1, PsPre); - - if (s_trail) - { if (ntrail) - sprintf(snap, "%s%d.trail", oFname?oFname->name:"msc", ntrail); - else - sprintf(snap, "%s.trail", oFname?oFname->name:"msc"); - if (!(fd = fopen(snap, "r"))) - { snap[strlen(snap)-2] = '\0'; - if (!(fd = fopen(snap, "r"))) - fatal("cannot open trail file", (char *) 0); - } - TotSteps = 1; - while (fgets(snap, 256, fd)) TotSteps++; - fclose(fd); - } - TotSteps += 10; - R = (int *) emalloc(TotSteps * sizeof(int)); - D = (int *) emalloc(TotSteps * sizeof(int)); - M = (short *) emalloc(TotSteps * sizeof(short)); - T = (short *) emalloc(TotSteps * sizeof(short)); - L = (char **) emalloc(TotSteps * sizeof(char *)); - I = (char **) emalloc(TotSteps * sizeof(char *)); - ProcLine = (char *) emalloc(1024 * sizeof(char)); - startpage(); -} - -void -putpostlude(void) -{ putpages(); - fprintf(pfd, "%%%%Trailer\n"); - fprintf(pfd, "end\n"); - fprintf(pfd, "%%%%Pages: %d\n", pspno); - fprintf(pfd, "%%%%EOF\n"); - fclose(pfd); - /* stderr, in case user redirected output */ - fprintf(stderr, "spin: wrote %d pages into '%s.ps'\n", - pspno, oFname?oFname->name:"msc"); - exit(0); -} - -void -psline(int x0, int iy0, int x1, int iy1, float r, float g, float b, int w) -{ int y0 = MH-iy0; - int y1 = MH-iy1; - - if (y1 > y0) y1 -= MH; - - fprintf(pfd, "gsave\n"); - fprintf(pfd, "%d %d moveto\n", x0*WW, y0); - fprintf(pfd, "%d %d lineto\n", x1*WW, y1); - fprintf(pfd, "%d setlinewidth\n", w); - fprintf(pfd, "0 setlinecap\n"); - fprintf(pfd, "1 setlinejoin\n"); - fprintf(pfd, "%f %f %f setrgbcolor AdjustColor\n", r,g,b); - fprintf(pfd, "stroke\ngrestore\n"); -} - -void -colbox(int x, int y, int w, int h, float r, float g, float b) -{ fprintf(pfd, "%d %d moveto\n", x - w, y-h); - fprintf(pfd, "%d %d lineto\n", x + w, y-h); - fprintf(pfd, "%d %d lineto\n", x + w, y+h); - fprintf(pfd, "%d %d lineto\n", x - w, y+h); - fprintf(pfd, "%d %d lineto\n", x - w, y-h); - fprintf(pfd, "%f %f %f setrgbcolor AdjustColor\n", r,g,b); - fprintf(pfd, "closepath fill\n"); -} - -void -putgrid(int p) -{ int i; - - for (i = p ; i >= 0; i--) - { if (!ProcLine[i]) - { psline(i, 0, i, MH-1, (float) (0.4), (float) (0.4), (float) (1.0), 1); - ProcLine[i] = 1; - } } -} - -void -putarrow(int from, int to) -{ - T[D[from]] = D[to]; -} - -void -stepnumber(int i) -{ int y = MH-(i*HH)%MH; - - fprintf(pfd, "gsave\n"); - fprintf(pfd, "/Courier-Bold findfont 6 scalefont "); - fprintf(pfd, "ISOEncode setfont\n"); - fprintf(pfd, "0.000 0.000 0.000 setrgbcolor AdjustColor\n"); - fprintf(pfd, "%d %d [\n", -40, y); - fprintf(pfd, " (%d)\n] 10 -0.5 0.5 0 ", R[i]); - fprintf(pfd, "false DrawText\ngrestore\n"); - fprintf(pfd, "%d %d moveto\n", -20, y); - fprintf(pfd, "%d %d lineto\n", M[i]*WW, y); - fprintf(pfd, "1 setlinewidth\n0 setlinecap\n1 setlinejoin\n"); - fprintf(pfd, "0.92 0.92 0.92 setrgbcolor AdjustColor\n"); - fprintf(pfd, "stroke\n"); -} - -void -spitbox(int x, int dx, int y, char *s) -{ float r,g,b, bw; int a; char d[256]; - - if (!dx) - { stepnumber(y); - putgrid(x); - } - bw = (float)2.7*(float)strlen(s); - colbox(x*WW+dx, MH-(y*HH)%MH, (int) (bw+1.0), - 5, (float) 0.,(float) 0.,(float) 0.); - if (s[0] == '~') - { switch (s[1]) { - case 'B': r = (float) 0.2; g = (float) 0.2; b = (float) 1.; - break; - case 'G': r = (float) 0.2; g = (float) 1.; b = (float) 0.2; - break; - case 'R': - default : r = (float) 1.; g = (float) 0.2; b = (float) 0.2; - break; - } - s += 2; - } else if (strchr(s, '!')) - { r = (float) 1.; g = (float) 1.; b = (float) 1.; - } else if (strchr(s, '?')) - { r = (float) 0.; g = (float) 1.; b = (float) 1.; - } else - { r = (float) 1.; g = (float) 1.; b = (float) 0.; - if (!dx - && sscanf(s, "%d:%250s", &a, d) == 2 /* was &d */ - && a >= 0 && a < TotSteps) - { if (!I[a] - || strlen(I[a]) <= strlen(s)) - I[a] = emalloc((int) strlen(s)+1); - strcpy(I[a], s); - } } - colbox(x*WW+dx, MH-(y*HH)%MH, (int) bw, 4, r,g,b); - fprintf(pfd, "gsave\n"); - fprintf(pfd, "/Courier-Bold findfont 8 scalefont "); - fprintf(pfd, "ISOEncode setfont\n"); - fprintf(pfd, "0.000 0.000 0.000 setrgbcolor AdjustColor\n"); - fprintf(pfd, "%d %d [\n", x*WW+dx, MH-(y*HH)%MH); - fprintf(pfd, " (%s)\n] 10 -0.5 0.5 0 ", s); - fprintf(pfd, "false DrawText\ngrestore\n"); -} - -void -putpages(void) -{ int i, lasti=0; float nmh; - - if (maxx*WW > MW-RH/2) - { Scaler = (float) (MW-RH/2) / (float) (maxx*WW); - fprintf(pfd, "%f %f scale\n", Scaler, Scaler); - nmh = (float) MH; nmh /= Scaler; MH = (int) nmh; - } - - for (i = TotSteps-1; i >= 0; i--) - { if (!I[i]) continue; - spitbox(i, 0, 0, I[i]); - } - if (ldepth >= TotSteps) ldepth = TotSteps-1; - for (i = 0; i <= ldepth; i++) - { if (!M[i] && !L[i]) continue; /* no box here */ - if (6+i*HH >= MH*pspno) - { fprintf(pfd, "showpage\nrestore\n"); startpage(); } - if (T[i] > 0) /* red arrow */ - { int reali = i*HH; - int realt = T[i]*HH; - int topop = (reali)/MH; topop *= MH; - reali -= topop; realt -= topop; - - if (M[i] == M[T[i]] && reali == realt) - /* an rv handshake */ - psline( M[lasti], reali+2-3*HH/2, - M[i], reali, - (float) 1.,(float) 0.,(float) 0., 2); - else - psline( M[i], reali, - M[T[i]], realt, - (float) 1.,(float) 0.,(float) 0., 2); - - if (realt >= MH) T[T[i]] = -i; - - } else if (T[i] < 0) /* arrow from prev page */ - { int reali = (-T[i])*HH; - int realt = i*HH; - int topop = (realt)/MH; topop *= MH; - reali -= topop; realt -= topop; - - psline( M[-T[i]], reali, - M[i], realt, - (float) 1., (float) 0., (float) 0., 2); - } - if (L[i]) - { spitbox(M[i], 0, i, L[i]); - /* free(L[i]); */ - lasti = i; - } - } - fprintf(pfd, "showpage\nrestore\n"); -} - -void -putbox(int x) -{ - if (ldepth >= TotSteps) - { fprintf(stderr, "max length of %d steps exceeded - ps file truncated\n", - TotSteps); - putpostlude(); - } - M[ldepth] = x; - if (x > maxx) maxx = x; -} - -void -pstext(int x, char *s) -{ char *tmp = emalloc((int) strlen(s)+1); - - strcpy(tmp, s); - if (depth == 0) - I[x] = tmp; - else - { putbox(x); - if (depth >= TotSteps || ldepth >= TotSteps) - { fprintf(stderr, "max nr of %d steps exceeded\n", - TotSteps); - fatal("aborting", (char *) 0); - } - - D[depth] = ldepth; - R[ldepth] = depth; - L[ldepth] = tmp; - ldepth += 2; - } -} - -void -dotag(FILE *fd, char *s) -{ extern int columns, notabs; extern RunList *X; - int i = (!strncmp(s, "MSC: ", 5))?5:0; - int pid = s_trail ? pno : (X?X->pid:0); - - if (columns == 2) - pstext(pid, &s[i]); - else - { if (!notabs) - { printf(" "); - for (i = 0; i <= pid; i++) - printf(" "); - } - fprintf(fd, "%s", s); - fflush(fd); - } -} diff -Nru /n/sources/plan9/sys/src/cmd/spin/reprosrc.c /sys/src/cmd/spin/reprosrc.c --- /n/sources/plan9/sys/src/cmd/spin/reprosrc.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/reprosrc.c Mon Feb 22 00:00:00 2021 @@ -1,22 +1,21 @@ /***** spin: reprosrc.c *****/ -/* Copyright (c) 2002-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include +#include #include "spin.h" #include "y.tab.h" static int indent = 1; -extern ProcList *rdy; -void repro_seq(Sequence *); +extern YYSTYPE yylval; +extern ProcList *ready; +static void repro_seq(Sequence *); void doindent(void) @@ -48,7 +47,7 @@ printf(" };\n"); } -void +static void repro_seq(Sequence *s) { Element *e; Symbol *v; @@ -132,5 +131,258 @@ void repro_src(void) { - repro_proc(rdy); + repro_proc(ready); +} + +static int in_decl; +static int in_c_decl; +static int in_c_code; + +void +blip(int n, char *b) +{ char mtxt[1024]; + + strcpy(mtxt, ""); + + switch (n) { + default: if (n > 0 && n < 256) + sprintf(mtxt, "%c", n); + else + sprintf(mtxt, "<%d?>", n); + + break; + case '(': strcpy(mtxt, "("); in_decl++; break; + case ')': strcpy(mtxt, ")"); in_decl--; break; + case '{': strcpy(mtxt, "{"); break; + case '}': strcpy(mtxt, "}"); break; + case '\t': sprintf(mtxt, "\\t"); break; + case '\f': sprintf(mtxt, "\\f"); break; + case '\n': sprintf(mtxt, "\\n"); break; + case '\r': sprintf(mtxt, "\\r"); break; + case 'c': sprintf(mtxt, "condition"); break; + case 's': sprintf(mtxt, "send"); break; + case 'r': sprintf(mtxt, "recv"); break; + case 'R': sprintf(mtxt, "recv poll"); break; + case '@': sprintf(mtxt, "@"); break; + case '?': sprintf(mtxt, "(x->y:z)"); break; + case NEXT: sprintf(mtxt, "X"); break; + case ALWAYS: sprintf(mtxt, "[]"); break; + case EVENTUALLY: sprintf(mtxt, "<>"); break; + case IMPLIES: sprintf(mtxt, "->"); break; + case EQUIV: sprintf(mtxt, "<->"); break; + case UNTIL: sprintf(mtxt, "U"); break; + case WEAK_UNTIL: sprintf(mtxt, "W"); break; + case IN: sprintf(mtxt, "in"); break; + case ACTIVE: sprintf(mtxt, "active"); break; + case AND: sprintf(mtxt, "&&"); break; + case ARROW: sprintf(mtxt, "->"); break; + case ASGN: sprintf(mtxt, "="); break; + case ASSERT: sprintf(mtxt, "assert"); break; + case ATOMIC: sprintf(mtxt, "atomic"); break; + case BREAK: sprintf(mtxt, "break"); break; + case C_CODE: sprintf(mtxt, "c_code"); in_c_code++; break; + case C_DECL: sprintf(mtxt, "c_decl"); in_c_decl++; break; + case C_EXPR: sprintf(mtxt, "c_expr"); break; + case C_STATE: sprintf(mtxt, "c_state"); break; + case C_TRACK: sprintf(mtxt, "c_track"); break; + case CLAIM: sprintf(mtxt, "never"); break; + case CONST: sprintf(mtxt, "%d", yylval->val); break; + case DECR: sprintf(mtxt, "--"); break; + case D_STEP: sprintf(mtxt, "d_step"); break; + case D_PROCTYPE: sprintf(mtxt, "d_proctype"); break; + case DO: sprintf(mtxt, "do"); break; + case DOT: sprintf(mtxt, "."); break; + case ELSE: sprintf(mtxt, "else"); break; + case EMPTY: sprintf(mtxt, "empty"); break; + case ENABLED: sprintf(mtxt, "enabled"); break; + case EQ: sprintf(mtxt, "=="); break; + case EVAL: sprintf(mtxt, "eval"); break; + case FI: sprintf(mtxt, "fi"); break; + case FOR: sprintf(mtxt, "for"); break; + case FULL: sprintf(mtxt, "full"); break; + case GE: sprintf(mtxt, ">="); break; + case GET_P: sprintf(mtxt, "get_priority"); break; + case GOTO: sprintf(mtxt, "goto"); break; + case GT: sprintf(mtxt, ">"); break; + case HIDDEN: sprintf(mtxt, "hidden"); break; + case IF: sprintf(mtxt, "if"); break; + case INCR: sprintf(mtxt, "++"); break; + + case INLINE: sprintf(mtxt, "inline"); break; + case INIT: sprintf(mtxt, "init"); break; + case ISLOCAL: sprintf(mtxt, "local"); break; + + case LABEL: sprintf(mtxt, ""); break; + + case LE: sprintf(mtxt, "<="); break; + case LEN: sprintf(mtxt, "len"); break; + case LSHIFT: sprintf(mtxt, "<<"); break; + case LT: sprintf(mtxt, "<"); break; + case LTL: sprintf(mtxt, "ltl"); break; + + case NAME: sprintf(mtxt, "%s", yylval->sym->name); break; + + case XU: switch (yylval->val) { + case XR: sprintf(mtxt, "xr"); break; + case XS: sprintf(mtxt, "xs"); break; + default: sprintf(mtxt, ""); break; + } + break; + + case TYPE: switch (yylval->val) { + case BIT: sprintf(mtxt, "bit"); break; + case BYTE: sprintf(mtxt, "byte"); break; + case CHAN: sprintf(mtxt, "chan"); in_decl++; break; + case INT: sprintf(mtxt, "int"); break; + case MTYPE: sprintf(mtxt, "mtype"); break; + case SHORT: sprintf(mtxt, "short"); break; + case UNSIGNED: sprintf(mtxt, "unsigned"); break; + default: sprintf(mtxt, ""); break; + } + break; + + case NE: sprintf(mtxt, "!="); break; + case NEG: sprintf(mtxt, "!"); break; + case NEMPTY: sprintf(mtxt, "nempty"); break; + case NFULL: sprintf(mtxt, "nfull"); break; + + case NON_ATOMIC: sprintf(mtxt, ""); break; + + case NONPROGRESS: sprintf(mtxt, "np_"); break; + case OD: sprintf(mtxt, "od"); break; + case OF: sprintf(mtxt, "of"); break; + case OR: sprintf(mtxt, "||"); break; + case O_SND: sprintf(mtxt, "!!"); break; + case PC_VAL: sprintf(mtxt, "pc_value"); break; + case PRINT: sprintf(mtxt, "printf"); break; + case PRINTM: sprintf(mtxt, "printm"); break; + case PRIORITY: sprintf(mtxt, "priority"); break; + case PROCTYPE: sprintf(mtxt, "proctype"); break; + case PROVIDED: sprintf(mtxt, "provided"); break; + case RETURN: sprintf(mtxt, "return"); break; + case RCV: sprintf(mtxt, "?"); break; + case R_RCV: sprintf(mtxt, "??"); break; + case RSHIFT: sprintf(mtxt, ">>"); break; + case RUN: sprintf(mtxt, "run"); break; + case SEP: sprintf(mtxt, "::"); break; + case SEMI: sprintf(mtxt, ";"); break; + case SET_P: sprintf(mtxt, "set_priority"); break; + case SHOW: sprintf(mtxt, "show"); break; + case SND: sprintf(mtxt, "!"); break; + + case INAME: + case UNAME: + case PNAME: + case STRING: sprintf(mtxt, "%s", yylval->sym->name); break; + + case TRACE: sprintf(mtxt, "trace"); break; + case TIMEOUT: sprintf(mtxt, "(timeout)"); break; + case TYPEDEF: sprintf(mtxt, "typedef"); break; + case UMIN: sprintf(mtxt, "-"); break; + case UNLESS: sprintf(mtxt, "unless"); break; + } + strcat(b, mtxt); +} + +void +purge(char *b) +{ + if (strlen(b) == 0) return; + + if (b[strlen(b)-1] != ':') /* label? */ + { if (b[0] == ':' && b[1] == ':') + { indent--; + doindent(); + indent++; + } else + { doindent(); + } + } + printf("%s\n", b); + strcpy(b, ""); + + in_decl = 0; + in_c_code = 0; + in_c_decl = 0; +} + +int pp_mode; +extern int lex(void); + +void +pretty_print(void) +{ int c, lastc = 0; + char buf[1024]; + + pp_mode = 1; + indent = 0; + strcpy(buf, ""); + while ((c = lex()) != EOF) + { + if ((lastc == IF || lastc == DO) && c != SEP) + { indent--; /* c_code if */ + } + if (c == C_DECL || c == C_STATE + || c == C_TRACK || c == SEP + || c == DO || c == IF + || (c == TYPE && !in_decl)) + { purge(buf); /* start on new line */ + } + + if (c == '{' + && lastc != OF && lastc != IN + && lastc != ATOMIC && lastc != D_STEP + && lastc != C_CODE && lastc != C_DECL && lastc != C_EXPR) + { purge(buf); + } + + if (c == PREPROC) + { int oi = indent; + purge(buf); + assert(strlen(yylval->sym->name) < sizeof(buf)); + strcpy(buf, yylval->sym->name); + indent = 0; + purge(buf); + indent = oi; + continue; + } + + if (c != ':' && c != SEMI + && c != ',' && c != '(' + && c != '#' && lastc != '#' + && c != ARROW && lastc != ARROW + && c != '.' && lastc != '.' + && c != '!' && lastc != '!' + && c != SND && lastc != SND + && c != RCV && lastc != RCV + && c != O_SND && lastc != O_SND + && c != R_RCV && lastc != R_RCV + && (c != ']' || lastc != '[') + && (c != '>' || lastc != '<') + && (c != GT || lastc != LT) + && c != '@' && lastc != '@' + && (lastc != '(' || c != ')') + && (lastc != '/' || c != '/') + && c != DO && c != OD && c != IF && c != FI + && c != SEP && strlen(buf) > 0) + strcat(buf, " "); + + if (c == '}' || c == OD || c == FI) + { purge(buf); + indent--; + } + blip(c, buf); + + if (c == '{' || c == DO || c == IF) + { purge(buf); + indent++; + } + + if (c == '}' || c == BREAK || c == SEMI || c == ELSE + || (c == ':' && lastc == NAME)) + { purge(buf); + } + lastc = c; + } + purge(buf); } diff -Nru /n/sources/plan9/sys/src/cmd/spin/run.c /sys/src/cmd/spin/run.c --- /n/sources/plan9/sys/src/cmd/spin/run.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/run.c Mon Feb 22 00:00:00 2021 @@ -1,31 +1,31 @@ /***** spin: run.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include #include "spin.h" #include "y.tab.h" -extern RunList *X, *run; +extern RunList *X_lst, *run_lst; extern Symbol *Fname; extern Element *LastStep; -extern int Rvous, lineno, Tval, interactive, MadeChoice; +extern int Rvous, lineno, Tval, interactive, MadeChoice, Priority_Sum; extern int TstOnly, verbose, s_trail, xspin, jumpsteps, depth; -extern int analyze, nproc, nstop, no_print, like_java; +extern int analyze, nproc, nstop, no_print, like_java, old_priority_rules; +extern short Have_claim; static long Seed = 1; static int E_Check = 0, Escape_Check = 0; static int eval_sync(Element *); static int pc_enabled(Lextok *n); -extern void sr_buf(int, int); +static int get_priority(Lextok *n); +static void set_priority(Lextok *n, Lextok *m); +extern void sr_buf(int, int, const char *); void Srand(unsigned int s) @@ -42,15 +42,14 @@ Element * rev_escape(SeqList *e) -{ Element *r; +{ Element *r = (Element *) 0; - if (!e) - return (Element *) 0; + if (e) + { if ((r = rev_escape(e->nxt)) == ZE) /* reversed order */ + { r = eval_sub(e->this->frst); + } } - if ((r = rev_escape(e->nxt)) != ZE) /* reversed order */ - return r; - - return eval_sub(e->this->frst); + return r; } Element * @@ -235,7 +234,7 @@ } else { SeqList *x; if (!(e->status & (D_ATOM)) - && e->esc && verbose&32) + && e->esc && (verbose&32)) { printf("Stmnt ["); comment(stdout, e->n, 0); printf("] has escape(s): "); @@ -261,7 +260,11 @@ if (like_java) { if ((g = rev_escape(e->esc)) != ZE) { if (verbose&4) - printf("\tEscape taken\n"); + { printf("\tEscape taken (-J) "); + if (g->n && g->n->fn) + printf("%s:%d", g->n->fn->name, g->n->ln); + printf("\n"); + } Escape_Check--; return g; } @@ -279,12 +282,14 @@ } } } Escape_Check--; } - switch (e->n->ntyp) { + case ASGN: + if (check_track(e->n) == STRUCT) { break; } + /* else fall thru */ case TIMEOUT: case RUN: case PRINT: case PRINTM: case C_CODE: case C_EXPR: - case ASGN: case ASSERT: + case ASSERT: case 's': case 'r': case 'c': /* toplevel statements only */ LastStep = e; @@ -335,7 +340,8 @@ t = Sym_typ(now->rgt); break; } - typ_ck(Sym_typ(now->lft), t, "assignment"); + typ_ck(Sym_typ(now->lft), t, "assignment"); + return setval(now->lft, eval(now->rgt)); } @@ -343,7 +349,7 @@ nonprogress(void) /* np_ */ { RunList *r; - for (r = run; r; r = r->nxt) + for (r = run_lst; r; r = r->nxt) { if (has_lab(r->pc, 4)) /* 4=progress */ return 0; } @@ -352,7 +358,8 @@ int eval(Lextok *now) -{ +{ int temp; + if (now) { lineno = now->ln; Fname = now->fn; @@ -367,11 +374,19 @@ case UMIN: return -eval(now->lft); case '~': return ~eval(now->lft); - case '/': return (eval(now->lft) / eval(now->rgt)); + case '/': temp = eval(now->rgt); + if (temp == 0) + { fatal("division by zero", (char *) 0); + } + return (eval(now->lft) / temp); case '*': return (eval(now->lft) * eval(now->rgt)); case '-': return (eval(now->lft) - eval(now->rgt)); case '+': return (eval(now->lft) + eval(now->rgt)); - case '%': return (eval(now->lft) % eval(now->rgt)); + case '%': temp = eval(now->rgt); + if (temp == 0) + { fatal("taking modulo of zero", (char *) 0); + } + return (eval(now->lft) % temp); case LT: return (eval(now->lft) < eval(now->rgt)); case GT: return (eval(now->lft) > eval(now->rgt)); case '&': return (eval(now->lft) & eval(now->rgt)); @@ -398,7 +413,22 @@ case NEMPTY: return (qlen(now)>0); case ENABLED: if (s_trail) return 1; return pc_enabled(now->lft); - case EVAL: return eval(now->lft); + + case GET_P: return get_priority(now->lft); + case SET_P: set_priority(now->lft->lft, now->lft->rgt); return 1; + + case EVAL: if (now->lft->ntyp == ',') + { Lextok *fix = now->lft; + do { /* new */ + if (eval(fix->lft) == 0) /* usertype6 */ + { return 0; + } + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + return 1; + } + return eval(now->lft); + case PC_VAL: return pc_value(now->lft); case NONPROGRESS: return nonprogress(); case NAME: return getval(now); @@ -411,7 +441,9 @@ case 'c': return eval(now->lft); /* condition */ case PRINT: return TstOnly?1:interprint(stdout, now); case PRINTM: return TstOnly?1:printm(stdout, now); - case ASGN: return assign(now); + case ASGN: + if (check_track(now) == STRUCT) { return 1; } + return assign(now); case C_CODE: if (!analyze) { printf("%s:\t", now->sym->name); @@ -438,6 +470,11 @@ case '.': return 1; /* return label for compound */ case '@': return 0; /* stop state */ case ELSE: return 1; /* only hit here in guided trails */ + + case ',': /* reached through option -A with array initializer */ + case 0: + return 0; /* not great, but safe */ + default : printf("spin: bad node type %d (run)\n", now->ntyp); if (s_trail) printf("spin: trail file doesn't match spec?\n"); fatal("aborting", 0); @@ -447,18 +484,26 @@ int printm(FILE *fd, Lextok *n) -{ extern char Buf[]; +{ extern char GBuf[]; + char *s = 0; int j; - Buf[0] = '\0'; + GBuf[0] = '\0'; if (!no_print) - if (!s_trail || depth >= jumpsteps) { + if (!s_trail || depth >= jumpsteps) + { + if (n->lft->sym + && n->lft->sym->mtype_name) + { s = n->lft->sym->mtype_name->name; + } + if (n->lft->ismtyp) - j = n->lft->val; - else - j = eval(n->lft); - sr_buf(j, 1); - dotag(fd, Buf); + { j = n->lft->val; + } else /* constant */ + { j = eval(n->lft); + } + sr_buf(j, 1, s); + dotag(fd, GBuf); } return 1; } @@ -466,12 +511,12 @@ int interprint(FILE *fd, Lextok *n) { Lextok *tmp = n->lft; - char c, *s = n->sym->name; + char c, *s = n->sym->name, *t = 0; int i, j; char lbuf[512]; /* matches value in sr_buf() */ - extern char Buf[]; /* global, size 4096 */ - char tBuf[4096]; /* match size of global Buf[] */ + extern char GBuf[]; /* global, size 4096 */ + char tBuf[4096]; /* match size of global GBuf[] */ - Buf[0] = '\0'; + GBuf[0] = '\0'; if (!no_print) if (!s_trail || depth >= jumpsteps) { for (i = 0; i < (int) strlen(s); i++) @@ -479,14 +524,14 @@ case '\"': break; /* ignore */ case '\\': switch(s[++i]) { - case 't': strcat(Buf, "\t"); break; - case 'n': strcat(Buf, "\n"); break; + case 't': strcat(GBuf, "\t"); break; + case 'n': strcat(GBuf, "\n"); break; default: goto onechar; } break; case '%': if ((c = s[++i]) == '%') - { strcat(Buf, "%"); /* literal */ + { strcat(GBuf, "%"); /* literal */ break; } if (!tmp) @@ -494,16 +539,26 @@ break; } j = eval(tmp->lft); + + if (c == 'e' + && tmp->lft + && tmp->lft->sym + && tmp->lft->sym->mtype_name) + { t = tmp->lft->sym->mtype_name->name; + } + tmp = tmp->rgt; switch(c) { case 'c': sprintf(lbuf, "%c", j); break; case 'd': sprintf(lbuf, "%d", j); break; - case 'e': strcpy(tBuf, Buf); /* event name */ - Buf[0] = '\0'; - sr_buf(j, 1); - strcpy(lbuf, Buf); - strcpy(Buf, tBuf); + case 'e': strcpy(tBuf, GBuf); /* event name */ + GBuf[0] = '\0'; + + sr_buf(j, 1, t); + + strcpy(lbuf, GBuf); + strcpy(GBuf, tBuf); break; case 'o': sprintf(lbuf, "%o", j); break; @@ -515,12 +570,12 @@ goto append; default: onechar: lbuf[0] = s[i]; lbuf[1] = '\0'; -append: strcat(Buf, lbuf); +append: strcat(GBuf, lbuf); break; } - dotag(fd, Buf); + dotag(fd, GBuf); } - if (strlen(Buf) >= 4096) fatal("printf string too long", 0); + if (strlen(GBuf) >= 4096) fatal("printf string too long", 0); return 1; } @@ -542,6 +597,7 @@ verbose = v; return i; + case SET_P: case C_CODE: case C_EXPR: case PRINT: case PRINTM: case ASGN: case ASSERT: @@ -580,8 +636,9 @@ switch (e->n->ntyp) { case '@': - return X->pid == (nproc-nstop-1); + return X_lst->pid == (nproc-nstop-1); case '.': + case SET_P: return 1; case GOTO: if (Rvous) return 0; @@ -618,16 +675,99 @@ int result = 0; RunList *Y, *oX; - if (pid == X->pid) - fatal("used: enabled(pid=thisproc) [%s]", X->n->name); + if (pid == X_lst->pid) + fatal("used: enabled(pid=thisproc) [%s]", X_lst->n->name); - for (Y = run; Y; Y = Y->nxt) + for (Y = run_lst; Y; Y = Y->nxt) if (--i == pid) - { oX = X; X = Y; - result = Enabled0(Y->pc); - X = oX; + { oX = X_lst; X_lst = Y; + result = Enabled0(X_lst->pc); + X_lst = oX; break; } return result; } +int +pc_highest(Lextok *n) +{ int i = nproc - nstop; + int pid = eval(n); + int target = 0, result = 1; + RunList *Y, *oX; + + if (X_lst->prov && !eval(X_lst->prov)) + { return 0; /* can't be highest unless fully enabled */ + } + + for (Y = run_lst; Y; Y = Y->nxt) + { if (--i == pid) + { target = Y->priority; + break; + } } +if (0) printf("highest for pid %d @ priority = %d\n", pid, target); + + oX = X_lst; + i = nproc - nstop; + for (Y = run_lst; Y; Y = Y->nxt) + { i--; +if (0) printf(" pid %d @ priority %d\t", Y->pid, Y->priority); + if (Y->priority > target) + { X_lst = Y; +if (0) printf("enabled: %s\n", Enabled0(X_lst->pc)?"yes":"nope"); +if (0) printf("provided: %s\n", eval(X_lst->prov)?"yes":"nope"); + if (Enabled0(X_lst->pc) && (!X_lst->prov || eval(X_lst->prov))) + { result = 0; + break; + } } +else +if (0) printf("\n"); + } + X_lst = oX; + + return result; +} + +int +get_priority(Lextok *n) +{ int i = nproc - nstop; + int pid = eval(n); + RunList *Y; + + if (old_priority_rules) + { return 1; + } + + for (Y = run_lst; Y; Y = Y->nxt) + { if (--i == pid) + { return Y->priority; + } } + return 0; +} + +void +set_priority(Lextok *n, Lextok *p) +{ int i = nproc - nstop - Have_claim; + int pid = eval(n); + RunList *Y; + + if (old_priority_rules) + { return; + } + for (Y = run_lst; Y; Y = Y->nxt) + { if (--i == pid) + { Priority_Sum -= Y->priority; + Y->priority = eval(p); + Priority_Sum += Y->priority; + if (1) + { printf("%3d: setting priority of proc %d (%s) to %d\n", + depth, pid, Y->n->name, Y->priority); + } } } + if (verbose&32) + { printf("\tPid\tName\tPriority\n"); + for (Y = run_lst; Y; Y = Y->nxt) + { printf("\t%d\t%s\t%d\n", + Y->pid, + Y->n->name, + Y->priority); + } } +} diff -Nru /n/sources/plan9/sys/src/cmd/spin/sched.c /sys/src/cmd/spin/sched.c --- /n/sources/plan9/sys/src/cmd/spin/sched.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/sched.c Mon Feb 22 00:00:00 2021 @@ -1,41 +1,43 @@ /***** spin: sched.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include #include "spin.h" #include "y.tab.h" extern int verbose, s_trail, analyze, no_wrapup; -extern char *claimproc, *eventmap, Buf[]; +extern char *claimproc, *eventmap, GBuf[]; extern Ordered *all_names; extern Symbol *Fname, *context; extern int lineno, nr_errs, dumptab, xspin, jumpsteps, columns; extern int u_sync, Elcnt, interactive, TstOnly, cutoff; -extern short has_enabled; -extern int limited_vis, old_scope_rules, product, nclaims; - -RunList *X = (RunList *) 0; -RunList *run = (RunList *) 0; -RunList *LastX = (RunList *) 0; /* previous executing proc */ -ProcList *rdy = (ProcList *) 0; +extern short has_enabled, has_priority, has_code, replay; +extern int limited_vis, product, nclaims, old_priority_rules; +extern int old_scope_rules, scope_seq[128], scope_level, has_stdin; + +extern int pc_highest(Lextok *n); +extern void putpostlude(void); + +RunList *X_lst = (RunList *) 0; +RunList *run_lst = (RunList *) 0; +RunList *LastX = (RunList *) 0; /* previous executing proc */ +ProcList *ready = (ProcList *) 0; Element *LastStep = ZE; -int nproc=0, nstop=0, Tval=0; +int nproc=0, nstop=0, Tval=0, Priority_Sum = 0; int Rvous=0, depth=0, nrRdy=0, MadeChoice; short Have_claim=0, Skip_claim=0; -static int Priority_Sum = 0; static void setlocals(RunList *); static void setparams(RunList *, ProcList *, Lextok *); static void talk(RunList *); +extern char *which_mtype(const char *); + void runnable(ProcList *p, int weight, int noparams) { RunList *r = (RunList *) emalloc(sizeof(RunList)); @@ -44,11 +46,15 @@ r->tn = p->tn; r->b = p->b; r->pid = nproc++ - nstop + Skip_claim; + r->priority = weight; + p->priority = (unsigned char) weight; /* not quite the best place of course */ if (!noparams && ((verbose&4) || (verbose&32))) - printf("Starting %s with pid %d\n", + { printf("Starting %s with pid %d", p->n?p->n->name:"--", r->pid); - + if (has_priority) printf(" priority %d", r->priority); + printf("\n"); + } if (!p->s) fatal("parsing error, no sequence %s", p->n?p->n->name:"--"); @@ -59,18 +65,20 @@ if (p->s->last) p->s->last->status |= ENDSTATE; /* normal end state */ - r->nxt = run; + r->nxt = run_lst; r->prov = p->prov; - r->priority = weight; + if (weight < 1 || weight > 255) + { fatal("bad process priority, valid range: 1..255", (char *) 0); + } if (noparams) setlocals(r); Priority_Sum += weight; - run = r; + run_lst = r; } ProcList * -ready(Symbol *n, Lextok *p, Sequence *s, int det, Lextok *prov, enum btypes b) +mk_rdy(Symbol *n, Lextok *p, Sequence *s, int det, Lextok *prov, enum btypes b) /* n=name, p=formals, s=body det=deterministic prov=provided */ { ProcList *r = (ProcList *) emalloc(sizeof(ProcList)); Lextok *fp, *fpt; int j; extern int Npars; @@ -80,29 +88,81 @@ r->s = s; r->b = b; r->prov = prov; - r->tn = nrRdy++; + r->tn = (short) nrRdy++; + n->sc = scope_seq[scope_level]; /* scope_level should be 0 */ + if (det != 0 && det != 1) { fprintf(stderr, "spin: bad value for det (cannot happen)\n"); } - r->det = (short) det; - r->nxt = rdy; - rdy = r; + r->det = (unsigned char) det; + r->nxt = ready; + ready = r; for (fp = p, j = 0; fp; fp = fp->rgt) for (fpt = fp->lft; fpt; fpt = fpt->rgt) - j++; /* count # of parameters */ + { j++; /* count # of parameters */ + } Npars = max(Npars, j); - return rdy; + return ready; +} + +void +check_mtypes(Lextok *pnm, Lextok *args) /* proctype name, actual params */ +{ ProcList *p = NULL; + Lextok *fp, *fpt, *at; + char *s, *t; + + if (pnm && pnm->sym) + { for (p = ready; p; p = p->nxt) + { if (strcmp(pnm->sym->name, p->n->name) == 0) + { /* found */ + break; + } } } + + if (!p) + { fatal("cannot find proctype '%s'", + (pnm && pnm->sym)?pnm->sym->name:"?"); + } + + for (fp = p->p, at = args; fp; fp = fp->rgt) + for (fpt = fp->lft; at && fpt; fpt = fpt->rgt, at = at->rgt) + { + if (fp->lft->val != MTYPE) + { continue; + } + if (!at->lft->sym) + { printf("spin:%d unrecognized mtype value\n", + pnm->ln); + continue; + } + s = "_unnamed_"; + if (fp->lft->sym->mtype_name) + { t = fp->lft->sym->mtype_name->name; + } else + { t = "_unnamed_"; + } + if (at->lft->ntyp != CONST) + { fatal("wrong arg type '%s'", at->lft->sym->name); + } + s = which_mtype(at->lft->sym->name); + if (s && strcmp(s, t) != 0) + { printf("spin: %s:%d, Error: '%s' is type '%s', but should be type '%s'\n", + pnm->fn->name, pnm->ln, + at->lft->sym->name, s, t); + fatal("wrong arg type '%s'", at->lft->sym->name); + } } } int find_maxel(Symbol *s) { ProcList *p; - for (p = rdy; p; p = p->nxt) - if (p->n == s) - return p->s->maxel++; + for (p = ready; p; p = p->nxt) + { if (p->n == s) + { return p->s->maxel++; + } } + return Elcnt++; } @@ -112,7 +172,7 @@ Lextok *f, *t; int cnt; - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { if (!p->p) continue; cnt = -1; for (f = p->p; f; f = f->rgt) /* types */ @@ -129,16 +189,17 @@ announce(char *w) { if (columns) - { extern char Buf[]; + { extern char GBuf[]; extern int firstrow; firstrow = 1; if (columns == 2) - { sprintf(Buf, "%d:%s", - run->pid - Have_claim, run->n->name); - pstext(run->pid - Have_claim, Buf); + { sprintf(GBuf, "%d:%s", + run_lst->pid - Have_claim, run_lst->n->name); + pstext(run_lst->pid - Have_claim, GBuf); } else - printf("proc %d = %s\n", - run->pid - Have_claim, run->n->name); + { printf("proc %d = %s\n", + run_lst->pid - Have_claim, run_lst->n->name); + } return; } @@ -154,10 +215,10 @@ else whoruns(1); printf("creates proc %2d (%s)", - run->pid - Have_claim, - run->n->name); - if (run->priority > 1) - printf(" priority %d", run->priority); + run_lst->pid - Have_claim, + run_lst->n->name); + if (run_lst->priority > 1) + printf(" priority %d", run_lst->priority); printf("\n"); } @@ -171,19 +232,22 @@ Symbol *s = m->sym; /* proctype name */ Lextok *n = m->lft; /* actual parameters */ - if (m->val < 1) m->val = 1; /* minimum priority */ - for (p = rdy; p; p = p->nxt) - if (strcmp(s->name, p->n->name) == 0) + if (m->val < 1) + { m->val = 1; /* minimum priority */ + } + for (p = ready; p; p = p->nxt) + { if (strcmp(s->name, p->n->name) == 0) { if (nproc-nstop >= MAXP) { printf("spin: too many processes (%d max)\n", MAXP); break; } runnable(p, m->val, 0); announce((char *) 0); - setparams(run, p, n); - setlocals(run); /* after setparams */ - return run->pid - Have_claim + Skip_claim; /* effective simu pid */ - } + setparams(run_lst, p, n); + setlocals(run_lst); /* after setparams */ + check_mtypes(m, m->lft); + return run_lst->pid - Have_claim + Skip_claim; /* effective simu pid */ + } } return 0; /* process not found */ } @@ -194,7 +258,7 @@ Lextok *f, *t; /* formal pars */ int cnt = 0; - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { if (strcmp(s->name, p->n->name) == 0) { if (m->lft) /* actual param list */ { lineno = m->lft->ln; @@ -217,14 +281,14 @@ { ProcList *p; RunList *r, *q = (RunList *) 0; - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) if (p->tn == n && p->b == N_CLAIM) { runnable(p, 1, 1); goto found; } printf("spin: couldn't find claim %d (ignored)\n", n); if (verbose&32) - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) printf("\t%d = %s\n", p->tn, p->n->name); Skip_claim = 1; @@ -232,23 +296,23 @@ found: /* move claim to far end of runlist, and reassign it pid 0 */ if (columns == 2) - { extern char Buf[]; + { extern char GBuf[]; depth = 0; - sprintf(Buf, "%d:%s", 0, p->n->name); - pstext(0, Buf); - for (r = run; r; r = r->nxt) + sprintf(GBuf, "%d:%s", 0, p->n->name); + pstext(0, GBuf); + for (r = run_lst; r; r = r->nxt) { if (r->b != N_CLAIM) - { sprintf(Buf, "%d:%s", r->pid+1, r->n->name); - pstext(r->pid+1, Buf); + { sprintf(GBuf, "%d:%s", r->pid+1, r->n->name); + pstext(r->pid+1, GBuf); } } } - if (run->pid == 0) return; /* it is the first process started */ + if (run_lst->pid == 0) return; /* it is the first process started */ - q = run; run = run->nxt; + q = run_lst; run_lst = run_lst->nxt; q->pid = 0; q->nxt = (RunList *) 0; /* remove */ done: Have_claim = 1; - for (r = run; r; r = r->nxt) + for (r = run_lst; r; r = r->nxt) { r->pid = r->pid+Have_claim; /* adjust */ if (!r->nxt) { r->nxt = q; @@ -261,7 +325,7 @@ { RunList *r; int rval = -1; - for (r = run; r; r = r->nxt) + for (r = run_lst; r; r = r->nxt) if (strcmp(n, r->n->name) == 0) { if (rval >= 0) { printf("spin: remote ref to proctype %s, ", n); @@ -278,8 +342,7 @@ { limited_vis = 0; if (columns) - { extern void putpostlude(void); - if (columns == 2) putpostlude(); + { if (columns == 2) putpostlude(); if (!no_wrapup) printf("-------------\nfinal state:\n-------------\n"); } @@ -293,15 +356,15 @@ verbose = ov; verbose &= ~1; /* no more globals */ verbose |= 32; /* add process states */ - for (X = run; X; X = X->nxt) - talk(X); + for (X_lst = run_lst; X_lst; X_lst = X_lst->nxt) + talk(X_lst); verbose = ov; /* restore */ } printf("%d process%s created\n", nproc - Have_claim + Skip_claim, (xspin || nproc!=1)?"es":""); short_cut: - if (xspin) alldone(0); /* avoid an abort from xspin */ + if (s_trail || xspin) alldone(0); /* avoid an abort from xspin */ if (fini) alldone(1); } @@ -345,6 +408,24 @@ return e; } +static int +x_can_run(void) /* the currently selected process in X_lst can run */ +{ + if (X_lst->prov && !eval(X_lst->prov)) + { +if (0) printf("pid %d cannot run: not provided\n", X_lst->pid); + return 0; + } + if (has_priority && !old_priority_rules) + { Lextok *n = nn(ZN, CONST, ZN, ZN); + n->val = X_lst->pid; +if (0) printf("pid %d %s run (priority)\n", X_lst->pid, pc_highest(n)?"can":"cannot"); + return pc_highest(n); + } +if (0) printf("pid %d can run\n", X_lst->pid); + return 1; +} + static RunList * pickproc(RunList *Y) { SeqList *z; Element *has_else; @@ -352,42 +433,60 @@ int j, k, nr_else = 0; if (nproc <= nstop+1) - { X = run; + { X_lst = run_lst; return NULL; } if (!interactive || depth < jumpsteps) - { /* was: j = (int) Rand()%(nproc-nstop); */ + { if (has_priority && !old_priority_rules) /* new 6.3.2 */ + { j = Rand()%(nproc-nstop); + for (X_lst = run_lst; X_lst; X_lst = X_lst->nxt) + { if (j-- <= 0) + break; + } + if (X_lst == NULL) + { fatal("unexpected, pickproc", (char *)0); + } + j = nproc - nstop; + while (j-- > 0) + { if (x_can_run()) + { Y = X_lst; + break; + } + X_lst = (X_lst->nxt)?X_lst->nxt:run_lst; + } + return Y; + } if (Priority_Sum < nproc-nstop) fatal("cannot happen - weights", (char *)0); j = (int) Rand()%Priority_Sum; - while (j - X->priority >= 0) - { j -= X->priority; - Y = X; - X = X->nxt; - if (!X) { Y = NULL; X = run; } + while (j - X_lst->priority >= 0) + { j -= X_lst->priority; + Y = X_lst; + X_lst = X_lst->nxt; + if (!X_lst) { Y = NULL; X_lst = run_lst; } } + } else { int only_choice = -1; int no_choice = 0, proc_no_ch, proc_k; Tval = 0; /* new 4.2.6 */ try_again: printf("Select a statement\n"); -try_more: for (X = run, k = 1; X; X = X->nxt) - { if (X->pid > 255) break; +try_more: for (X_lst = run_lst, k = 1; X_lst; X_lst = X_lst->nxt) + { if (X_lst->pid > 255) break; - Choices[X->pid] = (short) k; + Choices[X_lst->pid] = (short) k; - if (!X->pc - || (X->prov && !eval(X->prov))) - { if (X == run) - Choices[X->pid] = 0; + if (!X_lst->pc || !x_can_run()) + { if (X_lst == run_lst) + Choices[X_lst->pid] = 0; continue; } - X->pc = silent_moves(X->pc); - if (!X->pc->sub && X->pc->n) + X_lst->pc = silent_moves(X_lst->pc); + if (!X_lst->pc->sub && X_lst->pc->n) { int unex; - unex = !Enabled0(X->pc); + unex = !Enabled0(X_lst->pc); if (unex) no_choice++; else @@ -397,18 +496,18 @@ continue; } printf("\tchoice %d: ", k++); - p_talk(X->pc, 0); + p_talk(X_lst->pc, 0); if (unex) printf(" unexecutable,"); printf(" ["); - comment(stdout, X->pc->n, 0); - if (X->pc->esc) printf(" + Escape"); + comment(stdout, X_lst->pc->n, 0); + if (X_lst->pc->esc) printf(" + Escape"); printf("]\n"); } else { has_else = ZE; proc_no_ch = no_choice; proc_k = k; - for (z = X->pc->sub, j=0; z; z = z->nxt) + for (z = X_lst->pc->sub, j=0; z; z = z->nxt) { Element *y = silent_moves(z->this->frst); int unex; if (!y) continue; @@ -429,7 +528,7 @@ continue; } printf("\tchoice %d: ", k++); - p_talk(X->pc, 0); + p_talk(X_lst->pc, 0); if (unex) printf(" unexecutable,"); printf(" ["); @@ -440,16 +539,16 @@ { if (no_choice-proc_no_ch >= (k-proc_k)-1) { only_choice = nr_else; printf("\tchoice %d: ", nr_else); - p_talk(X->pc, 0); + p_talk(X_lst->pc, 0); printf(" [else]\n"); } else { no_choice++; printf("\tchoice %d: ", nr_else); - p_talk(X->pc, 0); + p_talk(X_lst->pc, 0); printf(" unexecutable, [else]\n"); } } } } - X = run; + X_lst = run_lst; if (k - no_choice < 2 && Tval == 0) { Tval = 1; no_choice = 0; only_choice = -1; @@ -487,12 +586,12 @@ } } MadeChoice = 0; Y = NULL; - for (X = run; X; Y = X, X = X->nxt) - { if (!X->nxt - || X->nxt->pid > 255 - || j < Choices[X->nxt->pid]) + for (X_lst = run_lst; X_lst; Y = X_lst, X_lst = X_lst->nxt) + { if (!X_lst->nxt + || X_lst->nxt->pid > 255 + || j < Choices[X_lst->nxt->pid]) { - MadeChoice = 1+j-Choices[X->pid]; + MadeChoice = 1+j-Choices[X_lst->pid]; break; } } } @@ -505,15 +604,17 @@ if (nclaims > 1) { printf(" the model contains %d never claims:", nclaims); - for (p = rdy; p; p = p->nxt) + for (p = ready; p; p = p->nxt) { if (p->b == N_CLAIM) { printf("%s%s", q?", ":" ", p->n->name); q = p; } } printf("\n"); printf(" only one claim is used in a verification run\n"); - printf(" choose which one with ./pan -N name (defaults to -N %s)\n", + printf(" choose which one with ./pan -a -N name (defaults to -N %s)\n", q?q->n->name:"--"); + printf(" or use e.g.: spin -search -ltl %s %s\n", + q?q->n->name:"--", Fname?Fname->name:"filename"); } } @@ -532,6 +633,10 @@ dumplabels(); return; } + if (has_code && !analyze) + { printf("spin: warning: c_code fragments remain uninterpreted\n"); + printf(" in random simulations with spin; use ./pan -r instead\n"); + } if (has_enabled && u_sync > 0) { printf("spin: error, cannot use 'enabled()' in "); @@ -542,28 +647,32 @@ { sync_product(); alldone(0); } - if (analyze) + if (analyze && (!replay || has_code)) { gensrc(); multi_claims(); return; } + if (replay && !has_code) + { return; + } if (s_trail) { match_trail(); return; } + if (claimproc) printf("warning: never claim not used in random simulation\n"); if (eventmap) printf("warning: trace assertion not used in random simulation\n"); - X = run; + X_lst = run_lst; Y = pickproc(Y); - while (X) - { context = X->n; - if (X->pc && X->pc->n) - { lineno = X->pc->n->ln; - Fname = X->pc->n->fn; + while (X_lst) + { context = X_lst->n; + if (X_lst->pc && X_lst->pc->n) + { lineno = X_lst->pc->n->ln; + Fname = X_lst->pc->n->fn; } if (cutoff > 0 && depth >= cutoff) { printf("-------------\n"); @@ -581,48 +690,49 @@ } #endif depth++; LastStep = ZE; - oX = X; /* a rendezvous could change it */ + oX = X_lst; /* a rendezvous could change it */ go = 1; - if (X->prov && X->pc - && !(X->pc->status & D_ATOM) - && !eval(X->prov)) + if (X_lst->pc + && !(X_lst->pc->status & D_ATOM) + && !x_can_run()) { if (!xspin && ((verbose&32) || (verbose&4))) - { p_talk(X->pc, 1); + { p_talk(X_lst->pc, 1); printf("\t<>\n"); } go = 0; } - if (go && (e = eval_sub(X->pc))) + if (go && (e = eval_sub(X_lst->pc))) { if (depth >= jumpsteps && ((verbose&32) || (verbose&4))) - { if (X == oX) + { if (X_lst == oX) if (!(e->status & D_ATOM) || (verbose&32)) /* no talking in d_steps */ - { p_talk(X->pc, 1); + { if (!LastStep) LastStep = X_lst->pc; + /* A. Tanaka, changed order */ + p_talk(LastStep, 1); printf(" ["); - if (!LastStep) LastStep = X->pc; comment(stdout, LastStep->n, 0); printf("]\n"); } if (verbose&1) dumpglobals(); - if (verbose&2) dumplocal(X); + if (verbose&2) dumplocal(X_lst, 0); if (!(e->status & D_ATOM)) if (xspin) printf("\n"); } - if (oX != X - || (X->pc->status & (ATOM|D_ATOM))) /* new 5.0 */ + if (oX != X_lst + || (X_lst->pc->status & (ATOM|D_ATOM))) /* new 5.0 */ { e = silent_moves(e); notbeyond = 0; } - oX->pc = e; LastX = X; + oX->pc = e; LastX = X_lst; if (!interactive) Tval = 0; memset(is_blocked, 0, 256); - if (X->pc && (X->pc->status & (ATOM|L_ATOM)) - && (notbeyond == 0 || oX != X)) - { if ((X->pc->status & L_ATOM)) + if (X_lst->pc && (X_lst->pc->status & (ATOM|L_ATOM)) + && (notbeyond == 0 || oX != X_lst)) + { if ((X_lst->pc->status & L_ATOM)) notbeyond = 1; continue; /* no process switch */ } @@ -631,40 +741,42 @@ if (oX->pc && (oX->pc->status & D_ATOM)) { non_fatal("stmnt in d_step blocks", (char *)0); } - if (X->pc - && X->pc->n - && X->pc->n->ntyp == '@' - && X->pid == (nproc-nstop-1)) - { if (X != run && Y != NULL) - Y->nxt = X->nxt; + if (X_lst->pc + && X_lst->pc->n + && X_lst->pc->n->ntyp == '@' + && X_lst->pid == (nproc-nstop-1)) + { if (X_lst != run_lst && Y != NULL) + Y->nxt = X_lst->nxt; else - run = X->nxt; + run_lst = X_lst->nxt; nstop++; - Priority_Sum -= X->priority; + Priority_Sum -= X_lst->priority; if (verbose&4) { whoruns(1); dotag(stdout, "terminates\n"); } - LastX = X; + LastX = X_lst; if (!interactive) Tval = 0; if (nproc == nstop) break; memset(is_blocked, 0, 256); - /* proc X is no longer in runlist */ - X = (X->nxt) ? X->nxt : run; + /* proc X_lst is no longer in runlist */ + X_lst = (X_lst->nxt) ? X_lst->nxt : run_lst; } else - { if (p_blocked(X->pid)) - { if (Tval) break; - Tval = 1; - if (depth >= jumpsteps) - { oX = X; - X = (RunList *) 0; /* to suppress indent */ + { if (p_blocked(X_lst->pid)) + { if (Tval && !has_stdin) + { break; + } + if (!Tval && depth >= jumpsteps) + { oX = X_lst; + X_lst = (RunList *) 0; /* to suppress indent */ dotag(stdout, "timeout\n"); - X = oX; + X_lst = oX; + Tval = 1; } } } } - if (!run || !X) break; /* new 5.0 */ + if (!run_lst || !X_lst) break; /* new 5.0 */ - Y = pickproc(X); + Y = pickproc(X_lst); notbeyond = 0; } context = ZS; @@ -673,7 +785,7 @@ int complete_rendez(void) -{ RunList *orun = X, *tmp; +{ RunList *orun = X_lst, *tmp; Element *s_was = LastStep; Element *e; int j, ointer = interactive; @@ -686,46 +798,46 @@ interactive = 0; j = (int) Rand()%Priority_Sum; /* randomize start point */ - X = run; - while (j - X->priority >= 0) - { j -= X->priority; - X = X->nxt; - if (!X) X = run; + X_lst = run_lst; + while (j - X_lst->priority >= 0) + { j -= X_lst->priority; + X_lst = X_lst->nxt; + if (!X_lst) X_lst = run_lst; } for (j = nproc - nstop; j > 0; j--) - { if (X != orun - && (!X->prov || eval(X->prov)) - && (e = eval_sub(X->pc))) + { if (X_lst != orun + && (!X_lst->prov || eval(X_lst->prov)) + && (e = eval_sub(X_lst->pc))) { if (TstOnly) - { X = orun; + { X_lst = orun; Rvous = 0; goto out; } if ((verbose&32) || (verbose&4)) - { tmp = orun; orun = X; X = tmp; - if (!s_was) s_was = X->pc; + { tmp = orun; orun = X_lst; X_lst = tmp; + if (!s_was) s_was = X_lst->pc; p_talk(s_was, 1); printf(" ["); comment(stdout, s_was->n, 0); printf("]\n"); - tmp = orun; orun = X; X = tmp; - if (!LastStep) LastStep = X->pc; + tmp = orun; /* orun = X_lst; */ X_lst = tmp; + if (!LastStep) LastStep = X_lst->pc; p_talk(LastStep, 1); printf(" ["); comment(stdout, LastStep->n, 0); printf("]\n"); } Rvous = 0; /* before silent_moves */ - X->pc = silent_moves(e); + X_lst->pc = silent_moves(e); out: interactive = ointer; return 1; } - X = X->nxt; - if (!X) X = run; + X_lst = X_lst->nxt; + if (!X_lst) X_lst = run_lst; } Rvous = 0; - X = orun; + X_lst = orun; interactive = ointer; return 0; } @@ -747,6 +859,7 @@ t->name = s->name; t->type = s->type; t->hidden = s->hidden; + t->isarray = s->isarray; t->nbits = s->nbits; t->nel = s->nel; t->ini = s->ini; @@ -780,9 +893,9 @@ setlocals(RunList *r) { Ordered *walk; Symbol *sp; - RunList *oX = X; + RunList *oX = X_lst; - X = r; + X_lst = r; for (walk = all_names; walk; walk = walk->next) { sp = walk->entry; if (sp @@ -802,13 +915,13 @@ sp->name); } } - X = oX; + X_lst = oX; } static void oneparam(RunList *r, Lextok *t, Lextok *a, ProcList *p) { int k; int at, ft; - RunList *oX = X; + RunList *oX = X_lst; if (!a) fatal("missing actual parameters: '%s'", p->n->name); @@ -817,7 +930,7 @@ k = eval(a->lft); at = Sym_typ(a->lft); - X = r; /* switch context */ + X_lst = r; /* switch context */ ft = Sym_typ(t); if (at != ft && (at == CHAN || ft == CHAN)) @@ -832,7 +945,7 @@ addsymbol(r, t->sym); (void) setval(t, k); - X = oX; + X_lst = oX; } static void @@ -857,17 +970,19 @@ findloc(Symbol *s) { Symbol *r; - if (!X) + if (!X_lst) { /* fatal("error, cannot eval '%s' (no proc)", s->name); */ return ZS; } - for (r = X->symtab; r; r = r->next) - if (strcmp(r->name, s->name) == 0 - && (old_scope_rules || strcmp((const char *)r->bscp, (const char *)s->bscp) == 0)) - break; + for (r = X_lst->symtab; r; r = r->next) + { if (strcmp(r->name, s->name) == 0 + && (old_scope_rules + || strcmp((const char *)r->bscp, (const char *)s->bscp) == 0)) + { break; + } } if (!r) - { addsymbol(X, s); - r = X->symtab; + { addsymbol(X_lst, s); + r = X_lst->symtab; } return r; } @@ -924,15 +1039,19 @@ void whoruns(int lnr) -{ if (!X) return; +{ if (!X_lst) return; if (lnr) printf("%3d: ", depth); printf("proc "); - if (Have_claim && X->pid == 0) + if (Have_claim && X_lst->pid == 0) printf(" -"); else - printf("%2d", X->pid - Have_claim); - printf(" (%s) ", X->n->name); + printf("%2d", X_lst->pid - Have_claim); + if (old_priority_rules) + { printf(" (%s) ", X_lst->n->name); + } else + { printf(" (%s:%d) ", X_lst->n->name, X_lst->priority); + } } static void @@ -942,7 +1061,7 @@ { p_talk(r->pc, 1); printf("\n"); if (verbose&1) dumpglobals(); - if (verbose&2) dumplocal(r); + if (verbose&2) dumplocal(r, 1); } } @@ -955,7 +1074,7 @@ if (e && e->n) newnever = e->n->ln; - if (Have_claim && X && X->pid == 0 + if (Have_claim && X_lst && X_lst->pid == 0 && lastnever != newnever && e) { if (xspin) { printf("MSC: ~G line %d\n", newnever); @@ -1011,8 +1130,9 @@ { fatal("remote ref to label '%s' inside d_step", n->sym->name); } - if ((i = find_lab(n->sym, n->lft->sym, 1)) == 0) - fatal("unknown labelname: %s", n->sym->name); + if ((i = find_lab(n->sym, n->lft->sym, 1)) == 0) /* remotelab */ + { fatal("unknown labelname: %s", n->sym->name); + } return i; } @@ -1038,16 +1158,17 @@ } } if (prno < 0) - return 0; /* non-existing process */ + { return 0; /* non-existing process */ + } #if 0 i = nproc - nstop; - for (Y = run; Y; Y = Y->nxt) + for (Y = run_lst; Y; Y = Y->nxt) { --i; printf(" %s: i=%d, prno=%d, ->pid=%d\n", Y->n->name, i, prno, Y->pid); } #endif i = nproc - nstop + Skip_claim; /* 6.0: added Skip_claim */ - for (Y = run; Y; Y = Y->nxt) + for (Y = run_lst; Y; Y = Y->nxt) if (--i == prno) { if (strcmp(Y->n->name, n->lft->sym->name) != 0) { printf("spin: remote reference error on '%s[%d]'\n", @@ -1056,36 +1177,40 @@ } if (strcmp(n->sym->name, "_p") == 0) { if (Y->pc) - return Y->pc->seqno; + { return Y->pc->seqno; + } /* harmless, can only happen with -t */ return 0; } -#if 1 - /* new 4.0 allow remote variables */ - oX = X; - X = Y; + + /* check remote variables */ + oX = X_lst; + X_lst = Y; onl = n->lft; n->lft = n->rgt; os = n->sym; - n->sym = findloc(n->sym); - + if (!n->sym->context) + { n->sym->context = Y->n; + } + { int rs = old_scope_rules; + old_scope_rules = 1; /* 6.4.0 */ + n->sym = findloc(n->sym); + old_scope_rules = rs; + } i = getval(n); n->sym = os; n->lft = onl; - X = oX; + X_lst = oX; return i; -#else - break; -#endif } printf("remote ref: %s[%d] ", n->lft->sym->name, prno-added); non_fatal("%s not found", n->sym->name); printf("have only:\n"); i = nproc - nstop - 1; - for (Y = run; Y; Y = Y->nxt, i--) + for (Y = run_lst; Y; Y = Y->nxt, i--) if (!strcmp(Y->n->name, n->lft->sym->name)) printf("\t%d\t%s\n", i, Y->n->name); diff -Nru /n/sources/plan9/sys/src/cmd/spin/spin.h /sys/src/cmd/spin/spin.h --- /n/sources/plan9/sys/src/cmd/spin/spin.h Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/spin.h Mon Feb 22 00:00:00 2021 @@ -1,13 +1,10 @@ /***** spin: spin.h *****/ -/* Copyright (c) 1989-2009 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #ifndef SEEN_SPIN_H #define SEEN_SPIN_H @@ -15,8 +12,11 @@ #include #include #include +#if !defined(WIN32) && !defined(WIN64) + #include +#endif -enum { INIV, PUTV, LOGV }; /* for pangen[14].c */ +enum { INIV, PUTV, LOGV }; /* used in pangen1.c */ enum btypes { NONE, N_CLAIM, I_PROC, A_PROC, P_PROC, E_TRACE, N_TRACE }; typedef struct Lextok { @@ -60,6 +60,7 @@ unsigned char colnr; /* for use with xspin during simulation */ unsigned char isarray; /* set if decl specifies array bound */ unsigned char *bscp; /* block scope */ + int sc; /* scope seq no -- set only for proctypes */ int nbits; /* optional width specifier */ int nel; /* 1 if scalar, >1 if array */ int setat; /* last depth value changed */ @@ -71,6 +72,7 @@ struct Access *access;/* e.g., senders and receives of chan */ Lextok *ini; /* initial value, or chan-def */ Lextok *Slst; /* template for structure if struct */ + struct Symbol *mtype_name; /* if type == MTYPE else nil */ struct Symbol *Snm; /* name of the defining struct */ struct Symbol *owner; /* set for names of subfields in typedefs */ struct Symbol *context; /* 0 if global, or procname */ @@ -82,6 +84,12 @@ struct Ordered *next; } Ordered; +typedef struct Mtypes_t { + char *nm; /* name of mtype, or "_unnamed_" */ + Lextok *mt; /* the linked list of names */ + struct Mtypes_t *nxt; /* linked list of mtypes */ +} Mtypes_t; + typedef struct Queue { short qid; /* runtime q index */ int qlen; /* nr messages stored */ @@ -90,6 +98,7 @@ int *fld_width; /* type of each field */ int *contents; /* the values stored */ int *stepnr; /* depth when each msg was sent */ + char **mtp; /* if mtype, name of list, else 0 */ struct Queue *nxt; /* linked list */ } Queue; @@ -142,6 +151,7 @@ Element *frst; Element *last; /* links onto continuations */ Element *extent; /* last element in original */ + int minel; /* minimum Seqno, set and used only in guided.c */ int maxel; /* 1+largest id in sequence */ } Sequence; @@ -164,6 +174,11 @@ struct Lbreak *nxt; } Lbreak; +typedef struct L_List { + Lextok *n; + struct L_List *nxt; +} L_List; + typedef struct RunList { Symbol *n; /* name */ int tn; /* ordinal of type */ @@ -186,9 +201,15 @@ short tn; /* ordinal number */ unsigned char det; /* deterministic */ unsigned char unsafe; /* contains global var inits */ + unsigned char priority; /* process priority, if any */ struct ProcList *nxt; /* linked list */ } ProcList; +typedef struct QH { + int n; + struct QH *nxt; +} QH; + typedef Lextok *Lexptr; #define YYSTYPE Lexptr @@ -230,20 +251,21 @@ #define MAXSCOPESZ 1024 #ifndef max -#define max(a,b) (((a)<(b)) ? (b) : (a)) + #define max(a,b) (((a)<(b)) ? (b) : (a)) #endif #ifdef PC - #define MFLAGS "wb" + #define MFLAGS "wb" #else - #define MFLAGS "w" + #define MFLAGS "w" #endif /***** prototype definitions *****/ Element *eval_sub(Element *); Element *get_lab(Lextok *, int); -Element *huntele(Element *, int, int); +Element *huntele(Element *, unsigned int, int); Element *huntstart(Element *); +Element *mk_skip(void); Element *target(Element *); Lextok *do_unless(Lextok *, Lextok *); @@ -254,8 +276,9 @@ Lextok *rem_lab(Symbol *, Lextok *, Symbol *); Lextok *rem_var(Symbol *, Lextok *, Symbol *, Lextok *); Lextok *tail_add(Lextok *, Lextok *); +Lextok *return_statement(Lextok *); -ProcList *ready(Symbol *, Lextok *, Sequence *, int, Lextok *, enum btypes); +ProcList *mk_rdy(Symbol *, Lextok *, Sequence *, int, Lextok *, enum btypes); SeqList *seqlist(Sequence *, SeqList *); Sequence *close_seq(int); @@ -266,7 +289,9 @@ Symbol *lookup(char *); Symbol *prep_inline(Symbol *, Lextok *); +char *put_inline(FILE *, char *); char *emalloc(size_t); +char *erealloc(void*, size_t, size_t); long Rand(void); int any_oper(Lextok *, int); @@ -274,6 +299,7 @@ int c_add_sv(FILE *); int cast_val(int, int, int); int checkvar(Symbol *, int); +int check_track(Lextok *); int Cnt_flds(Lextok *); int cnt_mpars(Lextok *); int complete_rendez(void); @@ -316,7 +342,6 @@ int tl_main(int, char *[]); int Width_set(int *, int, Lextok *); int yyparse(void); -int yywrap(void); int yylex(void); void AST_track(Lextok *, int); @@ -327,7 +352,6 @@ void c_add_def(FILE *); void c_add_loc(FILE *, char *); void c_add_locinit(FILE *, int, char *); -void c_add_use(FILE *); void c_chandump(FILE *); void c_preview(void); void c_struct(FILE *, char *, Symbol *); @@ -348,7 +372,7 @@ void dumpclaims(FILE *, int, char *); void dumpglobals(void); void dumplabels(void); -void dumplocal(RunList *); +void dumplocal(RunList *, int); void dumpsrc(int, int); void fatal(char *, char *); void fix_dest(Symbol *, Symbol *); @@ -363,20 +387,22 @@ void ini_struct(Symbol *); void loose_ends(void); void make_atomic(Sequence *, int); +void mark_last(void); void match_trail(void); void no_side_effects(char *); void nochan_manip(Lextok *, Lextok *, int); void non_fatal(char *, char *); -void ntimes(FILE *, int, int, char *c[]); +void ntimes(FILE *, int, int, const char *c[]); void open_seq(int); void p_talk(Element *, int); -void pickup_inline(Symbol *, Lextok *); +void pickup_inline(Symbol *, Lextok *, Lextok *); void plunk_c_decls(FILE *); void plunk_c_fcts(FILE *); void plunk_expr(FILE *, char *); void plunk_inline(FILE *, char *, int, int); void prehint(Symbol *); void preruse(FILE *, Lextok *); +void pretty_print(void); void prune_opts(Lextok *); void pstext(int, char *); void pushbreak(void); @@ -391,13 +417,12 @@ void sched(void); void setaccess(Symbol *, Symbol *, int, int); void set_lab(Symbol *, Element *); -void setmtype(Lextok *); +void setmtype(Lextok *, Lextok *); void setpname(Lextok *); -void setptype(Lextok *, int, Lextok *); +void setptype(Lextok *, Lextok *, int, Lextok *); void setuname(Lextok *); void setutype(Lextok *, Symbol *, Lextok *); void setxus(Lextok *, int); -void show_lab(void); void Srand(unsigned); void start_claim(int); void struct_name(Lextok *, Symbol *, int, char *); @@ -413,8 +438,13 @@ void undostmnt(Lextok *, int); void unrem_Seq(void); void unskip(int); -void varcheck(Element *, Element *); void whoruns(int); void wrapup(int); void yyerror(char *, ...); + +extern int unlink(const char *); + +#define TMP_FILE1 "._s_p_i_n_" +#define TMP_FILE2 "._n_i_p_s_" + #endif diff -Nru /n/sources/plan9/sys/src/cmd/spin/spin.y /sys/src/cmd/spin/spin.y --- /n/sources/plan9/sys/src/cmd/spin/spin.y Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/spin.y Mon Feb 22 00:00:00 2021 @@ -1,13 +1,10 @@ /***** spin: spin.y *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ %{ #include "spin.h" @@ -17,9 +14,10 @@ #endif #include -#define YYDEBUG 0 +#define YYMAXDEPTH 20000 /* default is 10000 */ +#define YYDEBUG 0 #define Stop nn(ZN,'@',ZN,ZN) -#define PART0 "place initialized var decl of " +#define PART0 "place initialized declaration of " #define PART1 "place initialized chan decl of " #define PART2 " at start of proctype " @@ -30,35 +28,42 @@ extern void for_setup(Lextok *, Lextok *, Lextok *); extern Lextok *for_index(Lextok *, Lextok *); extern Lextok *sel_index(Lextok *, Lextok *, Lextok *); +extern void keep_track_off(Lextok *); +extern void safe_break(void); +extern void restore_break(void); extern int u_sync, u_async, dumptab, scope_level; -extern int initialization_ok, split_decl; -extern short has_sorted, has_random, has_enabled, has_pcvalue, has_np; -extern short has_code, has_state, has_io; +extern int initialization_ok; +extern short has_sorted, has_random, has_enabled, has_pcvalue, has_np, has_priority; +extern short has_code, has_state, has_ltl, has_io; +extern void check_mtypes(Lextok *, Lextok *); extern void count_runs(Lextok *); extern void no_internals(Lextok *); extern void any_runs(Lextok *); +extern void explain(int); extern void ltl_list(char *, char *); extern void validref(Lextok *, Lextok *); +extern void sanity_check(Lextok *); extern char yytext[]; int Mpars = 0; /* max nr of message parameters */ int nclaims = 0; /* nr of never claims */ int ltl_mode = 0; /* set when parsing an ltl formula */ int Expand_Ok = 0, realread = 1, IArgs = 0, NamesNotAdded = 0; -int in_for = 0; +int in_for = 0, in_seq = 0, par_cnt = 0; +int dont_simplify = 0; char *claimproc = (char *) 0; char *eventmap = (char *) 0; -static char *ltl_name; -static int Embedded = 0, inEventMap = 0, has_ini = 0; +static char *ltl_name; +static int Embedded = 0, inEventMap = 0, has_ini = 0; %} -%token ASSERT PRINT PRINTM +%token ASSERT PRINT PRINTM PREPROC %token C_CODE C_DECL C_EXPR C_STATE C_TRACK -%token RUN LEN ENABLED EVAL PC_VAL -%token TYPEDEF MTYPE INLINE LABEL OF -%token GOTO BREAK ELSE SEMI +%token RUN LEN ENABLED SET_P GET_P EVAL PC_VAL +%token TYPEDEF MTYPE INLINE RETURN LABEL OF +%token GOTO BREAK ELSE SEMI ARROW %token IF FI DO OD FOR SELECT IN SEP DOTDOT %token ATOMIC NON_ATOMIC D_STEP UNLESS %token TIMEOUT NONPROGRESS @@ -109,20 +114,27 @@ | utype /* user defined types */ | c_fcts /* c functions etc. */ | ns /* named sequence */ - | SEMI /* optional separator */ + | semi /* optional separator */ | error ; +l_par : '(' { par_cnt++; } + ; + +r_par : ')' { par_cnt--; } + ; + + proc : inst /* optional instantiator */ proctype NAME { - setptype($3, PROCTYPE, ZN); + setptype(ZN, $3, PROCTYPE, ZN); setpname($3); context = $3->sym; context->ini = $2; /* linenr and file */ Expand_Ok++; /* expand struct names in decl */ has_ini = 0; } - '(' decl ')' { Expand_Ok--; + l_par decl r_par { Expand_Ok--; if (has_ini) fatal("initializer in parameter list", (char *) 0); } @@ -131,16 +143,16 @@ body { ProcList *rl; if ($1 != ZN && $1->val > 0) { int j; - rl = ready($3->sym, $6, $11->sq, $2->val, $10, A_PROC); + rl = mk_rdy($3->sym, $6, $11->sq, $2->val, $10, A_PROC); for (j = 0; j < $1->val; j++) { runnable(rl, $9?$9->val:1, 1); + announce(":root:"); } - announce(":root:"); if (dumptab) $3->sym->ini = $1; } else - { rl = ready($3->sym, $6, $11->sq, $2->val, $10, P_PROC); + { rl = mk_rdy($3->sym, $6, $11->sq, $2->val, $10, P_PROC); } - if (rl && has_ini == 1) /* global initializations, unsafe */ + if (rl && has_ini == 1) /* global initializations, unsafe */ { /* printf("proctype %s has initialized data\n", $3->sym->name); */ @@ -156,7 +168,7 @@ inst : /* empty */ { $$ = ZN; } | ACTIVE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 1; } - | ACTIVE '[' CONST ']' { + | ACTIVE '[' const_expr ']' { $$ = nn(ZN,CONST,ZN,ZN); $$->val = $3->val; if ($3->val > 255) non_fatal("max nr of processes is 255\n", ""); @@ -178,16 +190,16 @@ init : INIT { context = $1->sym; } Opt_priority body { ProcList *rl; - rl = ready(context, ZN, $4->sq, 0, ZN, I_PROC); + rl = mk_rdy(context, ZN, $4->sq, 0, ZN, I_PROC); runnable(rl, $3?$3->val:1, 1); announce(":root:"); context = ZS; } ; -ltl : LTL optname2 { ltl_mode = 1; ltl_name = $2->sym->name; } - ltl_body { if ($4) ltl_list($2->sym->name, $4->sym->name); - ltl_mode = 0; +ltl : LTL optname2 { ltl_mode = 1; ltl_name = $2->sym->name; } + ltl_body { if ($4) ltl_list($2->sym->name, $4->sym->name); + ltl_mode = 0; has_ltl = 1; } ; @@ -205,7 +217,7 @@ } claimproc = $1->sym->name; } - body { (void) ready($1->sym, ZN, $4->sq, 0, ZN, N_CLAIM); + body { (void) mk_rdy($1->sym, ZN, $4->sq, 0, ZN, N_CLAIM); context = ZS; } ; @@ -236,21 +248,26 @@ } body { if (strcmp($1->sym->name, ":trace:") == 0) - { (void) ready($1->sym, ZN, $3->sq, 0, ZN, E_TRACE); + { (void) mk_rdy($1->sym, ZN, $3->sq, 0, ZN, E_TRACE); } else - { (void) ready($1->sym, ZN, $3->sq, 0, ZN, N_TRACE); + { (void) mk_rdy($1->sym, ZN, $3->sq, 0, ZN, N_TRACE); } context = ZS; inEventMap--; } ; -utype : TYPEDEF NAME { if (context) - fatal("typedef %s must be global", - $2->sym->name); +utype : TYPEDEF NAME '{' { if (context) + { fatal("typedef %s must be global", + $2->sym->name); + } owner = $2->sym; + in_seq = $1->ln; + } + decl_lst '}' { setuname($5); + owner = ZS; + in_seq = 0; } - '{' decl_lst '}' { setuname($5); owner = ZS; } ; nm : NAME { $$ = $1; } @@ -260,8 +277,8 @@ } ; -ns : INLINE nm '(' { NamesNotAdded++; } - args ')' { prep_inline($2->sym, $5); +ns : INLINE nm l_par { NamesNotAdded++; } + args r_par { prep_inline($2->sym, $5); NamesNotAdded--; } ; @@ -297,6 +314,8 @@ NamesNotAdded--; $$ = nn(ZN, C_CODE, ZN, ZN); $$->sym = s; + $$->ln = $1->ln; + $$->fn = $1->fn; has_code = 1; } | C_DECL { Symbol *s; @@ -306,23 +325,32 @@ s->type = CODE_DECL; $$ = nn(ZN, C_CODE, ZN, ZN); $$->sym = s; + $$->ln = $1->ln; + $$->fn = $1->fn; has_code = 1; } ; cexpr : C_EXPR { Symbol *s; NamesNotAdded++; s = prep_inline(ZS, ZN); +/* if context is 0 this was inside an ltl formula + mark the last inline added to seqnames */ + if (!context) + { mark_last(); + } NamesNotAdded--; $$ = nn(ZN, C_EXPR, ZN, ZN); $$->sym = s; + $$->ln = $1->ln; + $$->fn = $1->fn; no_side_effects(s->name); has_code = 1; } ; -body : '{' { open_seq(1); } +body : '{' { open_seq(1); in_seq = $1->ln; } sequence OS { add_seq(Stop); } - '}' { $$->sq = close_seq(0); + '}' { $$->sq = close_seq(0); in_seq = 0; if (scope_level != 0) { non_fatal("missing '}' ?", 0); scope_level = 0; @@ -337,9 +365,13 @@ step : one_decl { $$ = ZN; } | XU vref_lst { setxus($2, $1->val); $$ = ZN; } | NAME ':' one_decl { fatal("label preceding declaration,", (char *)0); } - | NAME ':' XU { fatal("label predecing xr/xs claim,", 0); } + | NAME ':' XU { fatal("label preceding xr/xs claim,", 0); } | stmnt { $$ = $1; } - | stmnt UNLESS stmnt { $$ = do_unless($1, $3); } + | stmnt UNLESS { if ($1->ntyp == DO) { safe_break(); } } + stmnt { if ($1->ntyp == DO) { restore_break(); } + $$ = do_unless($1, $4); + } + | error ; vis : /* empty */ { $$ = ZN; } @@ -348,12 +380,18 @@ | ISLOCAL { $$ = $1; } ; -asgn: /* empty */ - | ASGN +asgn : /* empty */ { $$ = ZN; } + | ':' NAME ASGN { $$ = $2; /* mtype decl */ } + | ASGN { $$ = ZN; /* mtype decl */ } + ; + +osubt : /* empty */ { $$ = ZN; } + | ':' NAME { $$ = $2; } ; -one_decl: vis TYPE var_list { setptype($3, $2->val, $1); - $$ = $3; +one_decl: vis TYPE osubt var_list { setptype($3, $4, $2->val, $1); + $4->val = $2->val; + $$ = $4; } | vis UNAME var_list { setutype($3, $2->sym, $1); $$ = expand($3, Expand_Ok); @@ -361,7 +399,7 @@ | vis TYPE asgn '{' nlst '}' { if ($2->val != MTYPE) fatal("malformed declaration", 0); - setmtype($5); + setmtype($3, $5); if ($1) non_fatal("cannot %s mtype (ignored)", $1->sym->name); @@ -387,34 +425,66 @@ | ivar ',' var_list { $$ = nn($1, TYPE, ZN, $3); } ; +c_list : CONST { $1->ntyp = CONST; $$ = $1; } + | CONST ',' c_list { $1->ntyp = CONST; $$ = nn($1, ',', $1, $3); } + ; + ivar : vardcl { $$ = $1; $1->sym->ini = nn(ZN,CONST,ZN,ZN); $1->sym->ini->val = 0; + if (!initialization_ok) + { Lextok *zx, *xz; + zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + xz = nn(zx, ASGN, zx, $1->sym->ini); + keep_track_off(xz); + /* make sure zx doesnt turn out to be a STRUCT later */ + add_seq(xz); + } } - | vardcl ASGN expr { $$ = $1; + | vardcl ASGN '{' c_list '}' { /* array initialization */ + if (!$1->sym->isarray) + fatal("%s must be an array", $1->sym->name); + $$ = $1; + $1->sym->ini = $4; + has_ini = 1; + $1->sym->hidden |= (4|8); /* conservative */ + if (!initialization_ok) + { Lextok *zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + add_seq(nn(zx, ASGN, zx, $4)); + } + } + | vardcl ASGN expr { $$ = $1; /* initialized scalar */ $1->sym->ini = $3; - trackvar($1,$3); if ($3->ntyp == CONST || ($3->ntyp == NAME && $3->sym->context)) { has_ini = 2; /* local init */ } else { has_ini = 1; /* possibly global */ } - if (!initialization_ok && split_decl) - { nochan_manip($1, $3, 0); - no_internals($1); - non_fatal(PART0 "'%s'" PART2, $1->sym->name); + trackvar($1, $3); + if (any_oper($3, RUN)) + { fatal("cannot use 'run' in var init, saw", (char *) 0); + } + nochan_manip($1, $3, 0); + no_internals($1); + if (!initialization_ok) + { Lextok *zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + add_seq(nn(zx, ASGN, zx, $3)); + $1->sym->ini = 0; /* Patrick Trentlin */ } } - | vardcl ASGN ch_init { $1->sym->ini = $3; + | vardcl ASGN ch_init { $1->sym->ini = $3; /* channel declaration */ $$ = $1; has_ini = 1; - if (!initialization_ok && split_decl) + if (!initialization_ok) { non_fatal(PART1 "'%s'" PART2, $1->sym->name); } } ; -ch_init : '[' CONST ']' OF +ch_init : '[' const_expr ']' OF '{' typ_list '}' { if ($2->val) u_async++; else @@ -424,6 +494,8 @@ } $$ = nn(ZN, CHAN, ZN, $6); $$->val = $2->val; + $$->ln = $1->ln; + $$->fn = $1->fn; } ; @@ -436,7 +508,23 @@ } $1->sym->nel = 1; $$ = $1; } - | NAME '[' CONST ']' { $1->sym->nel = $3->val; $1->sym->isarray = 1; $$ = $1; } + | NAME '[' const_expr ']' { $1->sym->nel = $3->val; $1->sym->isarray = 1; $$ = $1; } + | NAME '[' NAME ']' { /* make an exception for an initialized scalars */ + $$ = nn(ZN, CONST, ZN, ZN); + fprintf(stderr, "spin: %s:%d, warning: '%s' in array bound ", + $1->fn->name, $1->ln, $3->sym->name); + if ($3->sym->ini + && $3->sym->ini->val > 0) + { fprintf(stderr, "evaluated as %d\n", $3->sym->ini->val); + $$->val = $3->sym->ini->val; + } else + { fprintf(stderr, "evaluated as 1 by default (to avoid zero)\n"); + $$->val = 1; + } + $1->sym->nel = $$->val; + $1->sym->isarray = 1; + $$ = $1; + } ; varref : cmpnd { $$ = mk_explicit($1, Expand_Ok, NAME); } @@ -475,16 +563,19 @@ stmnt : Special { $$ = $1; initialization_ok = 0; } | Stmnt { $$ = $1; initialization_ok = 0; - if (inEventMap) - non_fatal("not an event", (char *)0); + if (inEventMap) non_fatal("not an event", (char *)0); } ; -for_pre : FOR '(' { in_for = 1; } - varref { $$ = $4; } +for_pre : FOR l_par { in_for = 1; } + varref { trapwonly($4 /*, "for" */); + pushbreak(); /* moved up */ + $$ = $4; + } ; -for_post: '{' sequence OS '}' ; +for_post: '{' sequence OS '}' + | SEMI '{' sequence OS '}' Special : varref RCV { Expand_Ok++; } rargs { Expand_Ok--; has_io++; @@ -497,25 +588,30 @@ $$->val=0; trackchanuse($4, ZN, 'S'); any_runs($4); } - | for_pre ':' expr DOTDOT expr ')' { + | for_pre ':' expr DOTDOT expr r_par { for_setup($1, $3, $5); in_for = 0; } - for_post { $$ = for_body($1, 1); + for_post { $$ = for_body($1, 1); } - | for_pre IN varref ')' { $$ = for_index($1, $3); in_for = 0; + | for_pre IN varref r_par { $$ = for_index($1, $3); in_for = 0; } - for_post { $$ = for_body($5, 1); + for_post { $$ = for_body($5, 1); } - | SELECT '(' varref ':' expr DOTDOT expr ')' { + | SELECT l_par varref ':' expr DOTDOT expr r_par { + trapwonly($3 /*, "select" */); $$ = sel_index($3, $5, $7); } | IF options FI { $$ = nn($1, IF, ZN, ZN); $$->sl = $2->sl; + $$->ln = $1->ln; + $$->fn = $1->fn; prune_opts($$); } | DO { pushbreak(); } options OD { $$ = nn($1, DO, ZN, ZN); $$->sl = $3->sl; + $$->ln = $1->ln; + $$->fn = $1->fn; prune_opts($$); } | BREAK { $$ = nn(ZN, GOTO, ZN, ZN); @@ -537,9 +633,22 @@ } $1->sym->type = LABEL; } + | NAME ':' { $$ = nn($1, ':',ZN,ZN); + if ($1->sym->type != 0 + && $1->sym->type != LABEL) { + non_fatal("bad label-name %s", + $1->sym->name); + } + $$->lft = nn(ZN, 'c', nn(ZN,CONST,ZN,ZN), ZN); + $$->lft->lft->val = 1; /* skip */ + $1->sym->type = LABEL; + } + | error { $$ = nn(ZN, 'c', nn(ZN,CONST,ZN,ZN), ZN); + $$->lft->val = 1; /* skip */ + } ; -Stmnt : varref ASGN full_expr { $$ = nn($1, ASGN, $1, $3); +Stmnt : varref ASGN full_expr { $$ = nn($1, ASGN, $1, $3); /* assignment */ trackvar($1, $3); nochan_manip($1, $3, 0); no_internals($1); @@ -560,10 +669,11 @@ if ($1->sym->type == CHAN) fatal("arithmetic on chan id's", (char *)0); } - | PRINT '(' STRING { realread = 0; } - prargs ')' { $$ = nn($3, PRINT, $5, ZN); realread = 1; } - | PRINTM '(' varref ')' { $$ = nn(ZN, PRINTM, $3, ZN); } - | PRINTM '(' CONST ')' { $$ = nn(ZN, PRINTM, $3, ZN); } + | SET_P l_par two_args r_par { $$ = nn(ZN, SET_P, $3, ZN); has_priority++; } + | PRINT l_par STRING { realread = 0; } + prargs r_par { $$ = nn($3, PRINT, $5, ZN); realread = 1; } + | PRINTM l_par varref r_par { $$ = nn(ZN, PRINTM, $3, ZN); } + | PRINTM l_par CONST r_par { $$ = nn(ZN, PRINTM, $3, ZN); } | ASSERT full_expr { $$ = nn(ZN, ASSERT, $2, ZN); AST_track($2, 0); } | ccode { $$ = $1; } | varref R_RCV { Expand_Ok++; } @@ -597,23 +707,40 @@ | ATOMIC '{' { open_seq(0); } sequence OS '}' { $$ = nn($1, ATOMIC, ZN, ZN); $$->sl = seqlist(close_seq(3), 0); - make_atomic($$->sl->this, 0); + $$->ln = $1->ln; + $$->fn = $1->fn; + make_atomic($$->sl->this, 0); } | D_STEP '{' { open_seq(0); rem_Seq(); } sequence OS '}' { $$ = nn($1, D_STEP, ZN, ZN); $$->sl = seqlist(close_seq(4), 0); + $$->ln = $1->ln; + $$->fn = $1->fn; make_atomic($$->sl->this, D_ATOM); unrem_Seq(); } | '{' { open_seq(0); } sequence OS '}' { $$ = nn(ZN, NON_ATOMIC, ZN, ZN); $$->sl = seqlist(close_seq(5), 0); + $$->ln = $1->ln; + $$->fn = $1->fn; } | INAME { IArgs++; } - '(' args ')' { pickup_inline($1->sym, $4); IArgs--; } + l_par args r_par { initialization_ok = 0; + pickup_inline($1->sym, $4, ZN); + IArgs--; + } Stmnt { $$ = $7; } + + | varref ASGN INAME { IArgs++; /* inline call */ } + l_par args r_par { initialization_ok = 0; + pickup_inline($3->sym, $6, $1); + IArgs--; + } + Stmnt { $$ = $9; } + | RETURN full_expr { $$ = return_statement($2); } ; options : option { $$->sl = seqlist($1->sq, 0); } @@ -622,22 +749,49 @@ option : SEP { open_seq(0); } sequence OS { $$ = nn(ZN,0,ZN,ZN); - $$->sq = close_seq(6); } + $$->sq = close_seq(6); + $$->ln = $1->ln; + $$->fn = $1->fn; + } ; OS : /* empty */ - | SEMI { /* redundant semi at end of sequence */ } + | semi { /* redundant semi at end of sequence */ } + ; + +semi : SEMI + | ARROW ; -MS : SEMI { /* at least one semi-colon */ } - | MS SEMI { /* but more are okay too */ } +MS : semi { /* at least one semi-colon */ } + | MS semi { /* but more are okay too */ } ; aname : NAME { $$ = $1; } | PNAME { $$ = $1; } ; -expr : '(' expr ')' { $$ = $2; } +const_expr: CONST { $$ = $1; } + | '-' const_expr %prec UMIN { $$ = $2; $$->val = -($2->val); } + | l_par const_expr r_par { $$ = $2; } + | const_expr '+' const_expr { $$ = $1; $$->val = $1->val + $3->val; } + | const_expr '-' const_expr { $$ = $1; $$->val = $1->val - $3->val; } + | const_expr '*' const_expr { $$ = $1; $$->val = $1->val * $3->val; } + | const_expr '/' const_expr { $$ = $1; + if ($3->val == 0) + { fatal("division by zero", (char *) 0); + } + $$->val = $1->val / $3->val; + } + | const_expr '%' const_expr { $$ = $1; + if ($3->val == 0) + { fatal("attempt to take modulo of zero", (char *) 0); + } + $$->val = $1->val % $3->val; + } + ; + +expr : l_par expr r_par { $$ = $2; } | expr '+' expr { $$ = nn(ZN, '+', $1, $3); } | expr '-' expr { $$ = nn(ZN, '-', $1, $3); } | expr '*' expr { $$ = nn(ZN, '*', $1, $3); } @@ -660,26 +814,24 @@ | '-' expr %prec UMIN { $$ = nn(ZN, UMIN, $2, ZN); } | SND expr %prec NEG { $$ = nn(ZN, '!', $2, ZN); } - | '(' expr SEMI expr ':' expr ')' { + | l_par expr ARROW expr ':' expr r_par { $$ = nn(ZN, OR, $4, $6); $$ = nn(ZN, '?', $2, $$); } | RUN aname { Expand_Ok++; if (!context) - fatal("used 'run' outside proctype", - (char *) 0); + fatal("used 'run' outside proctype", (char *) 0); } - '(' args ')' + l_par args r_par Opt_priority { Expand_Ok--; $$ = nn($2, RUN, $5, ZN); - $$->val = ($7) ? $7->val : 1; + $$->val = ($7) ? $7->val : 0; trackchanuse($5, $2, 'A'); trackrun($$); } - | LEN '(' varref ')' { $$ = nn($3, LEN, $3, ZN); } - | ENABLED '(' expr ')' { $$ = nn(ZN, ENABLED, $3, ZN); - has_enabled++; - } + | LEN l_par varref r_par { $$ = nn($3, LEN, $3, ZN); } + | ENABLED l_par expr r_par { $$ = nn(ZN, ENABLED, $3, ZN); has_enabled++; } + | GET_P l_par expr r_par { $$ = nn(ZN, GET_P, $3, ZN); has_priority++; } | varref RCV { Expand_Ok++; } '[' rargs ']' { Expand_Ok--; has_io++; $$ = nn($1, 'R', $1, $5); @@ -693,13 +845,14 @@ | cexpr { $$ = $1; } | CONST { $$ = nn(ZN,CONST,ZN,ZN); $$->ismtyp = $1->ismtyp; + $$->sym = $1->sym; $$->val = $1->val; } | TIMEOUT { $$ = nn(ZN,TIMEOUT, ZN, ZN); } | NONPROGRESS { $$ = nn(ZN,NONPROGRESS, ZN, ZN); has_np++; } - | PC_VAL '(' expr ')' { $$ = nn(ZN, PC_VAL, $3, ZN); + | PC_VAL l_par expr r_par { $$ = nn(ZN, PC_VAL, $3, ZN); has_pcvalue++; } | PNAME '[' expr ']' '@' NAME @@ -708,15 +861,15 @@ { $$ = rem_var($1->sym, $3, $6->sym, $6->lft); } | PNAME '@' NAME { $$ = rem_lab($1->sym, ZN, $3->sym); } | PNAME ':' pfld { $$ = rem_var($1->sym, ZN, $3->sym, $3->lft); } - | ltl_expr { $$ = $1; } + | ltl_expr { $$ = $1; /* sanity_check($1); */ } ; Opt_priority: /* none */ { $$ = ZN; } - | PRIORITY CONST { $$ = $2; } + | PRIORITY CONST { $$ = $2; has_priority++; } ; full_expr: expr { $$ = $1; } - | Expr { $$ = $1; } + | Expr { $$ = $1; } ; ltl_expr: expr UNTIL expr { $$ = nn(ZN, UNTIL, $1, $3); } @@ -724,9 +877,8 @@ | expr WEAK_UNTIL expr { $$ = nn(ZN, ALWAYS, $1, ZN); $$ = nn(ZN, OR, $$, nn(ZN, UNTIL, $1, $3)); } - | expr IMPLIES expr { - $$ = nn(ZN, '!', $1, ZN); - $$ = nn(ZN, OR, $$, $3); + | expr IMPLIES expr { $$ = nn(ZN, '!', $1, ZN); + $$ = nn(ZN, OR, $$, $3); } | expr EQUIV expr { $$ = nn(ZN, EQUIV, $1, $3); } | NEXT expr %prec NEG { $$ = nn(ZN, NEXT, $2, ZN); } @@ -736,7 +888,7 @@ /* an Expr cannot be negated - to protect Probe expressions */ Expr : Probe { $$ = $1; } - | '(' Expr ')' { $$ = $2; } + | l_par Expr r_par { $$ = $2; } | Expr AND Expr { $$ = nn(ZN, AND, $1, $3); } | Expr AND expr { $$ = nn(ZN, AND, $1, $3); } | expr AND Expr { $$ = nn(ZN, AND, $1, $3); } @@ -745,27 +897,35 @@ | expr OR Expr { $$ = nn(ZN, OR, $1, $3); } ; -Probe : FULL '(' varref ')' { $$ = nn($3, FULL, $3, ZN); } - | NFULL '(' varref ')' { $$ = nn($3, NFULL, $3, ZN); } - | EMPTY '(' varref ')' { $$ = nn($3, EMPTY, $3, ZN); } - | NEMPTY '(' varref ')' { $$ = nn($3,NEMPTY, $3, ZN); } +Probe : FULL l_par varref r_par { $$ = nn($3, FULL, $3, ZN); } + | NFULL l_par varref r_par { $$ = nn($3, NFULL, $3, ZN); } + | EMPTY l_par varref r_par { $$ = nn($3, EMPTY, $3, ZN); } + | NEMPTY l_par varref r_par { $$ = nn($3,NEMPTY, $3, ZN); } ; Opt_enabler: /* none */ { $$ = ZN; } - | PROVIDED '(' full_expr ')' { if (!proper_enabler($3)) - { non_fatal("invalid PROVIDED clause", - (char *)0); - $$ = ZN; - } else - $$ = $3; + | PROVIDED l_par full_expr r_par { + if (!proper_enabler($3)) + { non_fatal("invalid PROVIDED clause", (char *)0); + $$ = ZN; + } else + { $$ = $3; + } } + | PROVIDED error { $$ = ZN; + non_fatal("usage: provided ( ..expr.. )", (char *)0); } - | PROVIDED error { $$ = ZN; - non_fatal("usage: provided ( ..expr.. )", - (char *)0); - } ; -basetype: TYPE { $$->sym = ZS; +oname : /* empty */ { $$ = ZN; } + | ':' NAME { $$ = $2; } + ; + +basetype: TYPE oname { if ($2) + { if ($1->val != MTYPE) + { explain($1->val); + fatal("unexpected type", (char *) 0); + } } + $$->sym = $2 ? $2->sym : ZS; $$->val = $1->val; if ($$->val == UNSIGNED) fatal("unsigned cannot be used as mesg type", 0); @@ -780,6 +940,9 @@ | basetype ',' typ_list { $$ = nn($1, $1->val, ZN, $3); } ; +two_args: expr ',' expr { $$ = nn(ZN, ',', $1, $3); } + ; + args : /* empty */ { $$ = ZN; } | arg { $$ = $1; } ; @@ -789,7 +952,7 @@ ; margs : arg { $$ = $1; } - | expr '(' arg ')' { if ($1->ntyp == ',') + | expr l_par arg r_par { if ($1->ntyp == ',') $$ = tail_add($1, $3); else $$ = nn(ZN, ',', $1, $3); @@ -810,10 +973,11 @@ rarg : varref { $$ = $1; trackvar($1, $1); trapwonly($1 /*, "rarg" */); } - | EVAL '(' expr ')' { $$ = nn(ZN,EVAL,$3,ZN); + | EVAL l_par expr r_par { $$ = nn(ZN,EVAL,$3,ZN); trapwonly($1 /*, "eval rarg" */); } | CONST { $$ = nn(ZN,CONST,ZN,ZN); $$->ismtyp = $1->ismtyp; + $$->sym = $1->sym; $$->val = $1->val; } | '-' CONST %prec UMIN { $$ = nn(ZN,CONST,ZN,ZN); @@ -831,12 +995,12 @@ else $$ = nn(ZN, ',', $1, $3); } - | rarg '(' rargs ')' { if ($1->ntyp == ',') + | rarg l_par rargs r_par { if ($1->ntyp == ',') $$ = tail_add($1, $3); else $$ = nn(ZN, ',', $1, $3); } - | '(' rargs ')' { $$ = $2; } + | l_par rargs r_par { $$ = $2; } ; nlst : NAME { $$ = nn($1, NAME, ZN, ZN); @@ -892,22 +1056,25 @@ case EQUIV: binop(n, "<->"); break; + case C_EXPR: + fprintf(fd, "c_expr { %s }", put_inline(fd, n->sym->name)); + break; default: comment(fd, n, 0); break; } } -#define TMP_FILE "_S_p_I_n_.tmp" - -extern int unlink(const char *); +#ifdef __MINGW32__ +extern ssize_t getline(char **, size_t *, FILE *); /* see main.c */ +#endif static Lextok * ltl_to_string(Lextok *n) { Lextok *m = nn(ZN, 0, ZN, ZN); - char *retval; - char formula[1024]; - FILE *tf = fopen(TMP_FILE, "w+"); /* tmpfile() fails on Windows 7 */ + ssize_t retval; + char *ltl_formula = NULL; + FILE *tf = fopen(TMP_FILE1, "w+"); /* tmpfile() fails on Windows 7 */ /* convert the parsed ltl to a string by writing into a file, using existing functions, @@ -920,25 +1087,68 @@ if (!tf) { fatal("cannot create temporary file", (char *) 0); } + dont_simplify = 1; recursive(tf, n); + dont_simplify = 0; (void) fseek(tf, 0L, SEEK_SET); - memset(formula, 0, sizeof(formula)); - retval = fgets(formula, sizeof(formula), tf); + size_t linebuffsize = 0; + retval = getline(<l_formula, &linebuffsize, tf); fclose(tf); - (void) unlink(TMP_FILE); + + (void) unlink(TMP_FILE1); if (!retval) - { printf("%p\n", retval); - fatal("could not translate ltl formula", 0); + { printf("%ld\n", (long int) retval); + fatal("could not translate ltl ltl_formula", 0); } - if (1) printf("ltl %s: %s\n", ltl_name, formula); - - m->sym = lookup(formula); + if (1) printf("ltl %s: %s\n", ltl_name, ltl_formula); + m->sym = lookup(ltl_formula); +#ifndef __MINGW32__ + free(ltl_formula); +#endif return m; } + +int +is_temporal(int t) +{ + return (t == EVENTUALLY || t == ALWAYS || t == UNTIL + || t == WEAK_UNTIL || t == RELEASE); +} + +int +is_boolean(int t) +{ + return (t == AND || t == OR || t == IMPLIES || t == EQUIV); +} + +#if 0 +/* flags correct formula like: ltl { true U (true U true) } */ +void +sanity_check(Lextok *t) /* check proper embedding of ltl_expr */ +{ + if (!t) return; + sanity_check(t->lft); + sanity_check(t->rgt); + + if (t->lft && t->rgt) + { if (!is_boolean(t->ntyp) + && (is_temporal(t->lft->ntyp) + || is_temporal(t->rgt->ntyp))) + { printf("spin: attempt to apply '"); + explain(t->ntyp); + printf("' to '"); + explain(t->lft->ntyp); + printf("' and '"); + explain(t->rgt->ntyp); + printf("'\n"); + /* non_fatal("missing parentheses?", (char *)0); */ + } } +} +#endif void yyerror(char *fmt, ...) diff -Nru /n/sources/plan9/sys/src/cmd/spin/spinlex.c /sys/src/cmd/spin/spinlex.c --- /n/sources/plan9/sys/src/cmd/spin/spinlex.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/spinlex.c Mon Feb 22 00:00:00 2021 @@ -1,15 +1,15 @@ /***** spin: spinlex.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include +#include +#include +#include #include "spin.h" #include "y.tab.h" @@ -21,9 +21,11 @@ Symbol *nm; /* name of the type */ Lextok *cn; /* contents */ Lextok *params; /* formal pars if any */ + Lextok *rval; /* variable to assign return value, if any */ char **anms; /* literal text for actual pars */ char *prec; /* precondition for c_code or c_expr */ int uiid; /* unique inline id */ + int is_expr; /* c_expr in an ltl formula */ int dln, cln; /* def and call linenr */ Symbol *dfn, *cfn; /* def and call filename */ struct IType *nxt; /* linked list */ @@ -33,16 +35,19 @@ Symbol *s; Symbol *t; Symbol *ival; + Symbol *fnm; + int lno; struct C_Added *nxt; } C_Added; -extern RunList *X; -extern ProcList *rdy; +extern RunList *X_lst; +extern ProcList *ready; extern Symbol *Fname, *oFname; extern Symbol *context, *owner; extern YYSTYPE yylval; -extern short has_last, has_code; -extern int verbose, IArgs, hastrack, separate, ltl_mode; +extern short has_last, has_code, has_priority; +extern int verbose, IArgs, hastrack, separate, in_for; +extern int implied_semis, ltl_mode, in_seq, par_cnt; short has_stack = 0; int lineno = 1; @@ -58,64 +63,85 @@ static unsigned char in_comment=0; static int IArgno = 0, Inlining = -1; static int check_name(char *); - -#if 1 -#define Token(y) { if (in_comment) goto again; \ - yylval = nn(ZN,0,ZN,ZN); return y; } +static int last_token = 0; #define ValToken(x, y) { if (in_comment) goto again; \ - yylval = nn(ZN,0,ZN,ZN); yylval->val = x; return y; } + yylval = nn(ZN,0,ZN,ZN); \ + yylval->val = x; \ + last_token = y; \ + return y; \ + } #define SymToken(x, y) { if (in_comment) goto again; \ - yylval = nn(ZN,0,ZN,ZN); yylval->sym = x; return y; } -#else -#define Token(y) { yylval = nn(ZN,0,ZN,ZN); \ - if (!in_comment) return y; else goto again; } - -#define ValToken(x, y) { yylval = nn(ZN,0,ZN,ZN); yylval->val = x; \ - if (!in_comment) return y; else goto again; } - -#define SymToken(x, y) { yylval = nn(ZN,0,ZN,ZN); yylval->sym = x; \ - if (!in_comment) return y; else goto again; } -#endif + yylval = nn(ZN,0,ZN,ZN); \ + yylval->sym = x; \ + last_token = y; \ + return y; \ + } -static int getinline(void); -static void uninline(void); +static int getinline(void); +static void uninline(void); -#if 1 -#define Getchar() ((Inlining<0)?getc(yyin):getinline()) -#define Ungetch(c) {if (Inlining<0) ungetc(c,yyin); else uninline();} +static int PushBack; +static int PushedBack; +static char pushedback[4096]; -#else +static void +push_back(char *s) +{ + if (PushedBack + strlen(s) > 4094) + { fatal("select statement too large", 0); + } + strcat(pushedback, s); + PushedBack += strlen(s); +} static int Getchar(void) { int c; + if (PushedBack > 0 && PushBack < PushedBack) + { c = pushedback[PushBack++]; + if (PushBack == PushedBack) + { pushedback[0] = '\0'; + PushBack = PushedBack = 0; + } + return c; /* expanded select statement */ + } if (Inlining<0) - c = getc(yyin); - else - c = getinline(); + { do { c = getc(yyin); + } while (c == 0); // ignore null chars + // eventually there will always be an EOF + } else + { c = getinline(); + } +#if 0 if (0) { printf("<%c:%d>[%d] ", c, c, Inlining); } else { printf("%c", c); } +#endif return c; } static void Ungetch(int c) { + if (PushedBack > 0 && PushBack > 0) + { PushBack--; + return; + } + if (Inlining<0) - ungetc(c,yyin); - else - uninline(); + { ungetc(c,yyin); + } else + { uninline(); + } if (0) - { printf(""); + { printf("\n\n", c); } } -#endif static int notdollar(int c) @@ -148,12 +174,16 @@ yytext[i++]= (char) first; while (tst(c = Getchar())) - { yytext[i++] = (char) c; + { if (c == EOF) + { break; + } + yytext[i++] = (char) c; if (c == '\\') { c = Getchar(); yytext[i++] = (char) c; /* no tst */ } } yytext[i] = '\0'; + Ungetch(c); } @@ -162,7 +192,8 @@ { int c; if ((c = Getchar()) == tok) - return ifyes; + { return ifyes; + } Ungetch(c); return ifno; @@ -264,6 +295,20 @@ return 0; } +Lextok * +return_statement(Lextok *n) +{ + if (Inline_stub[Inlining]->rval) + { Lextok *g = nn(ZN, NAME, ZN, ZN); + Lextok *h = Inline_stub[Inlining]->rval; + g->sym = lookup("rv_"); + return nn(h, ASGN, h, n); + } else + { fatal("return statement outside inline", (char *) 0); + } + return ZN; +} + static int getinline(void) { int c; @@ -275,12 +320,16 @@ c = *Inliner[Inlining]++; } } else + { c = *Inliner[Inlining]++; + } if (c == '\0') - { lineno = Inline_stub[Inlining]->cln; + { + lineno = Inline_stub[Inlining]->cln; Fname = Inline_stub[Inlining]->cfn; Inlining--; + #if 0 if (verbose&32) printf("spin: %s:%d, done inlining %s\n", @@ -331,7 +380,17 @@ r->s = s; /* pointer to a data object */ r->t = t; /* size of object, or "global", or "local proctype_name" */ r->ival = ival; + r->lno = lineno; + r->fnm = Fname; r->nxt = c_added; + + if(strncmp(r->s->name, "\"unsigned unsigned", 18) == 0) + { int i; + for (i = 10; i < 18; i++) + { r->s->name[i] = ' '; + } + /* printf("corrected <%s>\n", r->s->name); */ + } c_added = r; } @@ -344,6 +403,8 @@ r->t = t; r->ival = stackonly; /* abuse of name */ r->nxt = c_tracked; + r->fnm = Fname; + r->lno = lineno; c_tracked = r; if (stackonly != ZS) @@ -359,31 +420,74 @@ } char * -jump_etc(char *op) -{ char *p = op; +skip_white(char *p) +{ + if (p != NULL) + { while (*p == ' ' || *p == '\t') + p++; + } else + { fatal("bad format - 1", (char *) 0); + } + return p; +} - /* kludgy - try to get the type separated from the name */ +char * +skip_nonwhite(char *p) +{ + if (p != NULL) + { while (*p != ' ' && *p != '\t') + p++; + } else + { fatal("bad format - 2", (char *) 0); + } + return p; +} - while (*p == ' ' || *p == '\t') - p++; /* initial white space */ - while (*p != ' ' && *p != '\t') - p++; /* type name */ - while (*p == ' ' || *p == '\t') - p++; /* white space */ - while (*p == '*') - p++; /* decorations */ - while (*p == ' ' || *p == '\t') - p++; /* white space */ +static char * +jump_etc(C_Added *r) +{ char *op = r->s->name; + char *p = op; + char *q = (char *) 0; + int oln = lineno; + Symbol *ofnm = Fname; + + /* try to get the type separated from the name */ + lineno = r->lno; + Fname = r->fnm; + + p = skip_white(p); /* initial white space */ + + if (strncmp(p, "enum", strlen("enum")) == 0) /* special case: a two-part typename */ + { p += strlen("enum")+1; + p = skip_white(p); + } + if (strncmp(p, "unsigned", strlen("unsigned")) == 0) /* possibly a two-part typename */ + { p += strlen("unsigned")+1; + q = p = skip_white(p); + } + p = skip_nonwhite(p); /* type name */ + p = skip_white(p); /* white space */ + while (*p == '*') p++; /* decorations */ + p = skip_white(p); /* white space */ if (*p == '\0') - fatal("c_state format (%s)", op); + { if (q) + { p = q; /* unsigned with implied 'int' */ + } else + { fatal("c_state format (%s)", op); + } } if (strchr(p, '[') - && !strchr(p, '{')) + && (!r->ival + || !r->ival->name + || !strchr(r->ival->name, '{'))) /* was !strchr(p, '{')) */ { non_fatal("array initialization error, c_state (%s)", p); - return (char *) 0; + p = (char *) 0; } + lineno = oln; + Fname = ofnm; + return p; } @@ -404,7 +508,7 @@ if (*q == '\\') *q++ = ' '; /* skip over the next */ } - p = jump_etc(r->s->name); /* e.g., "int **q" */ + p = jump_etc(r); /* e.g., "int **q" */ if (p) fprintf(fd, " now.%s = %s;\n", p, r->ival->name); @@ -416,7 +520,7 @@ if (*q == '\\') *q++ = ' '; /* skip over the next */ } - p = jump_etc(r->s->name); /* e.g., "int **q" */ + p = jump_etc(r); /* e.g., "int **q" */ if (p) fprintf(fd, " %s = %s;\n", p, r->ival->name); /* no now. prefix */ @@ -437,8 +541,7 @@ { for (q = r->ival->name; *q; q++) if (*q == '\"') *q = ' '; - - p = jump_etc(r->s->name); /* e.g., "int **q" */ + p = jump_etc(r); /* e.g., "int **q" */ q = r->t->name + strlen(" Local"); while (*q == ' ' || *q == '\t') @@ -455,14 +558,14 @@ continue; if (frst) - { fprintf(fd, "\tuchar *this = pptr(h);\n"); + { fprintf(fd, "\tuchar *_this = pptr(h);\n"); frst = 0; } if (p) - fprintf(fd, " ((P%d *)this)->%s = %s;\n", - tpnr, p, r->ival->name); - + { fprintf(fd, "\t\t((P%d *)_this)->%s = %s;\n", + tpnr, p, r->ival->name); + } } fprintf(fd, "}\n"); } @@ -597,19 +700,22 @@ strcpy(buf, s); strcat(buf, " "); for (r = c_added; r; r = r->nxt) /* pickup local decls */ - if (strncmp(r->t->name, " Local", strlen(" Local")) == 0) + { if (strncmp(r->t->name, " Local", strlen(" Local")) == 0) { p = r->t->name + strlen(" Local"); +fprintf(fd, "/* XXX p=<%s>, s=<%s>, buf=<%s> r->s->name=<%s>XXX */\n", p, s, buf, r->s->name); while (*p == ' ' || *p == '\t') - p++; - if (strcmp(p, buf) == 0) - fprintf(fd, " %s;\n", r->s->name); - } + { p++; + } + if (strcmp(p, buf) == 0 + || (strncmp(p, "init", 4) == 0 && strncmp(buf, ":init:", 6) == 0)) + { fprintf(fd, " %s;\n", r->s->name); + } } } } void c_add_def(FILE *fd) /* 3 - called in plunk_c_fcts() */ { C_Added *r; - fprintf(fd, "#if defined(C_States) && defined(HAS_TRACK)\n"); + fprintf(fd, "#if defined(C_States) && (HAS_TRACK==1)\n"); for (r = c_added; r; r = r->nxt) { r->s->name[strlen(r->s->name)-1] = ' '; r->s->name[0] = ' '; /* remove the "s */ @@ -662,7 +768,7 @@ fprintf(fd, "void\nc_update(uchar *p_t_r)\n{\n"); fprintf(fd, "#ifdef VERBOSE\n"); - fprintf(fd, " printf(\"c_update %%u\\n\", p_t_r);\n"); + fprintf(fd, " printf(\"c_update %%p\\n\", p_t_r);\n"); fprintf(fd, "#endif\n"); for (r = c_added; r; r = r->nxt) { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 @@ -707,7 +813,7 @@ fprintf(fd, "void\nc_revert(uchar *p_t_r)\n{\n"); fprintf(fd, "#ifdef VERBOSE\n"); - fprintf(fd, " printf(\"c_revert %%u\\n\", p_t_r);\n"); + fprintf(fd, " printf(\"c_revert %%p\\n\", p_t_r);\n"); fprintf(fd, "#endif\n"); for (r = c_added; r; r = r->nxt) { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 @@ -740,11 +846,13 @@ plunk_reverse(fd, p->nxt, matchthis); if (!p->nm->context - && p->nm->type == matchthis) + && p->nm->type == matchthis + && p->is_expr == 0) { fprintf(fd, "\n/* start of %s */\n", p->nm->name); z = (char *) p->cn; while (*z == '\n' || *z == '\r' || *z == '\\') - z++; + { z++; + } /* e.g.: \#include "..." */ y = z; @@ -791,27 +899,41 @@ { char buf[128]; ProcList *p; - if (!X) return; + if (!X_lst) return; - for (p = rdy; p; p = p->nxt) - { if (strcmp(p->n->name, X->n->name) == 0) + for (p = ready; p; p = p->nxt) + { if (strcmp(p->n->name, X_lst->n->name) == 0) continue; sprintf(buf, "P%s->", p->n->name); if (strstr((char *)tmp->cn, buf)) { printf("spin: in proctype %s, ref to object in proctype %s\n", - X->n->name, p->n->name); + X_lst->n->name, p->n->name); fatal("invalid variable ref in '%s'", tmp->nm->name); } } } +extern short terse; +extern short nocast; + void plunk_expr(FILE *fd, char *s) { IType *tmp; + char *q; tmp = find_inline(s); check_inline(tmp); - fprintf(fd, "%s", (char *) tmp->cn); + if (terse && nocast) + { for (q = (char *) tmp->cn; q && *q != '\0'; q++) + { fflush(fd); + if (*q == '"') + { fprintf(fd, "\\"); + } + fprintf(fd, "%c", *q); + } + } else + { fprintf(fd, "%s", (char *) tmp->cn); + } } void @@ -823,9 +945,11 @@ { tmp = find_inline(n->sym->name); if (tmp->prec) { fprintf(fd, "if (!(%s)) { if (!readtrail) { depth++; ", tmp->prec); - fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t;"); - fprintf(fd, "trpt->st = tt; uerror(\"%s\"); continue; } ", tmp->prec); - fprintf(fd, "else { printf(\"pan: precondition false: %s\\n\"); ", tmp->prec); + fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t; trpt->st = tt; "); + fprintf(fd, "uerror(\"c_expr line %d precondition false: %s\"); continue;", + tmp->dln, tmp->prec); + fprintf(fd, " } else { printf(\"pan: precondition false: %s\\n\"); ", + tmp->prec); fprintf(fd, "_m = 3; goto P999; } } \n\t\t"); } } else @@ -845,6 +969,23 @@ || strchr(bdy, '(') > bdy); /* possible C-function call */ } +char * +put_inline(FILE *fd, char *s) +{ IType *tmp; + + tmp = find_inline(s); + check_inline(tmp); + return (char *) tmp->cn; +} + +void +mark_last(void) +{ + if (seqnames) + { seqnames->is_expr = 1; + } +} + void plunk_inline(FILE *fd, char *s, int how, int gencode) /* c_code with precondition */ { IType *tmp; @@ -856,7 +997,8 @@ if (how && tmp->prec) { fprintf(fd, "if (!(%s)) { if (!readtrail) {", tmp->prec); - fprintf(fd, " uerror(\"%s\"); continue; ", + fprintf(fd, " uerror(\"c_code line %d precondition false: %s\"); continue; ", + tmp->dln, tmp->prec); fprintf(fd, "} else { "); fprintf(fd, "printf(\"pan: precondition false: %s\\n\"); _m = 3; goto P999; } } ", @@ -871,10 +1013,19 @@ fprintf(fd, " }\n"); } +int +side_scan(char *t, char *pat) +{ char *r = strstr(t, pat); + return (r + && *(r-1) != '"' + && *(r-1) != '\''); +} + void no_side_effects(char *s) { IType *tmp; char *t; + char *z; /* could still defeat this check via hidden * side effects in function calls, @@ -883,10 +1034,21 @@ tmp = find_inline(s); t = (char *) tmp->cn; + while (t && *t == ' ') + { t++; + } - if (strchr(t, ';') - || strstr(t, "++") - || strstr(t, "--")) + z = strchr(t, '('); + if (z + && z > t + && isalnum((int) *(z-1)) + && strncmp(t, "spin_mutex_free(", strlen("spin_mutex_free(")) != 0) + { goto bad; /* fct call */ + } + + if (side_scan(t, ";") + || side_scan(t, "++") + || side_scan(t, "--")) { bad: lineno = tmp->dln; Fname = tmp->dfn; @@ -896,8 +1058,10 @@ while ((t = strchr(t, '=')) != NULL) { if (*(t-1) == '!' || *(t-1) == '>' - || *(t-1) == '<') - { t++; + || *(t-1) == '<' + || *(t-1) == '"' + || *(t-1) == '\'') + { t += 2; continue; } t++; @@ -908,7 +1072,7 @@ } void -pickup_inline(Symbol *t, Lextok *apars) +pickup_inline(Symbol *t, Lextok *apars, Lextok *rval) { IType *tmp; Lextok *p, *q; int j; tmp = find_inline(t->name); @@ -917,6 +1081,7 @@ fatal("inlines nested too deeply", 0); tmp->cln = lineno; /* remember calling point */ tmp->cfn = Fname; /* and filename */ + tmp->rval = rval; for (p = apars, q = tmp->params, j = 0; p && q; p = p->rgt, q = q->rgt) j++; /* count them */ @@ -939,10 +1104,14 @@ tmp->cfn->name, tmp->cln, t->name, tmp->dfn->name, tmp->dln); #endif for (j = 0; j < Inlining; j++) - if (Inline_stub[j] == Inline_stub[Inlining]) - fatal("cyclic inline attempt on: %s", t->name); + { if (Inline_stub[j] == Inline_stub[Inlining]) + { fatal("cyclic inline attempt on: %s", t->name); + } } + last_token = SEMI; /* avoid insertion of extra semi */ } +extern int pp_mode; + static void do_directive(int first) { int c = first; /* handles lines starting with pound */ @@ -1031,7 +1200,8 @@ s->context = context; s->type = CODE_FRAG; } else - s->type = PREDEF; + { s->type = PREDEF; + } p = &Buf1[0]; Buf2[0] = '\0'; @@ -1059,12 +1229,14 @@ dln = lineno; if (s->type == CODE_FRAG) { if (verbose&32) - sprintf(Buf1, "\t/* line %d %s */\n\t\t", + { sprintf(Buf1, "\t/* line %d %s */\n\t\t", lineno, Fname->name); - else - strcpy(Buf1, ""); + } else + { strcpy(Buf1, ""); + } } else - sprintf(Buf1, "\n#line %d \"%s\"\n{", lineno, Fname->name); + { sprintf(Buf1, "\n#line %d \"%s\"\n{", lineno, Fname->name); + } p += strlen(Buf1); firstchar = 1; @@ -1088,11 +1260,13 @@ if (--nest <= 0) { *p = '\0'; if (s->type == CODE_FRAG) - *--p = '\0'; /* remove trailing '}' */ + { *--p = '\0'; /* remove trailing '}' */ + } def_inline(s, dln, &Buf1[0], &Buf2[0], nms); if (firstchar) - printf("%3d: %s, warning: empty inline definition (%s)\n", + { printf("%3d: %s, warning: empty inline definition (%s)\n", dln, Fname->name, s->name); + } return s; /* normal return */ } break; @@ -1110,6 +1284,29 @@ case '\f': cnr++; break; + case '"': + do { + c = Getchar(); + *p++ = (char) c; + if (c == '\\') + { *p++ = (char) Getchar(); + } + if (p - Buf1 >= SOMETHINGBIG) + { fatal("inline text too long", 0); + } + } while (c != '"'); /* end of string */ + /* *p = '\0'; */ + break; + case '\'': + c = Getchar(); + *p++ = (char) c; + if (c == '\\') + { *p++ = (char) Getchar(); + } + c = Getchar(); + *p++ = (char) c; + assert(c == '\''); + break; default: firstchar = 0; cnr++; @@ -1133,18 +1330,204 @@ } static int +pre_proc(void) +{ char b[512]; + int c, i = 0; + + b[i++] = '#'; + while ((c = Getchar()) != '\n' && c != EOF) + { b[i++] = (char) c; + } + b[i] = '\0'; + yylval = nn(ZN, 0, ZN, ZN); + yylval->sym = lookup(b); + return PREPROC; +} + +static int specials[] = { + '}', ')', ']', + OD, FI, ELSE, BREAK, + C_CODE, C_EXPR, C_DECL, + NAME, CONST, INCR, DECR, 0 +}; + +int +follows_token(int c) +{ int i; + + for (i = 0; specials[i]; i++) + { if (c == specials[i]) + { return 1; + } } + return 0; +} +#define DEFER_LTL +#ifdef DEFER_LTL +/* defer ltl formula to the end of the spec + * no matter where they appear in the original + */ + +static int deferred = 0; +static FILE *defer_fd; + +int +get_deferred(void) +{ + if (!defer_fd) + { return 0; /* nothing was deferred */ + } + fclose(defer_fd); + + defer_fd = fopen(TMP_FILE2, "r"); + if (!defer_fd) + { non_fatal("cannot retrieve deferred ltl formula", (char *) 0); + return 0; + } + fclose(yyin); + yyin = defer_fd; + return 1; +} + +void +zap_deferred(void) +{ + (void) unlink(TMP_FILE2); +} + +int +put_deferred(void) +{ int c, cnt; + if (!defer_fd) + { defer_fd = fopen(TMP_FILE2, "w+"); + if (!defer_fd) + { non_fatal("cannot defer ltl expansion", (char *) 0); + return 0; + } } + fprintf(defer_fd, "ltl "); + cnt = 0; + while ((c = getc(yyin)) != EOF) + { if (c == '{') + { cnt++; + } + if (c == '}') + { cnt--; + if (cnt == 0) + { break; + } } + fprintf(defer_fd, "%c", c); + } + fprintf(defer_fd, "}\n"); + fflush(defer_fd); + return 1; +} +#endif + +#define EXPAND_SELECT +#ifdef EXPAND_SELECT +static char tmp_hold[256]; +static int tmp_has; + +void +new_select(void) +{ tmp_hold[0] = '\0'; + tmp_has = 0; +} + +static int +scan_to(int stop, int (*tst)(int), char *buf, int bufsz) +{ int c, i = 0; + + do { c = Getchar(); + if (tmp_has < sizeof(tmp_hold)) + { tmp_hold[tmp_has++] = c; + } + if (c == '\n') + { lineno++; + } else if (buf && i < bufsz-1) + { buf[i++] = c; + } else if (buf && i >= bufsz-1) + { buf[bufsz-1] = '\0'; + fatal("name too long", buf); + } + if (tst && !tst(c) && c != ' ' && c != '\t') + { break; + } + } while (c != stop && c != EOF); + + if (buf) + { if (i <= 0) + { fatal("input error", (char *) 0); + } + buf[i-1] = '\0'; + } + + if (c != stop) + { if (0) + { printf("saw: '%c', expected '%c'\n", c, stop); + } + if (tmp_has < sizeof(tmp_hold)) + { tmp_hold[tmp_has] = '\0'; + push_back(tmp_hold); + if (0) + { printf("pushed back: <'%s'>\n", tmp_hold); + } + return 0; /* internal expansion fails */ + } else + { fatal("expecting select ( name : constant .. constant )", 0); + } } + return 1; /* success */ +} +#endif + +int lex(void) { int c; - again: c = Getchar(); +/* more: */ yytext[0] = (char) c; yytext[1] = '\0'; switch (c) { case EOF: +#ifdef DEFER_LTL + if (!deferred) + { deferred = 1; + if (get_deferred()) + { goto again; + } + } else + { zap_deferred(); + } +#endif return c; case '\n': /* newline */ lineno++; + /* make most semi-colons optional */ + if (implied_semis + /* && context */ + && in_seq + && par_cnt == 0 + && follows_token(last_token)) + { if (last_token == '}') + { do { c = Getchar(); + if (c == '\n') + { lineno++; + } + } while (c == ' ' || c == '\t' || + c == '\f' || c == '\n' || + c == '\r'); + Ungetch(c); + if (0) printf("%d: saw %d\n", lineno, c); + if (c == 'u') /* first letter of UNLESS */ + { goto again; + } } + if (0) + { printf("insert ; line %d, last_token %d in_seq %d\n", + lineno-1, last_token, in_seq); + } + ValToken(1, SEMI); + } + /* else fall thru */ case '\r': /* carriage return */ goto again; @@ -1153,6 +1536,10 @@ case '#': /* preprocessor directive */ if (in_comment) goto again; + if (pp_mode) + { last_token = PREPROC; + return pre_proc(); + } do_directive(c); goto again; @@ -1188,15 +1575,89 @@ } if (isdigit_(c)) - { getword(c, isdigit_); - ValToken(atoi(yytext), CONST) + { long int nr; + getword(c, isdigit_); + errno = 0; + nr = strtol(yytext, NULL, 10); + if (errno != 0) + { fprintf(stderr, "spin: value out of range: '%s' read as '%d'\n", + yytext, (int) nr); + } + ValToken((int)nr, CONST) } if (isalpha_(c) || c == '_') { getword(c, isalnum_); if (!in_comment) { c = check_name(yytext); - if (c) return c; + +/* replace timeout with (timeout) */ + if (c == TIMEOUT + && Inlining < 0 + && last_token != '(') + { push_back("timeout)"); + last_token = '('; + return '('; + } +/* end */ + +#ifdef EXPAND_SELECT + if (c == SELECT && Inlining < 0) + { char name[64], from[32], upto[32]; + int i, a, b; + new_select(); + if (!scan_to('(', 0, 0, 0) + || !scan_to(':', isalnum, name, sizeof(name)) + || !scan_to('.', isdigit, from, sizeof(from)) + || !scan_to('.', 0, 0, 0) + || !scan_to(')', isdigit, upto, sizeof(upto))) + { goto not_expanded; + } + a = atoi(from); + b = atoi(upto); + if (0) + { printf("Select %s from %d to %d\n", + name, a, b); + } + if (a > b) + { non_fatal("bad range in select statement", 0); + goto again; + } + if (b - a <= 32) + { push_back("if "); + for (i = a; i <= b; i++) + { char buf[256]; + push_back(":: "); + sprintf(buf, "%s = %d ", + name, i); + push_back(buf); + } + push_back("fi "); + } else + { char buf[256]; + sprintf(buf, "%s = %d; do ", + name, a); + push_back(buf); + sprintf(buf, ":: (%s < %d) -> %s++ ", + name, b, name); + push_back(buf); + push_back(":: break od; "); + } + goto again; + } +not_expanded: +#endif + +#ifdef DEFER_LTL + if (c == LTL && !deferred) + { if (put_deferred()) + { goto again; + } } +#endif + if (c) + { last_token = c; + return c; + } /* else fall through */ } goto again; @@ -1230,7 +1691,7 @@ if (!c) { in_comment = 0; goto again; } break; case ':': c = follow(':', SEP, ':'); break; - case '-': c = follow('>', SEMI, follow('-', DECR, '-')); break; + case '-': c = follow('>', ARROW, follow('-', DECR, '-')); break; case '+': c = follow('+', INCR, '+'); break; case '<': c = follow('<', LSHIFT, follow('=', LE, LT)); break; case '>': c = follow('>', RSHIFT, follow('=', GE, GT)); break; @@ -1245,7 +1706,7 @@ case '}': scope_level--; set_cur_scope(); break; default : break; } - Token(c) + ValToken(0, c) } static struct { @@ -1294,6 +1755,7 @@ {"fi", FI, 0, 0}, {"for", FOR, 0, 0}, {"full", FULL, 0, 0}, + {"get_priority", GET_P, 0, 0}, {"goto", GOTO, 0, 0}, {"hidden", HIDDEN, 0, ":hide:"}, {"if", IF, 0, 0}, @@ -1319,9 +1781,11 @@ {"priority", PRIORITY, 0, 0}, {"proctype", PROCTYPE, 0, 0}, {"provided", PROVIDED, 0, 0}, + {"return", RETURN, 0, 0}, {"run", RUN, 0, 0}, {"d_step", D_STEP, 0, 0}, - {"select", SELECT, 0, 0}, + {"select", SELECT, 0, 0}, + {"set_priority", SET_P, 0, 0}, {"short", TYPE, SHORT, 0}, {"skip", CONST, 1, 0}, {"timeout", TIMEOUT, 0, 0}, @@ -1353,17 +1817,26 @@ { yylval->val = Names[i].val; if (Names[i].sym) yylval->sym = lookup(Names[i].sym); + if (Names[i].tok == IN && !in_for) + { continue; + } return Names[i].tok; } } if ((yylval->val = ismtype(s)) != 0) { yylval->ismtyp = 1; + yylval->sym = (Symbol *) emalloc(sizeof(Symbol)); + yylval->sym->name = (char *) emalloc(strlen(s)+1); + strcpy(yylval->sym->name, s); return CONST; } if (strcmp(s, "_last") == 0) has_last++; + if (strcmp(s, "_priority") == 0) + has_priority++; + if (Inlining >= 0 && !ReDiRect) { Lextok *tt, *t = Inline_stub[Inlining]->params; @@ -1393,8 +1866,9 @@ /* check for occurrence of param as field of struct */ { char *ptr = Inline_stub[Inlining]->anms[i]; + char *optr = ptr; while ((ptr = strstr(ptr, s)) != NULL) - { if (*(ptr-1) == '.' + { if ((ptr > optr && *(ptr-1) == '.') || *(ptr+strlen(s)) == '.') { fatal("formal par of %s used in structure name", Inline_stub[Inlining]->nm->name); @@ -1428,13 +1902,16 @@ if (hold) { c = hold; hold = 0; + last_token = c; } else { c = lex(); if (last == ELSE && c != SEMI + && c != ARROW && c != FI) { hold = c; last = 0; + last_token = SEMI; return SEMI; } if (last == '}' @@ -1447,12 +1924,14 @@ && c != '}' && c != UNLESS && c != SEMI + && c != ARROW && c != EOF) { hold = c; last = 0; + last_token = SEMI; return SEMI; /* insert ';' */ } - if (c == SEMI) + if (c == SEMI || c == ARROW) { /* if context, we're not in a typedef * because they're global. * if owner, we're at the end of a ref @@ -1463,6 +1942,7 @@ if (context) owner = ZS; hold = lex(); /* look ahead */ if (hold == '}' + || hold == ARROW || hold == SEMI) { c = hold; /* omit ';' */ hold = 0; @@ -1481,19 +1961,26 @@ { IArgno = 0; IArg_cont[0][0] = '\0'; } else + { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); strcat(IArg_cont[IArgno], yytext); + } } else if (strcmp(yytext, ")") == 0) { if (--IArg_nst > 0) + { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); strcat(IArg_cont[IArgno], yytext); + } } else if (c == CONST && yytext[0] == '\'') { sprintf(yytext, "'%c'", yylval->val); + assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); strcat(IArg_cont[IArgno], yytext); } else if (c == CONST) { sprintf(yytext, "%d", yylval->val); + assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); strcat(IArg_cont[IArgno], yytext); } else { switch (c) { + case ARROW: strcpy(yytext, "->"); break; /* NEW */ case SEP: strcpy(yytext, "::"); break; case SEMI: strcpy(yytext, ";"); break; case DECR: strcpy(yytext, "--"); break; @@ -1514,6 +2001,7 @@ case AND: strcpy(yytext, "&&"); break; case OR: strcpy(yytext, "||"); break; } + assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); strcat(IArg_cont[IArgno], yytext); } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/structs.c /sys/src/cmd/spin/structs.c --- /n/sources/plan9/sys/src/cmd/spin/structs.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/structs.c Mon Feb 22 00:00:00 2021 @@ -1,13 +1,10 @@ /***** spin: structs.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" @@ -27,7 +24,8 @@ static UType *Pnames = 0; static Lextok *cpnn(Lextok *, int, int, int); -extern void sr_mesg(FILE *, int, int); +extern void sr_mesg(FILE *, int, int, const char *); +extern void Done_case(char *, Symbol *); void setuname(Lextok *n) @@ -104,7 +102,8 @@ { lineno = n->ln; Fname = n->fn; if (n->sym->type) - fatal("redeclaration of '%s'", n->sym->name); + { fatal("redeclaration of '%s'", n->sym->name); + } if (n->sym->nbits > 0) non_fatal("(%s) only an unsigned can have width-field", @@ -240,12 +239,18 @@ { Lextok *fp, *tl, *n; int cnt = 0; + if (!m) + { return 0; + } + if (m->ntyp == ',') { n = m; goto is_lst; } - if (!m->sym || m->ntyp != STRUCT) - return 1; + if (!m->sym + || m->ntyp != STRUCT) + { return 1; + } n = getuname(m->sym); is_lst: @@ -316,7 +321,7 @@ static Lextok * cpnn(Lextok *s, int L, int R, int S) -{ Lextok *d; extern int Nid; +{ Lextok *d; extern int Nid_nr; if (!s) return ZN; @@ -334,7 +339,7 @@ { d->sym = (Symbol *) emalloc(sizeof(Symbol)); memcpy(d->sym, s->sym, sizeof(Symbol)); if (d->sym->type == CHAN) - d->sym->Nid = ++Nid; + d->sym->Nid = ++Nid_nr; } if (s->sq || s->sl) fatal("cannot happen cpnn", (char *) 0); @@ -409,14 +414,14 @@ { Lextok *fp, *tl; char eprefix[128]; int ix; - extern void Done_case(char *, Symbol *); + memset(eprefix, 0, sizeof(eprefix)); ini_struct(z); if (z->nel == 1 && z->isarray == 0) - sprintf(eprefix, "%s%s.", s, z->name); + snprintf(eprefix, sizeof(eprefix)-1, "%s%s.", s, z->name); for (ix = 0; ix < z->nel; ix++) { if (z->nel > 1 || z->isarray == 1) - sprintf(eprefix, "%s%s[%d].", s, z->name, ix); + snprintf(eprefix, sizeof(eprefix)-1, "%s%s[%d].", s, z->name, ix); for (fp = z->Sval[ix]; fp; fp = fp->rgt) for (tl = fp->lft; tl; tl = tl->rgt) { if (tl->sym->type == STRUCT) @@ -432,12 +437,13 @@ char eprefix[128]; int ix; + memset(eprefix, 0, sizeof(eprefix)); ini_struct(z); if (z->nel == 1 && z->isarray == 0) - sprintf(eprefix, "%s%s.", s, z->name); + snprintf(eprefix, sizeof(eprefix)-1, "%s%s.", s, z->name); for (ix = 0; ix < z->nel; ix++) { if (z->nel > 1 || z->isarray == 1) - sprintf(eprefix, "%s%s[%d].", s, z->name, ix); + snprintf(eprefix, sizeof(eprefix)-1, "%s%s[%d].", s, z->name, ix); for (fp = z->Sval[ix]; fp; fp = fp->rgt) for (tl = fp->lft; tl; tl = tl->rgt) { if (tl->sym->type == STRUCT) @@ -501,15 +507,22 @@ { if (tl->sym->type == CHAN) doq(tl->sym, jx, r); else - { printf("\t\t"); + { char *s = 0; + printf("\t\t"); if (r) printf("%s(%d):", r->n->name, r->pid); printf("%s.%s", eprefix, tl->sym->name); if (tl->sym->nel > 1 || tl->sym->isarray == 1) printf("[%d]", jx); printf(" = "); + + if (tl->sym->type == MTYPE + && tl->sym->mtype_name) + { s = tl->sym->mtype_name->name; + } + sr_mesg(stdout, tl->sym->val[jx], - tl->sym->type == MTYPE); + tl->sym->type == MTYPE, s); printf("\n"); } } } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/sym.c /sys/src/cmd/spin/sym.c --- /n/sources/plan9/sys/src/cmd/spin/sym.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/sym.c Mon Feb 22 00:00:00 2021 @@ -1,13 +1,10 @@ /***** spin: sym.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" @@ -20,13 +17,13 @@ Symbol *context = ZS; Ordered *all_names = (Ordered *)0; -int Nid = 0; +int Nid_nr = 0; -Lextok *Mtype = (Lextok *) 0; +Mtypes_t *Mtypes; +Lextok *runstmnts = ZN; static Ordered *last_name = (Ordered *)0; static Symbol *symtab[Nhash+1]; -static Lextok *runstmnts = ZN; static int samename(Symbol *a, Symbol *b) @@ -36,12 +33,12 @@ return !strcmp(a->name, b->name); } -int -hash(char *s) -{ int h=0; +unsigned int +hash(const char *s) +{ unsigned int h = 0; while (*s) - { h += *s++; + { h += (unsigned int) *s++; h <<= 1; if (h&(Nhash+1)) h |= 1; @@ -53,29 +50,41 @@ disambiguate(void) { Ordered *walk; Symbol *sp; + char *n, *m; if (old_scope_rules) return; - /* if the same name appears in two different scopes, - prepend the scope_prefix to the names */ + /* prepend the scope_prefix to the names */ for (walk = all_names; walk; walk = walk->next) { sp = walk->entry; if (sp->type != 0 && sp->type != LABEL && strlen((const char *)sp->bscp) > 1) - { char *n = (char *) emalloc(strlen((const char *)sp->name) + { if (sp->context) + { m = (char *) emalloc(strlen((const char *)sp->bscp) + 1); + sprintf(m, "_%d_", sp->context->sc); + if (strcmp((const char *) m, (const char *) sp->bscp) == 0) + { continue; + /* 6.2.0: only prepend scope for inner-blocks, + not for top-level locals within a proctype + this means that you can no longer use the same name + for a global and a (top-level) local variable + */ + } } + + n = (char *) emalloc(strlen((const char *)sp->name) + strlen((const char *)sp->bscp) + 1); sprintf(n, "%s%s", sp->bscp, sp->name); - sp->name = n; /* discord the old memory */ + sp->name = n; /* discard the old memory */ } } } Symbol * lookup(char *s) { Symbol *sp; Ordered *no; - int h = hash(s); + unsigned int h = hash(s); if (old_scope_rules) { /* same scope - global refering to global or local to local */ @@ -222,7 +231,7 @@ } void -setptype(Lextok *n, int t, Lextok *vis) /* predefined types */ +setptype(Lextok *mtype_name, Lextok *n, int t, Lextok *vis) /* predefined types */ { int oln = lineno, cnt = 1; extern int Expand_Ok; while (n) @@ -233,11 +242,31 @@ } n->sym->type = (short) t; + if (mtype_name && t != MTYPE) + { lineno = n->ln; Fname = n->fn; + fatal("missing semi-colon after '%s'?", + mtype_name->sym->name); + lineno = oln; + } + + if (mtype_name && n->sym->mtype_name + && strcmp(mtype_name->sym->name, n->sym->mtype_name->name) != 0) + { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but assigned type '%s'\n", + n->fn->name, n->ln, + n->sym->name, + mtype_name->sym->name, + n->sym->mtype_name->name); + non_fatal("type error", (char *) 0); + } + + n->sym->mtype_name = mtype_name?mtype_name->sym:0; /* if mtype, else 0 */ + if (Expand_Ok) { n->sym->hidden |= (4|8|16); /* formal par */ if (t == CHAN) setaccess(n->sym, ZS, cnt, 'F'); } + if (t == UNSIGNED) { if (n->sym->nbits < 0 || n->sym->nbits >= 32) fatal("(%s) has invalid width-field", n->sym->name); @@ -249,6 +278,7 @@ { non_fatal("(%s) only an unsigned can have width-field", n->sym->name); } + if (vis) { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0) { n->sym->hidden |= 1; @@ -262,9 +292,10 @@ { n->sym->hidden |= 64; } } + if (t == CHAN) - n->sym->Nid = ++Nid; - else + { n->sym->Nid = ++Nid_nr; + } else { n->sym->Nid = 0; if (n->sym->ini && n->sym->ini->ntyp == CHAN) @@ -272,13 +303,14 @@ lineno = n->ln; fatal("chan initializer for non-channel %s", n->sym->name); - } - } + } } + if (n->sym->nel <= 0) - { lineno = n->ln; Fname = n->fn; - non_fatal("bad array size for '%s'", n->sym->name); - lineno = oln; + { lineno = n->ln; Fname = n->fn; + non_fatal("bad array size for '%s'", n->sym->name); + lineno = oln; } + n = n->rgt; cnt++; } } @@ -321,7 +353,7 @@ has_xu = 1; if (m_loss && t == XS) - { printf("spin: warning, %s:%d, xs tag not compatible with -m (message loss)\n", + { printf("spin: %s:%d, warning, xs tag not compatible with -m (message loss)\n", (p->fn != NULL) ? p->fn->name : "stdin", p->ln); } @@ -354,18 +386,46 @@ } } +Lextok ** +find_mtype_list(const char *s) +{ Mtypes_t *lst; + + for (lst = Mtypes; lst; lst = lst->nxt) + { if (strcmp(lst->nm, s) == 0) + { return &(lst->mt); + } } + + /* not found, create it */ + lst = (Mtypes_t *) emalloc(sizeof(Mtypes_t)); + lst->nm = (char *) emalloc(strlen(s)+1); + strcpy(lst->nm, s); + lst->nxt = Mtypes; + Mtypes = lst; + return &(lst->mt); +} + void -setmtype(Lextok *m) -{ Lextok *n; +setmtype(Lextok *mtype_name, Lextok *m) +{ Lextok **mtl; /* mtype list */ + Lextok *n, *Mtype; int cnt, oln = lineno; + char *s = "_unnamed_"; if (m) { lineno = m->ln; Fname = m->fn; } + if (mtype_name && mtype_name->sym) + { s = mtype_name->sym->name; + } + + mtl = find_mtype_list(s); + Mtype = *mtl; + if (!Mtype) - Mtype = m; - else + { *mtl = Mtype = m; + } else { for (n = Mtype; n->rgt; n = n->rgt) - ; + { ; + } n->rgt = m; /* concatenate */ } @@ -382,24 +442,45 @@ n->lft->sym->ini = nn(ZN,CONST,ZN,ZN); n->lft->sym->ini->val = cnt; } else if (n->lft->sym->ini->val != cnt) - non_fatal("name %s appears twice in mtype declaration", + { non_fatal("name %s appears twice in mtype declaration", n->lft->sym->name); - } + } } + lineno = oln; if (cnt > 256) - fatal("too many mtype elements (>255)", (char *)0); + { fatal("too many mtype elements (>255)", (char *) 0); + } +} + +char * +which_mtype(const char *str) /* which mtype is str, 0 if not an mtype at all */ +{ Mtypes_t *lst; + Lextok *n; + + for (lst = Mtypes; lst; lst = lst->nxt) + for (n = lst->mt; n; n = n->rgt) + { if (strcmp(str, n->lft->sym->name) == 0) + { return lst->nm; + } } + + return (char *) 0; } int ismtype(char *str) /* name to number */ -{ Lextok *n; - int cnt = 1; +{ Mtypes_t *lst; + Lextok *n; + int cnt; + + for (lst = Mtypes; lst; lst = lst->nxt) + { cnt = 1; + for (n = lst->mt; n; n = n->rgt) + { if (strcmp(str, n->lft->sym->name) == 0) + { return cnt; + } + cnt++; + } } - for (n = Mtype; n; n = n->rgt) - { if (strcmp(str, n->lft->sym->name) == 0) - return cnt; - cnt++; - } return 0; } @@ -484,7 +565,9 @@ } } -if (1) printf("\t{scope %s}", sp->bscp); + if (!old_scope_rules) + { printf("\t{scope %s}", sp->bscp); + } printf("\n"); } @@ -507,7 +590,7 @@ printf("\t"); } -static struct X { +static struct X_lkp { int typ; char *nm; } xx[] = { { 'A', "exported as run parameter" }, @@ -536,11 +619,16 @@ return; report: chname(sp); - for (i = d = 0; i < (int) (sizeof(xx)/sizeof(struct X)); i++) + for (i = d = 0; i < (int) (sizeof(xx)/sizeof(struct X_lkp)); i++) { b = 0; for (a = sp->access; a; a = a->lnk) - if (a->typ == xx[i].typ) b++; - if (b == 0) continue; d++; + { if (a->typ == xx[i].typ) + { b++; + } } + if (b == 0) + { continue; + } + d++; printf("\n\t%s by: ", xx[i].nm); for (a = sp->access; a; a = a->lnk) if (a->typ == xx[i].typ) @@ -583,14 +671,14 @@ if (!(verbose&32) || has_code) continue; - printf("spin: warning, %s, ", Fname->name); + printf("spin: %s:0, warning, ", Fname->name); sputtype(buf, walk->entry->type); if (walk->entry->context) printf("proctype %s", walk->entry->context->name); else printf("global"); - printf(", '%s%s' variable is never used\n", + printf(", '%s%s' variable is never used (other than in print stmnts)\n", buf, walk->entry->name); } } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl.h /sys/src/cmd/spin/tl.h --- /n/sources/plan9/sys/src/cmd/spin/tl.h Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl.h Mon Feb 22 00:00:00 2021 @@ -1,16 +1,16 @@ /***** tl_spin: tl.h *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +#ifndef TLH +#define TLH #include #include @@ -66,6 +66,7 @@ #ifdef NXT , NEXT /* 269 */ #endif + , CEXPR /* 270 */ }; Node *Canonical(Node *); @@ -84,14 +85,16 @@ extern char *emalloc(size_t); /* in main.c */ +extern unsigned int hash(const char *); /* in sym.c */ + int anywhere(int, Node *, Node *); int dump_cond(Node *, Node *, int); -int hash(char *); /* in sym.c */ int isalnum_(int); /* in spinlex.c */ int isequal(Node *, Node *); int tl_Getchar(void); void *tl_emalloc(int); +void *tl_erealloc(void*, int, int); void a_stats(void); void addtrans(Graph *, char *, Node *, char *); void cache_stats(void); @@ -130,3 +133,5 @@ #define Assert(x, y) { if (!(x)) { tl_explain(y); \ Fatal(": assertion failed\n",(char *)0); } } + +#endif diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_buchi.c /sys/src/cmd/spin/tl_buchi.c --- /n/sources/plan9/sys/src/cmd/spin/tl_buchi.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_buchi.c Mon Feb 22 00:00:00 2021 @@ -1,21 +1,19 @@ /***** tl_spin: tl_buchi.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" extern int tl_verbose, tl_clutter, Total, Max_Red; extern char *claim_name; +extern void put_uform(void); FILE *tl_out; /* if standalone: = stdout; */ @@ -66,6 +64,7 @@ #ifdef NXT case NEXT: #endif + case CEXPR: return p; case OR: p->lft = Prune(p->lft); @@ -553,10 +552,22 @@ rev_trans(t->nxt); if (t->redundant && !tl_verbose) return; - fprintf(tl_out, "\t:: ("); - if (dump_cond(t->cond, t->cond, 1)) - fprintf(tl_out, "1"); - fprintf(tl_out, ") -> goto %s\n", t->name->name); + + if (strcmp(t->name->name, "accept_all") == 0) /* 6.2.4 */ + { /* not d_step because there may be remote refs */ + fprintf(tl_out, "\t:: atomic { ("); + if (dump_cond(t->cond, t->cond, 1)) + fprintf(tl_out, "1"); + fprintf(tl_out, ") -> assert(!("); + if (dump_cond(t->cond, t->cond, 1)) + fprintf(tl_out, "1"); + fprintf(tl_out, ")) }\n"); + } else + { fprintf(tl_out, "\t:: ("); + if (dump_cond(t->cond, t->cond, 1)) + fprintf(tl_out, "1"); + fprintf(tl_out, ") -> goto %s\n", t->name->name); + } tcnt++; } @@ -578,11 +589,11 @@ && Max_Red == 0) fprintf(tl_out, "T0%s:\n", &(b->name->name[6])); - fprintf(tl_out, "\tif\n"); + fprintf(tl_out, "\tdo\n"); tcnt = 0; rev_trans(b->trans); if (!tcnt) fprintf(tl_out, "\t:: false\n"); - fprintf(tl_out, "\tfi;\n"); + fprintf(tl_out, "\tod;\n"); Total++; } @@ -629,7 +640,6 @@ void fsm_print(void) { State *b; int cnt1, cnt2=0; - extern void put_uform(void); if (tl_clutter) clutter(); diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_cache.c /sys/src/cmd/spin/tl_cache.c --- /n/sources/plan9/sys/src/cmd/spin/tl_cache.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_cache.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_cache.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" @@ -24,9 +21,10 @@ static Cache *stored = (Cache *) 0; static unsigned long Caches, CacheHits; -static int ismatch(Node *, Node *); +static int ismatch(Node *, Node *); +static int sameform(Node *, Node *); + extern void fatal(char *, char *); -int sameform(Node *, Node *); void ini_cache(void) @@ -190,7 +188,7 @@ return all_lfts(ntyp, b, a); } -int /* a better isequal() */ +static int /* a better isequal() */ sameform(Node *a, Node *b) { if (!a && !b) return 1; @@ -214,6 +212,7 @@ #ifdef NXT case NEXT: #endif + case CEXPR: return sameform(a->lft, b->lft); case U_OPER: case V_OPER: diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_lex.c /sys/src/cmd/spin/tl_lex.c --- /n/sources/plan9/sys/src/cmd/spin/tl_lex.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_lex.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_lex.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include #include @@ -27,11 +24,19 @@ static void tl_getword(int first, int (*tst)(int)) -{ int i=0; char c; +{ int i=0; int c; yytext[i++] = (char ) first; - while (tst(c = tl_Getchar())) - yytext[i++] = c; + + c = tl_Getchar(); + while (c != -1 && tst(c)) + { yytext[i++] = (char) c; + c = tl_Getchar(); + } + +/* while (tst(c = tl_Getchar())) + * yytext[i++] = c; + */ yytext[i] = '\0'; tl_UnGetchar(); } @@ -69,10 +74,11 @@ c = tl_peek(i++); /* look ahead without changing position */ while ((c != want || nesting > 0) && c != -1 && i < 2047) - { if (islower((int) c)) + { if (islower((int) c) || c == '_') { peek_buf[0] = c; j = 1; - while (j < (int) sizeof(peek_buf) && isalnum((int)(c = tl_peek(i)))) + while (j < (int) sizeof(peek_buf) + && (isalnum((int)(c = tl_peek(i))) || c == '_')) { peek_buf[j++] = c; i++; } @@ -83,15 +89,21 @@ } peek_buf[j] = '\0'; if (strcmp(peek_buf, "always") == 0 + || strcmp(peek_buf, "equivalent") == 0 || strcmp(peek_buf, "eventually") == 0 || strcmp(peek_buf, "until") == 0 - || strcmp(peek_buf, "next") == 0) + || strcmp(peek_buf, "next") == 0 + || strcmp(peek_buf, "c_expr") == 0) { return 0; } } else - { char c_nxt = tl_peek(i); - if (((c == 'U' || c == 'V' || c == 'X') && !isalnum_(c_prev) && !isalnum_(c_nxt)) + { int c_nxt = tl_peek(i); + if (((c == 'U' || c == 'V' || c == 'X') + && !isalnum_(c_prev) + && (c_nxt == -1 || !isalnum_(c_nxt))) || (c == '<' && c_nxt == '>') + || (c == '<' && c_nxt == '-') + || (c == '-' && c_nxt == '>') || (c == '[' && c_nxt == ']')) { return 0; } } @@ -146,6 +158,9 @@ { if (is_predicate(c)) { read_upto_closing(c); tl_yylval = tl_nn(PREDICATE,ZN,ZN); + if (!tl_yylval) + { fatal("unexpected error 4", (char *) 0); + } tl_yylval->sym = tl_lookup(yytext); return PREDICATE; } } @@ -175,10 +190,16 @@ { Token(NEXT); } #endif + if (strcmp("c_expr", yytext) == 0) + { Token(CEXPR); + } if (strcmp("not", yytext) == 0) { Token(NOT); } tl_yylval = tl_nn(PREDICATE,ZN,ZN); + if (!tl_yylval) + { fatal("unexpected error 5", (char *) 0); + } tl_yylval->sym = tl_lookup(yytext); return PREDICATE; } @@ -221,7 +242,7 @@ Symbol * tl_lookup(char *s) { Symbol *sp; - int h = hash(s); + unsigned int h = hash(s); for (sp = symtab[h]; sp; sp = sp->next) if (strcmp(sp->name, s) == 0) diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_main.c /sys/src/cmd/spin/tl_main.c --- /n/sources/plan9/sys/src/cmd/spin/tl_main.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_main.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_main.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" @@ -26,7 +23,7 @@ unsigned long All_Mem = 0; char *claim_name; -static char uform[4096]; +static char *uform; static int hasuform=0, cnt=0; extern void cache_stats(void); @@ -57,10 +54,21 @@ for (i = 0; i < hasuform; i++) { if (uform[i] == '(') - { k++; + { if (i > 0 + && ((uform[i-1] == '"' && uform[i+1] == '"') + || (uform[i-1] == '\'' && uform[i+1] == '\''))) + { continue; + } + k++; } else if (uform[i] == ')') - { k--; + { if (i > 0 + && ((uform[i-1] == '"' && uform[i+1] == '"') + || (uform[i-1] == '\'' && uform[i+1] == '\''))) + { continue; + } + k--; } } + if (k != 0) { tl_errs++; tl_yyerror("parentheses not balanced"); @@ -91,17 +99,22 @@ int tl_main(int argc, char *argv[]) { int i; - extern int /* verbose, */ xspin; + extern int xspin, s_trail; tl_verbose = 0; /* was: tl_verbose = verbose; */ - tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */ - + if (xspin && s_trail) + { tl_clutter = 1; + /* generating claims for a replay should + be done the same as when generating the + pan.c that produced the error-trail */ + } else + { tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */ + } newstates = 0; state_cnt = 0; tl_errs = 0; tl_terse = 0; All_Mem = 0; - memset(uform, 0, sizeof(uform)); hasuform=0; cnt=0; claim_name = (char *) 0; @@ -119,12 +132,13 @@ case 'f': argc--; argv++; for (i = 0; argv[1][i]; i++) { if (argv[1][i] == '\t' - || argv[1][i] == '\"' || argv[1][i] == '\n') argv[1][i] = ' '; } + size_t len = strlen(argv[1]); + uform = tl_emalloc(len + 1); strcpy(uform, argv[1]); - hasuform = (int) strlen(uform); + hasuform = (int) len; break; case 'v': tl_verbose++; break; @@ -195,6 +209,12 @@ case PREDICATE: fprintf(tl_out, "(%s)", n->sym->name); break; + case CEXPR: + fprintf(tl_out, "c_expr"); + fprintf(tl_out, " {"); + dump(n->lft); + fprintf(tl_out, "}"); + break; case -1: fprintf(tl_out, " D "); break; @@ -222,6 +242,7 @@ #ifdef NXT case NEXT: printf("X"); break; #endif + case CEXPR: printf("c_expr"); break; case TRUE: printf("true"); break; case FALSE: printf("false"); break; case ';': printf("end of formula"); break; @@ -235,10 +256,14 @@ int i; printf("tl_spin: "); +#if 1 + printf(s1, s2); /* prevent a compiler warning */ +#else if (s2) printf(s1, s2); else printf(s1); +#endif if (tl_yychar != -1 && tl_yychar != 0) { printf(", saw '"); tl_explain(tl_yychar); diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_mem.c /sys/src/cmd/spin/tl_mem.c --- /n/sources/plan9/sys/src/cmd/spin/tl_mem.c Wed Aug 31 19:01:04 2005 +++ /sys/src/cmd/spin/tl_mem.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_mem.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" @@ -52,22 +49,24 @@ if (u >= A_LARGE) { log(ALLOC, 0, 1); if (tl_verbose) - printf("tl_spin: memalloc %ld bytes\n", u); + { printf("tl_spin: memalloc %ld bytes\n", u); + } m = (union M *) emalloc((int) u*sizeof(union M)); All_Mem += (unsigned long) u*sizeof(union M); } else { if (!freelist[u]) { r = req[u] += req[u] ? req[u] : 1; if (r >= NOTOOBIG) - r = req[u] = NOTOOBIG; + { r = req[u] = NOTOOBIG; + } log(POOL, u, r); freelist[u] = (union M *) emalloc((int) r*u*sizeof(union M)); All_Mem += (unsigned long) r*u*sizeof(union M); m = freelist[u] + (r-2)*u; for ( ; m >= freelist[u]; m -= u) - m->link = m+u; - } + { m->link = m+u; + } } log(ALLOC, u, 1); m = freelist[u]; freelist[u] = m->link; @@ -75,13 +74,27 @@ m->size = (u|A_USER); for (r = 1; r < u; ) - (&m->size)[r++] = 0; + { (&m->size)[r++] = 0; + } rp = (void *) (m+1); memset(rp, 0, U); return rp; } +/* could be more efficient, but not a bottleneck */ +void* +tl_erealloc(void *v, int U, int old_size) +{ void* tmp = tl_emalloc(U); + + if (v) + { strncpy(tmp, v, old_size); + tfree(v); + } + + return tmp; +} + void tfree(void *v) { union M *m = (union M *) v; @@ -89,7 +102,8 @@ --m; if ((m->size&0xFF000000) != A_USER) - Fatal("releasing a free block", (char *)0); + { Fatal("releasing a free block", (char *)0); + } u = (m->size &= 0xFFFFFF); if (u >= A_LARGE) @@ -113,8 +127,8 @@ a = event[ALLOC][i]; f = event[FREE][i]; - if(p|a|f) - printf("%5d\t%6ld\t%6ld\t%6ld\n", - i, p, a, f); - } + if (p|a|f) + { printf("%5d\t%6ld\t%6ld\t%6ld\n", + i, p, a, f); + } } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_parse.c /sys/src/cmd/spin/tl_parse.c --- /n/sources/plan9/sys/src/cmd/spin/tl_parse.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_parse.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_parse.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" @@ -44,6 +41,9 @@ ptr = tl_yylval; tl_yychar = tl_yylex(); ptr->lft = tl_factor(); + if (!ptr->lft) + { fatal("malformed expression", (char *) 0); + } ptr = push_negation(ptr); break; case ALWAYS: @@ -72,6 +72,14 @@ ptr = tl_nn(NEXT, ptr, ZN); break; #endif + case CEXPR: + tl_yychar = tl_yylex(); + ptr = tl_factor(); + if (ptr->ntyp != PREDICATE) + { tl_yyerror("expected {...} after c_expr"); + } + ptr = tl_nn(CEXPR, ptr, ZN); + break; case EVENTUALLY: tl_yychar = tl_yylex(); diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_rewrt.c /sys/src/cmd/spin/tl_rewrt.c --- /n/sources/plan9/sys/src/cmd/spin/tl_rewrt.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_rewrt.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_rewrt.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" @@ -143,6 +140,9 @@ } s = DoDump(N); + if (!s) + { fatal("unexpected error 6", (char *) 0); + } if (can->ntyp != tok) /* only one element in list so far */ { ptr = &can; goto insert; diff -Nru /n/sources/plan9/sys/src/cmd/spin/tl_trans.c /sys/src/cmd/spin/tl_trans.c --- /n/sources/plan9/sys/src/cmd/spin/tl_trans.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/tl_trans.c Mon Feb 22 00:00:00 2021 @@ -1,16 +1,13 @@ /***** tl_spin: tl_trans.c *****/ -/* Copyright (c) 1995-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -/* Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, */ -/* presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + * + * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper, + * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995. + */ #include "tl.h" @@ -23,7 +20,10 @@ static Graph *Nodes_Set = (Graph *) 0; static Graph *Nodes_Stack = (Graph *) 0; -static char dumpbuf[2048]; +static char *dumpbuf = NULL; +static size_t dumpbuf_size = 0; +static size_t dumpbuf_capacity = 0; + static int Red_cnt = 0; static int Lab_cnt = 0; static int Base = 0; @@ -52,6 +52,20 @@ static void sdump(Node *); void +append_to_dumpbuf(char* s) +{ + size_t len = strlen(s); + size_t size_needed = dumpbuf_size + len + 1; + if (size_needed > dumpbuf_capacity) { + dumpbuf = tl_erealloc(dumpbuf, size_needed, dumpbuf_capacity); + dumpbuf_capacity = size_needed; + } + + strncpy(&(dumpbuf[dumpbuf_size]), s, len + 1); + dumpbuf_size += len; +} + +void ini_trans(void) { Stack_mx = 0; @@ -62,7 +76,10 @@ Nodes_Set = (Graph *) 0; Nodes_Stack = (Graph *) 0; - memset(dumpbuf, 0, sizeof(dumpbuf)); + dumpbuf_capacity = 4096; + dumpbuf = tl_emalloc(dumpbuf_capacity); + dumpbuf_size = 0; + memset(dumpbuf, 0, dumpbuf_capacity); Red_cnt = 0; Lab_cnt = 0; Base = 0; @@ -149,6 +166,8 @@ mk_grn(Node *n) { Graph *p; + if (!n) return; + n = right_linked(n); more: for (p = Nodes_Set; p; p = p->nxt) @@ -169,6 +188,8 @@ mk_red(Node *n) { Graph *p; + if (!n) return; + n = right_linked(n); for (p = Nodes_Set; p; p = p->nxt) { if (p->outgoing @@ -257,6 +278,15 @@ q = dupnode(pp); q = rewrite(q); + if (q->ntyp == CEXPR) + { if (!frst) fprintf(tl_out, " && "); + fprintf(tl_out, "c_expr { "); + dump_cond(q->lft, r, 1); + fprintf(tl_out, " } "); + frst = 0; + return frst; + } + if (q->ntyp == PREDICATE || q->ntyp == NOT #ifndef NXT @@ -437,13 +467,16 @@ /* remove duplicates from b */ for (p1 = a; p1; p1 = p1->next) { p3 = ZS; - for (p2 = b; p2; p2 = p2->next) - { if (strcmp(p1->name, p2->name)) + p2 = b; + while (p2) + { if (strcmp(p1->name, p2->name)) { p3 = p2; + p2 = p2->next; continue; } tmp = p2->next; tfree((void *) p2); + p2 = tmp; if (p3) p3->next = tmp; else @@ -469,9 +502,11 @@ ng(tl_lookup("init"), ZS, ZN, ZN, ZN); p1 = pop_stack(); - p1->nxt = Nodes_Set; - p1->Other = p1->Old = orig; - Nodes_Set = p1; + if (p1) + { p1->nxt = Nodes_Set; + p1->Other = p1->Old = orig; + Nodes_Set = p1; + } for (g = Nodes_Set; g; g = g->nxt) { for (q1 = g->incoming; q1; q1 = q2) @@ -533,29 +568,33 @@ sdump(Node *n) { switch (n->ntyp) { - case PREDICATE: strcat(dumpbuf, n->sym->name); + case PREDICATE: append_to_dumpbuf(n->sym->name); break; - case U_OPER: strcat(dumpbuf, "U"); + case U_OPER: append_to_dumpbuf("U"); goto common2; - case V_OPER: strcat(dumpbuf, "V"); + case V_OPER: append_to_dumpbuf("V"); goto common2; - case OR: strcat(dumpbuf, "|"); + case OR: append_to_dumpbuf("|"); goto common2; - case AND: strcat(dumpbuf, "&"); + case AND: append_to_dumpbuf("&"); common2: sdump(n->rgt); common1: sdump(n->lft); break; #ifdef NXT - case NEXT: strcat(dumpbuf, "X"); + case NEXT: append_to_dumpbuf("X"); goto common1; #endif - case NOT: strcat(dumpbuf, "!"); + case CEXPR: append_to_dumpbuf("c_expr {"); + sdump(n->lft); + append_to_dumpbuf("}"); + break; + case NOT: append_to_dumpbuf("!"); goto common1; - case TRUE: strcat(dumpbuf, "T"); + case TRUE: append_to_dumpbuf("T"); break; - case FALSE: strcat(dumpbuf, "F"); + case FALSE: append_to_dumpbuf("F"); break; - default: strcat(dumpbuf, "?"); + default: append_to_dumpbuf("?"); break; } } @@ -568,9 +607,15 @@ if (n->ntyp == PREDICATE) return n->sym; - dumpbuf[0] = '\0'; - sdump(n); - return tl_lookup(dumpbuf); + if (dumpbuf) { + dumpbuf[0] = '\0'; + dumpbuf_size = 0; + sdump(n); + return tl_lookup(dumpbuf); + } + + sdump(n); + return tl_lookup(""); } static int @@ -735,6 +780,7 @@ break; case PREDICATE: case NOT: + case CEXPR: if (can_release) releasenode(1, now); push_stack(g); break; diff -Nru /n/sources/plan9/sys/src/cmd/spin/vars.c /sys/src/cmd/spin/vars.c --- /n/sources/plan9/sys/src/cmd/spin/vars.c Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/vars.c Mon Feb 22 00:00:00 2021 @@ -1,26 +1,25 @@ /***** spin: vars.c *****/ -/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ #include "spin.h" #include "y.tab.h" +extern char GBuf[]; +extern int analyze, jumpsteps, nproc, nstop, columns, old_priority_rules; +extern int lineno, depth, verbose, xspin, limited_vis, Pid_nr; +extern Lextok *Xu_List; extern Ordered *all_names; -extern RunList *X, *LastX; +extern RunList *X_lst, *LastX; +extern short no_arrays, Have_claim, terse; extern Symbol *Fname; -extern char Buf[]; -extern int lineno, depth, verbose, xspin, limited_vis; -extern int analyze, jumpsteps, nproc, nstop, columns; -extern short no_arrays, Have_claim; -extern void sr_mesg(FILE *, int, int); -extern void sr_buf(int, int); + +extern void sr_buf(int, int, const char *); +extern void sr_mesg(FILE *, int, int, const char *); static int getglobal(Lextok *); static int setglobal(Lextok *, int); @@ -37,27 +36,59 @@ if (strcmp(s->name, "_last") == 0) return (LastX)?LastX->pid:0; if (strcmp(s->name, "_p") == 0) - return (X && X->pc)?X->pc->seqno:0; + return (X_lst && X_lst->pc)?X_lst->pc->seqno:0; if (strcmp(s->name, "_pid") == 0) - { if (!X) return 0; - return X->pid - Have_claim; + { if (!X_lst) return 0; + return X_lst->pid - Have_claim; + } + if (strcmp(s->name, "_priority") == 0) + { if (!X_lst) return 0; + + if (old_priority_rules) + { non_fatal("cannot refer to _priority with -o6", (char *) 0); + return 1; + } + return X_lst->priority; } + if (strcmp(s->name, "_nr_pr") == 0) - return nproc-nstop; /* new 3.3.10 */ + { return nproc-nstop; /* new 3.3.10 */ + } if (s->context && s->type) - return getlocal(sn); + { return getlocal(sn); + } if (!s->type) /* not declared locally */ { s = lookup(s->name); /* try global */ sn->sym = s; /* fix it */ } + return getglobal(sn); } int setval(Lextok *v, int n) { + if (strcmp(v->sym->name, "_last") == 0 + || strcmp(v->sym->name, "_p") == 0 + || strcmp(v->sym->name, "_pid") == 0 + || strcmp(v->sym->name, "_nr_qs") == 0 + || strcmp(v->sym->name, "_nr_pr") == 0) + { non_fatal("illegal assignment to %s", v->sym->name); + } + if (strcmp(v->sym->name, "_priority") == 0) + { if (old_priority_rules) + { non_fatal("cannot refer to _priority with -o6", (char *) 0); + return 1; + } + if (!X_lst) + { non_fatal("no context for _priority", (char *) 0); + return 1; + } + X_lst->priority = n; + } + if (v->sym->context && v->sym->type) return setlocal(v, n); if (!v->sym->type) @@ -90,6 +121,7 @@ checkvar(Symbol *s, int n) { int i, oln = lineno; /* calls on eval() change it */ Symbol *ofnm = Fname; + Lextok *z, *y; if (!in_bound(s, n)) return 0; @@ -101,13 +133,20 @@ /* not a STRUCT */ if (s->val == (int *) 0) /* uninitialized */ { s->val = (int *) emalloc(s->nel*sizeof(int)); + z = s->ini; for (i = 0; i < s->nel; i++) - { if (s->type != CHAN) - { rm_selfrefs(s, s->ini); - s->val[i] = eval(s->ini); + { if (z && z->ntyp == ',') + { y = z->lft; + z = z->rgt; + } else + { y = z; + } + if (s->type != CHAN) + { rm_selfrefs(s, y); + s->val[i] = eval(y); } else if (!analyze) - s->val[i] = qmake(s); - } } + { s->val[i] = qmake(s); + } } } lineno = oln; Fname = ofnm; @@ -119,14 +158,16 @@ { Symbol *s = sn->sym; int i, n = eval(sn->lft); - if (s->type == 0 && X && (i = find_lab(s, X->n, 0))) + if (s->type == 0 && X_lst && (i = find_lab(s, X_lst->n, 0))) /* getglobal */ { printf("findlab through getglobal on %s\n", s->name); return i; /* can this happen? */ } if (s->type == STRUCT) - return Rval_struct(sn, s, 1); /* 1 = check init */ + { return Rval_struct(sn, s, 1); /* 1 = check init */ + } if (checkvar(s, n)) - return cast_val(s->type, s->val[n], s->nbits); + { return cast_val(s->type, s->val[n], s->nbits); + } return 0; } @@ -146,18 +187,18 @@ } if (v != i+s+ (int) u) - { char buf[64]; sprintf(buf, "%d->%d (%d)", v, i+s+u, t); + { char buf[64]; sprintf(buf, "%d->%d (%d)", v, i+s+(int)u, t); non_fatal("value (%s) truncated in assignment", buf); } - return (int)(i+s+u); + return (int)(i+s+(int)u); } static int setglobal(Lextok *v, int m) { if (v->sym->type == STRUCT) - (void) Lval_struct(v, v->sym, 1, m); - else + { (void) Lval_struct(v, v->sym, 1, m); + } else { int n = eval(v->lft); if (checkvar(v->sym, n)) { int oval = v->sym->val[n]; @@ -171,9 +212,7 @@ void dumpclaims(FILE *fd, int pid, char *s) -{ extern Lextok *Xu_List; extern int Pid; - extern short terse; - Lextok *m; int cnt = 0; int oPid = Pid; +{ Lextok *m; int cnt = 0; int oPid = Pid_nr; for (m = Xu_List; m; m = m->rgt) if (strcmp(m->sym->name, s) == 0) @@ -182,7 +221,7 @@ } if (cnt == 0) return; - Pid = pid; + Pid_nr = pid; fprintf(fd, "#ifndef XUSAFE\n"); for (m = Xu_List; m; m = m->rgt) { if (strcmp(m->sym->name, s) != 0) @@ -197,7 +236,7 @@ fprintf(fd, "\"%s\");\n", s); } fprintf(fd, "#endif\n"); - Pid = oPid; + Pid_nr = oPid; } void @@ -229,6 +268,7 @@ } for (j = 0; j < sp->nel; j++) { int prefetch; + char *s = 0; if (sp->type == CHAN) { doq(sp, j, 0); continue; @@ -246,44 +286,47 @@ printf("\t\t%s", sp->name); if (sp->nel > 1 || sp->isarray) printf("[%d]", j); printf(" = "); - sr_mesg(stdout, prefetch, - sp->type == MTYPE); + if (sp->type == MTYPE + && sp->mtype_name) + { s = sp->mtype_name->name; + } + sr_mesg(stdout, prefetch, sp->type == MTYPE, s); printf("\n"); if (limited_vis && (sp->hidden&2)) { int colpos; - Buf[0] = '\0'; + GBuf[0] = '\0'; if (!xspin) { if (columns == 2) - sprintf(Buf, "~G%s = ", sp->name); + sprintf(GBuf, "~G%s = ", sp->name); else - sprintf(Buf, "%s = ", sp->name); + sprintf(GBuf, "%s = ", sp->name); } - sr_buf(prefetch, sp->type == MTYPE); + sr_buf(prefetch, sp->type == MTYPE, s); if (sp->colnr == 0) - { sp->colnr = maxcolnr; + { sp->colnr = (unsigned char) maxcolnr; maxcolnr = 1+(maxcolnr%10); } colpos = nproc+sp->colnr-1; if (columns == 2) - { pstext(colpos, Buf); + { pstext(colpos, GBuf); continue; } if (!xspin) - { printf("\t\t%s\n", Buf); + { printf("\t\t%s\n", GBuf); continue; } - printf("MSC: ~G %s %s\n", sp->name, Buf); + printf("MSC: ~G %s %s\n", sp->name, GBuf); printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ", depth, colpos); printf("(state 0)\t[printf('MSC: globvar\\\\n')]\n"); printf("\t\t%s", sp->name); if (sp->nel > 1 || sp->isarray) printf("[%d]", j); - printf(" = %s\n", Buf); + printf(" = %s\n", GBuf); } } } } void -dumplocal(RunList *r) +dumplocal(RunList *r, int final) { static Lextok *dummy = ZN; Symbol *z, *s; int i; @@ -293,7 +336,8 @@ s = r->symtab; if (!dummy) - dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN); + { dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN); + } for (z = s; z; z = z->next) { if (z->type == STRUCT) @@ -301,14 +345,18 @@ continue; } for (i = 0; i < z->nel; i++) - { if (z->type == CHAN) + { char *t = 0; + if (z->type == CHAN) { doq(z, i, r); continue; } + if ((verbose&4) && !(verbose&64) + && !final && (z->setat < depth && jumpsteps != depth)) - continue; + { continue; + } dummy->sym = z; dummy->lft->val = i; @@ -317,35 +365,40 @@ r->n->name, r->pid - Have_claim, z->name); if (z->nel > 1 || z->isarray) printf("[%d]", i); printf(" = "); - sr_mesg(stdout, getval(dummy), z->type == MTYPE); + + if (z->type == MTYPE + && z->mtype_name) + { t = z->mtype_name->name; + } + sr_mesg(stdout, getval(dummy), z->type == MTYPE, t); printf("\n"); if (limited_vis && (z->hidden&2)) { int colpos; - Buf[0] = '\0'; + GBuf[0] = '\0'; if (!xspin) { if (columns == 2) - sprintf(Buf, "~G%s(%d):%s = ", + sprintf(GBuf, "~G%s(%d):%s = ", r->n->name, r->pid, z->name); else - sprintf(Buf, "%s(%d):%s = ", + sprintf(GBuf, "%s(%d):%s = ", r->n->name, r->pid, z->name); } - sr_buf(getval(dummy), z->type==MTYPE); + sr_buf(getval(dummy), z->type==MTYPE, t); if (z->colnr == 0) - { z->colnr = maxcolnr; + { z->colnr = (unsigned char) maxcolnr; maxcolnr = 1+(maxcolnr%10); } colpos = nproc+z->colnr-1; if (columns == 2) - { pstext(colpos, Buf); + { pstext(colpos, GBuf); continue; } if (!xspin) - { printf("\t\t%s\n", Buf); + { printf("\t\t%s\n", GBuf); continue; } printf("MSC: ~G %s(%d):%s %s\n", - r->n->name, r->pid, z->name, Buf); + r->n->name, r->pid, z->name, GBuf); printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ", depth, colpos); @@ -353,6 +406,6 @@ printf("\t\t%s(%d):%s", r->n->name, r->pid, z->name); if (z->nel > 1 || z->isarray) printf("[%d]", i); - printf(" = %s\n", Buf); + printf(" = %s\n", GBuf); } } } } diff -Nru /n/sources/plan9/sys/src/cmd/spin/version.h /sys/src/cmd/spin/version.h --- /n/sources/plan9/sys/src/cmd/spin/version.h Mon Dec 12 01:03:06 2011 +++ /sys/src/cmd/spin/version.h Mon Feb 22 00:00:00 2021 @@ -1 +1,9 @@ -#define SpinVersion "Spin Version 6.1.0 -- 4 May 2011" +/***** spin: version.h *****/ + +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ + +#define SpinVersion "Spin Version 6.5.1 -- 31 July 2020"