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 Thu Dec 31 00:00:00 2015 @@ -0,0 +1,40 @@ + Spin open source distribution + ============================= + + Copyright (c) 1989-2016 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 Jan 11 00:00:00 2016 @@ -1,20 +1,18 @@ /***** 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; @@ -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 */ @@ -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 (!("); @@ -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 *th; + fprintf(th, "#ifndef ELSE_IN_GUARD\n"); + fprintf(th, " #define ELSE_IN_GUARD\n"); + fprintf(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, seqno); + fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid); /* next state */ + fprintf(fd, "reached[%d][tt] = 1;\n", Pid); /* 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 Sun Mar 19 00:00:00 2017 @@ -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,7 +922,7 @@ || !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) @@ -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) @@ -967,8 +1038,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 +1057,7 @@ rv = nn(ZN, DO, ZN, ZN); rv->sl = t0->sl; + return rv; } @@ -1002,6 +1072,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 +1088,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 +1096,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 +1133,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 Thu Dec 31 00:00:00 2015 @@ -1,17 +1,15 @@ /***** 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; @@ -19,7 +17,7 @@ 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; @@ -74,12 +72,70 @@ return (!Have_claim || !X || X->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 match_trail(void) { int i, a, nst; 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; /* @@ -141,10 +197,23 @@ 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) + { if (depth == -2) { if (verbose) + { printf("starting claim %d\n", pno); + } + start_claim(pno); + continue; + } + if (depth == -4) + { if (verbose) + { 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 @@ -198,8 +267,8 @@ 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, pno, nst); } for (X = run; X; X = X->nxt) @@ -209,8 +278,8 @@ if (!X) { 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, pno - 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"); @@ -224,7 +293,21 @@ lost_trail(); } } else - { X->pc = dothis; + { int min_seq = find_min(X->ps); + int max_seq = find_max(X->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)", + pno, X->pid, X->n->name, X->tn, X->b, nst, min_seq, max_seq); + } + printf("\n"); + continue; + /* lost_trail(); */ + } + X->pc = dothis; } lineno = dothis->n->ln; 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 Sep 18 00:00:00 2017 @@ -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,11 @@ 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; + +static void add_comptime(char *); +static void add_runtime(char *); Symbol *Fname, *oFname; @@ -43,13 +44,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; static int seedy; /* be verbose about chosen seed */ static int inlineonly; /* show inlined code */ static int dataflow = 1; @@ -72,6 +76,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[4096]; static FILE *fd_ltl = (FILE *) 0; static char *PreArg[64]; static int PreCnt = 0; @@ -81,78 +88,506 @@ 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 -E -x c" /* 6.4.0 new default on all systems */ + /* 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"); + } + + 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"); } - exit(estatus); +} + +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; + QH *j; + int i; + char *tmp = (char *) emalloc(strlen("spin -t") + + strlen(pan_runtime) + strlen(Fname->name) + 8); + 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; 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 "); + 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) + { +#ifdef PC + /* make sure that if compilation fails we do not continue */ + (void) unlink("./pan.exe"); +#else + (void) unlink("./pan"); +#endif + } +runit: + if (norecompile && tmp != tmp2) + { estatus = 0; + } else + { if (itsr > 0) /* else it happens below */ + { estatus = e_system(1, tmp); /* compile or run */ + } } + if (replay || estatus < 0) + { goto skipahead; + } + /* !replay */ + if (itsr == 0) /* 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--; /* 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") == 0) + { strcpy(PreProc, "gcc-4 -std=gnu99 -E -x c"); + } else if (e_system(0, "gcc-3 --version > pan.pre") == 0) + { strcpy(PreProc, "gcc-3 -std=gnu99 -E -x c"); } } #endif + + assert(strlen(PreProc) < sizeof(precmd)); strcpy(precmd, PreProc); for (i = 1; i <= PreCnt; i++) { strcat(precmd, " "); @@ -163,15 +598,12 @@ alldone(1); } sprintf(cmd, "%s %s > %s", precmd, a, b); - if (system((const char *)cmd)) + if (e_system(2, (const char *)cmd)) /* preprocessing */ { (void) unlink((const char *) b); if (a_tmp) (void) unlink((const char *) a); fprintf(stdout, "spin: preprocessing failed\n"); /* 4.1.2 was stderr */ alldone(1); /* no return, error exit */ } -#ifdef PC -out: -#endif if (a_tmp) (void) unlink((const char *) a); } @@ -203,7 +635,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 +645,45 @@ 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-search (or -run) 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 -bcs use the bounded-context-switching algorithm\n"); + printf("\t -bitstate or -bit, use bitstate storage\n"); + printf("\t -biterate use bitstate with iterative search refinement (-w18..-w35)\n"); + printf("\t -swarmN,M like -biterate, but running all iterations in parallel\n"); + printf("\t perform N parallel runs and increment -w every M runs\n"); + printf("\t default value for N is 10, default for M is 1\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 -link file.c link executable pan to file.c\n"); + printf("\t -collapse use collapse state compression\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 -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 +697,7 @@ alldone(1); } -void +int optimizations(int nr) { switch (nr) { @@ -269,11 +736,113 @@ 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 }, + { "-permuted", "-DPERMUTED", 0 }, + { "-p_permute", "-DPERMUTED", 1 }, + { "-p_rotate", "-DPERMUTED", 1 }, + { "-p_reverse", "-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 */ + 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 */ + 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; + } } + + tmp = (char *) emalloc(strlen(pan_runtime)+strlen(s)+2); + sprintf(tmp, "%s %s", pan_runtime, s); + pan_runtime = tmp; } int @@ -288,14 +857,14 @@ 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 +896,99 @@ 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 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; + 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,12 +1002,15 @@ 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); @@ -390,7 +1030,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 +1054,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 +1085,25 @@ 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 +1111,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 +1141,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) @@ -521,7 +1177,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 +1184,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 +1213,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 +1241,19 @@ void trapwonly(Lextok *n /* , char *unused */) -{ extern int realread; - short i = (n->sym)?n->sym->type:0; +{ short i = (n->sym)?n->sym->type:0; - if (i != MTYPE - && i != BIT - && i != BYTE - && i != SHORT - && i != INT - && i != UNSIGNED) - return; + /* printf("%s realread %d type %d\n", n->sym?n->sym->name:"--", realread, i); */ - if (realread) - n->sym->hidden |= 128; /* var is read at least once */ + 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 +1282,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; @@ -804,6 +1461,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 +1501,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 Thu Sep 8 00:00:00 2016 @@ -1,14 +1,12 @@ /***** 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 "spin.h" #include "y.tab.h" @@ -24,9 +22,10 @@ extern int nproc, nstop; extern short Have_claim; +QH *qh; Queue *qtab = (Queue *) 0; /* linked list of queues */ Queue *ltab[MAXQ]; /* linear list of queues */ -int nqs = 0, firstrow = 1; +int nqs = 0, firstrow = 1, has_stdin = 0; char Buf[4096]; static Lextok *n_rem = (Lextok *) 0; @@ -73,7 +72,7 @@ return eval(s->ini); q = (Queue *) emalloc(sizeof(Queue)); - q->qid = ++nqs; + q->qid = (short) ++nqs; q->nslots = s->ini->val; q->nflds = cnt_mpars(s->ini->rgt); q->setat = depth; @@ -130,7 +129,7 @@ if (whichq == -1) { printf("Error: sending to an uninitialized chan\n"); - whichq = 0; + /* whichq = 0; */ return 0; } if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) @@ -143,6 +142,37 @@ 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 +180,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,7 +251,8 @@ typ_ck(int ft, int at, char *s) { if ((verbose&32) && ft != at - && (ft == CHAN || at == CHAN)) + && (ft == CHAN || at == CHAN) + && (at != PREDEF || strcmp(s, "recv") != 0)) { char buf[128], tag1[64], tag2[64]; (void) sputtype(tag1, ft); (void) sputtype(tag2, at); @@ -428,7 +474,11 @@ sr_buf(v, q->fld_width[j] == MTYPE); if (j == q->nflds - 1) { int cnr; - if (s_trail) cnr = pno; else cnr = X?X->pid - Have_claim:0; + if (s_trail) + { cnr = pno; + } else + { cnr = X?X->pid - Have_claim:0; + } if (tr[0] == '[') strcat(Buf, "]"); pstext(cnr, Buf); } @@ -464,12 +514,6 @@ } } -typedef struct QH { - int n; - struct QH *nxt; -} QH; -static QH *qh; - void qhide(int q) { QH *p = (QH *) emalloc(sizeof(QH)); @@ -571,7 +615,11 @@ sr_mesg(FILE *fd, int v, int j) { Buf[0] ='\0'; sr_buf(v, j); +#if 1 + fprintf(fd, Buf, (char *) 0); /* prevent compiler warning */ +#else fprintf(fd, Buf); +#endif } void @@ -634,7 +682,8 @@ /* ok on the rhs of an assignment: */ 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) @@ -657,7 +706,8 @@ int cnt; struct BaseName *nxt; } BaseName; -BaseName *bsn; + +static BaseName *bsn; void newbasename(char *s) @@ -777,8 +827,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 Sep 18 00:00:00 2017 @@ -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 Thu Dec 31 00:00:00 2015 @@ -0,0 +1,376 @@ +/***** 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, pno, depth; +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) + { 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; + 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/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 Sep 18 00:00:00 2017 @@ -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" @@ -25,7 +21,7 @@ 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 short has_sorted, has_random, has_provided, has_priority; extern Queue *ltab[]; int Npars=0, u_sync=0, u_async=0, hastrack = 1; @@ -51,14 +47,14 @@ { if (!p) return; reverse_names(p->nxt); - fprintf(th, " \"%s\",\n", p->n->name); + fprintf(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(tc, " %d, /* %s */\n", p->b, p->n->name); } static int @@ -89,11 +85,11 @@ fprintf(th, " #else\n"); fprintf(th, " #define NCORE 1\n"); fprintf(th, " #endif\n"); - fprintf(th, "#endif\n"); + fprintf(th, "#endif\n\n"); putunames(th); - fprintf(tc, "short Air[] = { "); + fprintf(tc, "\nshort 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_ */ @@ -104,19 +100,21 @@ } fprintf(tc, " };\n"); - fprintf(th, "char *procname[] = {\n"); + fprintf(tc, "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(tc, " \":np_:\",\n"); + fprintf(tc, " 0\n"); + fprintf(tc, "};\n\n"); + + fprintf(tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM); + fprintf(tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC); + fprintf(tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n", P_PROC, E_TRACE, N_TRACE); - fprintf(th, "int Btypes[] = {\n"); + + fprintf(tc, "int Btypes[] = {\n"); reverse_types(rdy); - fprintf(th, " 0 /* :np_: */\n"); - fprintf(th, "};\n\n"); + fprintf(tc, " 0 /* :np_: */\n"); + fprintf(tc, "};\n\n"); here: for (p = rdy; p; p = p->nxt) @@ -137,6 +135,7 @@ i = blog(mst); fprintf(th, "\n"); + fprintf(th, "#ifndef NOCLAIM\n"); fprintf(th, " #undef VERI\n"); fprintf(th, " #define VERI %d\n", nrRdy+1); @@ -157,7 +156,11 @@ { fprintf(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(tc, "#ifndef NOCLAIM\n"); + fprintf(tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); + fprintf(tc, "#endif\n"); + fprintf(th, " #define Air%d (0)\n\n", nrRdy+1); fprintf(th, "#endif\n"); /* @@ -171,11 +174,11 @@ * mapstate [ claimnr ][ curstate ] */ } else - { fprintf(th, "\n#define Pclaim P0\n"); + { fprintf(th, "#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(tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); } ntimes(th, 0, 1, Head0); @@ -191,6 +194,8 @@ c_add_stack(th); ntimes(th, 0, 1, Header0); + } else + { fprintf(th, "extern char *emalloc(unsigned long);\n"); } ntimes(th, 0, 1, Head1); @@ -224,15 +229,14 @@ 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); - + if (0 && hastrack) /* not really a problem */ + { fprintf(th, "#ifdef BFS_PAR\n"); + fprintf(th, " #error cannot use BFS_PAR on models with c_track stmnts\n"); + fprintf(th, "#endif\n"); + } if (separate != 2) dohidden(); } @@ -240,40 +244,26 @@ void genaddproc(void) { ProcList *p; - int i = 0, j; + int i = 0; if (separate == 2) goto shortcut; - fprintf(tc, "\n#ifdef TRIX\n"); + ntimes(tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */ + + fprintf(tc, "#ifdef TRIX\n"); fprintf(tc, "int what_p_size(int);\n"); fprintf(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(tc, 0, 1, R7a); fprintf(tc, "#endif\n\n"); - fprintf(tc, "int\naddproc(int calling_pid, int n"); + ntimes(tc, 0, 1, R7b); + + fprintf(tc, "int\naddproc(int calling_pid, int priority, int n"); for (/* i = 0 */; i < Npars; i++) fprintf(tc, ", int par%d", i); @@ -322,8 +312,17 @@ do_locinits(FILE *fd) { ProcList *p; + /* 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 = rdy; p; p = p->nxt) - c_add_locinit(fd, p->tn, p->n->name); + { c_add_locinit(fd, p->tn, p->n->name); + } } void @@ -336,6 +335,9 @@ { for (p = rdy; p; p = p->nxt) { if (p->b == N_CLAIM) { ntimes(tc, p->tn, p->tn+1, R0); /* claims only */ + fprintf(tc, "#ifdef HAS_CODE\n"); + ntimes(tc, p->tn, p->tn+1, R00); + fprintf(tc, "#endif\n"); } } } break; case 1: @@ -343,13 +345,28 @@ for (p = rdy; p; p = p->nxt) { if (p->b != N_CLAIM) { ntimes(tc, p->tn, p->tn+1, R0); /* all except claims */ + fprintf(tc, "#ifdef HAS_CODE\n"); + ntimes(tc, p->tn, p->tn+1, R00); + fprintf(tc, "#endif\n"); } } break; case 0: ntimes(tc, 0, 1, Code0); ntimes(tc, 0, nrRdy+1, R0); /* +1 for np_ */ + fprintf(tc, "#ifdef HAS_CODE\n"); + ntimes(tc, 0, nrRdy+1, R00); /* +1 for np_ */ + fprintf(tc, "#endif\n"); break; } + /* new place, make sure Maxbody is set to its final value here */ + fprintf(tc, "\n"); + + if (separate != 2) + { ntimes(tc, 1, u_sync+u_async+1, R3); /* 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"); + } for (p = rdy; p; p = p->nxt) end_labs(p->n, p->tn); @@ -380,9 +397,9 @@ 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, Code2e); /* multicore */ ntimes(tc, 0, 1, Code2c); /* multicore */ ntimes(tc, 0, 1, Code2d); @@ -391,12 +408,6 @@ 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"); - - /* after the value of Maxbody has settled */ if (doglobal("", INIV) > 0) { fprintf(tc, "#ifdef VAR_RANGES\n"); (void) doglobal("logval(\"", LOGV); @@ -437,7 +448,7 @@ && strcmp(l->c->name, s->name) == 0) { fprintf(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", @@ -464,7 +475,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++) @@ -604,8 +615,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; } @@ -651,7 +662,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 +676,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); @@ -755,10 +773,8 @@ 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"); @@ -835,13 +851,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); + fatal("cannot hide channels (%s)", sp->name); fprintf(th, "/* hidden variable: */"); typ2c(sp); } } - fprintf(th, "int _; /* a predefined write-only variable */\n\n"); } void @@ -898,20 +913,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; } } @@ -948,15 +981,17 @@ 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(th, "#ifdef HAS_PRIORITY\n"); + fprintf(th, " unsigned _priority : 8; /* 0..255 */\n"); + fprintf(th, "#endif\n"); LstSet = ZS; nBits = 8 + blog(m1) + blog(m0); k = dolocal(tc, "", PUTV, i, s, b); /* includes pars */ - c_add_loc(th, s); fprintf(th, "} P%d;\n", i); if ((!LstSet && k > 0) || has_state) - fprintf(th, "#define Air%d 0\n", i); + fprintf(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); if (k == 0) @@ -987,31 +1022,32 @@ fatal("cannot happen Air %s", LstSet->name); } -done: fprintf(th, ")\n"); +done: fprintf(th, ")\n\n"); } } static void tc_predef_np(void) -{ int i = nrRdy; /* 1+ highest proctype nr */ +{ + fprintf(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(th, "#define _nstates%d 3 /* np_ */\n", nrRdy); + fprintf(th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy); + fprintf(th, "#define _start%d 0 /* np_ */\n", nrRdy); - fprintf(tc, "\tcase %d: /* np_ */\n", i); + fprintf(tc, "\tcase %d: /* np_ */\n", nrRdy); if (separate == 1) - { fprintf(tc, "\t\tini_claim(%d, h);\n", i); + { fprintf(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(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy); + fprintf(tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy); + + fprintf(tc, "#ifdef HAS_PRIORITY\n"); + fprintf(tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy); + fprintf(tc, "#endif\n"); + + fprintf(tc, "\t\treached%d[0] = 1;\n", nrRdy); + fprintf(tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy); } fprintf(tc, "\t\tbreak;\n"); } @@ -1079,7 +1115,7 @@ return; ini = huntele(e, e->status, -1)->seqno; - fprintf(th, "#define start%d %d\n", i, ini); + fprintf(th, "#define _start%d %d\n", i, ini); if (i == eventmapnr) fprintf(th, "#define start_event %d\n", ini); @@ -1087,6 +1123,12 @@ 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, "#ifdef HAS_PRIORITY\n"); + + fprintf(tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n", + i, (P->priority<1)? 1 : P->priority); + + fprintf(tc, "#endif\n"); fprintf(tc, "\t\treached%d[%d]=1;\n", i, ini); if (P->b == N_CLAIM) { fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", i); @@ -1158,17 +1200,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 +1220,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 +1234,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 +1248,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; } @@ -1266,7 +1319,7 @@ } 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++) @@ -1296,12 +1349,11 @@ Queue *q; ntimes(tc, 0, 1, Addq0); + if (has_io && !nqs) fprintf(th, "#define NQS 1 /* nqs=%d, but has_io */\n", nqs); 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); for (q = qtab; q; q = q->nxt) if (q->nslots > qmax) @@ -1512,14 +1564,14 @@ fprintf(tc, " case %d: j = sizeof(Q%d); break;\n", q->qid, q->qid); ntimes(tc, 0, 1, R8b); + ntimes(th, 0, 1, Proto); /* function prototypes */ - ntimes(th, 0, 1, Proto); /* tag on function prototypes */ fprintf(th, "void qsend(int, int"); for (j = 0; j < Mpars; j++) fprintf(th, ", int"); - fprintf(th, ", int);\n"); + fprintf(th, ", int);\n\n"); - fprintf(th, "#define Addproc(x) addproc(256, x"); + fprintf(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"); 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 Fri Aug 18 00:00:00 2017 @@ -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 @@ -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];", "", @@ -588,21 +655,79 @@ "}", "", "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)", + " { char tmp[32];", + " sprintf(tmp, \"-RS%%u \", (uint) t_id-1);", + " strcat(sbuf, tmp);", + " }", + " break;", + " default:", + " continue;", + " }", + " }", + "#endif", + " if (depth < 0)", + " { continue;", + " }", + "#ifdef PERMUTED", + " if (strlen(sbuf) > 0)", + " { fprintf(efd, \"add: %%s\\n\", sbuf);", + " exit(1);", + " }", + "#endif", " if (i > now._nr_pr)", " { printf(\"pan: Error, proc %%d invalid pid \", i);", " printf(\"transition %%d\\n\", t_id);", @@ -635,11 +760,13 @@ " q = transmognify(t->tp);", " if (gui) simvals[0] = \'\\0\';", + " 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 +776,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 +813,12 @@ " { 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) {", " 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 +829,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 +857,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 +864,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 +1027,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 +1047,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 +1124,7 @@ " return h; /* no memcpy */", " }", /* else */ " bfs_size_limit++;", - "#endif", + " #endif", " h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n);", " }", "", @@ -1057,22 +1139,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 +1165,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 +1204,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 +1216,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 +1235,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 +1278,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,60 +1310,69 @@ " 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", + "#endif", + " #ifdef TRIX", " re_populate();", - "#else", + " #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;", "", " if (shortcut)", " {", - " #ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"claim: shortcut\\n\");", - " #endif", + " #endif", " goto store_it; /* no claim move */", " }", "", @@ -1283,73 +1382,73 @@ " 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", + " #endif", + " #ifdef HAS_UNLESS", " E_state = t2->e_trans;", - " #endif", + " #endif", " if (t2->st > 0)", " { ((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,29 +1456,29 @@ " 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", + " #ifdef VERI", " ((P0 *)this)->_p = tt; /* reset claim */", " if (t2)", " do_reverse(t2, 0, 0);", @@ -1388,11 +1487,9 @@ " } }", " this = othis;", " trpt->o_pm = o_opm;", - "#endif", + " #endif", "}", "", - "Trail *ntrpt;", /* 4.2.8 */ - "", "void", "bfs(void)", "{ Trans *t; Trail *otrpt, *x;", @@ -1402,7 +1499,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 +1507,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 +1553,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,7 +1570,7 @@ " }", " continue;", " }", - "#ifndef NOREDUCE", + " #ifndef NOREDUCE", " if (boq == -1 && !(trpt->tau&8) && nps == 0)", " for (II = now._nr_pr-1; II >= BASE; II -= 1)", " {", @@ -1490,14 +1587,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;", @@ -1513,33 +1610,41 @@ " this = pptr(II);", " tt = (int) ((P0 *)this)->_p;", " ot = (uchar) ((P0 *)this)->_t;", - "#if SYNC", + " #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 +1654,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;", " }", "", - " /* 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;", " _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 +1734,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 */", @@ -1648,49 +1751,50 @@ " 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", + " #ifdef VERBOSE", " printf(\"\\treset state of %%d from %%d to %%d\\n\",", " otrpt->pr, ((P0 *)this)->_p, otrpt->st);", - "#endif", + " #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 +1816,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 +1854,7 @@ 0, }; -static char *Code2d[] = { +static const char *Code2d[] = { "clock_t start_time;", "#if NCORE>1", "clock_t crash_stamp;", @@ -1753,6 +1863,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 +1878,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 +1915,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 +1984,10 @@ "}", "#endif", "", + "#ifdef BFS_PAR", + "int ncores = 0;", + "#endif", + "", "void", "do_the_search(void)", "{ int i;", @@ -1874,11 +2002,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 +2023,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 +2065,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", "}", @@ -1961,40 +2097,40 @@ "do_reverse(Trans *t, short II, uchar M)", "{ uchar _m = M;", " int tt = (int) ((P0 *)this)->_p;", - "#include REVERSE_MOVES", + "#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", + " #ifdef M_LOSS", " uchar delta_m = 0;", - "#endif", - "#ifdef EVENT_TRACE", + " #endif", + " #ifdef EVENT_TRACE", " short oboq = boq;", " 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;", "#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,63 +2143,62 @@ " { 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;", " 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)", @@ -2082,6 +2217,74 @@ " 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 +2316,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 +2331,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 +2339,9 @@ "#if NCORE>1", " leave_critical(GLOBAL_LOCK);", "#endif", + "#ifdef BFS_PAR", + " x_critical(BFS_GLOB);", + "#endif", "}", "#ifdef SC", "void", @@ -2197,35 +2407,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 +2420,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 +2443,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 +2601,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 +2631,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 +2694,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 +2754,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 +2827,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 +2862,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 +2943,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 +2969,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 +2981,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 +3018,36 @@ "#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", + "#ifdef DEBUG", " printf(\"%%3d: fairness Rule 3.: _a_t = %%d\\n\",", - " depth, now._a_t);", - "#endif", + " (int) 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,8 +3096,7 @@ "#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;", @@ -2773,10 +3106,11 @@ " 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 +3120,8 @@ " depth, II, trpt->tau);", "#endif", " goto Again;", + " } else", + " { continue;", " } } }", " trpt->tau &= ~32;", "#endif", @@ -2844,11 +3180,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 +3193,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 +3208,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 +3226,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 +3239,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 +3254,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,7 +3263,7 @@ " 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", @@ -2948,8 +3287,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 +3319,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 +3342,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 +3353,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 +3389,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 */ @@ -3160,8 +3513,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 +3611,7 @@ " maxdepth -= DDD;", " hiwater -= DDD;", " if(verbose)", - " printf(\"unzap %%d: %%d\\n\", CNT2, hiwater);", + " printf(\"unzap %%ld: %%ld\\n\", CNT2, hiwater);", " }", "#endif", @@ -3275,7 +3634,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) */", @@ -3294,20 +3653,26 @@ " ot = trpt->o_ot; II = trpt->pr;", " 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", @@ -3389,18 +3754,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 +3831,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 +3881,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 +3945,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 +3965,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 +3991,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 +4001,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 +4069,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 +4087,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 +4174,7 @@ " return x;", "}", "#endif", + "int do_hashgen = 0;", "void", "wrap_stats(void)", "{", @@ -3823,18 +4183,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 +4216,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 +4245,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 +4265,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 (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 +4289,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 +4312,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 +4354,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 +4416,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- \");", @@ -4063,7 +4470,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 +4479,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 +4585,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 +4608,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 +4669,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 +4687,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 +4739,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 +4785,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 +4801,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 +4812,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 +4849,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 +5003,7 @@ "#endif", "", "void", - "set_masks(void) /* 4.2.5 */", + "set_masks(void)", "{", " if (WS == 4 && ssize >= 32)", " { mask = 0xffffffff;", @@ -4491,30 +5032,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 +5065,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,7 +5222,7 @@ "#endif", "", "#ifdef BITSTATE", - " bstore = bstore_reg; /* default */", + " b_store = bstore_reg; /* default */", "#endif", "#if NCORE>1", " { int i, j;", @@ -4617,19 +5239,31 @@ " 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\");", + " 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 +5277,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 +5323,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 +5336,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 +5451,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 +5517,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 +5572,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 (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\");", - " }", + "#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(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 +5669,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 +5685,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 +5748,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 +5779,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", @@ -4946,13 +5802,8 @@ " #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 +5825,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 +5863,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)", @@ -5056,7 +5895,7 @@ " fprintf(efd, \"requires -a flag to fully verify\\n\");", " }", " #else", - " if (!state_tables", + " if (verbose && !state_tables", " #ifdef HAS_CODE", " && !readtrail", " #endif", @@ -5068,6 +5907,7 @@ " #endif", "#endif", "#ifndef SAFETY", + " #if 0", " if (!a_cycles", " #ifdef HAS_CODE", " && !readtrail", @@ -5079,6 +5919,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 +5936,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 +5957,7 @@ " } }", "#endif", "#ifdef RANDSTOR", - " srand(s_rand);", + " srand(s_rand+HASH_NR);", /* main - RANDSTOR */ "#endif", "#if SYNC>0 && ASYNC==0", " set_recvs();", @@ -5152,7 +5997,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 +6028,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 +6040,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 +6075,7 @@ "}", "", "char *", - "Malloc(unsigned long n)", + "Malloc(ulong n)", "{ char *tmp;", "#ifdef MEMLIM", " if (memcnt + (double) n > memlim)", @@ -5233,7 +6085,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 +6133,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 +6164,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 +6191,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 +6215,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); */", @@ -5380,7 +6244,7 @@ " 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);", @@ -5419,7 +6283,7 @@ "#endif", "static char unwinding;", "void", - "uerror(char *str)", + "dfs_uerror(char *str)", "{ static char laststr[256];", " int is_cycle;", "", @@ -5433,7 +6297,7 @@ "#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 +6324,7 @@ "#endif", "#ifdef BFS", " if (depth > 1) trpt--;", - " nuerror(str);", + " nuerror();", " if (depth > 1) trpt++;", "#else", " putrail();", @@ -5494,6 +6358,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 +6485,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 +6586,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 +6624,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 +6640,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", @@ -5798,6 +6686,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 +6702,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 +6832,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 +6896,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 +6938,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 +6946,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 +7003,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 +7145,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 +7168,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 +7185,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 +7278,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 +7290,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 +7333,7 @@ " return v - (char *)&comp_now;", "}", -"#else", +"#else", /* !COLLAPSE */ "#if !defined(NOCOMP)", "int", "compress(char *vin, int n) /* default compression */", @@ -6439,9 +7387,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 +7419,7 @@ "#endif", "}", "#endif", -"#endif", +"#endif", /* COLLAPSE */ "#if defined(FULLSTACK) && defined(BITSTATE)", "#if defined(MA)", "#if !defined(onstack_now)", @@ -6488,8 +7434,8 @@ "#else", "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 +7487,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,108 +7510,156 @@ "#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 +7722,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 +7777,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 +7815,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 +7844,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 +7868,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 +7903,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 +7926,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 +7948,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 +7973,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 +8002,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 +8022,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 +8039,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 +8091,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 +8141,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 +8149,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 +8166,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 +8176,7 @@ " }", " #endif", "#endif", - "#ifdef REACH", + " #ifdef REACH", " if (tmp->D > depth)", " { tmp->D = depth;", " #ifdef CHECK", @@ -7160,6 +8186,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 +8207,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 +8229,7 @@ " #endif", " return 1; /* allow normal termination */", " }", - "#endif", + " #endif", " ntmp->nxt = tmp;", " if (!olst)", " H_tab[j1_spin] = ntmp;", @@ -7207,11 +8239,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 +8251,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 +8292,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 Sat Aug 27 00:00:00 2016 @@ -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,6 +12,7 @@ #include "pangen2.h" #include "pangen4.h" #include "pangen5.h" +#include "pangen7.h" #define DELTA 500 /* sets an upperbound on nr of chan names */ @@ -26,17 +23,21 @@ extern ProcList *rdy; extern RunList *run; +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; +int buzzed; +FILE *tc, *th, *tt, *tb; static FILE *tm; int OkBreak = -1, has_hidden = 0; /* has_hidden set in sym.c and structs.c */ @@ -44,6 +45,7 @@ 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,7 +56,7 @@ 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 */ +short has_ltl=0; /* has inline ltl formulae */ int mst=0; /* max nr of state/process */ int claimnr = -1; /* claim process, if any */ int eventmapnr = -1; /* event trace, if any */ @@ -76,9 +78,9 @@ 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 */ int has_global(Lextok *); -void Fatal(char *, char *); static int getweight(Lextok *); static int scan_seq(Sequence *); static void genconditionals(void); @@ -89,6 +91,29 @@ 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; @@ -117,14 +142,16 @@ { if (!q) return; reverse_procs(q->nxt); - fprintf(tc, " Addproc(%d);\n", q->tn); + fprintf(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(tc, " Addproc(%d, %d);\n", + q->tn, q->priority < 1 ? 1 : q->priority); forward_procs(q->nxt); } @@ -134,21 +161,13 @@ 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(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\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"); @@ -195,6 +214,9 @@ alldone(1); } + fprintf(th, "#ifndef PAN_H\n"); + fprintf(th, "#define PAN_H\n\n"); + fprintf(th, "#define SpinVersion \"%s\"\n", SpinVersion); fprintf(th, "#define PanSource \""); for (i = 0; oFname->name[i] != '\0'; i++) @@ -207,19 +229,69 @@ 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, "#define G_int %d\n\n", (int) sizeof(int)); + fprintf(th, "#define ulong unsigned long\n"); + fprintf(th, "#define ushort unsigned short\n"); fprintf(th, "#ifdef WIN64\n"); - fprintf(th, " #define ONE_L ((unsigned long) 1)\n"); - fprintf(th, " #define long long long\n"); + fprintf(th, " #define ONE_L (1L)\n"); + fprintf(th, "/* #define long long long */\n"); fprintf(th, "#else\n"); fprintf(th, " #define ONE_L (1L)\n"); - fprintf(th, "#endif\n"); + fprintf(th, "#endif\n\n"); - if (separate != 2) - { fprintf(th, "char *TrailFile = PanSource; /* default */\n"); - fprintf(th, "char *trailfilename;\n"); - } + fprintf(th, "#ifdef BFS_PAR\n"); + fprintf(th, " #define NRUNS %d\n", (runstmnts)?1:0); + fprintf(th, " #ifndef BFS\n"); + fprintf(th, " #define BFS\n"); + fprintf(th, " #endif\n"); + fprintf(th, " #ifndef PUTPID\n"); + fprintf(th, " #define PUTPID\n"); + fprintf(th, " #endif\n\n"); + fprintf(th, " #if !defined(USE_TDH) && !defined(NO_TDH)\n"); + fprintf(th, " #define USE_TDH\n"); + fprintf(th, " #endif\n"); + fprintf(th, " #if defined(USE_TDH) && !defined(NO_HC)\n"); + fprintf(th, " #define HC /* default for USE_TDH */\n"); + fprintf(th, " #endif\n"); + fprintf(th, " #ifndef BFS_MAXPROCS\n"); + fprintf(th, " #define BFS_MAXPROCS 64 /* max nr of cores to use */\n"); + fprintf(th, " #endif\n"); + + fprintf(th, " #define BFS_GLOB 0 /* global lock */\n"); + fprintf(th, " #define BFS_ORD 1 /* used with -DCOLLAPSE */\n"); + fprintf(th, " #define BFS_MEM 2 /* malloc from shared heap */\n"); + fprintf(th, " #define BFS_PRINT 3 /* protect printfs */\n"); + fprintf(th, " #define BFS_STATE 4 /* hashtable */\n\n"); + fprintf(th, " #define BFS_INQ 2 /* state is in q */\n\n"); + + fprintf(th, " #ifdef BFS_FIFO\n"); /* queue access */ + fprintf(th, " #define BFS_ID(a,b) (BFS_STATE + (int) ((a)*BFS_MAXPROCS+(b)))\n"); + fprintf(th, " #define BFS_MAXLOCKS (BFS_STATE + (BFS_MAXPROCS*BFS_MAXPROCS))\n"); + fprintf(th, " #else\n"); /* h_store access (not needed for o_store) */ + fprintf(th, " #ifndef BFS_W\n"); + fprintf(th, " #define BFS_W 10\n"); /* 1< 4) /* 64 bit machine */ - { fprintf(th, "#if !defined(HASH32) && !defined(HASH64)\n"); - fprintf(th, " #define HASH64\n"); - fprintf(th, "#endif\n"); - } - if (separate == 1 && !claimproc) { Symbol *n = (Symbol *) emalloc(sizeof(Symbol)); Sequence *s = (Sequence *) emalloc(sizeof(Sequence)); + s->minel = -1; claimproc = n->name = "_:never_template:_"; ready(n, ZN, s, 0, ZN, N_CLAIM); } @@ -259,18 +326,21 @@ fprintf(th, "#endif\n"); if (has_last) fprintf(th, "#define HAS_LAST %d\n", has_last); + if (has_priority && !old_priority_rules) + fprintf(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, " #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"); - 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, "#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"); @@ -289,22 +359,32 @@ if (has_remote) fprintf(th, "#define REM_REFS %d\n", has_remote); /* not yet used */ if (has_hidden) - fprintf(th, "#define HAS_HIDDEN %d\n", has_hidden); + { fprintf(th, "#define HAS_HIDDEN %d\n", has_hidden); + fprintf(th, "#if defined(BFS_PAR) || defined(BFS)\n"); + fprintf(th, " #error cannot use BFS on models with variables declared hidden\n"); + fprintf(th, "#endif\n"); + } if (has_last) fprintf(th, "#define HAS_LAST %d\n", has_last); + if (has_priority && !old_priority_rules) + fprintf(th, "#define HAS_PRIORITY %d\n", has_priority); if (has_sorted) fprintf(th, "#define HAS_SORTED %d\n", has_sorted); if (m_loss) fprintf(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 */ + if (has_ltl) + fprintf(th, "#define HAS_LTL 1\n"); + fprintf(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(th, "#if defined(RANDSTORE) && !defined(RANDSTOR)\n"); fprintf(th, " #define RANDSTOR RANDSTORE\n"); /* xspin uses RANDSTORE... */ fprintf(th, "#endif\n"); if (has_stack) fprintf(th, "#define HAS_STACK %d\n", has_stack); - if (has_enabled) + if (has_enabled || (has_priority && !old_priority_rules)) fprintf(th, "#define HAS_ENABLED 1\n"); if (has_unless) fprintf(th, "#define HAS_UNLESS %d\n", has_unless); @@ -315,6 +395,7 @@ if (has_badelse) fprintf(th, "#define HAS_BADELSE %d\n", has_badelse); if (has_enabled + || (has_priority && !old_priority_rules) || has_pcvalue || has_badelse || has_last) @@ -358,13 +439,13 @@ if (eventmap) { eventmapnr = fproc(eventmap); fprintf(th, "#define EVENT_TRACE %d\n", eventmapnr); - fprintf(th, "#define endevent endstate%d\n", eventmapnr); + fprintf(th, "#define endevent _endstate%d\n", eventmapnr); if (eventmap[2] == 'o') /* ":notrace:" */ fprintf(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, "\ntypedef struct S_F_MAP {\n"); + fprintf(th, " char *fnm;\n\tint from;\n\tint upto;\n"); fprintf(th, "} S_F_MAP;\n"); fprintf(tc, "/*** Generated by %s ***/\n", SpinVersion); @@ -380,18 +461,31 @@ case 2: fprintf(tc, "#include \"pan_t.h\"\n"); break; } + if (separate != 2) + { fprintf(tc, "char *TrailFile = PanSource; /* default */\n"); + fprintf(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"); + fprintf(tc, "#if NQS > 0\n"); + fprintf(tc, "short q_flds[NQS+1];\n"); + fprintf(tc, "short q_max[NQS+1];\n"); + fprintf(tc, "#endif\n"); + plunk_c_fcts(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(tc, 0, 1, Preamble); + ntimes(tc, 0, 1, Separate); /* things that moved out of pan.h */ + } else + { fprintf(tc, "extern int verbose;\n"); + fprintf(tc, "extern long depth, depthfound;\n"); + } fprintf(tc, "#ifndef NOBOUNDCHECK\n"); fprintf(tc, " #define Index(x, y)\tBoundcheck(x, y, II, tt, t)\n"); @@ -439,8 +533,13 @@ } fprintf(tm, "#define rand pan_rand\n"); + fprintf(tm, "#define pthread_equal(a,b) ((a)==(b))\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, " #ifdef BFS_PAR\n"); + fprintf(tm, " bfs_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(tm, " #else\n"); + fprintf(tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(tm, " #endif\n"); fprintf(tm, "#endif\n"); fprintf(tm, " switch (t->forw) {\n"); } else @@ -453,6 +552,7 @@ fprintf(tt, " char *, int, int, int);\n\n"); fprintf(tm, "#define rand pan_rand\n"); + fprintf(tm, "#define pthread_equal(a,b) ((a)==(b))\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"); @@ -488,24 +588,43 @@ } if (separate != 2) - { - fprintf(th, "struct {\n"); - fprintf(th, " int tp; short *src;\n"); - fprintf(th, "} src_all[] = {\n"); + { fprintf(th, "\n"); + for (p = rdy; p; p = p->nxt) + fprintf(th, "extern short src_ln%d[];\n", p->tn); + for (p = rdy; p; p = p->nxt) + fprintf(th, "extern S_F_MAP src_file%d[];\n", p->tn); + fprintf(th, "\n"); + + fprintf(tc, "uchar reached%d[3]; /* np_ */\n", nrRdy); + fprintf(tc, "uchar *loopstate%d; /* np_ */\n", nrRdy); + + fprintf(tc, "struct {\n"); + fprintf(tc, " int tp; short *src;\n"); + fprintf(tc, "} src_all[] = {\n"); for (p = rdy; p; p = p->nxt) - fprintf(th, " { %d, &src_ln%d[0] },\n", + fprintf(tc, " { %d, &src_ln%d[0] },\n", p->tn, p->tn); - fprintf(th, " { 0, (short *) 0 }\n"); - fprintf(th, "};\n"); + fprintf(tc, " { 0, (short *) 0 }\n"); + fprintf(tc, "};\n"); - fprintf(th, "S_F_MAP *flref[] = {\n"); /* 5.3.0 */ + fprintf(tc, "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(tc, " src_file%d%c\n", p->tn, p->nxt?',':' '); } - fprintf(th, "};\n"); + fprintf(tc, "};\n\n"); + } else + { fprintf(tc, "extern uchar reached%d[3]; /* np_ */\n", nrRdy); } - gencodetable(th); + gencodetable(tc); /* was th */ + + 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"); + } if (separate != 1) { tm_predef_np(); @@ -522,13 +641,13 @@ 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 BACKWARD_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"); } else { fprintf(th, "#define FORWARD_MOVES\t\"pan.m\"\n"); - fprintf(th, "#define REVERSE_MOVES\t\"pan.b\"\n"); + fprintf(th, "#define BACKWARD_MOVES\t\"pan.b\"\n"); fprintf(th, "#define TRANSITIONS\t\"pan.t\"\n"); } genaddproc(); @@ -540,42 +659,37 @@ 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"); + + fprintf(tc, " if (reversing == 0) {\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 (u_sync && !u_async) { spit_recvs(th, 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 BACKWARD_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, " extern int *proc_offset;\n"); fprintf(tc, "#else\n"); - fprintf(tc, " extern short proc_offset[];\n"); + fprintf(tc, " extern short *proc_offset;\n"); fprintf(tc, "#endif\n"); - fprintf(tc, "extern uchar proc_skip[];\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 *loopstate[];\n"); fprintf(tc, "extern uchar *stopstate[];\n"); fprintf(tc, "extern uchar *visstate[];\n\n"); fprintf(tc, "extern short *mapstate[];\n"); @@ -607,6 +721,37 @@ { c_wrapper(tc); c_chandump(tc); } + + fprintf(th, "#if defined(BFS_PAR) || NCORE>1\n"); + fprintf(th, " void e_critical(int);\n"); + fprintf(th, " void x_critical(int);\n"); + fprintf(th, " #ifdef BFS_PAR\n"); + fprintf(th, " void bfs_main(int, int);\n"); + fprintf(th, " void bfs_report_mem(void);\n"); + fprintf(th, " #endif\n"); + fprintf(th, "#endif\n"); + + fprintf(th, "\n\n/* end of PAN_H */\n#endif\n"); + fclose(th); + fclose(tt); + fclose(tm); + fclose(tb); + + if (!(th = fopen("pan.p", MFLAGS))) + { printf("spin: cannot create pan.p for -DBFS_PAR\n"); + return; /* we're done anyway */ + } + + ntimes(th, 0, 1, pan_par); /* BFS_PAR */ + fclose(th); + + fprintf(tc, "\nTrans *t_id_lkup[%d];\n\n", globmax+1); + + if (separate != 2) + { fprintf(tc, "\n#ifdef BFS_PAR\n\t#include \"pan.p\"\n#endif\n"); + } + fprintf(tc, "\n/* end of pan.c */\n"); + fclose(tc); } static int @@ -803,6 +948,9 @@ fprintf(tc, "}\n"); } +extern int find_min(Sequence *); +extern int find_max(Sequence *); + static void putproc(ProcList *p) { Pid = p->tn; @@ -812,15 +960,15 @@ && separate == 1) { fprintf(th, "extern uchar reached%d[];\n", Pid); #if 0 - fprintf(th, "extern short nstates%d;\n", Pid); + fprintf(th, "extern short _nstates%d;\n", Pid); #else - fprintf(th, "\n#define nstates%d %d\t/* %s */\n", + fprintf(th, "\n#define _nstates%d %d\t/* %s */\n", Pid, 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", + fprintf(th, "#define _endstate%d %d\n", Pid, p->s->last?p->s->last->seqno:0); return; } @@ -833,12 +981,18 @@ AllGlobal = (p->prov)?1:0; /* process has provided clause */ - fprintf(th, "\n#define nstates%d %d\t/* %s */\n", + fprintf(th, "\n#define _nstates%d %d\t/* %s */\n", Pid, p->s->maxel, p->n->name); +/* new */ + fprintf(th, "#define minseq%d %d\n", Pid, find_min(p->s)); + fprintf(th, "#define maxseq%d %d\n", Pid, find_max(p->s)); + +/* end */ + if (Pid == eventmapnr) - fprintf(th, "#define nstates_event nstates%d\n", Pid); + fprintf(th, "#define nstates_event _nstates%d\n", Pid); - fprintf(th, "#define endstate%d %d\n", Pid, p->s->last?p->s->last->seqno:0); + fprintf(th, "#define _endstate%d %d\n", Pid, 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); @@ -1041,10 +1195,10 @@ 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(tm, "// STATE %d - %s:%d - [", e->seqno, e->n->fn->name, e->n->ln); comment(tm, e->n, 0); - fprintf(tm, "] */\n\t\t"); + fprintf(tm, "]\n\t\t"); if (s->last->n->ntyp == BREAK) OkBreak = target(huntele(s->last->nxt, @@ -1065,7 +1219,7 @@ } fprintf(tb, "\tcase %d: ", uniq-1); - fprintf(tb, "/* STATE %d */\n", e->seqno); + fprintf(tb, "// STATE %d\n", e->seqno); fprintf(tb, "\t\tsv_restor();\n"); fprintf(tb, "\t\tgoto R999;\n"); if (e->nxt) @@ -1268,6 +1422,7 @@ switch (e->n->ntyp) { case ASGN: + if (check_track(e->n) == STRUCT) { break; } nr++; break; case 'r': @@ -1328,10 +1483,10 @@ } if (f && !f->merge && !f->merge_single && f->seqno != stopat) - { fprintf(tm, "\n\t\tbad hop %s:%d -- at %d, <", + { fprintf(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", + fprintf(tm, "> looking for %d -- merge %d:%d:%d ", stopat, f->merge, f->merge_start, f->merge_single); break; } @@ -1363,7 +1518,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) { @@ -1412,7 +1569,7 @@ if (!didcase) { fprintf(tb, "\n\tcase %d: ", casenr); - fprintf(tb, "/* STATE %d */\n\t\t", e->seqno); + fprintf(tb, "// STATE %d\n\t\t", e->seqno); didcase++; } @@ -1540,10 +1697,10 @@ casenr = Cached->m; fromcache = 1; - fprintf(tm, "/* STATE %d - %s:%d - [", + fprintf(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", + fprintf(tm, "] (%d:%d - %d) same as %d (%d:%d - %d)\n", e->merge_start, e->merge, e->merge_in, casenr, Cached->e->merge_start, Cached->e->merge, Cached->e->merge_in); @@ -1551,11 +1708,11 @@ goto gotit; } - fprintf(tm, "\tcase %d: /* STATE %d - %s:%d - [", + fprintf(tm, "\tcase %d: // STATE %d - %s:%d - [", uniq++, e->seqno, e->n->fn->name, e->n->ln); comment(tm, e->n, 0); nrbups = (e->merge || e->merge_start) ? nrhops(e) : nr_bup(e); - fprintf(tm, "] (%d:%d:%d - %d) */\n\t\t", + fprintf(tm, "] (%d:%d:%d - %d)\n\t\t", e->merge_start, e->merge, nrbups, e->merge_in); if (nrbups > MAXMERGE-1) @@ -1579,26 +1736,26 @@ /* 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, "#if NCLAIMS>1\n\t\t"); + 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, " { int nn = (int) ((Pclaim *)pptr(0))->_n;\n\t\t"); + fprintf(tm, " printf(\"depth %%ld: Claim %%s (%%d), state %%d (line %%d)\\n\",\n\t\t"); + fprintf(tm, " depth, procname[spin_c_typ[nn]], nn, "); + fprintf(tm, "(int) ((Pclaim *)pptr(0))->_p, src_claim[ (int) ((Pclaim *)pptr(0))->_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\t\t"); + 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 *)pptr(0))->_p, "); + fprintf(tm, "src_claim[ (int) ((Pclaim *)pptr(0))->_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"); } /* end */ @@ -1662,7 +1819,7 @@ if (e->merge || e->merge_start) { if (!didcase) { fprintf(tb, "\n\tcase %d: ", casenr); - fprintf(tb, "/* STATE %d */", e->seqno); + fprintf(tb, "// STATE %d", e->seqno); didcase++; } else fprintf(tb, ";"); @@ -1712,8 +1869,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 */ @@ -1863,7 +2020,7 @@ { fprintf(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; @@ -2083,6 +2240,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 +2269,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 +2291,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 +2327,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 +2340,7 @@ #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) void putstmnt(FILE *fd, Lextok *now, int m) @@ -2214,14 +2382,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 +2398,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 +2415,40 @@ for ( ; i < Npars; i++) fprintf(fd, ", 0"); fprintf(fd, ")"); +#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) @@ -2369,21 +2566,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++) @@ -2552,6 +2749,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, ""); @@ -2569,21 +2768,21 @@ 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 +2794,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 +2826,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--; } } @@ -2816,8 +3019,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 +3032,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 +3071,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,8 +3085,8 @@ break; case PRINTM: - if (has_enabled) - fprintf(fd, "if (TstOnly) return 1;\n\t\t"); + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T5 */\n\t\t"); fprintf(fd, "printm("); if (now->lft && now->lft->ismtyp) fprintf(fd, "%d", now->lft->val); @@ -2890,7 +3108,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 +3126,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 +3143,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; @@ -2948,7 +3166,7 @@ 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 +3177,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 +3211,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 +3224,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); + } 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, ".")) @@ -3090,7 +3320,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 +3336,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 Thu Dec 31 00:00:00 2015 @@ -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,146 +128,11 @@ " }", "#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;", "long maxdepth=10000;", @@ -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,32 +349,9 @@ " 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", @@ -349,17 +361,28 @@ "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 +393,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 +414,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 +427,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 +475,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 +508,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 +613,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 +881,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 +921,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 +940,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 +960,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 +977,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 +1000,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 +1038,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 +1057,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 Thu Dec 31 00:00:00 2015 @@ -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 *th, *tc; +extern int eventmapnr, old_priority_rules; typedef struct SRC { int ln, st; /* linenr, statenr */ @@ -36,10 +34,10 @@ putnr(int n) { if (col++ == 8) - { fprintf(th, "\n\t"); + { fprintf(tc, "\n\t"); /* was th */ col = 1; } - fprintf(th, "%3d, ", n); + fprintf(tc, "%3d, ", n); /* was th */ } static void @@ -49,7 +47,7 @@ return; if (lastfnm) - fprintf(th, "{ \"%s\", %d, %d },\n\t", + fprintf(tc, "{ \"%s\", %d, %d },\n\t", /* was th */ lastfnm->name, lastfrom, j-1); @@ -61,73 +59,118 @@ putfnm_flush(int j) { if (lastfnm) - fprintf(th, "{ \"%s\", %d, %d }\n", + fprintf(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 = tc; /* was 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,12 +178,16 @@ 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); @@ -153,27 +200,33 @@ { SRC *tmp, *lst; int j; static int did_claim = 0; + FILE *tz = tc; /* was 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,14 +234,18 @@ 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) @@ -324,6 +381,22 @@ case ENABLED: Cat3("enabled(", 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, "set_priority("); + comwork(fd, now->lft->lft, m); + fprintf(fd, ", "); + comwork(fd, now->lft->rgt, m); + fprintf(fd, ")"); + } + break; + case EVAL: Cat3("eval(", now->lft, ")"); break; @@ -346,12 +419,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]; @@ -379,7 +454,8 @@ 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 +481,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 Sat Aug 27 00:00:00 2016 @@ -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,7 +232,7 @@ 0, }; -static char *Addp0[] = { +static const char *Addp0[] = { /* addproc(....parlist... */ ")", "{ int j, h = now._nr_pr;", "#ifndef NOCOMP", @@ -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);", @@ -375,14 +349,16 @@ " memset((char *)pptr(h), 0, j);", " 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,19 @@ 0, }; -static char *Code0[] = { +static const char *Code0[] = { "void", "run(void)", "{ /* int i; */", " memset((char *)&now, 0, sizeof(State));", - " vsize = (unsigned long) (sizeof(State) - VECTORSZ);", + " 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 +678,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 +737,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,19 +755,19 @@ "#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;", "#ifdef TRIX", @@ -800,22 +788,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", + "inline 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 +949,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 +978,11 @@ 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 +1011,7 @@ " switch (((Q0 *)qptr(into))->_t) {", 0, }; -char *R14[] = { +const char *R14[] = { " default: Uerror(\"bad queue - unsend\");", " }", " return _m;", @@ -912,17 +1041,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 +1065,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 +1075,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 +1109,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);", @@ -995,23 +1135,266 @@ " char *q_name[MAXQ+1];", " 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 +1464,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 +1491,6 @@ "#ifdef PRINTF", " strcat(ctd, \"-DPRINTF \");", "#endif", - "#ifdef OTIM", - " strcat(ctd, \"-DOTIM \");", - "#endif", "#ifdef COLLAPSE", " strcat(ctd, \"-DCOLLAPSE \");", "#endif", @@ -1150,10 +1518,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 Thu Dec 31 00:00:00 2015 @@ -1,13 +1,10 @@ /***** 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" @@ -17,7 +14,7 @@ extern Symbol *Fname; extern int lineno, m_loss, Pid, 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); @@ -44,7 +41,7 @@ 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); break; @@ -153,7 +150,14 @@ fprintf(tb, "p_restor(II);\n\t\t"); break; + case SET_P: + fprintf(tb, "((P0 *)pptr((trpt->o_priority >> 8)))"); + fprintf(tb, "->_priority = trpt->o_priority & 255"); + break; + case ASGN: + if (check_track(now) == STRUCT) { break; } + nocast=1; putstmnt(tb,now->lft,m); nocast=0; fprintf(tb, " = trpt->bup.oval"); if (multi_oval > 0) @@ -319,7 +323,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 +335,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 +345,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 Thu Dec 31 00:00:00 2015 @@ -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 Thu Dec 31 00:00:00 2015 @@ -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" @@ -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 @@ -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. */ @@ -534,6 +535,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 +592,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 +614,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 +642,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: @@ -830,9 +847,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 Thu Dec 31 00:00:00 2015 @@ -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];", @@ -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 Thu Dec 31 00:00:00 2015 @@ -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" @@ -201,6 +191,8 @@ case '~': case 'c': case ENABLED: + case SET_P: + case GET_P: case ASSERT: case EVAL: def_use(now->lft, USE|code); @@ -1011,7 +1003,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,6 +1053,8 @@ case '~': case 'c': case ENABLED: + case SET_P: + case GET_P: case ASSERT: AST_track(now->lft, USE|code); break; @@ -1071,7 +1066,7 @@ 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': @@ -1983,7 +1978,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 +2006,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 +2163,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 +2210,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 Mar 13 00:00:00 2017 @@ -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];", @@ -256,10 +338,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)", @@ -420,7 +498,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 +518,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 +526,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 +537,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 +675,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 +716,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 +785,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 +1088,7 @@ " #endif", "", " #ifndef BITSTATE", - " H_tab = (struct H_el **) emalloc(n);", + " H_tab = (H_el **) emalloc(n);", " #endif", "#else", " #ifndef MEMLIM", @@ -1016,7 +1102,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 +1146,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 +1236,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 +1309,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 +1425,7 @@ "int unpack_state(SM_frame *, int);", "#endif", "", - "struct H_el *", + "H_el *", "grab_shared(int n)", "{", "#ifndef SEP_STATE", @@ -1399,7 +1433,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 +1498,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", "}", "", @@ -1586,7 +1620,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 +1631,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 +2116,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 +2238,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 +2619,7 @@ " #endif", "", " #ifndef BITSTATE", - " H_tab = (struct H_el **) emalloc(n);", + " H_tab = (H_el **) emalloc(n);", " #endif", "#else", " #ifndef MEMLIM", @@ -2594,7 +2632,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 +2775,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 Thu Dec 31 00:00:00 2015 @@ -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 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(); @@ -360,6 +356,7 @@ } } assert(p && p->b == N_CLAIM); Nacc[n] = 1; + has_accept = 1; l->e = e; l->nxt = labtab; @@ -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; } @@ -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 Apr 25 00:00:00 2016 @@ -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 doesnt 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 dont 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:%%d: %%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:%%d: %%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 Thu Dec 31 00:00:00 2015 @@ -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 YYSTYPE yylval; extern ProcList *rdy; -void repro_seq(Sequence *); +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; @@ -133,4 +132,253 @@ repro_src(void) { repro_proc(rdy); +} + +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 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 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 != '@' + && 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 == ':' && 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 Jan 11 00:00:00 2016 @@ -1,13 +1,10 @@ /***** 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" @@ -16,15 +13,18 @@ extern RunList *X, *run; 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); +static int get_priority(Lextok *n); +static void set_priority(Lextok *n, Lextok *m); extern void sr_buf(int, int); void @@ -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)); } @@ -398,6 +404,10 @@ case NEMPTY: return (qlen(now)>0); case ENABLED: if (s_trail) return 1; return pc_enabled(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: return eval(now->lft); case PC_VAL: return pc_value(now->lft); case NONPROGRESS: return nonprogress(); @@ -411,7 +421,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 +450,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); @@ -542,6 +559,7 @@ verbose = v; return i; + case SET_P: case C_CODE: case C_EXPR: case PRINT: case PRINTM: case ASGN: case ASSERT: @@ -582,6 +600,7 @@ case '@': return X->pid == (nproc-nstop-1); case '.': + case SET_P: return 1; case GOTO: if (Rvous) return 0; @@ -624,10 +643,91 @@ for (Y = run; Y; Y = Y->nxt) if (--i == pid) { oX = X; X = Y; - result = Enabled0(Y->pc); + result = Enabled0(X->pc); X = 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->prov && !eval(X->prov)) return 0; /* can't be highest unless fully enabled */ + + for (Y = run; 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; + i = nproc - nstop; + for (Y = run; Y; Y = Y->nxt) + { i--; +if (0) printf(" pid %d @ priority %d\t", Y->pid, Y->priority); + if (Y->priority > target) + { X = Y; +if (0) printf("enabled: %s\n", Enabled0(X->pc)?"yes":"nope"); +if (0) printf("provided: %s\n", eval(X->prov)?"yes":"nope"); + if (Enabled0(X->pc) && (!X->prov || eval(X->prov))) + { result = 0; + break; + } } +else +if (0) printf("\n"); + } + X = 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; 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; 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; 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 Thu Dec 31 00:00:00 2015 @@ -1,13 +1,10 @@ /***** 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" @@ -19,19 +16,21 @@ 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; +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); RunList *X = (RunList *) 0; RunList *run = (RunList *) 0; RunList *LastX = (RunList *) 0; /* previous executing proc */ ProcList *rdy = (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 *); @@ -44,11 +43,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:"--"); @@ -61,7 +64,9 @@ r->nxt = run; 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; @@ -80,11 +85,13 @@ 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->det = (unsigned char) det; r->nxt = rdy; rdy = r; @@ -137,8 +144,9 @@ run->pid - Have_claim, run->n->name); pstext(run->pid - Have_claim, Buf); } else - printf("proc %d = %s\n", - run->pid - Have_claim, run->n->name); + { printf("proc %d = %s\n", + run->pid - Have_claim, run->n->name); + } return; } @@ -171,9 +179,11 @@ Symbol *s = m->sym; /* proctype name */ Lextok *n = m->lft; /* actual parameters */ - if (m->val < 1) m->val = 1; /* minimum priority */ + 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 (strcmp(s->name, p->n->name) == 0) { if (nproc-nstop >= MAXP) { printf("spin: too many processes (%d max)\n", MAXP); break; @@ -183,7 +193,7 @@ setparams(run, p, n); setlocals(run); /* after setparams */ return run->pid - Have_claim + Skip_claim; /* effective simu pid */ - } + } } return 0; /* process not found */ } @@ -301,7 +311,7 @@ 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 +355,24 @@ return e; } +static int +x_can_run(void) /* the currently selected process in X can run */ +{ + if (X->prov && !eval(X->prov)) + { +if (0) printf("pid %d cannot run: not provided\n", X->pid); + return 0; + } + if (has_priority && !old_priority_rules) + { Lextok *n = nn(ZN, CONST, ZN, ZN); + n->val = X->pid; +if (0) printf("pid %d %s run (priority)\n", X->pid, pc_highest(n)?"can":"cannot"); + return pc_highest(n); + } +if (0) printf("pid %d can run\n", X->pid); + return 1; +} + static RunList * pickproc(RunList *Y) { SeqList *z; Element *has_else; @@ -356,7 +384,25 @@ 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 = run; X; X = X->nxt) + { if (j-- <= 0) + break; + } + if (X == NULL) + { fatal("unexpected, pickproc", (char *)0); + } + j = nproc - nstop; + while (j-- > 0) + { if (x_can_run()) + { Y = X; + break; + } + X = (X->nxt)?X->nxt:run; + } + return Y; + } if (Priority_Sum < nproc-nstop) fatal("cannot happen - weights", (char *)0); j = (int) Rand()%Priority_Sum; @@ -367,6 +413,7 @@ X = X->nxt; if (!X) { Y = NULL; X = run; } } + } else { int only_choice = -1; int no_choice = 0, proc_no_ch, proc_k; @@ -378,8 +425,7 @@ Choices[X->pid] = (short) k; - if (!X->pc - || (X->prov && !eval(X->prov))) + if (!X->pc || !x_can_run()) { if (X == run) Choices[X->pid] = 0; continue; @@ -512,8 +558,10 @@ } } 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 +580,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,15 +594,19 @@ { 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) @@ -583,9 +639,9 @@ depth++; LastStep = ZE; oX = X; /* a rendezvous could change it */ go = 1; - if (X->prov && X->pc + if (X->pc && !(X->pc->status & D_ATOM) - && !eval(X->prov)) + && !x_can_run()) { if (!xspin && ((verbose&32) || (verbose&4))) { p_talk(X->pc, 1); printf("\t<>\n"); @@ -597,9 +653,10 @@ && ((verbose&32) || (verbose&4))) { if (X == oX) if (!(e->status & D_ATOM) || (verbose&32)) /* no talking in d_steps */ - { p_talk(X->pc, 1); + { if (!LastStep) LastStep = X->pc; + /* A. Tanaka, changed order */ + p_talk(LastStep, 1); printf(" ["); - if (!LastStep) LastStep = X->pc; comment(stdout, LastStep->n, 0); printf("]\n"); } @@ -653,13 +710,15 @@ X = (X->nxt) ? X->nxt : run; } else { if (p_blocked(X->pid)) - { if (Tval) break; - Tval = 1; - if (depth >= jumpsteps) + { if (Tval && !has_stdin) + { break; + } + if (!Tval && depth >= jumpsteps) { oX = X; X = (RunList *) 0; /* to suppress indent */ dotag(stdout, "timeout\n"); X = oX; + Tval = 1; } } } } if (!run || !X) break; /* new 5.0 */ @@ -708,7 +767,7 @@ printf(" ["); comment(stdout, s_was->n, 0); printf("]\n"); - tmp = orun; orun = X; X = tmp; + tmp = orun; /* orun = X; */ X = tmp; if (!LastStep) LastStep = X->pc; p_talk(LastStep, 1); printf(" ["); @@ -747,6 +806,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; @@ -862,9 +922,11 @@ 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; + { 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; @@ -932,7 +994,11 @@ printf(" -"); else printf("%2d", X->pid - Have_claim); - printf(" (%s) ", X->n->name); + if (old_priority_rules) + { printf(" (%s) ", X->n->name); + } else + { printf(" (%s:%d) ", X->n->name, X->priority); + } } static void @@ -1011,8 +1077,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,7 +1105,8 @@ } } 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) @@ -1056,12 +1124,13 @@ } 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 */ + + /* check remote variables */ oX = X; X = Y; @@ -1069,17 +1138,20 @@ 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; return i; -#else - break; -#endif } printf("remote ref: %s[%d] ", n->lft->sym->name, prno-added); non_fatal("%s not found", n->sym->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 Sep 18 00:00:00 2017 @@ -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 */ @@ -142,6 +143,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 +166,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 +193,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 +243,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,6 +268,7 @@ 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); @@ -266,6 +281,7 @@ Symbol *lookup(char *); Symbol *prep_inline(Symbol *, Lextok *); +char *put_inline(FILE *, char *); char *emalloc(size_t); long Rand(void); @@ -274,6 +290,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 +333,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 +343,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 *); @@ -363,20 +378,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); @@ -397,7 +414,6 @@ 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 +429,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 Wed Apr 5 00:00:00 2017 @@ -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,41 @@ 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 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,10 +113,17 @@ | 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); @@ -122,7 +133,7 @@ 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); } @@ -134,8 +145,8 @@ rl = ready($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:"); + } if (dumptab) $3->sym->ini = $1; } else { rl = ready($3->sym, $6, $11->sq, $2->val, $10, P_PROC); @@ -156,7 +167,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", ""); @@ -185,9 +196,9 @@ } ; -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; } ; @@ -245,12 +256,17 @@ } ; -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 +276,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 +313,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 +324,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; @@ -339,7 +366,11 @@ | NAME ':' one_decl { fatal("label preceding declaration,", (char *)0); } | NAME ':' XU { fatal("label predecing 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 { printf("Not a Step\n"); } ; vis : /* empty */ { $$ = ZN; } @@ -387,34 +418,65 @@ | 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 '{' c_list '}' { + 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; $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)); } } | vardcl ASGN ch_init { $1->sym->ini = $3; $$ = $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 +486,8 @@ } $$ = nn(ZN, CHAN, ZN, $6); $$->val = $2->val; + $$->ln = $1->ln; + $$->fn = $1->fn; } ; @@ -436,7 +500,22 @@ } $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->val > 0) + { fprintf(stderr, "evaluated as %d\n", $3->sym->ini->val); + $$->val = $3->sym->ini->val; + } else + { fprintf(stderr, "evaluated as 8 by default (to avoid zero)\n"); + $$->val = 8; + } + $1->sym->nel = $$->val; + $1->sym->isarray = 1; + $$ = $1; + } ; varref : cmpnd { $$ = mk_explicit($1, Expand_Ok, NAME); } @@ -475,13 +554,15 @@ 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 '}' ; @@ -497,25 +578,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,6 +623,19 @@ } $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); @@ -560,10 +659,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 +697,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++; } + 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 +739,39 @@ 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; $$->val = $1->val / $3->val; } + | const_expr '%' const_expr { $$ = $1; $$->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,7 +794,7 @@ | '-' 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, $$); } @@ -670,16 +804,15 @@ 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); @@ -699,7 +832,7 @@ | 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,11 +841,11 @@ { $$ = 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; } @@ -736,7 +869,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,14 +878,14 @@ | 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)) + | PROVIDED l_par full_expr r_par { if (!proper_enabler($3)) { non_fatal("invalid PROVIDED clause", (char *)0); $$ = ZN; @@ -780,6 +913,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 +925,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,7 +946,7 @@ 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; @@ -831,12 +967,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 +1028,21 @@ 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 *); - 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 */ + char ltl_formula[2048]; + 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 +1055,66 @@ 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); + memset(ltl_formula, 0, sizeof(ltl_formula)); + retval = fgets(ltl_formula, sizeof(ltl_formula), tf); fclose(tf); - (void) unlink(TMP_FILE); + + (void) unlink(TMP_FILE1); if (!retval) { printf("%p\n", retval); - fatal("could not translate ltl formula", 0); + fatal("could not translate ltl ltl_formula", 0); } - if (1) printf("ltl %s: %s\n", ltl_name, formula); + if (1) printf("ltl %s: %s\n", ltl_name, ltl_formula); - m->sym = lookup(formula); + m->sym = lookup(ltl_formula); 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 Wed Apr 5 00:00:00 2017 @@ -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,6 +35,8 @@ Symbol *s; Symbol *t; Symbol *ival; + Symbol *fnm; + int lno; struct C_Added *nxt; } C_Added; @@ -41,8 +45,9 @@ 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,83 @@ 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(); + { c = getc(yyin); + } 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) @@ -154,6 +178,7 @@ yytext[i++] = (char) c; /* no tst */ } } yytext[i] = '\0'; + Ungetch(c); } @@ -162,7 +187,8 @@ { int c; if ((c = Getchar()) == tok) - return ifyes; + { return ifyes; + } Ungetch(c); return ifno; @@ -264,6 +290,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 +315,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 +375,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 +398,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 +415,71 @@ } 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, '{')) + if (strchr(p, '[') && !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 +500,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 +512,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 */ @@ -438,7 +534,7 @@ 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') @@ -460,9 +556,9 @@ } 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"); } @@ -599,6 +695,7 @@ for (r = c_added; r; r = r->nxt) /* pickup local decls */ 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) @@ -609,7 +706,7 @@ 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 +759,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 +804,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 +837,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; @@ -804,14 +903,28 @@ } } } +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 +936,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 +960,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 +988,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,6 +1004,14 @@ 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; @@ -884,9 +1025,9 @@ tmp = find_inline(s); t = (char *) tmp->cn; - if (strchr(t, ';') - || strstr(t, "++") - || strstr(t, "--")) + if (side_scan(t, ";") + || side_scan(t, "++") + || side_scan(t, "--")) { bad: lineno = tmp->dln; Fname = tmp->dfn; @@ -896,8 +1037,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 +1051,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 +1060,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 +1083,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 +1179,8 @@ s->context = context; s->type = CODE_FRAG; } else - s->type = PREDEF; + { s->type = PREDEF; + } p = &Buf1[0]; Buf2[0] = '\0'; @@ -1059,12 +1208,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 +1239,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 +1263,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 +1309,184 @@ } 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; +} + +int +scan_to(int stop, int (*tst)(int), char *buf) +{ 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) + { buf[i++] = c; + } + if (tst && !tst(c) && c != ' ' && c != '\t') + { break; + } + } while (c != stop && c != EOF); + + if (buf) + { 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(); 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 (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 +1495,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 +1534,79 @@ } 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; + +#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) + || !scan_to(':', isalnum, name) + || !scan_to('.', isdigit, from) + || !scan_to('.', 0, 0) + || !scan_to(')', isdigit, 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[128]; + push_back(":: "); + sprintf(buf, "%s = %d ", + name, i); + push_back(buf); + } + push_back("fi "); + } else + { char buf[128]; + 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 +1640,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 +1655,7 @@ case '}': scope_level--; set_cur_scope(); break; default : break; } - Token(c) + ValToken(0, c) } static struct { @@ -1294,6 +1704,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 +1730,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,6 +1766,9 @@ { 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; } } @@ -1364,6 +1780,9 @@ 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; @@ -1428,13 +1847,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 +1869,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 +1887,7 @@ if (context) owner = ZS; hold = lex(); /* look ahead */ if (hold == '}' + || hold == ARROW || hold == SEMI) { c = hold; /* omit ';' */ hold = 0; @@ -1481,19 +1906,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 +1946,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 Thu Dec 31 00:00:00 2015 @@ -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" 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 Tue May 31 00:00:00 2016 @@ -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" @@ -23,10 +20,10 @@ int Nid = 0; Lextok *Mtype = (Lextok *) 0; +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 */ @@ -321,7 +330,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); } @@ -484,7 +493,9 @@ } } -if (1) printf("\t{scope %s}", sp->bscp); + if (!old_scope_rules) + { printf("\t{scope %s}", sp->bscp); + } printf("\n"); } @@ -583,14 +594,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 Tue May 31 00:00:00 2016 @@ -1,16 +1,13 @@ /***** 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 */ - -/* 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 @@ -66,6 +63,7 @@ #ifdef NXT , NEXT /* 269 */ #endif + , CEXPR /* 270 */ }; Node *Canonical(Node *); @@ -84,9 +82,10 @@ 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); 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 Thu Dec 31 00:00:00 2015 @@ -1,16 +1,13 @@ /***** 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" @@ -66,6 +63,7 @@ #ifdef NXT case NEXT: #endif + case CEXPR: return p; case OR: p->lft = Prune(p->lft); @@ -553,10 +551,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 +588,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++; } 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 Thu Dec 31 00:00:00 2015 @@ -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 Tue May 31 00:00:00 2016 @@ -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 Thu Dec 31 00:00:00 2015 @@ -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" @@ -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,11 +99,17 @@ 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; @@ -119,7 +133,6 @@ 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] = ' '; } @@ -195,6 +208,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 +241,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 +255,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 Thu Dec 31 00:00:00 2015 @@ -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" 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 Thu Dec 31 00:00:00 2015 @@ -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 Thu Dec 31 00:00:00 2015 @@ -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 Thu Dec 31 00:00:00 2015 @@ -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,7 @@ static Graph *Nodes_Set = (Graph *) 0; static Graph *Nodes_Stack = (Graph *) 0; -static char dumpbuf[2048]; +static char dumpbuf[4096]; static int Red_cnt = 0; static int Lab_cnt = 0; static int Base = 0; @@ -149,6 +146,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 +168,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 +258,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 @@ -469,9 +479,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) @@ -549,6 +561,10 @@ case NEXT: strcat(dumpbuf, "X"); goto common1; #endif + case CEXPR: strcat(dumpbuf, "c_expr {"); + sdump(n->lft); + strcat(dumpbuf, "}"); + break; case NOT: strcat(dumpbuf, "!"); goto common1; case TRUE: strcat(dumpbuf, "T"); @@ -735,6 +751,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 Thu Dec 31 00:00:00 2015 @@ -1,13 +1,10 @@ /***** 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" @@ -17,7 +14,7 @@ extern Symbol *Fname; extern char Buf[]; extern int lineno, depth, verbose, xspin, limited_vis; -extern int analyze, jumpsteps, nproc, nstop, columns; +extern int analyze, jumpsteps, nproc, nstop, columns, old_priority_rules; extern short no_arrays, Have_claim; extern void sr_mesg(FILE *, int, int); extern void sr_buf(int, int); @@ -42,22 +39,54 @@ { if (!X) return 0; return X->pid - Have_claim; } + if (strcmp(s->name, "_priority") == 0) + { if (!X) return 0; + + if (old_priority_rules) + { non_fatal("cannot refer to _priority with -o6", (char *) 0); + return 1; + } + return X->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) + { non_fatal("no context for _priority", (char *) 0); + return 1; + } + X->priority = n; + } + if (v->sym->context && v->sym->type) return setlocal(v, n); if (!v->sym->type) @@ -90,6 +119,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 +131,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 +156,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 && (i = find_lab(s, X->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 +185,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]; @@ -260,7 +299,7 @@ } sr_buf(prefetch, sp->type == MTYPE); if (sp->colnr == 0) - { sp->colnr = maxcolnr; + { sp->colnr = (unsigned char) maxcolnr; maxcolnr = 1+(maxcolnr%10); } colpos = nproc+sp->colnr-1; @@ -332,7 +371,7 @@ } sr_buf(getval(dummy), z->type==MTYPE); if (z->colnr == 0) - { z->colnr = maxcolnr; + { z->colnr = (unsigned char) maxcolnr; maxcolnr = 1+(maxcolnr%10); } colpos = nproc+z->colnr-1; 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 Sat Aug 19 00:00:00 2017 @@ -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.4.7 -- 19 August 2017"