Update Gerard Holzmann's Spin from version 6.1.0 (4 May 2011) to 6.2.5 (4 May 2013). The manual was not updated between these two versions. For information, here are the differences between the original version from Gerard Holzmann and this Plan 9 version of Spin. --- /sys/src/cmd/spin/main.c +++ /sys/src/cmd/spin/main.c @@ -554,7 +554,7 @@ void non_fatal(char *s1, char *s2) -{ extern int yychar; extern char yytext[]; +{ extern char yytext[]; printf("spin: %s:%d, Error: ", Fname?Fname->name:(oFname?oFname->name:"nofilename"), lineno); @@ -566,11 +566,6 @@ else printf(s1); #endif - if (yychar > 0) - { printf(" saw '"); - explain(yychar); - printf("'"); - } if (strlen(yytext)>1) printf(" near '%s'", yytext); printf("\n"); --- /sys/src/cmd/spin/pangen1.c +++ /sys/src/cmd/spin/pangen1.c @@ -16,11 +16,6 @@ #include "pangen3.h" #include "pangen6.h" #include -#ifdef SOLARIS -#include -#else -#include -#endif extern FILE *tc, *th, *tt; extern Label *labtab; @@ -155,9 +150,9 @@ i); fprintf(th, " unsigned _n : %d; /* active-claim index */\n", blog(nclaims)); - if (i <= UINT8_MAX) /* in stdint.h = UCHAR_MAX from limits.h */ + if (i <= 255) /* in stdint.h = UCHAR_MAX from limits.h */ { fprintf(th, " uchar c_cur[NCLAIMS]; /* claim-states */\n"); - } else if (i <= UINT16_MAX) /* really USHRT_MAX from limits.h */ + } else if (i <= 65535) /* really USHRT_MAX from limits.h */ { fprintf(th, " ushort c_cur[NCLAIMS]; /* claim-states */\n"); } else /* the most unlikely case */ { fprintf(th, " uint c_cur[NCLAIMS]; /* claim-states */\n"); --- /sys/src/cmd/spin/spin.h +++ /sys/src/cmd/spin/spin.h @@ -15,9 +15,6 @@ #include #include #include -#ifndef PC -#include -#endif enum { INIV, PUTV, LOGV }; /* for pangen[14].c */ enum btypes { NONE, N_CLAIM, I_PROC, A_PROC, P_PROC, E_TRACE, N_TRACE }; Reference: /n/sources/patch/maybe/spin-625 Date: Sun Sep 15 23:04:55 CES 2013 Signed-off-by: djc@9grid.fr --- /sys/src/cmd/spin/dstep.c Sun Sep 15 19:38:29 2013 +++ /sys/src/cmd/spin/dstep.c Sun Sep 15 19:38:25 2013 @@ -204,7 +204,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 +216,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 (!("); @@ -266,15 +268,22 @@ 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); --- /sys/src/cmd/spin/flow.c Sun Sep 15 19:38:39 2013 +++ /sys/src/cmd/spin/flow.c Sun Sep 15 19:38:32 2013 @@ -13,7 +13,7 @@ #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]; @@ -39,6 +39,7 @@ open_seq(int top) { SeqList *t; Sequence *s = (Sequence *) emalloc(sizeof(Sequence)); + s->minel = -1; t = seqlist(s, cur_s); cur_s = t; @@ -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); } } @@ -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)) @@ -357,6 +360,15 @@ } } } +void +popbreak(void) +{ + if (!breakstack) + fatal("cannot happen, breakstack", (char *) 0); + + breakstack = breakstack->nxt; /* pop stack */ +} + static Element * if_seq(Lextok *n) { int tok = n->ntyp; @@ -410,13 +422,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 +587,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,6 +596,7 @@ 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; @@ -609,7 +615,9 @@ get_labspec(Lextok *n) { Symbol *s = n->sym; Label *l, *anymatch = (Label *) 0; +#if 0 int cur_uiid = n->uiid; +#endif /* * try to find a label with the same uiid * but if it doesn't exist, return any other @@ -619,7 +627,14 @@ { if (strcmp(s->name, l->s->name) == 0 && s->context == l->s->context) { anymatch = l; +#if 0 + if (0) printf("Label %s uiid now::then %d :: %d bcsp %s :: %s\n", + s->name, cur_uiid, l->uiid, s->bscp, l->s->bscp); + if (cur_uiid == l->uiid) /* best match */ +#else + if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0) +#endif { return l; } } } @@ -720,8 +735,9 @@ } 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); } } @@ -851,7 +867,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) @@ -967,8 +983,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 +1002,7 @@ rv = nn(ZN, DO, ZN, ZN); rv->sl = t0->sl; + return rv; } @@ -1002,6 +1017,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 +1033,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 +1041,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 +1078,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"); } } --- /sys/src/cmd/spin/guided.c Sun Sep 15 19:38:45 2013 +++ /sys/src/cmd/spin/guided.c Sun Sep 15 19:38:41 2013 @@ -12,6 +12,7 @@ #include "spin.h" #include #include +#include #include "y.tab.h" extern RunList *run, *X; @@ -19,7 +20,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 +75,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: @@ -141,10 +200,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 +270,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 +281,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 +296,19 @@ 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)\n", + pno, X->pid, X->n->name, X->tn, X->b, nst, min_seq, max_seq); + } + continue; + /* lost_trail(); */ + } + X->pc = dothis; } lineno = dothis->n->ln; --- /sys/src/cmd/spin/main.c Sun Sep 15 19:38:58 2013 +++ /sys/src/cmd/spin/main.c Sun Sep 15 23:04:41 2013 @@ -15,7 +15,6 @@ #include #include #include -/* #include */ #include #ifdef PC #include @@ -32,6 +31,8 @@ extern void repro_src(void); extern void qhide(int); extern char CurScope[MAXSCOPESZ]; +extern short has_provided; +extern int realread; Symbol *Fname, *oFname; @@ -44,7 +45,8 @@ int separate; /* separate compilation */ int export_ast; /* pangen5.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; int merger = 1, deadvar = 1; int ccache = 0; /* oyvind teig: 5.2.0 case caching off by default */ @@ -81,6 +83,7 @@ void explain(int); +#ifndef CPP /* to use visual C++: #define CPP "CL -E/E" or call spin as: "spin -PCL -E/E" @@ -89,7 +92,6 @@ #define CPP "icc -E/Pd+ -E/Q+" or call spin as: "spin -Picc -E/Pd+ -E/Q+" */ -#ifndef CPP #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 */ @@ -97,11 +99,14 @@ #ifdef SOLARIS #define CPP "/usr/ccs/lib/cpp" #else + #define CPP "cpp" + /* #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #define CPP "cpp" #else - #define CPP "/bin/cpp" /* classic Unix systems */ + #define CPP "/lib/cpp" #endif + */ #endif #endif #endif @@ -213,8 +218,10 @@ 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-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-S1 and -S2 separate pan source for claim and model\n"); @@ -230,7 +237,7 @@ alldone(1); } -void +int optimizations(int nr) { switch (nr) { @@ -269,11 +276,18 @@ 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 */ + default: printf("spin: bad or missing parameter on -o\n"); usage(); break; } + return 1; } int @@ -327,10 +341,13 @@ 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 'o': usedopts += optimizations(argv[1][2]); break; case 'P': PreProc = (char *) &argv[1][2]; break; - case 'p': verbose += 4; 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; @@ -349,9 +366,6 @@ alldone(0); break; case 'w': verbose += 64; break; -#if 0 - case 'x': split_decl = 0; break; /* experimental */ -#endif case 'X': xspin = notabs = 1; #ifndef PC signal(SIGPIPE, alldone); /* not posix... */ @@ -366,7 +380,7 @@ } 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]; @@ -463,6 +477,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,7 +507,10 @@ chanaccess(); if (!Caccess) - { if (!s_trail && (dataflow || merger)) + { if (has_provided && merger) + { merger = 0; /* cannot use statement merging in this case */ + } + if (!s_trail && (dataflow || merger)) ana_src(dataflow, merger); sched(); alldone(nr_errs); @@ -503,7 +521,7 @@ 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 +539,6 @@ strcat(add_ltl[4], fm); strcat(add_ltl[4], ")"); /* add_ltl[4] = fm; */ - nr_errs += tl_main(4, add_ltl); fflush(tl_out); @@ -540,11 +557,15 @@ { 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, but isn't really better code... */ +#else if (s2) printf(s1, s2); else printf(s1); +#endif if (strlen(yytext)>1) printf(" near '%s'", yytext); printf("\n"); @@ -560,7 +581,9 @@ (void) unlink("pan.h"); (void) unlink("pan.m"); (void) unlink("pan.t"); + (void) unlink("pan.p"); (void) unlink("pan.pre"); + (void) unlink("_spin_nvr.tmp"); alldone(1); } @@ -584,19 +607,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 @@ -804,6 +827,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 +867,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; --- /sys/src/cmd/spin/mesg.c Sun Sep 15 19:39:08 2013 +++ /sys/src/cmd/spin/mesg.c Sun Sep 15 19:39:01 2013 @@ -9,6 +9,7 @@ /* http://spinroot.com/ */ /* Send all bug-reports and/or questions to: bugs@spinroot.com */ +#include #include "spin.h" #include "y.tab.h" @@ -26,7 +27,7 @@ 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; @@ -130,7 +131,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 +144,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 +182,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]) @@ -571,7 +618,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 @@ -657,7 +708,8 @@ int cnt; struct BaseName *nxt; } BaseName; -BaseName *bsn; + +static BaseName *bsn; void newbasename(char *s) @@ -777,8 +829,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); --- /sys/src/cmd/spin/pangen1.c Sun Sep 15 19:39:25 2013 +++ /sys/src/cmd/spin/pangen1.c Sun Sep 15 19:39:13 2013 @@ -25,7 +25,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 +51,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 +89,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 +104,20 @@ } 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(tc, " \":np_:\",\n"); + fprintf(tc, "};\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, "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) @@ -157,7 +158,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 +176,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 +196,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 +231,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,39 +246,25 @@ 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"); + ntimes(tc, 0, 1, R7b); + fprintf(tc, "int\naddproc(int calling_pid, int n"); for (/* i = 0 */; i < Npars; i++) fprintf(tc, ", int par%d", i); @@ -322,8 +314,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 +337,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 +347,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 +399,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 +410,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); @@ -464,7 +477,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 +617,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; } @@ -835,13 +848,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 @@ -948,15 +960,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 +1001,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 = 1;\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"); } @@ -1087,6 +1102,10 @@ 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 = %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,7 +1177,7 @@ } } if (cnt >= 200 || !e) - fatal("confusing control structure", (char *) 0); + fatal("confusing control. structure", (char *) 0); return e; } @@ -1168,7 +1187,7 @@ 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; @@ -1186,6 +1205,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,7 +1219,7 @@ return e; e = g; } - if (cnt >= 200 || !e) + if (cnt >= 500 || !e) fatal("confusing control structure", (char *) 0); return e; } @@ -1266,7 +1288,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 +1318,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,12 +1533,12 @@ 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"); /* 256 is param outside the range of valid pids */ --- /sys/src/cmd/spin/pangen1.h Sun Sep 15 19:40:09 2013 +++ /sys/src/cmd/spin/pangen1.h Sun Sep 15 19:39:37 2013 @@ -10,7 +10,7 @@ /* Send all bug-reports and/or questions to: bugs@spinroot.com */ /* (c) 2007-2011: additions, enhancements, and bugfixes GJH */ -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 +35,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 +64,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)", @@ -127,7 +121,7 @@ "#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 +131,74 @@ " }", "#endif", "}", + "", "#ifdef HAS_PROVIDED", - "int provided(int, uchar, int, Trans *);", + " 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", - "", - "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); }", + " #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 enter_critical(w) { if (w < 3+NCORE) e_critical(w); }", - " #define leave_critical(w) { if (w < 3+NCORE) x_critical(w); }", + " #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", - "#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;", - "}", + " #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", - "int", - "cpu_printf(const char *fmt, ...)", - "{ va_list args;", - " va_start(args, fmt);", - " vprintf(fmt, args);", - " va_end(args);", - " return 1;", - "}", + " #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 +243,7 @@ "static int stackread;", "static Trail frameptr;", "Trail *", - "getframe(int d)", + "getframe(long d)", "{", " if (CNT1 == CNT2)", " return &trail[d];", @@ -266,25 +264,6 @@ " 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 */", @@ -310,7 +289,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 +310,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];", "", @@ -593,7 +583,7 @@ "getrail(void)", "{ FILE *fd;", " char *q;", - " int i, t_id, lastnever=-1; short II;", + " int i, t_id, lastnever = -1; short II;", " Trans *t;", " P0 *z;", "", @@ -640,6 +630,7 @@ " 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\");", @@ -730,23 +721,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 +728,11 @@ "#ifdef BITSTATE", "int", "bstore_mod(char *v, int n) /* hasharray size not a power of two */", - "{ unsigned long x, y;", - " unsigned int i = 1;", + "{ ulong x, y;", + " uint i = 1;", "", - " d_hash((uchar *) v, n); /* sets j3, j4, K1, K2 */", - " x = K1; y = j3;", /* was K2 before 5.1.1 */ + " d_hash((uchar *) v, n); /* sets j3_spin, j4_spin, K1, K2 */", + " 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 +885,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 +905,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 +982,7 @@ " return h; /* no memcpy */", " }", /* else */ " bfs_size_limit++;", - "#endif", + " #endif", " h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n);", " }", "", @@ -1057,22 +997,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 +1023,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 +1062,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 +1074,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 +1093,38 @@ "", "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", + " #endif", + " #ifdef CHECK", " printf(\"PUSH %%u (depth %%d, nr %%d)\\n\", t->frame, d, t->nr);", - "#endif", + " #endif", "}", "", "Trail *", "pop_bfs(void)", - "{ BFS_Trail *t;", + "{ BFS_State *t;", "", " if (!bfs_trail)", " { return (Trail *) 0;", @@ -1188,19 +1132,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 +1164,65 @@ " 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", + " #ifdef CHECK", " printf(\"POP %%u (depth %%d, nr %%d)\\n\", t->frame, t->frame->o_tt, t->nr);", - "#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 +1232,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 +1306,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 +1337,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 +1349,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 +1357,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 +1403,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 +1420,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 +1437,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 +1460,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, 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,56 +1504,56 @@ "", " 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", + " #endif", " printf(\"%%3d: proc %%d \", depth, II);", " printf(\"reverses %%d, %%d to %%d,\",", " t->forw, tt, t->st);", @@ -1606,24 +1561,22 @@ " 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 +1584,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 +1601,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", + " #ifdef DEBUG", " printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #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 +1666,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 +1704,7 @@ 0, }; -static char *Code2d[] = { +static const char *Code2d[] = { "clock_t start_time;", "#if NCORE>1", "clock_t crash_stamp;", @@ -1763,10 +1723,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 +1760,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 +1829,10 @@ "}", "#endif", "", + "#ifdef BFS_PAR", + "int ncores = 0;", + "#endif", + "", "void", "do_the_search(void)", "{ int i;", @@ -1874,11 +1847,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 +1868,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 +1910,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);", + " #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", "}", @@ -1967,34 +1948,34 @@ "#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 +1988,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 +2062,74 @@ " return res;", "}", "#endif", + "", + "#ifdef HAS_PRIORITY", + "int", + "highest_priority(int pid, Trans *t)", + "{ int i; uchar *othis = this;", + "", + "#ifdef VERI", + " if (pid == 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)", + "{", + " if (pid < 0 || pid >= (int) now._nr_pr)", + " return 0;", + " return ((P0 *)pptr(pid))->_priority;", + "}", + "int", + "set_priority(int pid, int pr)", + "{", + " 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 +2161,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 +2176,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 +2184,9 @@ "#if NCORE>1", " leave_critical(GLOBAL_LOCK);", "#endif", + "#ifdef BFS_PAR", + " x_critical(BFS_GLOB);", + "#endif", "}", "#ifdef SC", "void", @@ -2197,35 +2252,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", @@ -2259,6 +2285,35 @@ "{ 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", " #define FROM_P (BASE)", @@ -2382,34 +2437,50 @@ "#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 (fairness && now._cnt[1] != 1) /* was > 1 */", + " {", + " #ifdef CHECK", + " printf(\"\tfairness count non-zero\\n\");", + " #endif", + " /* treat as new state */", + " } else", + " { 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();", - " }", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", "#endif", - " goto Up;", + " 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 +2495,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,15 +2568,12 @@ /* 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", " {", " II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */", @@ -2534,7 +2602,7 @@ " 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", " printf(\"\tfairness count non-zero\\n\");", @@ -2615,7 +2683,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 +2709,10 @@ " if (HASH_NR != 0)", " { int oh = HASH_NR;", " HASH_NR = 0;", - " d_hash((char *) &now, vsize); /* set K1 */", + " d_hash((uchar *) &now, vsize); /* 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 +2721,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,26 +2758,26 @@ "#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;", " }", @@ -2776,7 +2844,7 @@ " continue;", " Cholds++;", " }", - "SelectIt: From = To = II; /* preselect process */", + " From = To = II; /* preselect process */", "#ifdef NIBIS", " t->om = 0;", "#endif", @@ -2978,9 +3046,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, t))", + " { continue;", + " }", + "#else", + " #ifdef HAS_PROVIDED", + " if (!provided(II, ot, tt, t))", + " { continue;", + " }", + " #endif", "#endif", + " /* check all trans of proc II - escapes first */", "#ifdef HAS_UNLESS", " trpt->e_state = 0;", @@ -3275,7 +3353,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) */", @@ -3464,12 +3542,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 */", @@ -3602,9 +3676,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 +3702,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 +3712,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", @@ -3733,7 +3803,7 @@ " onstack_zap();", "#ifndef NOREDUCE", " if (trpt->proviso)", - " gstore((char *) &now, vsize, 1);", + " g_store((char *) &now, vsize, 1);", "#endif", " }", "#endif", @@ -3823,18 +3893,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 +3926,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 +3955,11 @@ " (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)(((unsigned long)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", "#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 +3971,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 +3995,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(\" + Seperate 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,7 +4018,7 @@ " }", "#endif", "#ifdef BFS", - " printf(\" + Using Breadth-First Search\\n\");", + " printf(\" + Breadth-First Search\\n\");", "#endif", "#ifndef NOREDUCE", " printf(\" + Partial Order Reduction\\n\");", @@ -3934,9 +4026,8 @@ "#ifdef 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", @@ -4013,7 +4104,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 +4158,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 +4167,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 +4273,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 +4296,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 +4357,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 +4375,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 +4427,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 +4473,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 +4489,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 +4500,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,28 +4537,24 @@ " 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", + "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;", @@ -4491,30 +4603,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 +4636,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", + "", "int", "main(int argc, char *argv[])", "{ void to_compile(void);\n", " efd = stderr; /* default */", + "#if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + " uchar used_w = 0;", + "#endif", "", " if (G_long != sizeof(long)", " || G_int != sizeof(int))", @@ -4600,7 +4726,7 @@ "#endif", "", "#ifdef BITSTATE", - " bstore = bstore_reg; /* default */", + " b_store = bstore_reg; /* default */", "#endif", "#if NCORE>1", " { int i, j;", @@ -4617,19 +4743,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,7 +4781,9 @@ " 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;", @@ -4672,7 +4812,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,36 +4825,52 @@ " break;", "#endif", " case 'm': maxdepth = atoi(&argv[1][2]); break;", -"#ifndef NOCLAIM", + "#ifndef NOCLAIM", " case 'N':", - "#if NCLAIMS>1", - " if (isdigit(argv[1][2]))", + " #if NCLAIMS>1", + " if (isdigit((int)argv[1][2]))", " whichclaim = atoi(&argv[1][2]);", - " else if (isalpha(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 (argv[1][2] == '_')", + " { permuted = 1;", + " printf(\"pan: reversed active process creation\\n\");", + " break;", + " }", + "#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, \"option -P not recognized, ignored\\n\");", + " #endif", + "#else", + " fprintf(efd, \"option -P not recognized, ignored\\n\");", + "#endif", " break;", + "", "#ifdef SVDUMP", " case 'p': vprefix = atoi(&argv[1][2]); break;", "#endif", @@ -4736,9 +4892,10 @@ " }", " break;", "#ifdef HAS_CODE", + " #if HAS_CODE>0", " case 'r':", "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,16 +4903,33 @@ " }", " break;", " case 'S': silent = 1; goto samething;", + " #endif", "#endif", "#ifdef BITSTATE", " case 's': hfns = 1; break;", "#endif", - " case 'T': TMODE = 0444; break;", + " case 'T':", + " if (argv[1][2] == '_')", + " { t_reverse = 1;", + " printf(\"pan: reverse transition mode\\n\");", + " } else", + " { TMODE = 0444;", + " }", + " break;", " case 't': 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;", @@ -4782,21 +4956,63 @@ " }", " argc--; argv++;", " }", + "", + "#if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + " if (used_w == 0)", + " { if (ncores == 0) /* all cores used, by default */", + " { ssize -= blog2(BFS_MAXPROCS - 1);", + " } else", + " { ssize -= blog2(ncores);", + " } }", + "#endif", + "", + "#ifndef SAFETY", + " if (fairness && !a_cycles)", + " { fprintf(efd, \"error: -f requires the use of -a or -l\\n\");", + " usage(efd);", + " }", + " #if ACCEPT_LAB==0", + " if (a_cycles)", + " { fprintf(efd, \"warning: no accept labels are defined, \");", + " fprintf(efd, \"so option -a has no effect (ignored)\\n\");", + " a_cycles = 0;", + " }", + " #endif", + "#endif", + "", + "#ifdef BFS_PAR", + " uerror = bfs_uerror;", + " Uerror = bfs_Uerror;", + "#else", + " uerror = dfs_uerror;", + " Uerror = dfs_Uerror;", + "#endif", + " if (ssize <= 32) /* 6.2.0 */", + " { hasher = d_sfh;", + "#if !defined(BITSTATE) && defined(USE_TDH)", + " o_hash = o_hash32;", + "#endif", + " } else", + " { hasher = d_hash;", + "#if !defined(BITSTATE) && defined(USE_TDH)", + " o_hash = o_hash64;", + "#endif", + " }", " if (iterative && TMODE != 0666)", " { TMODE = 0666;", " fprintf(efd, \"warning: -T ignored when -i or -I is used\\n\");", " }", - "#if defined(HASH32) && !defined(SFH)", - " if (WS > 4)", - " { fprintf(efd, \"strong warning: compiling -DHASH32 on a 64-bit machine\\n\");", - " fprintf(efd, \" without -DSFH can slow down performance a lot\\n\");", - " }", - "#endif", "#if defined(WIN32) || defined(WIN64)", + " #ifndef _S_IWRITE", + " #define S_IWRITE 0000200 /* write permission, owner */", + " #endif", + " #ifndef _S_IREAD", + " #define S_IREAD 0000400 /* read permission, owner */", + " #endif", " if (TMODE == 0666)", - " TMODE = _S_IWRITE | _S_IREAD;", + " TMODE = S_IWRITE | S_IREAD;", " else", - " TMODE = _S_IREAD;", + " TMODE = S_IREAD;", "#endif", "#if NCORE>1", " store_proxy_pid = proxy_pid; /* for checks in mem_file() and someone_crashed() */", @@ -4904,6 +5120,16 @@ " #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 BCS", @@ -4918,14 +5144,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 +5167,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);", @@ -4986,21 +5202,17 @@ " { 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 +5237,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 +5269,7 @@ " fprintf(efd, \"requires -a flag to fully verify\\n\");", " }", " #else", - " if (!state_tables", + " if (verbose && !state_tables", " #ifdef HAS_CODE", " && !readtrail", " #endif", @@ -5095,13 +5308,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];", @@ -5223,7 +5440,7 @@ "}", "", "char *", - "Malloc(unsigned long n)", + "Malloc(ulong n)", "{ char *tmp;", "#ifdef MEMLIM", " if (memcnt + (double) n > memlim)", @@ -5233,7 +5450,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 +5498,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 +5529,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)", @@ -5333,8 +5557,13 @@ "#endif", "#ifdef VERBOSE", " printf(\"%%d 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 +5580,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); */", @@ -5419,7 +5648,7 @@ "#endif", "static char unwinding;", "void", - "uerror(char *str)", + "dfs_uerror(char *str)", "{ static char laststr[256];", " int is_cycle;", "", @@ -5433,7 +5662,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 +5689,7 @@ "#endif", "#ifdef BFS", " if (depth > 1) trpt--;", - " nuerror(str);", + " nuerror();", " if (depth > 1) trpt++;", "#else", " putrail();", @@ -5494,6 +5723,9 @@ "#endif", " if (errors >= upto && upto != 0)", " {", + "#ifdef BFS_PAR", + " bfs_shutdown(\"uerror\"); /* no return */", + "#endif", "#if NCORE>1", " sudden_stop(\"uerror\");", "#endif", @@ -5706,11 +5938,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 +5976,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 +5992,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 +6038,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 +6054,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 +6184,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 +6248,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 +6290,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 +6298,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 +6355,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 unsigned char *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 +6497,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 +6520,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 +6537,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 +6630,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 +6642,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 +6685,7 @@ " return v - (char *)&comp_now;", "}", -"#else", +"#else", /* !COLLAPSE */ "#if !defined(NOCOMP)", "int", "compress(char *vin, int n) /* default compression */", @@ -6439,9 +6739,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 +6771,7 @@ "#endif", "}", "#endif", -"#endif", +"#endif", /* COLLAPSE */ "#if defined(FULLSTACK) && defined(BITSTATE)", "#if defined(MA)", "#if !defined(onstack_now)", @@ -6488,8 +6786,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 +6839,7 @@ "#if !defined(NOREDUCE) && !defined(SAFETY)", " v->proviso = 0;", "#endif", - " v->nxt = last = (struct H_el *) 0;", + " v->nxt = last = (H_el *) 0;", " for (w = Free_list; w; Fa++, last=w, w = w->nxt)", " { if ((int) w->tagged <= n)", " { if (last)", @@ -6564,100 +6862,148 @@ "#endif", " return;", "}", + "", + "#ifndef BFS_PAR", + " void", + " onstack_put(void)", + " { H_el **tmp = H_tab;", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " uchar was_last = now._last;", + " now._last = 0;", + " #endif", + " H_tab = S_Tab;", + " if (h_store((char *)&now, vsize) != 0)", + " #if defined(BITSTATE) && defined(LC)", + " printf(\"pan: warning, double stack entry\\n\");", + " #else", + " #ifndef ZAPH", + " Uerror(\"cannot happen - unstack_put\");", + " #endif", + " #endif", + " H_tab = tmp;", + " trpt->ostate = Lstate;", + " PUT++;", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " now._last = was_last;", + " #endif", + " }", + " int", + " onstack_now(void)", + " { H_el *tmp;", + " H_el **tmp2 = H_tab;", + " char *v; int n, m = 1;\n", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " uchar was_last = now._last;", + " now._last = 0;", + " #endif", + " H_tab = S_Tab;", + " #ifdef NOCOMP", + " #if defined(BITSTATE) && defined(LC)", + " v = (char *) &comp_now;", + " n = compact_stack((char *)&now, vsize);", + " #else", + " v = (char *) &now;", + " n = vsize;", + " #endif", + " #else", + " v = (char *) &comp_now;", + " n = compress((char *)&now, vsize);", + " #endif", + " #if !defined(HC) && !(defined(BITSTATE) && defined(LC))", + " s_hash((uchar *)v, n);", + " #endif", + " H_tab = tmp2;", + " for (tmp = S_Tab[j1_spin]; tmp; Zn++, tmp = tmp->nxt)", + " { m = memcmp(((char *)&(tmp->state)),v,n);", + " if (m <= 0)", + " { Lstate = (H_el *) tmp; /* onstack_now */", + " break;", + " } }", + " PROBE++;", + " #if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " now._last = was_last;", + " #endif", + " return (m == 0);", + " }", + "#endif", /* !BFS_PAR */ +"#endif", /* !MA */ + "#endif", /* FULLSTACK && BITSTATE */ + + "#ifdef BITSTATE", + "void init_SS(ulong);", + "", "void", - "onstack_put(void)", - "{ struct H_el **tmp = H_tab;", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " uchar was_last = now._last;", - " now._last = 0;", - "#endif", - " H_tab = S_Tab;", - " if (hstore((char *)&now, vsize) != 0)", - "#if defined(BITSTATE) && defined(LC)", - " printf(\"pan: warning, double stack entry\\n\");", - "#else", - " #ifndef ZAPH", - " Uerror(\"cannot happen - unstack_put\");", + "sinit(void)", + "{", + " if (udmem)", + " { udmem *= 1024L*1024L;", + " #if NCORE>1", + " if (!readtrail)", + " { init_SS((ulong) udmem);", + " } else", " #endif", - "#endif", - " H_tab = tmp;", - " trpt->ostate = Lstate;", - " PUT++;", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " now._last = was_last;", - "#endif", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " SS = (uchar *) sh_pre_malloc((ulong) udmem);", + " #else", + " SS = (uchar *) emalloc(udmem);", + " #endif", + " b_store = bstore_mod;", + " } else", + " {", + " #if NCORE>1", + " init_SS(ONE_L<<(ssize-3));", + " #else", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " SS = (uchar *) sh_pre_malloc((ulong)(ONE_L<<(ssize-3)));", + " #else", + " SS = (uchar *) emalloc(ONE_L<<(ssize-3));", + " #endif", + " #endif", + " }", "}", - "int", - "onstack_now(void)", - "{ struct H_el *tmp;", - " struct H_el **tmp2 = H_tab;", - " char *v; int n, m = 1;\n", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " uchar was_last = now._last;", - " now._last = 0;", - "#endif", - " H_tab = S_Tab;", - "#ifdef NOCOMP", - "#if defined(BITSTATE) && defined(LC)", - " v = (char *) &comp_now;", - " n = compact_stack((char *)&now, vsize);", - "#else", - " v = (char *) &now;", - " n = vsize;", - "#endif", "#else", - " v = (char *) &comp_now;", - " n = compress((char *)&now, vsize);", - "#endif", - "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", - " s_hash((uchar *)v, n);", - "#endif", - " H_tab = tmp2;", - " for (tmp = S_Tab[j1_spin]; tmp; Zn++, tmp = tmp->nxt)", - " { m = memcmp(((char *)&(tmp->state)),v,n);", - " if (m <= 0)", - " { Lstate = (struct H_el *) tmp;", - " break;", - " } }", - " PROBE++;", - "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", - " now._last = was_last;", - "#endif", - " return (m == 0);", - "}", - "#endif", -"#endif", - - "#ifndef BITSTATE", + " #if !defined(MA) || defined(COLLAPSE)", + " void", + " set_H_tab(void)", + " {", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " H_tab = (H_el **) sh_pre_malloc((ulong)((ONE_L<1 && !defined(COLLAPSE)", - " if (!readtrail)", - " { void init_HT(unsigned long);", - " init_HT(0L);", - " }", - "#endif", - "#endif", - " #endif", - " #if !defined(MA) || defined(COLLAPSE)", - "#if NCORE>1", - " if (!readtrail)", - " { void init_HT(unsigned long);", - " init_HT((unsigned long) (ONE_L<1 && !defined(COLLAPSE)", + " if (!readtrail)", + " { void init_HT(ulong);", + " init_HT(0L);", + " }", + " #endif", + " #endif", + " #endif", + " #if !defined(MA) || defined(COLLAPSE)", + " #if NCORE>1 || (defined(BFS_PAR) && defined(USE_TDH) && !defined(WIN32) && !defined(WIN64))", + " if (!readtrail)", + " { void init_HT(ulong);", + " init_HT((ulong) (ONE_L<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 +7129,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 +7167,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 +7196,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 +7220,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 +7255,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 +7278,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 +7300,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 +7325,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++;", @@ -7013,17 +7374,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 +7391,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 +7443,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", @@ -7129,6 +7501,9 @@ " 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", @@ -7143,6 +7518,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 +7528,7 @@ " }", " #endif", "#endif", - "#ifdef REACH", + " #ifdef REACH", " if (tmp->D > depth)", " { tmp->D = depth;", " #ifdef CHECK", @@ -7160,6 +7538,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 +7559,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 +7581,7 @@ " #endif", " return 1; /* allow normal termination */", " }", - "#endif", + " #endif", " ntmp->nxt = tmp;", " if (!olst)", " H_tab[j1_spin] = ntmp;", @@ -7207,11 +7591,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,33 +7603,32 @@ " #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 */", " #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", @@ -7261,40 +7644,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 - 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);", + " 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, }; --- /sys/src/cmd/spin/pangen2.c Sun Sep 15 19:40:31 2013 +++ /sys/src/cmd/spin/pangen2.c Sun Sep 15 19:40:15 2013 @@ -16,6 +16,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,13 +27,16 @@ 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; + extern short has_stack; extern char *NextLab[]; @@ -44,6 +48,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() */ @@ -55,6 +60,7 @@ 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 */ @@ -78,7 +84,6 @@ static short _isok=0; /* checks usage of predefined variable _ */ int has_global(Lextok *); -void Fatal(char *, char *); static int getweight(Lextok *); static int scan_seq(Sequence *); static void genconditionals(void); @@ -89,6 +94,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; @@ -134,21 +162,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 +215,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 +230,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, "#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 +327,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 +360,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 +396,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) @@ -363,8 +445,8 @@ 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 +462,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"); @@ -440,7 +535,11 @@ fprintf(tm, "#define rand pan_rand\n"); fprintf(tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); - fprintf(tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(tm, " #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 @@ -488,24 +587,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, " { %d, &src_ln%d[0] },\n", + 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(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(); @@ -554,10 +672,6 @@ 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); } @@ -568,14 +682,15 @@ 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 +722,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 +949,9 @@ fprintf(tc, "}\n"); } +extern int find_min(Sequence *); +extern int find_max(Sequence *); + static void putproc(ProcList *p) { Pid = p->tn; @@ -835,6 +984,12 @@ 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); @@ -1268,6 +1423,7 @@ switch (e->n->ntyp) { case ASGN: + if (check_track(e->n) == STRUCT) { break; } nr++; break; case 'r': @@ -1579,26 +1735,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 */ @@ -1863,7 +2019,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 +2239,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 +2268,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 +2290,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 @@ -2173,6 +2338,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 +2380,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,8 +2396,7 @@ 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)); for (v = now->lft, i = 0; v; v = v->rgt, i++) @@ -2246,12 +2411,38 @@ for ( ; i < Npars; i++) fprintf(fd, ", 0"); fprintf(fd, ")"); + + /* 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); + } + 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, "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 +2560,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 +2743,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 +2762,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"); @@ -2623,12 +2816,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 +3009,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,10 +3022,17 @@ 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--; @@ -2853,8 +3055,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 +3069,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 +3092,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 +3110,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 +3127,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 +3150,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"); } @@ -3005,19 +3207,25 @@ 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); + } } } ptr = s->name; @@ -3090,7 +3298,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 +3314,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; --- /sys/src/cmd/spin/pangen2.h Sun Sep 15 19:40:49 2013 +++ /sys/src/cmd/spin/pangen2.h Sun Sep 15 19:40:40 2013 @@ -10,10 +10,10 @@ /* 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", +static const char *Pre0[] = { + "#ifdef SC", + " #define _FILE_OFFSET_BITS 64", /* allows file sizes greater than 2Gb */ + "#endif", "#include ", "#include ", "#include ", @@ -29,9 +29,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 +42,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 +121,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 +132,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;", @@ -260,7 +173,7 @@ "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[] = {", @@ -349,17 +262,25 @@ "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 T_REVERSE", + " int t_reverse = 1;", + "#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 +291,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 +312,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,32 +325,40 @@ " 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;", + "static 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;", + "uchar warned = 0, iterative = 0, exclusive = 0, like_java = 0, every_error = 0;", + "uchar noasserts = 0, noends = 0, bounded = 0;", "#if defined(T_RAND) || defined(P_RAND) || defined(RANDSTOR)", "unsigned int s_rand = 123; /* default seed */", @@ -447,10 +376,26 @@ "#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 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 +408,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 +513,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", @@ -871,11 +820,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 +839,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 +859,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 +876,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 +899,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 +937,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 +956,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);", "}", --- /sys/src/cmd/spin/pangen3.c Sun Sep 15 19:40:55 2013 +++ /sys/src/cmd/spin/pangen3.c Sun Sep 15 19:40:51 2013 @@ -12,8 +12,8 @@ #include "spin.h" #include "y.tab.h" -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 +36,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 +49,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,7 +61,7 @@ putfnm_flush(int j) { if (lastfnm) - fprintf(th, "{ \"%s\", %d, %d }\n", + fprintf(tc, "{ \"%s\", %d, %d }\n", /* was th */ lastfnm->name, lastfrom, j); } @@ -121,9 +121,10 @@ 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); for (j = 0, col = 0; j <= n; j++) { lst = (SRC *) 0; for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) @@ -138,9 +139,8 @@ if (!tmp) putnr(0); } - fprintf(th, "};\n"); - - fprintf(th, "uchar *loopstate%d;\n", m); + fprintf(tz, "};\n"); + fprintf(tz, "uchar *loopstate%d;\n", m); if (m == eventmapnr) fprintf(th, "#define reached_event reached%d\n", m); @@ -153,11 +153,11 @@ { 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); for (j = 0, col = 0; j <= n; j++) - { lst = (SRC *) 0; - for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) + { for (tmp = frst; tmp; tmp = tmp->nxt) if (tmp->st == j) { putnr(tmp->ln); break; @@ -165,11 +165,11 @@ if (!tmp) putnr(0); } - fprintf(th, "};\n"); + 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); for (j = 0, col = 0; j <= n; j++) { lst = (SRC *) 0; for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) @@ -185,10 +185,10 @@ 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 +324,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,7 +362,9 @@ } 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; @@ -379,7 +397,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, "["); --- /sys/src/cmd/spin/pangen3.h Sun Sep 15 19:41:07 2013 +++ /sys/src/cmd/spin/pangen3.h Sun Sep 15 19:40:59 2013 @@ -10,7 +10,7 @@ /* 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 *Head0[] = { +static const char *Head0[] = { "#if defined(BFS) && defined(REACH)", " #undef REACH", /* redundant with bfs */ "#endif", @@ -66,10 +66,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 +86,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 +130,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 +177,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 +211,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 +236,7 @@ 0, }; -static char *Addp0[] = { +static const char *Addp0[] = { /* addproc(....parlist... */ ")", "{ int j, h = now._nr_pr;", "#ifndef NOCOMP", @@ -289,18 +261,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 +335,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);", @@ -382,7 +360,8 @@ 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 +377,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 +402,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 +441,7 @@ 0, }; -static char *Addq11[] = { +static const char *Addq11[] = { "{ int j; uchar *z;\n", "#ifdef HAS_SORTED", " int k;", @@ -484,7 +469,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 +490,7 @@ 0, }; -static char *Addq3[] = { +static const char *Addq3[] = { " case 0: printf(\"queue %%d was deleted\\n\", from+1);", " }", " Uerror(\"bad queue q-zero\");", @@ -605,7 +590,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 +634,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 +642,7 @@ "}", "#endif\n", "#ifndef BITSTATE", - "#ifdef COLLAPSE", + " #ifdef COLLAPSE", "long", "col_q(int i, char *z)", "{ int j=0, k;", @@ -667,19 +652,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,7 +677,7 @@ 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);", @@ -701,19 +686,21 @@ " 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;", 0, }; -static char *R0a[] = { +static const char *R00[] = { + " NrStates[%d] = nstates%d;", + 0, +}; + +static const char *R0a[] = { " retrans(%d, nstates%d, start%d, src_ln%d, reached%d, loopstate%d);", 0, }; -static char *Code1[] = { +static const char *Code1[] = { "#ifdef NP", " #define ACCEPT_LAB 1 /* at least 1 in np_ */", "#else", @@ -749,12 +736,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 +754,19 @@ "#endif", 0, }; -static char *R3[] = { +static const char *R3[] = { " Maxbody = max(Maxbody, ((int) sizeof(Q%d)));", 0, }; -static char *R4[] = { +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 +787,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 +948,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 +977,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 +1010,7 @@ " switch (((Q0 *)qptr(into))->_t) {", 0, }; -char *R14[] = { +const char *R14[] = { " default: Uerror(\"bad queue - unsend\");", " }", " return _m;", @@ -912,17 +1040,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 +1064,8 @@ #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 q_cond(short, Trans *);", "int q_full(int);", "int q_len(int);", @@ -947,24 +1073,32 @@ "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 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 +1106,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,10 +1132,233 @@ " 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", + "", + "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)", + " 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 */ + " #if !defined(NOREDUCE) || !defined(BFS_PAR)", + " #define Q_PROVISO", + " #endif", + " #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", + " #ifdef Q_PROVISO", + " 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];", @@ -1007,15 +1367,18 @@ "#else", " strcpy(ctd, \"\");", "#endif", + "#ifdef BFS_PAR", + " strcat(ctd, \"-DBFS_PAR \");", + "#endif", "#ifdef NOVSZ", " strcat(ctd, \"-DNOVSZ \");", "#endif", "#ifdef REVERSE", " strcat(ctd, \"-DREVERSE \");", "#endif", - "#ifdef T_REVERSE", - " strcat(ctd, \"-DT_REVERSE \");", - "#endif", + " if (t_reverse)", + " { strcat(ctd, \"-DT_REVERSE \");", + " }", "#ifdef T_RAND", " #if T_RAND>0", " sprintf(carg, \"-DT_RAND=%%d \", T_RAND);", @@ -1081,20 +1444,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 +1471,6 @@ "#ifdef PRINTF", " strcat(ctd, \"-DPRINTF \");", "#endif", - "#ifdef OTIM", - " strcat(ctd, \"-DOTIM \");", - "#endif", "#ifdef COLLAPSE", " strcat(ctd, \"-DCOLLAPSE \");", "#endif", @@ -1150,10 +1498,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", --- /sys/src/cmd/spin/pangen4.c Sun Sep 15 19:41:14 2013 +++ /sys/src/cmd/spin/pangen4.c Sun Sep 15 19:41:10 2013 @@ -17,7 +17,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 +44,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 +153,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 +326,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 +338,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 +348,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; } --- /sys/src/cmd/spin/pangen4.h Sun Sep 15 19:41:23 2013 +++ /sys/src/cmd/spin/pangen4.h Sun Sep 15 19:41:17 2013 @@ -17,8 +17,9 @@ /* 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 +27,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 +468,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);", "}", "", --- /sys/src/cmd/spin/pangen5.c Sun Sep 15 19:41:34 2013 +++ /sys/src/cmd/spin/pangen5.c Sun Sep 15 19:41:27 2013 @@ -324,14 +324,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 +537,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 +594,16 @@ case C_EXPR: break; + case ',': /* only reached with SET_P */ + ana_stmnt(t, now->lft->rgt, RVAL); + break; + case '!': case UMIN: case '~': case ENABLED: + case SET_P: + case GET_P: case PC_VAL: case LEN: case FULL: @@ -628,6 +638,8 @@ break; case ASGN: + if (check_track(now) == STRUCT) { break; } + ana_stmnt(t, now->lft, LVAL); ana_stmnt(t, now->rgt, RVAL); break; @@ -830,9 +842,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; --- /sys/src/cmd/spin/pangen5.h Sun Sep 15 19:41:43 2013 +++ /sys/src/cmd/spin/pangen5.h Sun Sep 15 19:41:38 2013 @@ -9,7 +9,7 @@ /* http://spinroot.com/ */ /* Send all bug-reports and/or questions to: bugs@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];", --- /sys/src/cmd/spin/pangen6.c Sun Sep 15 19:41:59 2013 +++ /sys/src/cmd/spin/pangen6.c Sun Sep 15 19:41:48 2013 @@ -201,6 +201,8 @@ case '~': case 'c': case ENABLED: + case SET_P: + case GET_P: case ASSERT: case EVAL: def_use(now->lft, USE|code); @@ -1060,6 +1062,8 @@ case '~': case 'c': case ENABLED: + case SET_P: + case GET_P: case ASSERT: AST_track(now->lft, USE|code); break; --- /sys/src/cmd/spin/pangen6.h Sun Sep 15 19:42:28 2013 +++ /sys/src/cmd/spin/pangen6.h Sun Sep 15 19:42:10 2013 @@ -14,7 +14,80 @@ /* http://spinroot.com/ */ /* Bug-reports and/or questions can be send to: bugs@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;", + " }", + " #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", @@ -122,7 +195,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 +331,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 +491,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 +511,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 +519,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 +530,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 +668,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 */", @@ -1002,7 +1074,7 @@ " #endif", "", " #ifndef BITSTATE", - " H_tab = (struct H_el **) emalloc(n);", + " H_tab = (H_el **) emalloc(n);", " #endif", "#else", " #ifndef MEMLIM", @@ -1016,7 +1088,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.)", @@ -1150,58 +1222,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 +1295,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 +1411,7 @@ "int unpack_state(SM_frame *, int);", "#endif", "", - "struct H_el *", + "H_el *", "grab_shared(int n)", "{", "#ifndef SEP_STATE", @@ -1399,7 +1419,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 +1484,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 +1606,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 +1617,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 +2102,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 +2224,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 +2605,7 @@ " #endif", "", " #ifndef BITSTATE", - " H_tab = (struct H_el **) emalloc(n);", + " H_tab = (H_el **) emalloc(n);", " #endif", "#else", " #ifndef MEMLIM", @@ -2594,7 +2618,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 +2761,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", --- /sys/src/cmd/spin/pangen7.c Sun Sep 15 19:42:39 2013 +++ /sys/src/cmd/spin/pangen7.c Sun Sep 15 19:42:32 2013 @@ -55,21 +55,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 +151,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 +185,7 @@ static void pop_dsts(void) { - assert(dsts); + assert(dsts != NULL); dsts = dsts->nxt; } @@ -249,7 +249,7 @@ y = push_dsts(s->combo); if (!y) { if (once++ == 0) - { assert(s->succ); + { assert(s->succ != NULL); state_body(s, guard); } pop_dsts(); @@ -499,7 +499,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; } --- /sys/src/cmd/spin/pangen7.h Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/spin/pangen7.h Sun Sep 15 19:42:45 2013 @@ -0,0 +1,2339 @@ +/***** spin: pangen1.h *****/ + +/* Copyright (c) 2011-2012 */ +/* 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 */ + +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_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", + "", + " volatile BFS_Slot *head[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];", + "#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 };", + "", + "struct BFS_Slot {", + " #ifdef BFS_FIFO", + " enum bfs_types type; /* message type */", + " #endif", + " BFS_State *s_data; /* state data */", + " BFS_Slot *nxt; /* linked list */", + "};", + "", + "extern volatile uchar *bfs_get_shared_mem(key_t, size_t);", + "extern BFS_Slot * bfs_new_slot(BFS_Trail *);", + "extern BFS_Slot * bfs_next(void);", + "extern BFS_Slot * bfs_pack_state(Trail *, BFS_Trail *, int);", + "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 parallize 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;", + "static BFS_Slot *bfs_free_slot; /* local free list */", + "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(321);", + " 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, 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", + "}", + "#ifndef BFS_FIFO", + "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", + "", + "#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", + "", + "void", + "bfs_push_state(Trail *x, BFS_Trail *y, int tt)", + "{ int who_are_you;", + " BFS_Slot *n = bfs_pack_state(x, y, tt);", + "#ifdef BFS_FIFO", + " const int dst = 0;", + "#else", + " int dst = 1 - bfs_toggle;", + "#endif", + "", + "#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", + "#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;", + " while (bfs_qscan < Cores", + " && shared_memory->head[src][who_am_i][bfs_qscan] == (BFS_Slot *) 0)", + " { bfs_qscan++;", + " }", + " #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", + " 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;", + + " #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", + " {", + " #ifdef BFS_STAGGER", + " 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++)", + " { if (shared_memory->head[dst][p][i] != (BFS_Slot *) 0)", + " { 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", + "", + "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;", + "}", + "", + "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 = bfs_new_slot(g);", + "", + "#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)", + " 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, +}; --- /sys/src/cmd/spin/ps_msc.c Sun Sep 15 19:42:55 2013 +++ /sys/src/cmd/spin/ps_msc.c Sun Sep 15 19:42:47 2013 @@ -19,7 +19,7 @@ /* extern void free(void *); */ -static char *PsPre[] = { +static const char *PsPre[] = { "%%%%Pages: (atend)", "%%%%PageOrder: Ascend", "%%%%DocumentData: Clean7Bit", --- /sys/src/cmd/spin/reprosrc.c Sun Sep 15 19:43:01 2013 +++ /sys/src/cmd/spin/reprosrc.c Sun Sep 15 19:42:58 2013 @@ -15,6 +15,7 @@ static int indent = 1; +extern YYSTYPE yylval; extern ProcList *rdy; void repro_seq(Sequence *); @@ -133,4 +134,252 @@ 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); + 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); } --- /sys/src/cmd/spin/run.c Sun Sep 15 19:43:10 2013 +++ /sys/src/cmd/spin/run.c Sun Sep 15 19:43:06 2013 @@ -18,13 +18,15 @@ extern Element *LastStep; extern int Rvous, lineno, Tval, interactive, MadeChoice; 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; 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 @@ -281,10 +283,13 @@ } 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; @@ -398,6 +403,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 +420,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); @@ -542,6 +553,7 @@ verbose = v; return i; + case SET_P: case C_CODE: case C_EXPR: case PRINT: case PRINTM: case ASGN: case ASSERT: @@ -582,6 +594,7 @@ case '@': return X->pid == (nproc-nstop-1); case '.': + case SET_P: return 1; case GOTO: if (Rvous) return 0; @@ -624,10 +637,76 @@ 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; + int pid = eval(n); + RunList *Y; + + if (!old_priority_rules) + for (Y = run; Y; Y = Y->nxt) + { if (--i == pid) + { Y->priority = eval(p); + } } +} --- /sys/src/cmd/spin/sched.c Sun Sep 15 19:43:22 2013 +++ /sys/src/cmd/spin/sched.c Sun Sep 15 19:43:14 2013 @@ -19,8 +19,11 @@ 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; +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; @@ -44,11 +47,15 @@ r->tn = p->tn; r->b = p->b; r->pid = nproc++ - nstop + Skip_claim; + r->priority = weight; + p->priority = 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 +68,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; @@ -81,6 +90,8 @@ r->b = b; r->prov = prov; r->tn = 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"); } @@ -345,6 +356,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; @@ -378,8 +407,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,7 +540,7 @@ } } 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:"--"); } } @@ -583,9 +611,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"); @@ -653,13 +681,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 +738,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(" ["); --- /sys/src/cmd/spin/spin.h Sun Sep 15 19:43:33 2013 +++ /sys/src/cmd/spin/spin.h Sun Sep 15 19:43:25 2013 @@ -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,6 +193,7 @@ 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; @@ -244,6 +252,7 @@ Element *get_lab(Lextok *, int); Element *huntele(Element *, int, int); Element *huntstart(Element *); +Element *mk_skip(void); Element *target(Element *); Lextok *do_unless(Lextok *, Lextok *); @@ -254,6 +263,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); @@ -274,6 +284,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); @@ -367,16 +378,17 @@ 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 +409,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 *); --- /sys/src/cmd/spin/spin.y Sun Sep 15 19:43:47 2013 +++ /sys/src/cmd/spin/spin.y Sun Sep 15 19:43:40 2013 @@ -19,7 +19,7 @@ #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,10 +30,11 @@ 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 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 *); @@ -54,11 +55,11 @@ %} -%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 @@ -156,7 +157,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 +186,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; } ; @@ -390,31 +391,42 @@ ivar : vardcl { $$ = $1; $1->sym->ini = nn(ZN,CONST,ZN,ZN); $1->sym->ini->val = 0; + if (!initialization_ok) + { Lextok *zx, *xz; + zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + xz = nn(zx, ASGN, zx, $1->sym->ini); + keep_track_off(xz); + /* make sure zx doesnt turn out to be a STRUCT later */ + add_seq(xz); + } } | vardcl ASGN expr { $$ = $1; $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); + 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 @@ -436,7 +448,7 @@ } $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; } ; varref : cmpnd { $$ = mk_explicit($1, Expand_Ok, NAME); } @@ -475,13 +487,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 '(' { in_for = 1; } + varref { trapwonly($4 /*, "for" */); + pushbreak(); /* moved up */ + $$ = $4; + } ; for_post: '{' sequence OS '}' ; @@ -500,13 +514,14 @@ | for_pre ':' expr DOTDOT expr ')' { 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_post { $$ = for_body($5, 1); + for_post { $$ = for_body($5, 1); } | SELECT '(' varref ':' expr DOTDOT expr ')' { + trapwonly($3 /*, "select" */); $$ = sel_index($3, $5, $7); } | IF options FI { $$ = nn($1, IF, ZN, ZN); @@ -537,6 +552,16 @@ } $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; + } ; Stmnt : varref ASGN full_expr { $$ = nn($1, ASGN, $1, $3); @@ -560,6 +585,7 @@ if ($1->sym->type == CHAN) fatal("arithmetic on chan id's", (char *)0); } + | SET_P '(' two_args ')' { $$ = nn(ZN, SET_P, $3, ZN); has_priority++; } | PRINT '(' STRING { realread = 0; } prargs ')' { $$ = nn($3, PRINT, $5, ZN); realread = 1; } | PRINTM '(' varref ')' { $$ = nn(ZN, PRINTM, $3, ZN); } @@ -612,8 +638,19 @@ $$->sl = seqlist(close_seq(5), 0); } | INAME { IArgs++; } - '(' args ')' { pickup_inline($1->sym, $4); IArgs--; } + '(' args ')' { initialization_ok = 0; + pickup_inline($1->sym, $4, ZN); + IArgs--; + } Stmnt { $$ = $7; } + + | varref ASGN INAME { IArgs++; } + '(' args ')' { 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); } @@ -629,14 +666,28 @@ | SEMI { /* redundant semi at end of sequence */ } ; -MS : SEMI { /* at least one semi-colon */ } - | MS SEMI { /* but more are okay too */ } +semi : SEMI + | ARROW + ; + +MS : semi { /* at least one semi-colon */ } + | MS semi { /* but more are okay too */ } ; aname : NAME { $$ = $1; } | PNAME { $$ = $1; } ; +const_expr: CONST { $$ = $1; } + | '-' const_expr %prec UMIN { $$ = $2; $$->val = -($2->val); } + | '(' const_expr ')' { $$ = $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 : '(' expr ')' { $$ = $2; } | expr '+' expr { $$ = nn(ZN, '+', $1, $3); } | expr '-' expr { $$ = nn(ZN, '-', $1, $3); } @@ -660,7 +711,7 @@ | '-' expr %prec UMIN { $$ = nn(ZN, UMIN, $2, ZN); } | SND expr %prec NEG { $$ = nn(ZN, '!', $2, ZN); } - | '(' expr SEMI expr ':' expr ')' { + | '(' expr ARROW expr ':' expr ')' { $$ = nn(ZN, OR, $4, $6); $$ = nn(ZN, '?', $2, $$); } @@ -673,13 +724,12 @@ '(' args ')' 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++; - } + | ENABLED '(' expr ')' { $$ = nn(ZN, ENABLED, $3, ZN); has_enabled++; } + | GET_P '(' expr ')' { $$ = nn(ZN, GET_P, $3, ZN); has_priority++; } | varref RCV { Expand_Ok++; } '[' rargs ']' { Expand_Ok--; has_io++; $$ = nn($1, 'R', $1, $5); @@ -712,7 +762,7 @@ ; Opt_priority: /* none */ { $$ = ZN; } - | PRIORITY CONST { $$ = $2; } + | PRIORITY CONST { $$ = $2; has_priority++; } ; full_expr: expr { $$ = $1; } @@ -780,6 +830,9 @@ | basetype ',' typ_list { $$ = nn($1, $1->val, ZN, $3); } ; +two_args: expr ',' expr { $$ = nn(ZN, ',', $1, $3); } + ; + args : /* empty */ { $$ = ZN; } | arg { $$ = $1; } ; @@ -906,7 +959,7 @@ ltl_to_string(Lextok *n) { Lextok *m = nn(ZN, 0, ZN, ZN); char *retval; - char formula[1024]; + char formula[2048]; FILE *tf = fopen(TMP_FILE, "w+"); /* tmpfile() fails on Windows 7 */ /* convert the parsed ltl to a string @@ -926,6 +979,7 @@ memset(formula, 0, sizeof(formula)); retval = fgets(formula, sizeof(formula), tf); fclose(tf); + (void) unlink(TMP_FILE); if (!retval) --- /sys/src/cmd/spin/spinlex.c Sun Sep 15 19:44:00 2013 +++ /sys/src/cmd/spin/spinlex.c Sun Sep 15 19:43:52 2013 @@ -10,6 +10,7 @@ /* Send all bug-reports and/or questions to: bugs@spinroot.com */ #include +#include #include "spin.h" #include "y.tab.h" @@ -21,6 +22,7 @@ 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 */ @@ -41,7 +43,7 @@ extern Symbol *Fname, *oFname; extern Symbol *context, *owner; extern YYSTYPE yylval; -extern short has_last, has_code; +extern short has_last, has_code, has_priority; extern int verbose, IArgs, hastrack, separate, ltl_mode; short has_stack = 0; @@ -111,8 +113,8 @@ ungetc(c,yyin); else uninline(); - if (0) - { printf(""); + if (1) + { printf("\n\n", c); } } #endif @@ -162,7 +164,8 @@ { int c; if ((c = Getchar()) == tok) - return ifyes; + { return ifyes; + } Ungetch(c); return ifno; @@ -264,6 +267,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 +292,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", @@ -359,21 +380,45 @@ } char * +skip_white(char *p) +{ + if (p != NULL) + { while (*p == ' ' || *p == '\t') + p++; + } else + { fatal("bad format - 1", (char *) 0); + } + return p; +} + +char * +skip_nonwhite(char *p) +{ + if (p != NULL) + { while (*p != ' ' && *p != '\t') + p++; + } else + { fatal("bad format - 2", (char *) 0); + } + return p; +} + +char * jump_etc(char *op) { char *p = op; - /* kludgy - try to get the type separated from the name */ + /* try to get the type separated from the name */ - 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 */ + 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); + } + 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); @@ -460,9 +505,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 +644,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 +655,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 +708,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 +753,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 @@ -823,9 +869,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 @@ -856,7 +904,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; } } ", @@ -908,7 +957,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 +966,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 */ @@ -943,6 +993,8 @@ fatal("cyclic inline attempt on: %s", t->name); } +extern int pp_mode; + static void do_directive(int first) { int c = first; /* handles lines starting with pound */ @@ -1133,6 +1185,21 @@ } 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; +} + +int lex(void) { int c; @@ -1153,6 +1220,9 @@ case '#': /* preprocessor directive */ if (in_comment) goto again; + if (pp_mode) + { return pre_proc(); + } do_directive(c); goto again; @@ -1188,8 +1258,15 @@ } 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 == '_') @@ -1230,7 +1307,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; @@ -1294,6 +1371,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 +1397,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}, @@ -1364,6 +1444,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; @@ -1481,7 +1564,8 @@ { IArgno = 0; IArg_cont[0][0] = '\0'; } else - strcat(IArg_cont[IArgno], yytext); + { strcat(IArg_cont[IArgno], yytext); + } } else if (strcmp(yytext, ")") == 0) { if (--IArg_nst > 0) strcat(IArg_cont[IArgno], yytext); @@ -1494,6 +1578,7 @@ } else { switch (c) { + case ARROW: strcpy(yytext, "->"); break; /* NEW */ case SEP: strcpy(yytext, "::"); break; case SEMI: strcpy(yytext, ";"); break; case DECR: strcpy(yytext, "--"); break; --- /sys/src/cmd/spin/sym.c Sun Sep 15 19:44:07 2013 +++ /sys/src/cmd/spin/sym.c Sun Sep 15 19:44:03 2013 @@ -23,10 +23,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) @@ -53,22 +53,34 @@ 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 */ } } } @@ -321,7 +333,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 +496,9 @@ } } -if (1) printf("\t{scope %s}", sp->bscp); + if (!old_scope_rules) + { printf("\t{scope %s}", sp->bscp); + } printf("\n"); } @@ -583,14 +597,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); } } } --- /sys/src/cmd/spin/tl_buchi.c Sun Sep 15 19:44:16 2013 +++ /sys/src/cmd/spin/tl_buchi.c Sun Sep 15 19:44:10 2013 @@ -553,10 +553,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 +590,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++; } --- /sys/src/cmd/spin/tl_lex.c Sun Sep 15 19:44:24 2013 +++ /sys/src/cmd/spin/tl_lex.c Sun Sep 15 19:44:19 2013 @@ -83,15 +83,19 @@ } 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) { 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) && !isalnum_(c_nxt)) || (c == '<' && c_nxt == '>') + || (c == '<' && c_nxt == '-') + || (c == '-' && c_nxt == '>') || (c == '[' && c_nxt == ']')) { return 0; } } @@ -146,6 +150,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; } } @@ -179,6 +186,9 @@ { 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; } --- /sys/src/cmd/spin/tl_main.c Sun Sep 15 19:44:30 2013 +++ /sys/src/cmd/spin/tl_main.c Sun Sep 15 19:44:26 2013 @@ -235,10 +235,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); --- /sys/src/cmd/spin/tl_parse.c Sun Sep 15 19:44:37 2013 +++ /sys/src/cmd/spin/tl_parse.c Sun Sep 15 19:44:32 2013 @@ -44,6 +44,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: --- /sys/src/cmd/spin/tl_rewrt.c Sun Sep 15 19:44:42 2013 +++ /sys/src/cmd/spin/tl_rewrt.c Sun Sep 15 19:44:39 2013 @@ -143,6 +143,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; --- /sys/src/cmd/spin/tl_trans.c Sun Sep 15 19:44:52 2013 +++ /sys/src/cmd/spin/tl_trans.c Sun Sep 15 19:44:46 2013 @@ -23,7 +23,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; --- /sys/src/cmd/spin/vars.c Sun Sep 15 19:45:02 2013 +++ /sys/src/cmd/spin/vars.c Sun Sep 15 19:44:56 2013 @@ -17,7 +17,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,6 +42,16 @@ { 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 */ --- /sys/src/cmd/spin/version.h Sun Sep 15 19:45:10 2013 +++ /sys/src/cmd/spin/version.h Sun Sep 15 19:45:07 2013 @@ -1 +1 @@ -#define SpinVersion "Spin Version 6.1.0 -- 4 May 2011" +#define SpinVersion "Spin Version 6.2.5 -- 3 May 2013"