diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-11-22 21:09:31 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-11-22 21:09:31 +0100 |
commit | 28e9566dc539244b3b429c21c556d656733839c2 (patch) | |
tree | 1564ecdf009d240cb9247a10a0fcb6491e0424c4 /sys/src/cmd/spin/pangen1.h | |
parent | 077e719dfbf9bf2582bed80026251cc0d108c16e (diff) |
spin: Update to most recent version. (thanks Ori_B)
from Ori_B:
There were a small number of changes needed from the tarball
on spinroot.org:
- The mkfile needed to be updated
- Memory.h needed to not be included
- It needed to invoke /bin/cpp instead of gcc -E
- It depended on `yychar`, which our yacc doesn't
provide.
I'm still figuring out how to use spin, but it seems to do
the right thing when testing a few of the examples:
% cd $home/src/Spin/Examples/
% spin -a peterson.pml
% pcc pan.c -D_POSIX_SOURCE
% ./6.out
(Spin Version 6.4.7 -- 19 August 2017)
+ Partial Order Reduction
Full statespace search for:
never claim - (none specified)
assertion violations +
acceptance cycles - (not selected)
invalid end states +
State-vector 32 byte, depth reached 24, errors: 0
40 states, stored
27 states, matched
67 transitions (= stored+matched)
0 atomic steps
hash conflicts: 0 (resolved)
Stats on memory usage (in Megabytes):
0.002 equivalent memory usage for states (stored*(State-vector + overhead))
0.292 actual memory usage for states
128.000 memory used for hash table (-w24)
0.534 memory used for DFS stack (-m10000)
128.730 total actual memory usage
unreached in proctype user
/tmp/Spin/Examples/peterson.pml:20, state 10, "-end-"
(1 of 10 states)
pan: elapsed time 1.25 seconds
pan: rate 32 states/second
Diffstat (limited to 'sys/src/cmd/spin/pangen1.h')
-rw-r--r-- | sys/src/cmd/spin/pangen1.h | 6915 |
1 files changed, 5238 insertions, 1677 deletions
diff --git a/sys/src/cmd/spin/pangen1.h b/sys/src/cmd/spin/pangen1.h index 81facb646..e09930eec 100644 --- a/sys/src/cmd/spin/pangen1.h +++ b/sys/src/cmd/spin/pangen1.h @@ -1,20 +1,56 @@ /***** spin: pangen1.h *****/ -/* Copyright (c) 1989-2005 by Lucent Technologies, Bell Laboratories. */ -/* All Rights Reserved. This software is for educational purposes only. */ -/* No guarantee whatsoever is expressed or implied by the distribution of */ -/* this code. Permission is given to distribute this code provided that */ -/* this introductory message is not removed and no monies are exchanged. */ -/* Software written by Gerard J. Holzmann. For tool documentation see: */ -/* http://spinroot.com/ */ -/* Send all bug-reports and/or questions to: bugs@spinroot.com */ - -static char *Code2a[] = { /* the tail of procedure run() */ - "#if defined(VERI) && !defined(NOREDUCE) && !defined(NP)", +/* + * This file is part of the public release of Spin. It is subject to the + * terms in the LICENSE file that is included in this source directory. + * Tool documentation is available at http://spinroot.com + */ + +static const char *Code2a[] = { /* the tail of procedure run() */ + " if (state_tables)", + " { if (dodot) exit(0);", + " printf(\"\\nTransition Type: \");", + " printf(\"A=atomic; D=d_step; L=local; G=global\\n\");", + " printf(\"Source-State Labels: \");", + " printf(\"p=progress; e=end; a=accept;\\n\");", + "#ifdef MERGED", + " printf(\"Note: statement merging was used. Only the first\\n\");", + " printf(\" stmnt executed in each merge sequence is shown\\n\");", + " printf(\" (use spin -a -o3 to disable statement merging)\\n\");", + "#endif", + " pan_exit(0);", + " }", + "#if defined(BFS) && defined(TRIX)", /* before iniglobals */ + " { int i;", + " for (i = 0; i < MAXPROC+1; i++)", + " { processes[i] = (TRIX_v6 *) emalloc(sizeof(TRIX_v6));", + " processes[i]->body = (uchar *) emalloc(Maxbody * sizeof(char));", + " }", + " for (i = 0; i < MAXQ+1; i++)", + " { channels[i] = (TRIX_v6 *) emalloc(sizeof(TRIX_v6));", + " 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) && !defined(BFS) && !defined(HAS_LTL)", " if (!state_tables", - "#ifdef HAS_CODE", + " #ifdef HAS_CODE", " && !readtrail", - "#endif", + " #endif", + " #if NCORE>1", + " && core_id == 0", + " #endif", " )", " { printf(\"warning: for p.o. reduction to be valid \");", " printf(\"the never claim must be stutter-invariant\\n\");", @@ -24,14 +60,7 @@ static char *Code2a[] = { /* the tail of procedure run() */ "#endif", " UnBlock; /* disable rendez-vous */", "#ifdef BITSTATE", -#ifndef POWOW - " if (udmem)", - " { udmem *= 1024L*1024L;", - " SS = (uchar *) emalloc(udmem);", - " bstore = bstore_mod;", - " } else", -#endif - " SS = (uchar *) emalloc(1L<<(ssize-3));", + " sinit();", "#else", " hinit();", "#endif", @@ -39,18 +68,24 @@ static char *Code2a[] = { /* the tail of procedure run() */ " onstack_init();", "#endif", "#if defined(CNTRSTACK) && !defined(BFS)", - " LL = (uchar *) emalloc(1L<<(ssize-3));", + " LL = (uchar *) emalloc(ONE_L<<(ssize-3));", "#endif", - " stack = ( Stack *) emalloc(sizeof(Stack));", + " stack = (_Stack *) emalloc(sizeof(_Stack));", " svtack = (Svtack *) emalloc(sizeof(Svtack));", " /* a place to point for Pptr of non-running procs: */", - " noptr = (uchar *) emalloc(Maxbody * sizeof(char));", - "#ifdef SVDUMP", + " noqptr = noptr = (uchar *) emalloc(Maxbody * sizeof(char));", + "#if defined(SVDUMP) && defined(VERBOSE)", " if (vprefix > 0)", - " write(svfd, (uchar *) &vprefix, sizeof(int));", + " (void) write(svfd, (uchar *) &vprefix, sizeof(int));", "#endif", "#ifdef VERI", - " Addproc(VERI); /* never - pid = 0 */", + " Addproc(VERI,1); /* pid = 0, priority 1 */", + " #if NCLAIMS>1", + " if (claimname != NULL)", + " { whichclaim = find_claim(claimname);", + " select_claim(whichclaim);", + " }", + " #endif", "#endif", " active_procs(); /* started after never */", "#ifdef EVENT_TRACE", @@ -66,17 +101,21 @@ static char *Code2a[] = { /* the tail of procedure run() */ "#endif", " do_the_search();", "#ifdef BITSTATE", - " if (--Nrun > 0 && HASH_CONST[++HASH_NR])", + " if (--Nrun > 0 && HASH_CONST[++HASH_NR])", /* last entry is 0 */ " { printf(\"Run %%d:\\n\", HASH_NR);", " wrap_stats();", " printf(\"\\n\");", - " memset(SS, 0, 1L<<(ssize-3));", - "#if defined(CNTRSTACK)", - " memset(LL, 0, 1L<<(ssize-3));", + " if (udmem) /* Dillinger 3/2/09 */", + " { memset(SS, 0, udmem);", + " } else", + " { memset(SS, 0, ONE_L<<(ssize-3));", + " }", + "#ifdef CNTRSTACK", + " memset(LL, 0, ONE_L<<(ssize-3));", "#endif", - "#if defined(FULLSTACK)", + "#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;", @@ -86,8 +125,157 @@ static char *Code2a[] = { /* the tail of procedure run() */ " }", "#endif", "}", + "#ifdef HAS_PRIORITY", + "extern int highest_priority(int, short, Trans *);", + "extern int get_priority(int);", + "extern int set_priority(int, int);", + "#endif", + "#ifdef SPIN_HEAP", + "void *", + "spin_malloc(int n) /* reserved for use by Modex generated models */", + "{ char *spin_heap_ptr = &(now.spin_heap[now.spin_heap_n]);", + " if (now.spin_heap_n + n >= sizeof(now.spin_heap))", + " { Uerror(\"spin_heap limit reached\");", + " }", + " now.spin_heap_n += n;", + " return spin_heap_ptr;", + "}", + "void", + "spin_free(void *unused)", + "{ unused; /* ignore */", + "}", + "#endif", + "int", + "spin_join(int p, void **unused)", + "{ /* fprintf(stderr, \"join %%d when %%d\\n \", p, now._nr_pr); */", + " return (now._nr_pr <= p); /* process *p has stopped */", + "}", + "", + "int", + "spin_mutex_free(int *m)", + "{ return (*m == 0);", + "}", + "", + "int", + "spin_mutex_lock(int *m)", + "{ *m = 1;", + " return 1;", + "}", + "void", + "spin_mutex_destroy(int *m)", + "{ *m = 0;", + "}", + "void", + "spin_mutex_unlock(int *m)", + "{ *m = 0;", + "}", + "void", + "spin_mutex_init(int *m, void *val)", + "{", + " if (!val)", /* the 2nd arg must be NULL, for now */ + " { *m = 0;", + " } else", + " { Uerror(\"pthread_mutex_init: unsupported non-default init\");", + " }", + "}", + "", + "int", + "spin_cond_wait(int *cond, int *lck)", /*release and re-acquire lock *lck */ + "{ /* this version does not scale very far alas */", + " if (((P0 *)this)->_pid + 1 >= WS*8)", /* 32 or 64 */ + " { Uerror(\"pid exceeds range supported by pthread_cond_wait\");", + " }", + " if (((*cond)&1) == 0)", /* repeatedly tested, so: */ + " { spin_mutex_unlock(lck);", /* avoid double counting */ + " *cond |= (1<<(((P0 *)this)->_pid + 1));", + " return 0;", /* blocked, must test again */ + " } else", + " { /* if other processes are already waiting */", + " /* while our wait flag is 0, then they should go first */", + " if (((*cond)&(~(1 | (1<<(((P0 *)this)->_pid + 1))))) != 0)", + " { spin_mutex_unlock(lck);", + " return 0;", /* wait for the others to go first */ + " }", + " *cond &= ~1;", /* clear the 'go' bit andy wait flag */ + " *cond &= ~(1<<(((P0 *)this)->_pid + 1));", + " return 1;", /* okay to proceed */ + " }", + "}", + "void", + "spin_cond_signal(int *cond)", + "{", + " if ( ((*cond)&(~1)) != 0 )", /* procs are waiting */ + " { *cond |= 1;", /* set the 'go' bit */ + " }", + "}", + "", "#ifdef HAS_PROVIDED", - "int provided(int, uchar, int, Trans *);", + " int provided(int, uchar, int, Trans *);", + "#endif", + "#ifdef BFS_PAR", + " extern void bfs_shutdown(const char *);", + "#endif", + "", + "#if NCORE>1", + " #define GLOBAL_LOCK (0)", + " #ifndef CS_N", + " #define CS_N (256*NCORE)", /* must be a power of 2 */ + " #endif", + + " #ifdef NGQ", /* no global queue */ + " #define NR_QS (NCORE)", + " #define CS_NR (CS_N+1) /* 2^N + 1, nr critical sections */", + " #define GQ_RD GLOBAL_LOCK", /* not really used in this mode */ + " #define GQ_WR GLOBAL_LOCK", /* but just in case... */ + " #define CS_ID (1 + (int) (j1_spin & (CS_N-1))) /* mask: 2^N - 1, zero reserved */", + " #define QLOCK(n) (1+n)", /* overlaps first n zones of hashtable */ + " #else", + " #define NR_QS (NCORE+1)", /* add a global queue */ + " #define CS_NR (CS_N+3)", /* 2 extra locks for global q */ + " #define GQ_RD (1)", /* read access to global q */ + " #define GQ_WR (2)", /* write access to global q */ + " #define CS_ID (3 + (int) (j1_spin & (CS_N-1)))", + " #define QLOCK(n) (3+n)",/* overlaps first n zones of hashtable */ + " #endif", + "", + " #ifndef SEP_STATE", + " #define enter_critical(w) e_critical(w)", + " #define leave_critical(w) x_critical(w)", + " #else", + " #ifdef NGQ", + " #define enter_critical(w) { if (w < 1+NCORE) e_critical(w); }", + " #define leave_critical(w) { if (w < 1+NCORE) x_critical(w); }", + " #else", + " #define enter_critical(w) { if (w < 3+NCORE) e_critical(w); }", + " #define leave_critical(w) { if (w < 3+NCORE) x_critical(w); }", + " #endif", + " #endif", + "", + " int", + " cpu_printf(const char *fmt, ...)", /* only used with VERBOSE/CHECK/DEBUG */ + " { va_list args;", + " enter_critical(GLOBAL_LOCK); /* printing */", + " printf(\"cpu%%d: \", core_id);", + " fflush(stdout);", + " va_start(args, fmt);", + " vprintf(fmt, args);", + " va_end(args);", + " fflush(stdout);", + " leave_critical(GLOBAL_LOCK);", + " return 1;", + " }", + "#else", + " #define enter_critical(w) /* none */", + " #define leave_critical(w) /* none */", + "", + " int", + " cpu_printf(const char *fmt, ...)", + " { va_list args;", + " va_start(args, fmt);", + " vprintf(fmt, args);", + " va_end(args);", + " return 1;", + " }", "#endif", #ifndef PRINTF @@ -132,7 +320,7 @@ static char *Code2a[] = { /* the tail of procedure run() */ "static int stackread;", "static Trail frameptr;", "Trail *", - "getframe(int d)", + "getframe(long d)", "{", " if (CNT1 == CNT2)", " return &trail[d];", @@ -153,63 +341,103 @@ static char *Code2a[] = { /* the tail of procedure run() */ " 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", + "#if NCORE>1", + "extern void cleanup_shm(int);", + "volatile uint *search_terminated; /* to signal early termination */", + /* + * Meaning of bitflags in search_terminated: + * 1 set by pan_exit + * 2 set by wrapup + * 4 set by uerror + * 8 set by sudden_stop -- called after someone_crashed and [Uu]error + * 16 set by cleanup_shm + * 32 set by give_up -- called on signal + * 64 set by proxy_exit + * 128 set by proxy on write port failure + * 256 set by proxy on someone_crashed + * + * Flags 8|32|128|256 indicate abnormal termination + * + * The flags are checked in 4 functions in the code: + * sudden_stop() + * someone_crashed() (proxy and pan version) + * mem_hand_off() + */ "#endif", - "void", "pan_exit(int val)", - "{ if (signoff) printf(\"--end of output--\\n\");", + "{ 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\");", + " }", + "#if NCORE>1", + " if (search_terminated != NULL)", + " { *search_terminated |= 1; /* pan_exit */", + " }", + "#ifdef USE_DISK", + " { void dsk_stats(void);", + " dsk_stats();", + " }", + "#endif", + " if (!state_tables && !readtrail)", + " { 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;", + " }", + "#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];", + "", "char *", "transmognify(char *s)", "{ char *v, *w;", - " static char buf[2][2048];", " int i, toggle = 0;", - " if (!s || strlen(s) > 2047) return s;", - " memset(buf[0], 0, 2048);", - " memset(buf[1], 0, 2048);", - " strcpy(buf[toggle], s);", - " while ((v = strstr(buf[toggle], \"{c_code\")))", /* assign v */ + " memset(tbuf[0], 0, 2048);", + " memset(tbuf[1], 0, 2048);", + " strcpy(tbuf[toggle], s);", + " while ((v = strstr(tbuf[toggle], \"{c_code\")))", /* assign v */ " { *v = '\\0'; v++;", - " strcpy(buf[1-toggle], buf[toggle]);", + " strcpy(tbuf[1-toggle], tbuf[toggle]);", " for (w = v; *w != '}' && *w != '\\0'; w++) /* skip */;", " if (*w != '}') return s;", " *w = '\\0'; w++;", " for (i = 0; code_lookup[i].c; i++)", " if (strcmp(v, code_lookup[i].c) == 0", " && strlen(v) == strlen(code_lookup[i].c))", - " { if (strlen(buf[1-toggle])", + " { if (strlen(tbuf[1-toggle])", " + strlen(code_lookup[i].t)", " + strlen(w) > 2047)", " return s;", - " strcat(buf[1-toggle], code_lookup[i].t);", + " strcat(tbuf[1-toggle], code_lookup[i].t);", " break;", " }", - " strcat(buf[1-toggle], w);", + " strcat(tbuf[1-toggle], w);", " toggle = 1 - toggle;", " }", - " buf[toggle][2047] = '\\0';", - " return buf[toggle];", + " tbuf[toggle][2047] = '\\0';", + " return tbuf[toggle];", "}", "#else", "char * transmognify(char *s) { return s; }", @@ -223,7 +451,6 @@ static char *Code2a[] = { /* the tail of procedure run() */ "", " for (t = trans[ot][tt]; t; t = t->nxt)", " { printf(\"\\t\\t\");", - " q = transmognify(t->tp);", " for ( ; q && *q; q++)", " if (*q == '\\n')", @@ -233,6 +460,17 @@ static char *Code2a[] = { /* the tail of procedure run() */ " printf(\"\\n\");", " }", "}", + "", + "char *", + "find_source(int tp, int s)", + "{", + " if (s >= flref[tp]->from", + " && s <= flref[tp]->upto)", + " { return flref[tp]->fnm;", + " }", + " return PanSource; /* i.e., don't know */", + "}", + "", "void", "wrap_trail(void)", "{ static int wrap_in_progress = 0;", @@ -243,14 +481,15 @@ static char *Code2a[] = { /* the tail of procedure run() */ "", " printf(\"spin: trail ends after %%ld steps\\n\", depth);", " if (onlyproc >= 0)", - " { if (onlyproc >= now._nr_pr) pan_exit(0);", + " { if (onlyproc >= now._nr_pr) { pan_exit(0); }", " II = onlyproc;", " z = (P0 *)pptr(II);", " printf(\"%%3ld:\tproc %%d (%%s) \",", " depth, II, procname[z->_t]);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", - " { printf(\" line %%3d\",", + " { printf(\" %%s:%%d\",", + " find_source((int) z->_t, (int) z->_p),", " src_all[i].src[z->_p]);", " break;", " }", @@ -269,7 +508,8 @@ static char *Code2a[] = { /* the tail of procedure run() */ " depth, II, procname[z->_t]);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", - " { printf(\" line %%3d\",", + " { printf(\" %%s:%%d\",", + " find_source((int) z->_t, (int) z->_p),", " src_all[i].src[z->_p]);", " break;", " }", @@ -293,23 +533,100 @@ static char *Code2a[] = { /* the tail of procedure run() */ "findtrail(void)", "{ FILE *fd;", " char fnm[512], *q;", - " char MyFile[512];", + " char MyFile[512];", /* avoid using a non-writable string */ + " char MySuffix[16];", + " int try_core;", + " int candidate_files;", "", - " strcpy(MyFile, TrailFile);", /* avoid problem with non-writable strings */ + " if (trailfilename != NULL)", + " { fd = fopen(trailfilename, \"r\");", + " if (fd == NULL)", + " { printf(\"pan: cannot find %%s\\n\", trailfilename);", + " pan_exit(1);", + " } /* else */", + " goto success;", + " }", + "talk:", + " try_core = 1;", + " candidate_files = 0;", + " tprefix = \"trail\";", + " strcpy(MyFile, TrailFile);", + " do { /* see if there's more than one possible trailfile */", + " if (whichtrail)", + " { sprintf(fnm, \"%%s%%d.%%s\",", + " MyFile, whichtrail, tprefix);", + " fd = fopen(fnm, \"r\");", + " if (fd != NULL)", + " { candidate_files++;", + " if (verbose==100)", + " printf(\"trail%%d: %%s\\n\",", + " candidate_files, fnm);", + " fclose(fd);", + " }", + " if ((q = strchr(MyFile, \'.\')) != NULL)", + " { *q = \'\\0\';", /* e.g., strip .pml */ + " sprintf(fnm, \"%%s%%d.%%s\",", + " MyFile, whichtrail, tprefix);", + " *q = \'.\';", + " fd = fopen(fnm, \"r\");", + " if (fd != NULL)", + " { candidate_files++;", + " if (verbose==100)", + " printf(\"trail%%d: %%s\\n\",", + " candidate_files, fnm);", + " fclose(fd);", + " } }", + " } else", + " { sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", + " fd = fopen(fnm, \"r\");", + " if (fd != NULL)", + " { candidate_files++;", + " if (verbose==100)", + " printf(\"trail%%d: %%s\\n\",", + " candidate_files, fnm);", + " fclose(fd);", + " }", + " if ((q = strchr(MyFile, \'.\')) != NULL)", + " { *q = \'\\0\';", /* e.g., strip .pml */ + " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", + " *q = \'.\';", + " fd = fopen(fnm, \"r\");", + " if (fd != NULL)", + " { candidate_files++;", + " if (verbose==100)", + " printf(\"trail%%d: %%s\\n\",", + " candidate_files, fnm);", + " fclose(fd);", + " } } }", + " tprefix = MySuffix;", + " sprintf(tprefix, \"cpu%%d_trail\", try_core++);", + " } while (try_core <= NCORE);", "", + " if (candidate_files != 1)", + " { if (verbose != 100)", + " { printf(\"error: there are %%d trail files:\\n\",", + " candidate_files);", + " verbose = 100;", + " goto talk;", + " } else", + " { printf(\"pan: rm or mv all except one\\n\");", + " exit(1);", + " } }", + + " try_core = 1;", + " strcpy(MyFile, TrailFile); /* restore */", + " tprefix = \"trail\";", + "try_again:", " if (whichtrail)", " { sprintf(fnm, \"%%s%%d.%%s\", MyFile, whichtrail, tprefix);", " fd = fopen(fnm, \"r\");", " if (fd == NULL && (q = strchr(MyFile, \'.\')))", " { *q = \'\\0\';", /* e.g., strip .pml on original file */ - " sprintf(fnm, \"%%s%%d.%%s\", MyFile, whichtrail, tprefix);", + " sprintf(fnm, \"%%s%%d.%%s\",", + " MyFile, whichtrail, tprefix);", " *q = \'.\';", " fd = fopen(fnm, \"r\");", - " if (fd == NULL)", - " { printf(\"pan: cannot find %%s%%d.%%s or %%s\\n\", ", - " MyFile, whichtrail, tprefix, fnm);", - " pan_exit(1);", - " } }", + " }", " } else", " { sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", " fd = fopen(fnm, \"r\");", @@ -318,56 +635,122 @@ static char *Code2a[] = { /* the tail of procedure run() */ " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", " *q = \'.\';", " fd = fopen(fnm, \"r\");", - " if (fd == NULL)", - " { printf(\"pan: cannot find %%s.%%s or %%s\\n\", ", - " MyFile, tprefix, fnm);", - " pan_exit(1);", - " } } }", + " } }", " if (fd == NULL)", - " { printf(\"pan: cannot find trailfile %%s\\n\", fnm);", + " { if (try_core < NCORE)", + " { tprefix = MySuffix;", + " sprintf(tprefix, \"cpu%%d_trail\", try_core++);", + " goto try_again;", + " }", + " printf(\"pan: cannot find trailfile %%s\\n\", fnm);", " pan_exit(1);", " }", + "success:", + "#if NCORE>1 && defined(SEP_STATE)", + " { void set_root(void); /* for partial traces from local root */", + " set_root();", + " }", + "#endif", " return fd;", "}", "", "uchar do_transit(Trans *, short);", + "#ifdef PERMUTED", + "void set_permuted(int);", + "void set_reversed(int);", + "void set_rotated(int);", + "void set_randrot(int);", + "void (*p_reorder)(int) = set_permuted;", + "short p_rotate;", + "#endif", "", "void", "getrail(void)", "{ FILE *fd;", - " char *q;", - " int i, t_id, lastnever=-1; short II;", + " char *q, *pnm;", + " int i, t_id, lastnever = -1; short II;", " Trans *t;", " P0 *z;", - "", + "#ifdef PERMUTED", + " char sbuf[128];", + " memset(sbuf, 0, sizeof(sbuf));", + "#endif", " fd = findtrail(); /* exits if unsuccessful */", " while (fscanf(fd, \"%%ld:%%d:%%d\\n\", &depth, &i, &t_id) == 3)", " { if (depth == -1)", - " printf(\"<<<<<START OF CYCLE>>>>>\\n\");", + " { printf(\"<<<<<START OF CYCLE>>>>>\\n\");", + " }", + "#ifdef PERMUTED", " if (depth < 0)", - " continue;", + " { switch (depth) {", + " case -5:", + " if (i && !t_reverse)", + " { strcat(sbuf, \"-t_reverse \");", + " }", + " break;", + " case -6:", + " if (i && p_reorder != set_permuted)", + " { strcat(sbuf, \"-p_permute \");", + " } else", + " if (t_id && p_reorder != set_reversed)", + " { strcat(sbuf, \"-p_reverse \");", + " }", + " break;", + " case -7:", + " if (i", + " && (p_reorder != set_rotated || p_rotate != t_id))", + " { char tmp[32];", + " sprintf(tmp, \"-p_rotate%%d \", t_id);", + " strcat(sbuf, tmp);", + " }", + " break;", + " case -8:", + " if (i && p_reorder != set_randrot)", + " { strcat(sbuf, \"-p_randrot \");", + " }", + " if (s_rand != ++t_id)", + " { char tmp[32];", + " sprintf(tmp, \"-RS%%u \", (uint) t_id-1);", + " strcat(sbuf, tmp);", + " }", + " break;", + " default:", + " continue;", + " }", + " }", + "#endif", + " if (depth < 0)", + " { continue;", + " }", + "#ifdef PERMUTED", + " if (strlen(sbuf) > 0)", + " { fprintf(efd, \"add: %%s\\n\", sbuf);", + " exit(1);", + " }", + "#endif", " if (i > now._nr_pr)", " { printf(\"pan: Error, proc %%d invalid pid \", i);", " printf(\"transition %%d\\n\", t_id);", " break;", " }", " II = i;", - "", " z = (P0 *)pptr(II);", " for (t = trans[z->_t][z->_p]; t; t = t->nxt)", - " if (t->t_id == t_id)", + " if (t->t_id == (T_ID) t_id)", " break;", " if (!t)", " { for (i = 0; i < NrStates[z->_t]; i++)", " { t = trans[z->_t][i];", - " if (t && t->t_id == t_id)", - " { printf(\" Recovered at state %%d\\n\", i);", + " if (t && t->t_id == (T_ID) t_id)", + " { printf(\"\\tRecovered at state %%d\\n\", i);", " z->_p = i;", " goto recovered;", " } }", " printf(\"pan: Error, proc %%d type %%d state %%d: \",", " II, z->_t, z->_p);", " printf(\"transition %%d not found\\n\", t_id);", + " printf(\"pan: list of possible transitions in this process:\\n\");", + " if (z->_t >= 0 && z->_t <= _NP_)", " for (t = trans[z->_t][z->_p]; t; t = t->nxt)", " printf(\" t_id %%d -- case %%d, [%%s]\\n\",", " t->t_id, t->forw, t->tp);", @@ -377,11 +760,13 @@ static char *Code2a[] = { /* the tail of procedure run() */ " q = transmognify(t->tp);", " if (gui) simvals[0] = \'\\0\';", + " pnm = procname[z->_t];", " this = pptr(II);", " trpt->tau |= 1;", /* timeout always possible */ " if (!do_transit(t, II))", " { if (onlyproc >= 0 && II != onlyproc)", " goto moveon;", + " if (!verbose) break;", " printf(\"pan: error, next transition UNEXECUTABLE on replay\\n\");", " printf(\" most likely causes: missing c_track statements\\n\");", " printf(\" or illegal side-effects in c_expr statements\\n\");", @@ -391,16 +776,24 @@ static char *Code2a[] = { /* the tail of procedure run() */ " goto moveon;", " if (verbose)", - " { printf(\"depth: %%3ld proc: %%3d trans: %%3d (%%d procs) \",", - " depth, II, t_id, now._nr_pr);", - " printf(\"forw=%%3d [%%s]\\n\", t->forw, q);", - "", + " { printf(\"%%3ld: proc %%2d (%%s) \", depth, II, pnm);", + + " for (i = 0; src_all[i].src; i++)", + " if (src_all[i].tp == (int) z->_t)", + " { printf(\" %%s:%%d \",", + " find_source((int) z->_t, (int) z->_p),", + " src_all[i].src[z->_p]);", + " break;", + " }", + + " printf(\"(state %%d) trans {%%d,%%d} [%%s]\\n\",", + " z->_p, t_id, t->forw, q?q:\"\");", + " c_globals();", " for (i = 0; i < now._nr_pr; i++)", " { c_locals(i, ((P0 *)pptr(i))->_t);", " }", - " } else", - " if (strcmp(procname[z->_t], \":never:\") == 0)", + " } else if (Btypes[z->_t] == N_CLAIM)", " { if (lastnever != (int) z->_p)", " { for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", @@ -413,38 +806,39 @@ static char *Code2a[] = { /* the tail of procedure run() */ " }", " lastnever = z->_p;", " goto sameas;", - " } else", - " if (strcmp(procname[z->_t], \":np_:\") != 0)", + " } else if (Btypes[z->_t] != 0) /* not :np_: */", " {", "sameas: if (no_rck) goto moveon;", " if (coltrace)", " { printf(\"%%ld: \", depth);", " for (i = 0; i < II; i++)", " printf(\"\\t\\t\");", - " printf(\"%%s(%%d):\", procname[z->_t], II);", + " printf(\"%%s(%%d):\", pnm, II);", " printf(\"[%%s]\\n\", q?q:\"\");", " } else if (!silent)", " { if (strlen(simvals) > 0) {", " printf(\"%%3ld: proc %%2d (%%s)\", ", - " depth, II, procname[z->_t]);", + " depth, II, pnm);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", - " { printf(\" line %%3d \\\"pan_in\\\" \",", + " { printf(\" %%s:%%d \",", + " find_source((int) z->_t, (int) z->_p),", " src_all[i].src[z->_p]);", " break;", " }", " printf(\"(state %%d)\t[values: %%s]\\n\", z->_p, simvals);", " }", " printf(\"%%3ld: proc %%2d (%%s)\", ", - " depth, II, procname[z->_t]);", + " depth, II, pnm);", " for (i = 0; src_all[i].src; i++)", " if (src_all[i].tp == (int) z->_t)", - " { printf(\" line %%3d \\\"pan_in\\\" \",", + " { printf(\" %%s:%%d \",", + " find_source((int) z->_t, (int) z->_p),", " src_all[i].src[z->_p]);", " break;", " }", " printf(\"(state %%d)\t[%%s]\\n\", z->_p, q?q:\"\");", - " printf(\"\\n\");", + " /* printf(\"\\n\"); */", " } }", "moveon: z->_p = t->st;", " }", @@ -462,19 +856,22 @@ static char *Code2a[] = { /* the tail of procedure run() */ " }", " return -1;", "}", - "#ifdef VERI", - "void check_claim(int);", + "", + "#if NCORE>1 && !defined(GLOB_HEAP)", + " #define SEP_HEAP /* version 5.1.2 */", "#endif", "", "#ifdef BITSTATE", -#ifndef POWOW "int", "bstore_mod(char *v, int n) /* hasharray size not a power of two */", - "{ unsigned long x, y;", - " unsigned int i = 1;", - "", - " d_hash((uchar *) v, n); /* sets j3, j4, K1, K2 */", - " x = K2; y = j3;", + "{ ulong x, y;", + " uint i = 1;", + "#if defined(MURMUR) && (WS==8)", + " m_hash((uchar *) v, n); /* bstore_mod - sets j3_spin, j4_spin, K1, K2 */", + "#else", + " d_hash((uchar *) v, n); /* bstore_mod - sets j3_spin, j4_spin, K1, K2 */", + "#endif", + " x = K1; y = j3_spin;", /* was K2 before 5.1.1 */ " for (;;)", " { if (!(SS[x%%udmem]&(1<<y))) break;", /* take the hit in speed */ " if (i == hfns) {", @@ -483,8 +880,8 @@ static char *Code2a[] = { /* the tail of procedure run() */ "#endif", " return 1;", " }", - " x = (x + K1 + i);", /* no mask, using mod */ - " y = (y + j4) & 7;", + " x = (x + K2 + i);", /* no mask, using mod - was K1 before 5.1.1 */ + " y = (y + j4_spin) & 7;", " i++;", " }", "#ifdef RANDSTOR", @@ -493,8 +890,8 @@ static char *Code2a[] = { /* the tail of procedure run() */ " for (;;)", " { SS[x%%udmem] |= (1<<y);", " if (i == hfns) break;", /* done */ - " x = (x + K1 + i);", /* no mask */ - " y = (y + j4) & 7;", + " x = (x + K2 + i);", /* no mask - was K1 before 5.1.1 */ + " y = (y + j4_spin) & 7;", " i++;", " }", "#ifdef DEBUG", @@ -505,14 +902,16 @@ static char *Code2a[] = { /* the tail of procedure run() */ " }", " return 0;", "}", -#endif "int", "bstore_reg(char *v, int n) /* extended hashing, Peter Dillinger, 2004 */", - "{ unsigned long x, y;", - " unsigned int i = 1;", - "", - " d_hash((uchar *) v, n); /* sets j1-j4 */", - " x = j2; y = j3;", + "{ ulong x, y;", + " uint i = 1;", + "#if defined(MURMUR) && (WS==8)", + " m_hash((uchar *) v, n); /* bstore_reg - sets j1_spin-j4_spin */", + "#else", + " d_hash((uchar *) v, n); /* bstore_reg - sets j1_spin-j4_spin */", + "#endif", + " x = j2_spin; y = j3_spin;", " for (;;)", " { if (!(SS[x]&(1<<y))) break;", /* at least one bit not set */ " if (i == hfns) {", @@ -521,8 +920,8 @@ static char *Code2a[] = { /* the tail of procedure run() */ "#endif", " return 1;", " }", - " x = (x + j1 + i) & nmask;", - " y = (y + j4) & 7;", + " x = (x + j1_spin + i) & nmask;", + " y = (y + j4_spin) & 7;", " i++;", " }", "#ifdef RANDSTOR", @@ -531,8 +930,8 @@ static char *Code2a[] = { /* the tail of procedure run() */ " for (;;)", " { SS[x] |= (1<<y);", " if (i == hfns) break;", /* done */ - " x = (x + j1 + i) & nmask;", - " y = (y + j4) & 7;", + " x = (x + j1_spin + i) & nmask;", + " y = (y + j4_spin) & 7;", " i++;", " }", "#ifdef DEBUG", @@ -543,8 +942,8 @@ static char *Code2a[] = { /* the tail of procedure run() */ " }", " return 0;", "}", - "#endif", - "unsigned long TMODE = 0666; /* file permission bits for trail files */", + "#endif", /* BITSTATE */ + "ulong TMODE = 0666; /* file permission bits for trail files */", "", "int trcnt=1;", "char snap[64], fnm[512];", @@ -554,18 +953,34 @@ static char *Code2a[] = { /* the tail of procedure run() */ "{ int fd;", " char *q;", " char MyFile[512];", + " int w_flags = O_CREAT|O_WRONLY|O_TRUNC;", + "", + " if (exclusive == 1 && iterative == 0)", + " { w_flags |= O_EXCL;", + " }", "", " q = strrchr(TrailFile, \'/\');", " if (q == NULL) q = TrailFile; else q++;", " strcpy(MyFile, q); /* TrailFile is not a writable string */", "", " if (iterative == 0 && Nr_Trails++ > 0)", + " {", + "#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);", - " else", + "#endif", + " } else", + " {", + "#ifdef PUTPID", + " sprintf(fnm, \"%%s_%%s_%%d.%%s\", MyFile, progname, getpid(), tprefix);", + "#else", " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", - "", - " if ((fd = creat(fnm, TMODE)) < 0)", + "#endif", + " }", + " if ((fd = open(fnm, w_flags, TMODE)) < 0)", " { if ((q = strchr(MyFile, \'.\')))", " { *q = \'\\0\';", /* strip .pml */ " if (iterative == 0 && Nr_Trails-1 > 0)", @@ -574,91 +989,146 @@ static char *Code2a[] = { /* the tail of procedure run() */ " else", " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", " *q = \'.\';", - " fd = creat(fnm, TMODE);", + " fd = open(fnm, w_flags, TMODE);", " } }", " if (fd < 0)", " { printf(\"pan: cannot create %%s\\n\", fnm);", " perror(\"cause\");", " } else", - " { printf(\"pan: wrote %%s\\n\", fnm);", + " {", + "#if NCORE>1 && (defined(SEP_STATE) || !defined(FULL_TRAIL))", + " void write_root(void); ", + " write_root();", + "#else", + " printf(\"pan: wrote %%s\\n\", fnm);", + "#endif", " }", " return fd;", "}", - 0 -}; - -static char *Code2b[] = { /* breadth-first search option */ - "#ifdef BFS", - "#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;", - "#if VECTORSZ>32000", - " int *po;", - "#else", - " short *po;", - "#endif", - " int *qo;", - " uchar *ps, *qs;", - " 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;", + "#ifndef FREQ", + "#define FREQ (1000000)", "#endif", - " short boq;", - " struct BFS_Trail *nxt;", - "} BFS_Trail;", + "double freq = (double) FREQ;\n", + + "#ifdef TRIX", + "void sv_populate(void);", "", - "BFS_Trail *bfs_trail, *bfs_bot, *bfs_free;", + "void", + "re_populate(void) /* restore procs and chans from now._ids_ */", + "{ int i, cnt = 0;", + " char *b;", + "#ifdef V_TRIX", + " printf(\"%%4d: re_populate\\n\", depth);", + "#endif", + " for (i = 0; i < now._nr_pr; i++, cnt++)", + " { b = now._ids_[cnt];", + " processes[i]->psize = what_p_size( ((P0 *)b)->_t );", + " 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 */", + "#endif", + " }", + " for (i = 0; i < now._nr_qs; i++, cnt++)", + " { b = now._ids_[cnt];", + " channels[i]->psize = what_q_size( ((Q0 *)b)->_t );", + " memcpy(channels[i]->body, b, channels[i]->psize);", + "#ifndef BFS", + " channels[i]->modified = 1; /* re-populate */", + "#endif", + " }", + "}", + "#endif\n", + + "#ifdef BFS", /* breadth-first search */ + " #ifndef BFS_PAR", + " BFS_State *bfs_trail, *bfs_bot, *bfs_free;", + " SV_Hold *svfree;", + " #else", + " 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", "", - "SV_Hold *svhold, *svfree;", + " 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;", + "{ SV_Hold *h;", "", - " 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 */", - " }", - "", - " 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", + " if (bfs_size_limit >= BFS_LIMIT)", + " { h->sv = (State *) 0; /* means: read disk */", + " bfs_dsk_writes++; /* count */", + " if (bfs_dsk_write < 0 /* file descriptor */", + " || bfs_dsk_writes%%BFS_DSK_LIMIT == 0)", + " { char dsk_nm[32];", + " if (bfs_dsk_write >= 0)", + " { (void) close(bfs_dsk_write);", + " }", + " sprintf(dsk_nm, \"pan_bfs_%%d.tmp\", bfs_dsk_seqno_w++);", + " bfs_dsk_write = open(dsk_nm, WFLAGS, 0644);", + " if (bfs_dsk_write < 0)", + " { Uerror(\"could not create tmp disk file\");", + " }", + " printf(\"pan: created disk file %%s\\n\", dsk_nm);", + " }", + " if (write(bfs_dsk_write, (char *) &now, n) != n)", + " { Uerror(\"aborting -- disk write failed (disk full?)\");", + " }", + " return h; /* no memcpy */", + " }", /* else */ + " bfs_size_limit++;", + " #endif", " h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n);", " }", + "", + " memcpy((char *)h->sv, (char *)&now, n);", " return h;", "}", "", @@ -669,18 +1139,24 @@ static char *Code2b[] = { /* breadth-first search option */ "", " 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)", - "#if VECTORSZ>32000", + " #ifdef TRIX", + " )", + " #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", - " && (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", + " && (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", " break;", " if (!h)", " { h = (EV_Hold *) emalloc(sizeof(EV_Hold));", @@ -689,29 +1165,33 @@ static char *Code2b[] = { /* breadth-first search option */ " h->nrqs = now._nr_qs;", "", " h->sv = (char *) emalloc(n * sizeof(char));", + "#if !defined(NOCOMP) && !defined(HC)", " memcpy((char *) h->sv, (char *) Mask, n);", - "", + "#endif", + " #ifndef TRIX", " if (now._nr_pr > 0)", - " { h->po = (int *) emalloc(now._nr_pr * sizeof(int));", - " h->ps = (int *) emalloc(now._nr_pr * sizeof(int));", - "#if VECTORSZ>32000", + " { h->ps = (char *) emalloc(now._nr_pr * sizeof(int));", + " memcpy((char *) h->ps, (char *) proc_skip, now._nr_pr * sizeof(uchar));", + " #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", - " memcpy((char *) h->ps, (char *) proc_skip, now._nr_pr * sizeof(uchar));", + " #endif", " }", " if (now._nr_qs > 0)", - " { h->qo = (int *) emalloc(now._nr_qs * sizeof(int));", - " h->qs = (int *) emalloc(now._nr_qs * sizeof(int));", - "#if VECTORSZ>32000", + " { h->qs = (char *) emalloc(now._nr_qs * sizeof(int));", + " memcpy((char *) h->qs, (char *) q_skip, now._nr_qs * sizeof(uchar));", + " #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", - " memcpy((char *) h->qs, (char *) q_skip, now._nr_qs * sizeof(uchar));", + " #endif", " }", - "", + " #endif", " h->nxt = kept;", " kept = h;", " }", @@ -724,9 +1204,9 @@ static char *Code2b[] = { /* breadth-first search option */ "", " 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)", " { p->nxt = svfree;", " svfree = p;", @@ -736,171 +1216,239 @@ static char *Code2b[] = { /* breadth-first search option */ " }", "}", "", - "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 */", + " /* used for reconstructing path and recovering failed rvs etc */", " return t;", "}", "", "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", + " sv_populate();", + " #endif", " t->onow = getsv(vsize);", - " memcpy((char *)t->onow->sv, (char *)&now, 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 CHECK", - " printf(\"PUSH %%u (%%d)\\n\", t->frame, d);", - "#endif", + " #ifdef VERBOSE", + " t->nr = nstates;", + " #endif", + " #ifdef CHECK", + " #ifdef VERBOSE", + " printf(\"PUSH %%lu (depth %%d, nr %%lu)\\n\", (ulong) t->frame, d, t->nr);", + " #else", + " printf(\"PUSH %%lu (depth %%d)\\n\", (ulong) t->frame, d);", + " #endif", + " #endif", "}", "", "Trail *", "pop_bfs(void)", - "{ BFS_Trail *t;", + "{ BFS_State *t;", "", " if (!bfs_trail)", - " return (Trail *) 0;", - "", + " { return (Trail *) 0;", + " }", " t = bfs_trail;", " bfs_trail = t->nxt;", " if (!bfs_trail)", - " bfs_bot = (BFS_Trail *) 0;", - "#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)", - " if (t->lstate) t->lstate->tagged = 0;", - "#endif", - "", + " { bfs_bot = (BFS_State *) 0;", + " }", + " #if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)", + " if (t->lstate) /* bfs */", + " { t->lstate->tagged = 0; /* bfs */", + " }", + " #endif", " t->nxt = bfs_free;", " bfs_free = t;", "", " vsize = t->onow->sz;", " boq = t->boq;", - "", - " memcpy((uchar *) &now, (uchar *) t->onow->sv, vsize);", + " #ifdef BFS_DISK", + " if (t->onow->sv == (State *) 0)", + " { char dsk_nm[32];", + " bfs_dsk_reads++; /* count */", + " if (bfs_dsk_read >= 0 /* file descriptor */", + " && bfs_dsk_reads%%BFS_DSK_LIMIT == 0)", + " { (void) close(bfs_dsk_read);", + " sprintf(dsk_nm, \"pan_bfs_%%d.tmp\", bfs_dsk_seqno_r-1);", + " (void) unlink(dsk_nm);", + " bfs_dsk_read = -1;", + " }", + " if (bfs_dsk_read < 0)", + " { sprintf(dsk_nm, \"pan_bfs_%%d.tmp\", bfs_dsk_seqno_r++);", + " bfs_dsk_read = open(dsk_nm, RFLAGS);", + " if (bfs_dsk_read < 0)", + " { Uerror(\"could not open temp disk file\");", + " } }", + " if (read(bfs_dsk_read, (char *) &now, vsize) != vsize)", + " { Uerror(\"bad bfs disk file read\");", + " }", + " #ifndef NOVSZ", + " if (now._vsz != vsize)", + " { Uerror(\"disk read vsz mismatch\");", + " }", + " #endif", + " } else", + " #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);", - + "#endif", + " #ifdef TRIX", + " re_populate();", + " #else", " if (now._nr_pr > 0)", - "#if VECTORSZ>32000", + " #if VECTORSZ>32000", " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(int));", - "#else", + " #else", " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(short));", - "#endif", + " #endif", " memcpy((char *)proc_skip, (char *)t->omask->ps, now._nr_pr * sizeof(uchar));", " }", " if (now._nr_qs > 0)", - "#if VECTORSZ>32000", + " #if VECTORSZ>32000", " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(int));", - "#else", + " #else", " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(short));", - "#endif", + " #endif", " memcpy((uchar *)q_skip, (uchar *)t->omask->qs, now._nr_qs * sizeof(uchar));", " }", - - " freesv(t->onow); /* omask not freed */", - "#ifdef CHECK", - " printf(\"POP %%u (%%d)\\n\", t->frame, t->frame->o_tt);", - "#endif", + " #endif", + " #ifdef BFS_DISK", + " if (t->onow->sv != (State *) 0)", + " #endif", + " { freesv(t->onow); /* omask not freed */", + " }", + " #ifdef CHECK", + " #ifdef VERBOSE", + " printf(\"POP %%lu (depth %%d, nr %%lu)\\n\", (ulong) t->frame, t->frame->o_tt, t->nr);", + " #else", + " printf(\"POP %%lu (depth %%d)\\n\", (ulong) t->frame, t->frame->o_tt);", + " #endif", + " #endif", " return t->frame;", "}", "", "void", "store_state(Trail *ntrpt, int shortcut, short oboq)", "{", - "#ifdef VERI", + " #ifdef VERI", " Trans *t2 = (Trans *) 0;", " uchar ot; int tt, E_state;", " uchar o_opm = trpt->o_pm, *othis = this;", "", " if (shortcut)", " {", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"claim: shortcut\\n\");", - "#endif", + " #endif", " goto store_it; /* no claim move */", " }", "", - " this = (((uchar *)&now)+proc_offset[0]); /* 0 = never claim */", + " this = pptr(0); /* 0 = never claim */", " trpt->o_pm = 0;", /* to interpret else in never claim */ "", " tt = (int) ((P0 *)this)->_p;", " ot = (uchar) ((P0 *)this)->_t;", "", - "#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", - " if (E_state > 0", - " && E_state != t2->e_trans)", - " break;", - "#endif", + " #ifdef HAS_UNLESS", + " if (E_state > 0 && E_state != t2->e_trans)", + " { break;", + " }", + " #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", - " check_claim(t2->st);", - "#endif", + " #ifndef NOCLAIM", + " if (stopstate[ot][t2->st])", + " { uerror(\"end state in claim reached\");", + " }", + " #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)", /* atomic in claim */ - " Uerror(\"atomic in claim not supported in BFS mode\");", + " if (t2->atom&2)", + " { Uerror(\"atomic in claim not supported in BFS\");", + " }", "store_it:", "", - "#endif", /* VERI */ + " #endif", /* VERI */ "", - "#ifdef BITSTATE", - " if (!bstore((char *)&now, vsize))", - "#else", - "#ifdef MA", - " if (!gstore((char *)&now, vsize, 0))", - "#else", - " if (!hstore((char *)&now, vsize))", - "#endif", - "#endif", - " { nstates++;", - "#ifndef NOREDUCE", - " trpt->tau |= 64;", /* succ definitely outside stack */ - "#endif", - "#if SYNC", + " #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", + " trpt->tau |= 64;", /* bfs: succ definitely outside stack */ + " #endif", + " ndone = (ulong) (nstates/(freq));", + " if (ndone != sdone && mreached%%10 != 0)", + " { snapshot();", + " sdone = ndone;", + " #if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", + " if (nstates > ((double)(1<<(ssize+1))))", + " { void resize_hashtable(void);", + " resize_hashtable();", + " }", + " #endif", + " }", + " #if SYNC", " if (boq != -1)", " midrv++;", " else if (oboq != -1)", @@ -908,26 +1456,29 @@ static char *Code2b[] = { /* breadth-first search option */ " 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(QLIST) && !defined(BITSTATE)", - " if (Lstate && Lstate->tagged) trpt->tau |= 64;", - "#else", + " #if defined(Q_PROVISO) && !defined(NOREDUCE) && defined(FULLSTACK)", + " #if !defined(BITSTATE)", + " if (Lstate && Lstate->tagged)", + " { trpt->tau |= 64;", + " }", + " #else", " if (trpt->tau&32)", - " { BFS_Trail *tprov;", + " { BFS_State *tprov;", " for (tprov = bfs_trail; tprov; tprov = tprov->nxt)", - " if (!memcmp((uchar *)&now, (uchar *)tprov->onow->sv, vsize))", + " 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", + " #endif", " }", - "#ifdef VERI", + " #ifdef VERI", " ((P0 *)this)->_p = tt; /* reset claim */", " if (t2)", " do_reverse(t2, 0, 0);", @@ -936,11 +1487,9 @@ static char *Code2b[] = { /* breadth-first search option */ " } }", " this = othis;", " trpt->o_pm = o_opm;", - "#endif", + " #endif", "}", "", - "Trail *ntrpt;", /* 4.2.8 */ - "", "void", "bfs(void)", "{ Trans *t; Trail *otrpt, *x;", @@ -950,7 +1499,7 @@ static char *Code2b[] = { /* breadth-first search option */ " 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;", @@ -958,81 +1507,74 @@ static char *Code2b[] = { /* breadth-first search option */ "", " 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)", " { mreached = trpt->o_tt;", " if (mreached%%10 == 0)", - " { printf(\"Depth= %%7d States= %%7g \", mreached, nstates);", - " printf(\"Transitions= %%7g \", nstates+truncs);", - "#ifdef MA", - " printf(\"Nodes= %%7d \", nr_states);", - "#endif", - " printf(\"Memory= %%-6.3f\\n\", memcnt/1000000.);", - " fflush(stdout);", + " { snapshot();", " } }", " depth = trpt->o_tt;", " 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;", " printf(\"error: max search depth too small\\n\");", " }", " if (bounded)", - " uerror(\"depth limit reached\");", + " { uerror(\"depth limit reached\");", + " }", " continue;", " }", - -/* PO */ - "#ifndef NOREDUCE", + " #ifndef NOREDUCE", " if (boq == -1 && !(trpt->tau&8) && nps == 0)", " for (II = now._nr_pr-1; II >= BASE; II -= 1)", " {", - "Pickup: this = pptr(II);", + "Pickup: this = pptr(II);", " tt = (int) ((P0 *)this)->_p;", " ot = (uchar) ((P0 *)this)->_t;", " if (trans[ot][tt]->atom & 8)", /* safe */ @@ -1045,15 +1587,14 @@ static char *Code2b[] = { /* breadth-first search option */ " }", " From = To = II;", " trpt->tau |= 32; /* preselect marker */", - "#ifdef DEBUG", - " printf(\"%%3d: proc %%d PreSelected (tau=%%d)\\n\", ", + " #ifdef DEBUG", + " printf(\"%%3ld: proc %%d PreSelected (tau=%%d)\\n\", ", " depth, II, trpt->tau);", - "#endif", + " #endif", " goto MainLoop;", " } }", " trpt->tau &= ~32;", /* not preselected */ - "#endif", -/* PO */ + " #endif", /* if !NOREDUCE */ "Repeat:", " if (trpt->tau&8) /* atomic */", " { From = To = (short ) trpt->pr;", @@ -1066,32 +1607,44 @@ static char *Code2b[] = { /* breadth-first search option */ " _n = _m = 0;", " for (II = From; II >= To; II -= 1)", " {", - " this = (((uchar *)&now)+proc_offset[II]);", + " 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", + " if (boq != -1 && trpt->pr == II)", + " { continue;", + " }", + " #endif", " ntrpt->pr = (uchar) II;", " ntrpt->st = tt; ", - " trpt->o_pm &= ~1; /* no move yet */", - "#ifdef EVENT_TRACE", + " trpt->o_pm &= ~1; /* no move yet */", + " #ifdef EVENT_TRACE", " trpt->o_event = now._event;", - "#endif", - "#ifdef HAS_PROVIDED", - " if (!provided(II, ot, tt, t)) continue;", - "#endif", - "#ifdef HAS_UNLESS", + " #endif", + + " #ifdef HAS_PRIORITY", + " if (!highest_priority(((P0 *)this)->_pid, II, t))", + " { continue;", + " }", + " #else", + " #ifdef HAS_PROVIDED", + " if (!provided(II, ot, tt, t))", + " { continue;", + " }", + " #endif", + " #endif", + + " #ifdef HAS_UNLESS", " E_state = 0;", - "#endif", + " #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;", @@ -1101,136 +1654,147 @@ static char *Code2b[] = { /* breadth-first search option */ "", " trpt->o_pm |= 1; /* we moved */", " (trpt+1)->o_m = _m; /* for unsend */", - "#ifdef PEG", + " #ifdef PEG", " peg[t->forw]++;", - "#endif", - "#ifdef CHECK", - " printf(\"%%3d: proc %%d exec %%d, \",", + " #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:\tthe use of rendezvous stmnt in the escape clause\\n\");", + " { 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", - " if (t->st > 0) ((P0 *)this)->_p = t->st;", + " #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", - " printf(\"%%3d: proc %%d \", depth, II);", + " #ifdef CHECK", + " enter_critical(GLOBAL_LOCK); /* verbose mode */", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", + " printf(\"%%3lu: proc %%d \", depth, II);", " printf(\"reverses %%d, %%d to %%d,\",", " t->forw, tt, t->st);", - " printf(\" %%s [abit=%%d,adepth=%%d,\",", + " printf(\" %%s [abit=%%d,adepth=%%ld,\",", " t->tp, now._a_t, A_depth);", " printf(\"tau=%%d,%%d]\\n\",", " trpt->tau, (trpt-1)->tau);", - "#endif", + " leave_critical(GLOBAL_LOCK);", + " #endif", " reached[ot][t->st] = 1;", - " reached[ot][tt] = 1;", + " reached[ot][tt] = 1;", "", " ((P0 *)this)->_p = tt;", " _n |= _m;", " } }", -/* PO */ - "#ifndef NOREDUCE", + " #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", - " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", + " #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;", + " { goto Pickup;", + " }", " goto MainLoop;", " }", " trpt->tau &= ~(32|64);", - "#endif", -/* PO */ + " #endif", /* PO */ " if (_n != 0)", - " continue;", - "#ifdef DEBUG", - " printf(\"%%3d: no move [II=%%d, tau=%%d, boq=%%d, _nr_pr=%%d]\\n\",", + " { continue;", + " }", + " #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 */", - " if (!x) continue; /* root state */", + " x = (Trail *) trpt->ostate; /* pre-rv state */", + " if (!x)", + " { continue; /* root state */", + " }", " if ((x->tau&8) || (x->tau&32)) /* break atomic or preselect at parent */", " { x->o_pm |= 8; /* mark failure */", - " this = (((uchar *)&now)+proc_offset[otrpt->pr]);", - "#ifdef VERBOSE", + " this = pptr(otrpt->pr);", + " #ifdef VERBOSE", " printf(\"\\treset state of %%d from %%d to %%d\\n\",", " otrpt->pr, ((P0 *)this)->_p, otrpt->st);", - "#endif", + " #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", - " else printf(\"failed rv, tau at parent: %%d\\n\", x->tau);", - "#endif", + " #ifdef VERBOSE", + " else", + " { printf(\"failed rv, tau at parent: %%d\\n\", x->tau);", + " }", + " #endif", " } else if (now._nr_pr > 0)", " {", " if ((trpt->tau&8)) /* atomic */", " { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */", - "#ifdef DEBUG", - " printf(\"%%3d: atomic step proc %%d blocks\\n\",", + " #ifdef DEBUG", + " printf(\"%%3ld: atomic step proc %%d blocks\\n\",", " depth, II+1);", - "#endif", + " #endif", " goto Repeat;", " }", "", " if (!(trpt->tau&1)) /* didn't try timeout yet */", " { trpt->tau |= 1;", - "#ifdef DEBUG", - " printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #ifdef DEBUG", + " printf(\"%%ld: timeout\\n\", depth);", + " #endif", " goto MainLoop;", " }", - "#ifndef VERI", + " #ifndef VERI", " if (!noends && !a_cycles && !endstate())", - " uerror(\"invalid end state\");", - "#endif", + " { uerror(\"invalid end state\");", + " }", + " #endif", " } }", "}", + "#endif", /* !BFS_PAR */ "", "void", "putter(Trail *trpt, int fd)", @@ -1252,40 +1816,178 @@ static char *Code2b[] = { /* breadth-first search option */ "}", "", "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\", VERI);", - " write(fd, snap, strlen(snap));", - "#endif", - "#ifdef MERGED", - " sprintf(snap, \"-4:-4:-4\\n\");", - " 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();", + " { wrapup();", " }", "}", "#endif", /* BFS */ 0, }; -static char *Code2c[] = { +static const char *Code2d[] = { + "clock_t start_time;", + "#if NCORE>1", + "clock_t crash_stamp;", + "#endif", + "#if !defined(WIN32) && !defined(WIN64)", + "struct tms start_tm;", + "#endif", + "", + "#if SYNC", + "extern int q_zero(int);", + "extern int not_RV(int);", + "#endif", + "", + "void", + "start_timer(void)", + "{", + "#if defined(WIN32) || defined(WIN64)", + " start_time = clock();", + "#else", + " start_time = times(&start_tm);", + "#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(int report)", + "{ clock_t stop_time;", + "#if !defined(WIN32) && !defined(WIN64)", + " struct tms stop_tm;", + " stop_time = times(&stop_tm);", + " delta_time = ((double) (stop_time - start_time)) / ((double) sysconf(_SC_CLK_TCK));", + "#else", + " stop_time = clock();", + " delta_time = ((double) (stop_time - start_time)) / ((double) CLOCKS_PER_SEC);", + "#endif", + " if (readtrail || delta_time < 0.00) return;", + "#if NCORE>1", + " if (core_id == 0 && nstates > (double) 0)", + " { printf(\"\\ncpu%%d: elapsed time %%.3g seconds (%%g states visited)\\n\",", + " core_id, delta_time, nstates);", + " if (delta_time > 0.01)", + " { printf(\"cpu%%d: rate %%g states/second\\n\", core_id, nstates/delta_time);", + " }", + " { void check_overkill(void);", + " check_overkill();", + " } }", + "#else", + " if (report)", + " { report_time();", + " }", + "#endif", + "}", + "", + "#if NCORE>1", + "#ifdef T_ALERT", + "double t_alerts[17];", + "", + "void", + "crash_report(void)", + "{ int i;", + " printf(\"crash alert intervals:\\n\");", + " for (i = 0; i < 17; i++)", + " { printf(\"%%d\\t%%g\\n\", i, t_alerts[i]);", + "} }", + "#endif", + "", + "void", + "crash_reset(void)", + "{ /* false alarm */", + " if (crash_stamp != (clock_t) 0)", + " {", + "#ifdef T_ALERT", + " double delta_time;", + " int i;", + "#if defined(WIN32) || defined(WIN64)", + " delta_time = ((double) (clock() - crash_stamp)) / ((double) CLOCKS_PER_SEC);", + "#else", + " delta_time = ((double) (times(&start_tm) - crash_stamp)) / ((double) sysconf(_SC_CLK_TCK));", + "#endif", + " for (i = 0; i < 16; i++)", + " { if (delta_time <= (i*30))", + " { t_alerts[i] = delta_time;", + " break;", + " } }", + " if (i == 16) t_alerts[i] = delta_time;", + "#endif", + " if (verbose)", + " printf(\"cpu%%d: crash alert off\\n\", core_id);", + " }", + " crash_stamp = (clock_t) 0;", + "}", + "", + "int", + "crash_test(double maxtime)", + "{ double delta_time;", + " if (crash_stamp == (clock_t) 0)", + " { /* start timing */", + "#if defined(WIN32) || defined(WIN64)", + " crash_stamp = clock();", + "#else", + " crash_stamp = times(&start_tm);", + "#endif", + " if (verbose)", + " { printf(\"cpu%%d: crash detection\\n\", core_id);", + " }", + " return 0;", + " }", + "#if defined(WIN32) || defined(WIN64)", + " delta_time = ((double) (clock() - crash_stamp)) / ((double) CLOCKS_PER_SEC);", + "#else", + " delta_time = ((double) (times(&start_tm) - crash_stamp)) / ((double) sysconf(_SC_CLK_TCK));", + "#endif", + " return (delta_time >= maxtime);", + "}", + "#endif", + "", + "#ifdef BFS_PAR", + "int ncores = 0;", + "#endif", + "", "void", "do_the_search(void)", "{ int i;", @@ -1300,11 +2002,13 @@ static char *Code2c[] = { " 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", " }", @@ -1319,20 +2023,20 @@ static char *Code2c[] = { " }", "#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", @@ -1340,12 +2044,19 @@ static char *Code2c[] = { " { now._a_t = 2; /* set the A-bit */", " now._cnt[0] = now._nr_pr + 1;", /* NEW: +1 */ "#ifdef VERBOSE", - " printf(\"%%3d: fairness Rule 1, cnt=%%d, _a_t=%%d\\n\",", + " printf(\"%%3ld: fairness Rule 1, cnt=%%d, _a_t=%%d\\n\",", " depth, now._cnt[now._a_t&1], now._a_t);", "#endif", " }", "#endif", + " c_stack_start = (char *) &i; /* meant to be read-only */", + + "#if defined(HAS_CODE) && defined (C_INIT)", + " C_INIT; /* initialization of data that must precede fork() */", + " c_init_done++;", + "#endif", + "#if defined(C_States) && (HAS_TRACK==1)", " /* capture initial state of tracked C objects */", " c_update((uchar *) &(now.c_state[0]));", @@ -1354,17 +2065,30 @@ static char *Code2c[] = { "#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", - "#ifdef RANDOMIZE", - " srand(123);", - "#endif", - " new_state(); /* start 1st DFS */", + " #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+HASH_NR);", /* do_the_search */ + " #endif", + + " #if NCORE>1", + " mem_get();", + " #else", + " new_state(); /* start 1st DFS */", + " #endif", "#endif", "}", @@ -1373,42 +2097,41 @@ static char *Code2c[] = { "do_reverse(Trans *t, short II, uchar M)", "{ uchar _m = M;", " int tt = (int) ((P0 *)this)->_p;", - "#include REVERSE_MOVES", + "#include BACKWARD_MOVES", "R999: return _m;", "}", "#endif", "#ifndef INLINE", - "#ifdef EVENT_TRACE", + " #ifdef EVENT_TRACE", "static char _tp = 'n'; static int _qid = 0;", - "#endif", + " #endif", "uchar", "do_transit(Trans *t, short II)", "{ uchar _m = 0;", " int tt = (int) ((P0 *)this)->_p;", - "#ifdef M_LOSS", + " #ifdef M_LOSS", " uchar delta_m = 0;", - "#endif", - "#ifdef EVENT_TRACE", + " #endif", + " #ifdef EVENT_TRACE", " short oboq = boq;", " uchar ot = (uchar) ((P0 *)this)->_t;", - " if (ot == EVENT_TRACE) boq = -1;", + " 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", - " if (ot == EVENT_TRACE) boq = oboq;", - "#endif", + " #ifdef EVENT_TRACE", + " if (II == -EVENT_TRACE) boq = oboq;", + " #endif", " return _m;", - "#undef continue", + " #undef continue", "}", - "#ifdef EVENT_TRACE", "void", "require(char tp, int qid)", @@ -1417,67 +2140,65 @@ static char *Code2c[] = { "", " if (now._event != endevent)", " for (t = trans[EVENT_TRACE][now._event]; t; t = t->nxt)", - " { if (do_transit(t, EVENT_TRACE))", + " { 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))", + " { 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)", @@ -1496,21 +2217,132 @@ static char *Code2c[] = { " return res;", "}", "#endif", + "", + "#ifdef HAS_PRIORITY", + "int", + "highest_priority(int pid, short nII, Trans *t)", + "{ int i = pid; uchar *othis = this;", + "", + "#ifdef VERI", + " if (nII == 0)", + " { return 1;", /* never claim */ + " }", + "#endif", + "#ifdef HAS_PROVIDED", + " i = pid+BASE;", /* uncorrected process number */ + "#endif", + " if (i < 0", + " || i >= (int) now._nr_pr", + "#ifdef HAS_PROVIDED", + " || !provided(i, (uchar) ((P0 *)this)->_t, (int) ((P0 *)this)->_p, t)", + "#endif", + " )", + " { return 0;", + " }", + "", + " for (i = BASE; i < now._nr_pr; i++)", /* all except never, if present */ + " { this = pptr(i);", + " if (i != pid+BASE", + " && ((P0 *)this)->_priority > ((P0 *)pptr(pid+BASE))->_priority", + "#ifdef HAS_PROVIDED", + " && provided(i, (uchar) ((P0 *)this)->_t, (int) ((P0 *)this)->_p, 0)", + "#endif", + " && enabled(i+1, i-BASE))", /* enabled adds back BASE in 2nd arg */ + " { this = othis;", + " return 0;", + " } }", + " this = othis;", + " return 1;", + "}", + "int", + "get_priority(int pid)", + "{ pid += BASE; /* 6.2.7 */", + " if (pid < 0 || pid >= (int) now._nr_pr)", + " return 0;", + " return ((P0 *)pptr(pid))->_priority;", + "}", + "int", + "set_priority(int pid, int pr)", + "{ pid += BASE; /* 6.2.7 */", + " if (pid < 0 || pid >= (int) now._nr_pr)", + " {", + " #ifdef VERBOSE", + " printf(\"warning: bad pid %%d, no such process (set_priority)\\n\", pid);", + " #endif", + " return 1;", + " }", + " if (pr < 1 || pr > 255)", + " { Uerror(\"priority is out of range\");", + " }", + + " if (!TstOnly)", + " { (trpt+1)->o_priority = ", + " (((P0 *)pptr(pid))->_priority & 255) | (pid << 8);", + " ((P0 *)pptr(pid))->_priority = pr;", + " }", + + " return 1;", /* always executable */ + "}", + "#endif", + "", + "void", + "snap_time(void)", + "{ clock_t stop_time;", + " double delta_time;", + "#if !defined(WIN32) && !defined(WIN64)", + " struct tms stop_tm;", + " stop_time = times(&stop_tm);", + " delta_time = ((double) (stop_time - start_time)) / ((double) sysconf(_SC_CLK_TCK));", + "#else", + " stop_time = clock();", + " delta_time = ((double) (stop_time - start_time)) / ((double) CLOCKS_PER_SEC);", + "#endif", + " if (delta_time > 0.01)", + " { printf(\"t= %%8.3g \", delta_time);", + " printf(\"R= %%7.0g\", nstates/delta_time);", + " }", + " printf(\"\\n\");", + " if (quota > 0.1 && delta_time > quota)", + " { printf(\"Time limit of %%6.3g minutes exceeded\\n\", quota/60.0);", + "#if NCORE>1", + " fflush(stdout);", + " leave_critical(GLOBAL_LOCK);", + " sudden_stop(\"time-limit\");", + " exit(1);", + "#endif", + " wrapup();", + " }", + "}", "void", "snapshot(void)", - "{ static long sdone = (long) 0;", - " long ndone = (unsigned long) nstates/1000000;", - " if (ndone == sdone) return;", - " sdone = ndone;", - " printf(\"Depth= %%7d States= %%7g \", mreached, nstates);", - " printf(\"Transitions= %%7g \", nstates+truncs);", + "{", + "#ifdef BFS_PAR", + " e_critical(BFS_GLOB); /* bfs_par / snapshot */", + " printf(\"cpu%%d: \", who_am_i);", + "#endif", + "#if NCORE>1", + " enter_critical(GLOBAL_LOCK); /* ncore / snapshot */", + " printf(\"cpu%%d: \", core_id);", + "#endif", + " printf(\"Depth= %%7ld States= %%8.3g \",", + "#if NCORE>1", + " (long) (nr_handoffs * z_handoff) +", + "#endif", + " mreached, nstates);", + " printf(\"Transitions= %%8.3g \", nstates+truncs);", "#ifdef MA", - " printf(\"Nodes= %%7d \", nr_states);", + " printf(\"Nodes= %%7lu \", nr_states);", "#endif", - " printf(\"Memory= %%-6.3f\\n\", memcnt/1000000.);", + " printf(\"Memory= %%9.3f\\t\", memcnt/1048576.);", + " snap_time();", " fflush(stdout);", + "#if NCORE>1", + " leave_critical(GLOBAL_LOCK);", + "#endif", + "#ifdef BFS_PAR", + " x_critical(BFS_GLOB);", + "#endif", "}", - "#ifdef SC", "void", "stack2disk(void)", @@ -1552,46 +2384,246 @@ static char *Code2c[] = { "#endif", "uchar *", - "Pptr(int x)", /* as a fct, to avoid a problem with the p9 compiler */ - "{ if (x < 0 || x >= MAXPROC || !proc_offset[x])", /* does not exist */ + "Pptr(int x)", + "{ if (x < 0 || x >= MAXPROC", /* does not exist */ + "#ifdef TRIX", + " || !processes[x])", + "#else", + " || !proc_offset[x])", + "#endif", " return noptr;", " else", " return (uchar *) pptr(x);", + "}\n", + "uchar *", + "Qptr(int x)", + "{ if (x < 0 || x >= MAXQ", + "#ifdef TRIX", + " || !channels[x])", + "#else", + " || !q_offset[x])", + "#endif", + " return noqptr;", + " else", + " return (uchar *) qptr(x);", + "}\n", + "", + "#if NCLAIMS>1", + "void", + "select_claim(int n)", + "{ int m, i;", + " if (n < 0 || n >= NCLAIMS)", + " { uerror(\"non-existing claim\");", + " } else", + " { m = ((Pclaim *)pptr(0))->_n;", + " if (verbose)", + " { printf(\"%%d: Claim %%s (%%d), from state %%d\\n\",", + " (int) depth, procname[spin_c_typ[n]],", + " n, ((Pclaim *)pptr(0))->c_cur[n]);", + " } else", + " { printf(\"pan: ltl formula %%s\\n\",", + " procname[spin_c_typ[n]]);", + " }", + " ((Pclaim *)pptr(0))->c_cur[m] = ((Pclaim *)pptr(0))->_p;", + " ((Pclaim *)pptr(0))->_t = spin_c_typ[n];", + " ((Pclaim *)pptr(0))->_p = ((Pclaim *)pptr(0))->c_cur[n];", + " ((Pclaim *)pptr(0))->_n = n;", + " for (i = 0; src_all[i].src != (short *) 0; i++)", + " { if (src_all[i].tp == spin_c_typ[n])", + " { src_claim = src_all[i].src;", + " break;", + " } }", + " if (src_all[i].src == (short *) 0)", + " { uerror(\"cannot happen: src_ln ref\");", + " } }", "}", + "#else", + "void", + "select_claim(int n)", + "{ 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 P_REVERSE", + " #define FROM_P (BASE)", + " #define UPTO_P (now._nr_pr-1)", + " #define MORE_P (II <= To)", /* p.o. only */ + " #define INI_P (From-1)", /* fairness only */ + " #define CNT_P (1 + (To - From))", /* P_RAND start */ + " #define NDONE_P (From <= To)", /* P_RAND continue */ + " #define ALL_P (II = From; II <= To; II++)", + "#else", + " #define FROM_P (now._nr_pr-1)", + " #define UPTO_P (BASE)", + " #define MORE_P (II >= BASE)", + " #define INI_P (From+1)", + " #define CNT_P (1 + (From - To))", + " #define NDONE_P (From >= To)", + " #define ALL_P (II = From; II >= To; II--)", + "#endif", + "", + "#ifdef PERMUTED", + " #define CONTINUE0 { if (reversing&2) { II = oII; } continue; }", + " #define CONTINUE { if (reversing&2) { p_reorder(seed); II = oII; } continue; }", + "#else", + " #define CONTINUE0 { continue; }", + " #define CONTINUE { continue; }", + "#endif", + "#ifdef PERMUTED", + "uchar _permutation_[256];", + "void", + "set_reversed(int unused)", + "{ int i, n = now._nr_pr;", + " #ifdef VERBOSE", + " printf(\"%%ld: Set_reversed\\n\", depth);", + " #endif", + " #if defined(VERI) && !defined(NOCLAIM)", + " for (i = 1; i < n; i++)", + " { _permutation_[i] = n-i;", + " }", + " #else", + " for (i = 0; i < n; i++)", + " { _permutation_[i] = n-1-i;", + " }", + " #endif", + "}", + "void", + "set_rotated(int unused)", + "{ int i, n = now._nr_pr;", + " #ifdef VERBOSE", + " printf(\"%%ld: Set_rotated %%d\\n\", depth, p_rotate);", + " #endif", + " #if defined(VERI) && !defined(NOCLAIM)", + " for (i = 1; i < n; i++)", + " { _permutation_[i] = 1+(i-1+p_rotate)%%(n-1);", + " }", + " #else", + " for (i = 0; i < n; i++)", + " { _permutation_[i] = (i+p_rotate)%%n;", + " }", + " #endif", + "}", + "void", + "set_randrot(int unused)", + "{", + " if (now._nr_pr > 1)", + " { p_rotate = 1+rand()%%(now._nr_pr-1);", + " } else", + " { p_rotate = 0;", + " }", + " set_rotated(0);", + "}", + "void", + "set_permuted(int T)", + "{ /* permute nrs 1..n-1, leave 0 in place */", + " int i, j, k, n = now._nr_pr;", + " char tmp, *in = &(_permutation_[0]);", + " #ifdef VERBOSE", + " printf(\"%%ld: Set_permuted %%d\\n\", depth, T);", + " #endif", + " srand(T);", /* set_permuted */ + " for (i = 0; i < n; i++)", + " { in[i] = i;", + " }", + " if (n > 1)", + " { for (i = 0; i < n; i++)", + " {", + " #if defined(VERI) && !defined(NOCLAIM)", + " j = 1 + rand()%%(n-1);", + " k = 1 + rand()%%(n-1);", + " #else", + " j = rand()%%(n);", + " k = rand()%%(n);", + " #endif", + " tmp = in[j];", + " in[j] = in[k];", + " in[k] = tmp;", + " } }", + "}", + "", + " #ifdef VERBOSE", + " short", + " get_permuted(int x)", + " { printf(\"%%ld: Get_permuted %%d -> %%d\\n\",", + " depth, x, _permutation_[x]);", + " return (short) _permutation_[x];", + " }", + " #else", + " #define get_permuted(x) (short) _permutation_[x]", + " #endif", + "", + "#endif", "/*", " * new_state() is the main DFS search routine in the verifier", " * it has a lot of code ifdef-ed together to support", " * different search modes, which makes it quite unreadable.", - " * if you are studying the code, first use the C preprocessor", + " * if you are studying the code, use the C preprocessor", " * to generate a specific version from the pan.c source,", " * e.g. by saying:", " * gcc -E -DNOREDUCE -DBITSTATE pan.c > ppan.c", - " * and then study the resulting file, rather than this one", + " * and then study the resulting file, instead of this version", " */", - "#if !defined(BFS) && (!defined(BITSTATE) || !defined(MA))", + "", "void", "new_state(void)", "{ Trans *t;", " uchar _n, _m, ot;", - "#ifdef RANDOMIZE", + "#ifdef T_RAND", " short ooi, eoi;", "#endif", + "#ifdef PERMUTED", + " short oII; uint seed;", + "#endif", "#ifdef M_LOSS", " uchar delta_m = 0;", "#endif", " short II, JJ = 0, kk;", " int tt;", - " short From = now._nr_pr-1, To = BASE;", + " short From = FROM_P, To = UPTO_P;", + "#ifdef BCS", + " trpt->sched_limit = 0; /* at depth=0 only */", + "#endif", "Down:", "#ifdef CHECK", - " printf(\"%%d: Down - %%s\",", - " depth, (trpt->tau&4)?\"claim\":\"program\");", - " printf(\" %%saccepting [pids %%d-%%d]\\n\",", + " cpu_printf(\"%%d: Down - %%s %%saccepting [pids %%d-%%d]\\n\",", + " depth, (trpt->tau&4)?\"claim\":\"program\",", " (trpt->o_pm&2)?\"\":\"non-\", From, To);", "#endif", + "#ifdef P_RAND", + " trpt->p_skip = -1;", + "#endif", + "#ifdef SC", " if (depth > hiwater)", " { stack2disk();", @@ -1599,7 +2631,7 @@ static char *Code2c[] = { " hiwater += DDD;", " trpt -= DDD;", " if(verbose)", - " printf(\"zap %%d: %%d (maxdepth now %%d)\\n\",", + " printf(\"zap %%ld: %%ld (maxdepth now %%ld)\\n\",", " CNT1, hiwater, maxdepth);", " }", "#endif", @@ -1608,126 +2640,233 @@ static char *Code2c[] = { "#if defined(FULLSTACK) && defined(MA)", " trpt->proviso = 0;", "#endif", - " if (depth >= maxdepth)", - " { truncs++;", + "#ifdef NSUCC", + " trpt->n_succ = 0;", + "#endif", + "#if NCORE>1", + " if (mem_hand_off())", + " {", "#if SYNC", - " (trpt+1)->o_n = 1; /* not a deadlock */", + " (trpt+1)->o_n = 1; /* not a deadlock: as below */", + "#endif", + "#ifndef LOOPSTATE", + " (trpt-1)->tau |= 16; /* worstcase guess: as below */", + "#endif", + "#if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", "#endif", - " if (!warned)", + " goto Up;", + " }", + "#endif", + + " if (depth >= maxdepth)", + " { if (!warned)", " { warned = 1;", " printf(\"error: max search depth too small\\n\");", " }", - " if (bounded) uerror(\"depth limit reached\");", - " (trpt-1)->tau |= 16; /* worstcase guess */", + " if (bounded)", + " { uerror(\"depth limit reached\");", + " }", + " truncs++;", + "#if SYNC", + " (trpt+1)->o_n = 1; /* not a deadlock */", + "#endif", + "#ifndef LOOPSTATE", + " (trpt-1)->tau |= 16; /* worstcase guess */", + "#endif", + + "#if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", + "#endif", " goto Up;", " }", "AllOver:", - "#if defined(FULLSTACK) && !defined(MA)", + "#if (defined(FULLSTACK) && !defined(MA)) || NCORE>1", " /* if atomic or rv move, carry forward previous state */", - " trpt->ostate = (trpt-1)->ostate;", /* was: = (struct H_el *) 0;*/ + " trpt->ostate = (trpt-1)->ostate;", "#endif", "#ifdef VERI", " if ((trpt->tau&4) || ((trpt-1)->tau&128))", "#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", - " goto Up;", + "#ifndef NOFAIR", + " if (fairness && now._cnt[1] != 1) /* was > 1 */", + " {", + " #ifdef CHECK", + " printf(\"\tfairness count non-zero\\n\");", + " #endif", + " /* treat as new state */", + " } else", + "#endif", + " { depthfound = A_depth;", + " #ifdef CHECK", + " printf(\"matches seed\\n\");", + " #endif", + " #ifdef NP", + " uerror(\"non-progress cycle\");", + " #else", + " uerror(\"acceptance cycle\");", + " #endif", + " #if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", + " #endif", + " goto Up;", + " } }", + " #ifdef CHECK", + " else", + " {", + " printf(\"not seed\\n\");", " }", - "#ifdef CHECK", - " printf(\"not seed\\n\");", - "#endif", + " #endif", " }", "#endif", " if (!(trpt->tau&8)) /* if no atomic move */", " {", + "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " uchar was_last = now._last;", + " now._last = 0; /* value not stored */", + "#endif", "#ifdef BITSTATE", "#ifdef CNTRSTACK", /* -> bitstate, reduced, safety */ - " II = bstore((char *)&now, vsize);", - " trpt->j6 = j1; trpt->j7 = j2;", - " JJ = LL[j1] && LL[j2];", + " #if defined(BCS) && defined(STORE_CTX)", + " { int xj;", + " for (xj = trpt->sched_limit; xj <= sched_max; xj++)", + " { now._ctx = xj;", + " 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 = b_store((char *)&now, vsize);", + " trpt->j6 = j1_spin; trpt->j7 = j2_spin;", + " JJ = LL[j1_spin] && LL[j2_spin];", + " #endif", "#else", - "#ifdef FULLSTACK", - " JJ = onstack_now();", /* sets j1 */ - "#else", - "#ifndef NOREDUCE", - " JJ = II; /* worstcase guess for p.o. */", - "#endif", - "#endif", - " II = bstore((char *)&now, vsize);", /* sets 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 = b_store((char *)&now, vsize);", /* sets j1-j4 */ + " if (II != 0) { break; }", + " }", + " now._ctx = 0;", + " }", + " #else", + " JJ = onstack_now();", /* mangles j1 */ + " 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 = 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 = 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;", "#endif", "#endif", "#endif", " kk = (II == 1 || II == 2);", + /* actually, BCS implies HAS_LAST */ + "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " now._last = was_last; /* restore value */", + "#endif", + /* II==0 new state */ /* II==1 old state */ /* II==2 on current dfs stack */ /* II==3 on 1st dfs stack */ "#ifndef SAFETY", - - " if (!fairness && a_cycles)", + /* 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)))", - " { II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */", - "#ifdef VERBOSE", + " #ifndef NOFAIR", + " if (a_cycles && !fairness) /* 5.1.6 -- example by Hirofumi Watanabe */", + " #endif", + " if (depth > A_depth) /* forum example by adl */", + " {", + " II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */", + "#ifdef VERBOSE", " printf(\"state match on dfs stack\\n\");", - "#endif", + "#endif", " goto same_case;", " }", - + "#endif", "#if defined(FULLSTACK) && defined(BITSTATE)", " if (!JJ && (now._a_t&1) && depth > A_depth)", - " { int oj1 = j1;", + " { int oj1 = j1_spin;", " uchar o_a_t = now._a_t;", " now._a_t &= ~(1|16|32);", /* 1st stack */ - " if (onstack_now())", /* changes j1 */ + " if (onstack_now())", /* changes j1_spin */ " { II = 3;", "#ifdef VERBOSE", " printf(\"state match on 1st dfs stack\\n\");", "#endif", " }", " now._a_t = o_a_t;", /* restore */ - " j1 = oj1;", + " j1_spin = oj1;", " }", "#endif", " if (II == 3 && a_cycles && (now._a_t&1))", " {", "#ifndef NOFAIR", - " if (fairness && now._cnt[1] > 1) /* was != 0 */", + " if (fairness && now._cnt[1] != 1) /* was > 1 */", " {", - "#ifdef VERBOSE", + " #ifdef CHECK", " printf(\"\tfairness count non-zero\\n\");", - "#endif", + " #endif", " II = 0;", /* treat as new state */ " } else", "#endif", @@ -1741,47 +2880,114 @@ static char *Code2c[] = { "#else", " uerror(\"acceptance cycle\");", "#endif", + "#if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", + "#endif", " goto Up;", " }", " }", "#endif", "#ifndef NOREDUCE", - "#ifndef SAFETY", + " #ifndef SAFETY", + " #if NCORE>1 && !defined(SEP_STATE) && defined(V_PROVISO)", + " if (II != 0 && (!Lstate || Lstate->cpu_id < core_id))", + " { (trpt-1)->tau |= 16;", /* treat as a stack state */ + " }", + " #endif", " if ((II && JJ) || (II == 3))", " { /* marker for liveness proviso */", - " (trpt-1)->tau |= 16;", + " #ifndef LOOPSTATE", + " (trpt-1)->tau |= 16;", /* truncated on stack */ + " #endif", " truncs2++;", " }", "#else", + " #if NCORE>1 && !defined(SEP_STATE) && defined(V_PROVISO)", + " if (!(II != 0 && (!Lstate || Lstate->cpu_id < core_id)))", + " { /* treat as stack state */", + " (trpt-1)->tau |= 16;", + " } else", + " { /* treat as non-stack state */", + " (trpt-1)->tau |= 64;", + " }", + " #endif", " if (!II || !JJ)", " { /* successor outside stack */", " (trpt-1)->tau |= 64;", " }", - "#endif", + " #endif", + "#endif", + "#if defined(BCS) && (defined(NOREDUCE) || !defined(SAFETY))", + /* needed for BCS - cover cases where it would not otherwise be set */ + " if (!II || !JJ)", + " { (trpt-1)->tau |= 64;", + " }", "#endif", " if (II)", " { truncs++;", + "#if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " if (depth == 0)", + " { return;", + " } }", + "#endif", " goto Up;", " }", " if (!kk)", - " { nstates++;", - " if ((unsigned long) nstates%%1000000 == 0)", - " snapshot();", + " { static long sdone = (long) 0; long ndone;", + " nstates++;", + "#if defined(ZAPH) && defined(BITSTATE)", + " zstates += (double) hfns;", + "#endif", + " ndone = (ulong) (nstates/(freq));", + " if (ndone != sdone)", + " { snapshot();", + " sdone = ndone;", + "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", + " if (nstates > ((double)(ONE_L<<(ssize+1))))", + " { void resize_hashtable(void);", + " resize_hashtable();", + " }", + "#endif", + "#if defined(ZAPH) && defined(BITSTATE)", + " if (zstates > ((double)(ONE_L<<(ssize-2))))", + " { /* more than half the bits set */", + " void zap_hashtable(void);", + " zap_hashtable();", + " zstates = 0;", + " }", + "#endif", + " }", "#ifdef SVDUMP", " if (vprefix > 0)", + " #ifdef SHO", /* Store Hash Only */ + " /* always use the same hashfunction, for consistency across runs */", + " if (HASH_NR != 0)", + " { int oh = HASH_NR;", + " HASH_NR = 0;", + " d_hash((uchar *) &now, vsize); /* SHO - set K1 */", + " HASH_NR = oh;", + " }", + " if (write(svfd, (uchar *) &K1, sizeof(ulong)) != sizeof(ulong))", + " #else", " if (write(svfd, (uchar *) &now, vprefix) != vprefix)", - " { fprintf(efd, \"writing %%s.svd failed\\n\", Source);", + " #endif", + " { fprintf(efd, \"writing %%s.svd failed\\n\", PanSource);", " wrapup();", " }", "#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();", " }", "#endif", " }", + "#if defined(FULLSTACK) || defined(CNTRSTACK)", " onstack_put();", "#ifdef DEBUG2", @@ -1793,10 +2999,13 @@ static char *Code2c[] = { " printf(\"%%d: putting\\n\", depth);", "#endif", "#endif", + "#else", + " #if NCORE>1", + " trpt->ostate = Lstate;", + " #endif", "#endif", " } }", - " if (depth > mreached)", " mreached = depth;", "#ifdef VERI", @@ -1809,40 +3018,56 @@ static char *Code2c[] = { "#endif", "#ifdef VERI", " if (now._nr_pr == 0) /* claim terminated */", - " uerror(\"end state in claim reached\");", - " check_claim(((P0 *)pptr(0))->_p);", + " { uerror(\"end state in claim reached\");", + " }", + " if (stopstate[((Pclaim *)pptr(0))->_t][((Pclaim *)pptr(0))->_p])", + " { uerror(\"end state in claim reached\");", + " }", "Stutter:", " if (trpt->tau&4) /* must make a claimmove */", " {", - - "#ifndef NOFAIR", + " #ifndef NOFAIR", " if ((now._a_t&2) /* A-bit set */", " && now._cnt[now._a_t&1] == 1)", " { now._a_t &= ~2;", " now._cnt[now._a_t&1] = 0;", " trpt->o_pm |= 16;", - "#ifdef DEBUG", + "#ifdef DEBUG", " printf(\"%%3d: fairness Rule 3.: _a_t = %%d\\n\",", - " depth, now._a_t);", - "#endif", + " (int) depth, now._a_t);", + "#endif", " }", - "#endif", - + " #endif", " II = 0; /* never */", " goto Veri0;", " }", "#endif", + "#ifdef PERMUTED", + " if (reversing&2)", + " { seed = rand();", + " p_reorder(seed);", + " }", + "#endif", "#ifndef NOREDUCE", " /* Look for a process with only safe transitions */", " /* (special rules apply in the 2nd dfs) */", -"#ifdef SAFETY", - " if (boq == -1 && From != To)", -"#else", - "/* implied: #ifdef FULLSTACK */", " if (boq == -1 && From != To", + "", + "#ifdef SAFETY", + " #if NCORE>1", + " && (depth < z_handoff)", /* not for border states */ + " #endif", + " )", + "#else", + " #if NCORE>1", + " && ((a_cycles) || (!a_cycles && depth < z_handoff))", + " #endif", + " #ifdef BCS", + " && (sched_max > 0 || depth > BASE)", /* no po in initial state if -L0 */ + " #endif", " && (!(now._a_t&1)", " || (a_cycles &&", - "#ifndef BITSTATE", + " #ifndef BITSTATE", "#ifdef MA", "#ifdef VERI", " !((trpt-1)->proviso))", @@ -1852,63 +3077,58 @@ static char *Code2c[] = { "#else", "#ifdef VERI", " (trpt-1)->ostate &&", - " !(((char *)&((trpt-1)->ostate->state))[0] & 128))", + " !(((char *)&((trpt-1)->ostate->state))[0] & 128))", /* proviso bit in _a_t */ "#else", " !(((char *)&(trpt->ostate->state))[0] & 128))", "#endif", "#endif", - "#else", + " #else", "#ifdef VERI", " (trpt-1)->ostate &&", " (trpt-1)->ostate->proviso == 0)", "#else", " trpt->ostate->proviso == 0)", "#endif", - "#endif", + " #endif", " ))", - "/* #endif */", -"#endif", - " for (II = From; II >= To; II -= 1)", - " {", - "Resume: /* pick up here if preselect fails */", - " this = pptr(II);", - " tt = (int) ((P0 *)this)->_p;", - " ot = (uchar) ((P0 *)this)->_t;", - " if (trans[ot][tt]->atom & 8)", - " { t = trans[ot][tt];", - " if (t->qu[0] != 0)", - " { Ccheck++;", - " if (!q_cond(II, t))", - " continue;", - " Cholds++;", - " }", - " From = To = II;", + "#endif", /* SAFETY */ + " /* attempt Partial Order Reduction as preselect moves */", + "#ifdef BCS", + " if (trpt->sched_limit < sched_max)", /* po only if we can switch */ + "#endif", + " { for ALL_P {", /* PO preselect */ + "Resume: /* pick up here if preselect fails */", + " this = pptr(II);", + " tt = (int) ((P0 *)this)->_p;", + " ot = (uchar) ((P0 *)this)->_t;", + " if (trans[ot][tt]->atom & 8)", + " { t = trans[ot][tt];", + " if (t->qu[0] != 0)", + " { Ccheck++;", + " if (!q_cond(II, t))", + " { continue;", + " }", + " Cholds++;", + " }", + " From = To = II; /* preselect process */", "#ifdef NIBIS", - " t->om = 0;", + " t->om = 0;", "#endif", - " trpt->tau |= 32; /* preselect marker */", - "#ifdef DEBUG", - "#ifdef NIBIS", - " printf(\"%%3d: proc %%d Pre\", depth, II);", - " printf(\"Selected (om=%%d, tau=%%d)\\n\", ", - " t->om, trpt->tau);", - "#else", - " printf(\"%%3d: proc %%d PreSelected (tau=%%d)\\n\", ", - " depth, II, trpt->tau);", - "#endif", - "#endif", - " goto Again;", - " }", - " }", + " trpt->tau |= 32; /* preselect marker */", + "#ifdef DEBUG", + " printf(\"%%3ld: proc %%d PreSelected (tau=%%d)\\n\", ", + " depth, II, trpt->tau);", + "#endif", + " goto Again;", + " } else", + " { continue;", + " } } }", " trpt->tau &= ~32;", "#endif", "#if !defined(NOREDUCE) || (defined(ETIM) && !defined(VERI))", "Again:", "#endif", - " /* The Main Expansion Loop over Processes */", - - " trpt->o_pm &= ~(8|16|32|64); /* fairness-marks */", - + " trpt->o_pm &= ~(8|16|32|64); /* clear fairness-marks */", "#ifndef NOFAIR", " if (fairness && boq == -1", "#ifdef VERI", @@ -1917,36 +3137,136 @@ static char *Code2c[] = { " && !(trpt->tau&8))", " { /* A_bit = 1; Cnt = N in acc states with A_bit 0 */", " if (!(now._a_t&2))", /* A-bit not set */ - " {", - " if (a_cycles && (trpt->o_pm&2))", + " { if (a_cycles && (trpt->o_pm&2))", " { /* Accepting state */", " now._a_t |= 2;", - " now._cnt[now._a_t&1] = now._nr_pr + 1;", /* NEW +1 */ + " now._cnt[now._a_t&1] = now._nr_pr + 1;", " trpt->o_pm |= 8;", "#ifdef DEBUG", - " printf(\"%%3d: fairness Rule 1: cnt=%%d, _a_t=%%d\\n\",", + " printf(\"%%3ld: fairness Rule 1: cnt=%%d, _a_t=%%d\\n\",", " depth, now._cnt[now._a_t&1], now._a_t);", "#endif", " }", " } else", /* A-bit set */ " { /* A_bit = 0 when Cnt 0 */", - " if (now._cnt[now._a_t&1] == 1)", /* NEW: 1 iso 0 */ - " { now._a_t &= ~2;", /* reset a-bit */ - " now._cnt[now._a_t&1] = 0;", /* NEW: reset cnt */ + " if (now._cnt[now._a_t&1] == 1)", + " { now._a_t &= ~2;", /* reset a-bit */ + " now._cnt[now._a_t&1] = 0;", " trpt->o_pm |= 16;", "#ifdef DEBUG", - " printf(\"%%3d: fairness Rule 3: _a_t = %%d\\n\",", + " printf(\"%%3ld: fairness Rule 3: _a_t = %%d\\n\",", " depth, now._a_t);", "#endif", " } } }", "#endif", - " for (II = From; II >= To; II -= 1)", - " {", + "#ifdef BCS", /* bounded context switching */ + " trpt->bcs = trpt->b_pno = 0; /* initial */", + " if (From != To /* not a PO or atomic move */", + " && depth > BASE) /* there is a prior move */", + " { trpt->b_pno = now._last + BASE;", + " trpt->bcs = B_PHASE1;", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS phase 1 proc %%d limit %%d\\n\",", + " depth, trpt->b_pno, trpt->sched_limit);", + " #endif", + " /* allow only process b_pno to move in this phase */", + " }", + "c_switch: /* jumps here with bcs == B_PHASE2 with or wo B_FORCED added */", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS c_switch phase=%%d pno=%%d [forced %%d]\\n\",", + " depth, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", + " #endif", + "#endif", + + "#ifdef P_RAND", + " trpt->p_left = CNT_P;", + " if (trpt->p_left > 1)", + " { trpt->p_skip = rand() %% (trpt->p_left);", + " } else", + " { trpt->p_skip = -1;", + " }", + "r_switch:", + " #ifdef VERBOSE", + " printf(\"%%3ld: P_RAND r_switch p_skip=%%d p_left=%%d\\n\",", + " depth, trpt->p_skip, trpt->p_left);", + " #endif", + "#endif", + + " for ALL_P {", /* Main Loop */ + "#ifdef PERMUTED", + " if (reversing&2)", + " { oII = II;", + " if (From != To)", /* not atomic or preselected */ + " { II = get_permuted(II);", + " } }", + "#endif", + "#ifdef P_RAND", + " if (trpt->p_skip >= 0)", + " { trpt->p_skip--; /* skip random nr of procs */", + " #ifdef VERBOSE", + " printf(\"%%3ld: P_RAND skipping %%d [new p_skip=%%d p_left=%%d]\\n\",", + " depth, II, trpt->p_skip, trpt->p_left);", + " #endif", + " CONTINUE0;", + " }", + " if (trpt->p_left == 0)", + " {", + " #ifdef VERBOSE", + " printf(\"%%3ld: P_RAND done at %%d\\n\", depth, II);", + " #endif", + " break; /* done */", + " }", + " #ifdef VERBOSE", + " printf(\"%%3ld: P_RAND explore %%d [p_left=%%d]\\n\",", + " depth, II, trpt->p_left);", + " #endif", + " trpt->p_left--;", + "#endif", + "#if SYNC", " /* no rendezvous with same proc */", - " if (boq != -1 && trpt->pr == II) continue;", + " if (boq != -1 && trpt->pr == II)", + " { CONTINUE0;", + " }", "#endif", + + "#ifdef BCS", /* never claim with II==0 cannot get here */ + " if ((trpt->bcs & B_PHASE1)", + " && trpt->b_pno != II)", + " {", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS NotPre II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", + " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", + " #endif", + " CONTINUE0;", /* avoid context switch */ + " }", + " #ifdef VERBOSE", + " else if ((trpt->bcs & B_PHASE1) && trpt->b_pno == II)", + " printf(\"%%3ld: BCS IsPre II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", + " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", + " #endif", + + " if (trpt->bcs & B_PHASE2) /* 2nd phase */", + " { if (trpt->b_pno == II) /* was already done in phase 1 */", + " {", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS NoRepeat II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", + " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", + " #endif", + " CONTINUE0;", + " }", + " if (!(trpt->bcs & B_FORCED) /* unless forced */", + " && trpt->sched_limit >= sched_max)", + " {", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS Bound II=%%d bcs=%%d pno=%%d [forced %%d]\\n\",", + " depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0);", + " #endif", + " CONTINUE0; /* enforce bound */", + " } }", + "#endif", + "#ifdef VERI", "Veri0:", "#endif", @@ -1967,8 +3287,10 @@ static char *Code2c[] = { " { if (t->qu[0] == 0", /* unconditional */ " || q_cond(II, t))", /* true condition */ " { _m = t->om;", - " if (_m>_n||(_n>3&&_m!=0)) _n=_m;", - " continue; /* did it before */", + " if (_m>_n||(_n>3&&_m!=0))", + " { _n=_m;", + " }", + " CONTINUE0; /* did it before */", " } }", "#endif", " trpt->o_pm &= ~1; /* no move in this pid yet */", @@ -1990,16 +3312,26 @@ static char *Code2c[] = { " now._cnt[now._a_t&1] = 1;", "#endif", "#ifdef DEBUG", - " printf(\"%%3d: proc %%d fairness \", depth, II);", + " printf(\"%%3ld: proc %%d fairness \", depth, II);", " printf(\"Rule 2: --cnt to %%d (%%d)\\n\",", " now._cnt[now._a_t&1], now._a_t);", "#endif", " trpt->o_pm |= (32|64);", " }", "#endif", - "#ifdef HAS_PROVIDED", - " if (!provided(II, ot, tt, t)) continue;", + + "#ifdef HAS_PRIORITY", + " if (!highest_priority(((P0 *)this)->_pid, II, t))", + " { CONTINUE0;", + " }", + "#else", + " #ifdef HAS_PROVIDED", + " if (!provided(II, ot, tt, t))", + " { CONTINUE0;", + " }", + " #endif", "#endif", + " /* check all trans of proc II - escapes first */", "#ifdef HAS_UNLESS", " trpt->e_state = 0;", @@ -2007,27 +3339,31 @@ static char *Code2c[] = { " (trpt+1)->pr = (uchar) II;", /* for uerror */ " (trpt+1)->st = tt;", - "#ifdef RANDOMIZE", + "#ifdef T_RAND", " for (ooi = eoi = 0, t = trans[ot][tt]; t; t = t->nxt, ooi++)", - " if (strcmp(t->tp, \"else\") == 0)", - " eoi++;", - "", - " if (eoi)", + " { if (strcmp(t->tp, \"else\") == 0", + " #ifdef HAS_UNLESS", + " || t->e_trans != 0", + " #endif", + " )", + " { eoi++;", /* no break, must count ooi */ + " } }", + " if (eoi > 0)", " { t = trans[ot][tt];", - "#ifdef VERBOSE", - " printf(\"randomizer: suppressed, saw else\\n\");", - "#endif", - " } else", + " #ifdef VERBOSE", + " printf(\"randomizer: suppressed, saw else or escape\\n\");", + " #endif", + " } else if (ooi > 0)", " { eoi = rand()%%ooi;", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"randomizer: skip %%d in %%d\\n\", eoi, ooi);", - "#endif", + " #endif", " for (t = trans[ot][tt]; t; t = t->nxt)", " if (eoi-- <= 0) break;", " }", - "DOMORE:", + "domore:", " for ( ; t && ooi > 0; t = t->nxt, ooi--)", - "#else", + "#else", /* ie dont randomize */ " for (t = trans[ot][tt]; t; t = t->nxt)", "#endif", " {", @@ -2045,49 +3381,83 @@ static char *Code2c[] = { " break;", " }", "#endif", + " #if defined(TRIX) && !defined(TRIX_ORIG) && !defined(BFS)", + " (trpt+1)->p_bup = now._ids_[II];", + " #endif", " (trpt+1)->o_t = t;", /* for uerror */ "#ifdef INLINE", "#include FORWARD_MOVES", "P999: /* jumps here when move succeeds */", "#else", - " if (!(_m = do_transit(t, II))) continue;", + " if (!(_m = do_transit(t, II)))", + " { continue;", + " }", + "#endif", + "#ifdef BCS", + " if (depth > BASE", /* has prior move */ + " && II >= BASE", /* not claim */ + " && From != To", /* not atomic or po */ + " #ifndef BCS_NOFIX", + " /* added 5.2.5: prior move was not po */", + " && !((trpt-(BASE+1))->tau & 32)", + " #endif", + " && boq == -1", /* not rv */ + " && (trpt->bcs & B_PHASE2)", + " && trpt->b_pno != II /* context switch */", /* redundant */ + " && !(trpt->bcs & B_FORCED)) /* unless forced */", + " { (trpt+1)->sched_limit = 1 + trpt->sched_limit;", + " #ifdef VERBOSE", + " printf(\"%%3ld: up sched count to %%d\\n\", depth, (trpt+1)->sched_limit);", + " #endif", + " } else", + " { (trpt+1)->sched_limit = trpt->sched_limit;", + " #ifdef VERBOSE", + " printf(\"%%3ld: keep sched count at %%d\\n\", depth, (trpt+1)->sched_limit);", + " #endif", + " }", "#endif", " if (boq == -1)", -"#ifdef CTL", + "#ifdef CTL", " /* for branching-time, can accept reduction only if */", " /* the persistent set contains just 1 transition */", " { if ((trpt->tau&32) && (trpt->o_pm&1))", - " trpt->tau |= 16;", + " trpt->tau |= 16;", /* CTL */ " trpt->o_pm |= 1; /* we moved */", " }", -"#else", + "#else", " trpt->o_pm |= 1; /* we moved */", -"#endif", + "#endif", + + "#ifdef LOOPSTATE", + " if (loopstate[ot][tt])", + " {", + "#ifdef VERBOSE", + " printf(\"exiting from loopstate:\\n\");", + "#endif", + " trpt->tau |= 16;", /* exiting loopstate */ + " cnt_loops++;", + " }", + "#endif", + "#ifdef PEG", " peg[t->forw]++;", "#endif", - "#if defined(VERBOSE) || defined(CHECK)", "#if defined(SVDUMP)", - " printf(\"%%3d: proc %%d exec %%d \\n\", ", - " depth, II, t->t_id);", + " cpu_printf(\"%%3ld: proc %%d exec %%d \\n\", depth, II, t->t_id);", "#else", - " printf(\"%%3d: proc %%d exec %%d, \", ", - " depth, II, t->forw);", - " printf(\"%%d to %%d, %%s %%s %%s\", ", - " tt, t->st, t->tp,", + " cpu_printf(\"%%3ld: proc %%d exec %%d, %%d to %%d, %%s %%s %%s %%saccepting [tau=%%d]\\n\", ", + " depth, II, t->forw, 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\",", + " (boq != -1)?\"rendez-vous\":\"\",", " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);", + "#ifdef HAS_UNLESS", + " if (t->e_trans)", + " cpu_printf(\"\\t(escape to state %%d)\\n\", t->st);", "#endif", - "#ifdef RANDOMIZE", - " printf(\" randomizer %%d\\n\", ooi);", + "#endif", + "#ifdef T_RAND", + " cpu_printf(\"\\t(randomizer %%d)\\n\", ooi);", "#endif", "#endif", @@ -2143,9 +3513,16 @@ static char *Code2c[] = { " trpt->o_ot = ot; trpt->o_tt = tt;", " trpt->o_To = To; trpt->o_m = _m;", " trpt->tau = 0;", -"#ifdef RANDOMIZE", + "#ifdef PERMUTED", + " if (reversing&2)", + " { trpt->seed = seed;", + " trpt->oII = oII;", + " }", + "#endif", + + "#if defined(T_RAND) && !defined(BFS)", " trpt->oo_i = ooi;", -"#endif", + "#endif", " if (boq != -1 || (t->atom&2))", " { trpt->tau |= 8;", "#ifdef VERI", @@ -2171,30 +3548,76 @@ static char *Code2c[] = { " if (boq == -1 && (t->atom&2))", " { From = To = II; nlinks++;", " } else", - " { From = now._nr_pr-1; To = BASE;", + " { From = FROM_P; To = UPTO_P;", + " }", + "#if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Push_Stack_Tree(II, t->t_id);", + " }", + "#endif", + "#ifdef TRIX", + " if (processes[II])", /* last move could have been a delproc */ + " { processes[II]->modified = 1; /* transition in II */", + " #ifdef V_TRIX", + " printf(\"%%4d: process %%d modified\\n\", depth, II);", + " } else", + " { printf(\"%%4d: process %%d modified but gone (%%p)\\n\",", + " depth, II, trpt);", + " #endif", " }", + "#endif", " goto Down; /* pseudo-recursion */", "Up:", + "#ifdef TRIX", + " #ifndef TRIX_ORIG", + " #ifndef BFS", + " now._ids_[trpt->pr] = trpt->p_bup;", + " #endif", + " #else", + " if (processes[trpt->pr])", + " {", + " processes[trpt->pr]->modified = 1; /* reverse move */", + " #ifdef V_TRIX", + " printf(\"%%4d: unmodify pr %%d (%%p)\\n\",", + " depth, trpt->pr, trpt);", + " } else", + " { printf(\"%%4d: unmodify pr %%d (gone) (%%p)\\n\",", + " depth, trpt->pr, trpt);", + " #endif", + " }", + " #endif", + "#endif", "#ifdef CHECK", - " printf(\"%%d: Up - %%s\\n\", depth,", - " (trpt->tau&4)?\"claim\":\"program\");", + " cpu_printf(\"%%d: Up - %%s\\n\", depth,", + " (trpt->tau&4)?\"claim\":\"program\");", "#endif", - "#ifdef MA", - " if (depth <= 0) return;", - " /* e.g., if first state is old, after a restart */", + "#if NCORE>1", + " iam_alive();", + " #ifdef USE_DISK", + " mem_drain();", + " #endif", + "#endif", + "#if defined(MA) || NCORE>1", + " if (depth <= 0) return;", + " /* e.g., if first state is old, after a restart */", "#endif", "#ifdef SC", - " if (CNT1 > CNT2", - " && depth < hiwater - (HHH-DDD) + 2)", - " {", - " trpt += DDD;", - " disk2stack();", - " maxdepth -= DDD;", - " hiwater -= DDD;", - "if(verbose)", - "printf(\"unzap %%d: %%d\\n\", CNT2, hiwater);", - " }", + " if (CNT1 > CNT2", + " && depth < hiwater - (HHH-DDD) - 2)", /* 5.1.6: was + 2 */ + " {", + " trpt += DDD;", + " disk2stack();", + " maxdepth -= DDD;", + " hiwater -= DDD;", + " if(verbose)", + " printf(\"unzap %%ld: %%ld\\n\", CNT2, hiwater);", + " }", + "#endif", + + "#ifndef SAFETY", /* moved earlier in version 5.2.5 */ + " if ((now._a_t&1) && depth <= A_depth)", + " return; /* to checkcycles() */", "#endif", "#ifndef NOFAIR", @@ -2203,7 +3626,7 @@ static char *Code2c[] = { " _n = 1; trpt->o_pm &= ~128;", " depth--; trpt--;", "#if defined(VERBOSE) || defined(CHECK)", - " printf(\"%%3d: reversed fairness default move\\n\", depth);", + " printf(\"%%3ld: reversed fairness default move\\n\", depth);", "#endif", " goto Q999;", " }", @@ -2211,7 +3634,7 @@ static char *Code2c[] = { "#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) */", @@ -2226,61 +3649,63 @@ static char *Code2c[] = { "#ifdef EVENT_TRACE", " now._event = trpt->o_event;", "#endif", - "#ifndef SAFETY", - " if ((now._a_t&1) && depth <= A_depth)", - " return; /* to checkcycles() */", - "#endif", " t = trpt->o_t; _n = trpt->o_n;", " ot = trpt->o_ot; II = trpt->pr;", - " tt = trpt->o_tt; this = pptr(II);", + " tt = trpt->o_tt; this = Pptr(II);", " To = trpt->o_To; _m = trpt->o_m;", -"#ifdef RANDOMIZE", + "#ifdef PERMUTED", + " if (reversing&2)", + " { seed = trpt->seed;", + " oII = trpt->oII;", + " }", + "#endif", + "#if defined(T_RAND) && !defined(BFS)", " ooi = trpt->oo_i;", -"#endif", + "#endif", "#ifdef INLINE_REV", " _m = do_reverse(t, II, _m);", "#else", - "#include REVERSE_MOVES", + "#include BACKWARD_MOVES", "R999: /* jumps here when done */", "#endif", "#ifdef VERBOSE", - " printf(\"%%3d: 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, A_depth);", - " printf(\"tau=%%d,%%d]\\n\", ", - " trpt->tau, (trpt-1)->tau);", + " cpu_printf(\"%%3ld: proc %%d reverses %%d, %%d to %%d\\n\",", + " depth, II, t->forw, tt, t->st);", + " cpu_printf(\"\\t%%s [abit=%%d,adepth=%%ld,tau=%%d,%%d]\\n\", ", + " t->tp, now._a_t, A_depth, trpt->tau, (trpt-1)->tau);", "#endif", "#ifndef NOREDUCE", " /* pass the proviso tags */", " if ((trpt->tau&8) /* rv or atomic */", " && (trpt->tau&16))", - " (trpt-1)->tau |= 16;", - "#ifdef SAFETY", + " (trpt-1)->tau |= 16;", /* pass upward */ + " #ifdef SAFETY", " if ((trpt->tau&8) /* rv or atomic */", " && (trpt->tau&64))", " (trpt-1)->tau |= 64;", + " #endif", "#endif", + + "#if defined(BCS) && (defined(NOREDUCE) || !defined(SAFETY))", + /* for BCS, cover cases where 64 is otherwise not handled */ + " if ((trpt->tau&8)", + " && (trpt->tau&64))", + " (trpt-1)->tau |= 64;", "#endif", + " depth--; trpt--;", + "", + "#ifdef NSUCC", + " trpt->n_succ++;", + "#endif", "#ifdef NIBIS", " (trans[ot][tt])->om = _m; /* head of list */", "#endif", " /* i.e., not set if rv fails */", " if (_m)", - " {", - "#if defined(VERI) && !defined(NP)", - " if (II == 0 && verbose && !reached[ot][t->st])", - " {", - " printf(\"depth %%d: Claim reached state %%d (line %%d)\\n\",", - " depth, t->st, src_claim [t->st]);", - " fflush(stdout);", - " }", - "#endif", - " reached[ot][t->st] = 1;", + " { reached[ot][t->st] = 1;", " reached[ot][tt] = 1;", " }", "#ifdef HAS_UNLESS", @@ -2291,18 +3716,18 @@ static char *Code2c[] = { " ((P0 *)this)->_p = tt;", " } /* all options */", - "#ifdef RANDOMIZE", + "#ifdef T_RAND", " if (!t && ooi > 0)", /* means we skipped some initial options */ " { t = trans[ot][tt];", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " printf(\"randomizer: continue for %%d more\\n\", ooi);", - "#endif", - " goto DOMORE;", + " #endif", + " goto domore;", " }", - "#ifdef VERBOSE", + " #ifdef VERBOSE", " else", " printf(\"randomizer: done\\n\");", - "#endif", + " #endif", "#endif", "#ifndef NOFAIR", @@ -2312,12 +3737,12 @@ static char *Code2c[] = { " { if (trpt->o_pm&1)",/* it didn't block */ " {", "#ifdef VERI", - " if (now._cnt[now._a_t&1] == 1)", /* NEW: 1 iso 0 */ - " now._cnt[now._a_t&1] = 2;", /* NEW: 2 iso 1*/ + " if (now._cnt[now._a_t&1] == 1)", + " now._cnt[now._a_t&1] = 2;", "#endif", " now._cnt[now._a_t&1] += 1;", "#ifdef VERBOSE", - " printf(\"%%3d: proc %%d fairness \", depth, II);", + " printf(\"%%3ld: proc %%d fairness \", depth, II);", " printf(\"undo Rule 2, cnt=%%d, _a_t=%%d\\n\",", " now._cnt[now._a_t&1], now._a_t);", "#endif", @@ -2326,32 +3751,77 @@ static char *Code2c[] = { " { if (_n > 0)", /* a prev proc didn't */ " {", /* start over */ " trpt->o_pm &= ~64;", - " II = From+1;", + " II = INI_P;", /* after loop incr II == From */ " } } }", "#endif", - "#ifdef VERI", - " if (II == 0) break; /* never claim */", + " if (II == 0)", + " { break; /* never claim */", + " }", + "#endif", + " CONTINUE;", + " } /* ALL_P */", + + "#ifdef NSUCC", + " tally_succ(trpt->n_succ);", + "#endif", + + "#ifdef P_RAND", + " if (trpt->p_left > 0 && NDONE_P)", + " { trpt->p_skip = -1; /* probably rendundant */", + " #ifdef VERBOSE", + " printf(\"%%3ld: P_RAND -- explore remainder\\n\", depth);", + " #endif", + " goto r_switch; /* explore the remaining procs */", + " } else", + " {", + " #ifdef VERBOSE", + " printf(\"%%3ld: P_RAND -- none left\\n\", depth);", + " #endif", + " }", + "#endif", + + "#ifdef BCS", + " if (trpt->bcs & B_PHASE1)", + " { trpt->bcs = B_PHASE2; /* start 2nd phase */", + " if (_n == 0 || !(trpt->tau&64)) /* pre-move unexecutable or led to stackstate */", + " { trpt->bcs |= B_FORCED; /* forced switch */", + " }", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS move to phase 2, _n=%%d %%s\\n\", depth, _n,", + " (trpt->bcs & B_FORCED)?\"forced\":\"free\");", + " #endif", + " From = FROM_P; To = UPTO_P;", + " goto c_switch;", + " }", + "", + " if (_n == 0 /* no process could move */", + " && II >= BASE /* not the never claim */", + " && trpt->sched_limit >= sched_max)", + " { _n = 1;", + " #ifdef VERBOSE", + " printf(\"%%3ld: BCS not a deadlock\\n\", depth);", + " #endif", + " }", "#endif", - " } /* all processes */", "#ifndef NOFAIR", " /* Fairness: undo Rule 2 */", " if (trpt->o_pm&32) /* remains if proc blocked */", " {", "#ifdef VERI", - " if (now._cnt[now._a_t&1] == 1)", /* NEW: 1 iso 0 */ - " now._cnt[now._a_t&1] = 2;", /* NEW: 2 iso 1 */ + " if (now._cnt[now._a_t&1] == 1)", + " now._cnt[now._a_t&1] = 2;", "#endif", " now._cnt[now._a_t&1] += 1;", "#ifdef VERBOSE", - " printf(\"%%3d: proc -- fairness \", depth);", + " printf(\"%%3ld: proc -- fairness \", depth);", " printf(\"undo Rule 2, cnt=%%d, _a_t=%%d\\n\",", " now._cnt[now._a_t&1], now._a_t);", "#endif", " trpt->o_pm &= ~32;", " }", -"#ifndef NP", + "#ifndef NP", /* 12/97 non-progress cycles cannot be created * by stuttering extension, here or elsewhere */ @@ -2361,12 +3831,8 @@ static char *Code2c[] = { " && !(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 */", @@ -2382,14 +3848,14 @@ static char *Code2c[] = { "#else", " trpt->tau = 0;", "#endif", - " From = now._nr_pr-1; To = BASE;", + " From = FROM_P; To = UPTO_P;", "#if defined(VERBOSE) || defined(CHECK)", - " printf(\"%%3d: fairness default move \", depth);", + " printf(\"%%3ld: fairness default move \", depth);", " printf(\"(all procs block)\\n\");", "#endif", " goto Down;", " }", -"#endif", + "#endif", "Q999: /* returns here with _n>0 when done */;", " if (trpt->o_pm&8)", @@ -2397,7 +3863,7 @@ static char *Code2c[] = { " now._cnt[now._a_t&1] = 0;", " trpt->o_pm &= ~8;", "#ifdef VERBOSE", - " printf(\"%%3d: fairness undo Rule 1, _a_t=%%d\\n\",", + " printf(\"%%3ld: fairness undo Rule 1, _a_t=%%d\\n\",", " depth, now._a_t);", "#endif", " }", @@ -2406,7 +3872,7 @@ static char *Code2c[] = { " now._cnt[now._a_t&1] = 1;", /* NEW: restore cnt */ " trpt->o_pm &= ~16;", "#ifdef VERBOSE", - " printf(\"%%3d: fairness undo Rule 3, _a_t=%%d\\n\",", + " printf(\"%%3ld: fairness undo Rule 3, _a_t=%%d\\n\",", " depth, now._a_t);", "#endif", " }", @@ -2414,35 +3880,41 @@ static char *Code2c[] = { "#ifndef NOREDUCE", "#ifdef SAFETY", - " /* preselected move - no successors outside stack */", - " if ((trpt->tau&32) && !(trpt->tau&64))", - " { From = now._nr_pr-1; To = BASE;", - "#ifdef DEBUG", - " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", - " depth, II+1, _n, trpt->tau);", - "#endif", + " #ifdef LOOPSTATE", + " /* at least one move that was preselected at this */", + " /* level, blocked or was a loop control flow point */", + " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", + " #else", + " /* preselected move - no successors outside stack */", + " if ((trpt->tau&32) && !(trpt->tau&64))", + " #endif", + " { From = FROM_P; To = UPTO_P; /* undo From == To */", + " #ifdef DEBUG", + " printf(\"%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", + " depth, II+1, _n, trpt->tau);", + " #endif", " _n = 0; trpt->tau &= ~(16|32|64);", - " if (II >= BASE) /* II already decremented */", - " goto Resume;", - " else", - " goto Again;", - " }", + + " if (MORE_P) /* II already restored and updated */", + " { goto Resume;", + " } else", + " { goto Again;", + " } }", "#else", " /* at least one move that was preselected at this */", " /* level, blocked or truncated at the next level */", - "/* implied: #ifdef FULLSTACK */", " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", " {", - "#ifdef DEBUG", - " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", - " depth, II+1, (int) _n, trpt->tau);", - "#endif", + " #ifdef DEBUG", + " printf(\"%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", + " depth, II+1, (int) _n, trpt->tau);", + " #endif", " if (a_cycles && (trpt->tau&16))", " { if (!(now._a_t&1))", " {", - "#ifdef DEBUG", - " printf(\"%%3d: setting proviso bit\\n\", depth);", - "#endif", + " #ifdef DEBUG", + " printf(\"%%3ld: setting proviso bit\\n\", depth);", + " #endif", "#ifndef BITSTATE", "#ifdef MA", "#ifdef VERI", @@ -2466,27 +3938,26 @@ static char *Code2c[] = { " trpt->ostate->proviso = 1;", "#endif", "#endif", - " From = now._nr_pr-1; To = BASE;", + " From = FROM_P; To = UPTO_P;", " _n = 0; trpt->tau &= ~(16|32|64);", " goto Again; /* do full search */", " } /* else accept reduction */", " } else", - " { From = now._nr_pr-1; To = BASE;", + " { From = FROM_P; To = UPTO_P;", " _n = 0; trpt->tau &= ~(16|32|64);", - " if (II >= BASE) /* already decremented */", - " goto Resume;", - " else", - " goto Again;", - " } }", - "/* #endif */", + " if (MORE_P) /* II already updated */", + " { goto Resume;", + " } else", + " { goto Again;", + " } } }", "#endif", "#endif", " if (_n == 0 || ((trpt->tau&4) && (trpt->tau&2)))", " {", "#ifdef DEBUG", - " printf(\"%%3d: no move [II=%%d, tau=%%d, boq=%%d]\\n\",", - " depth, II, trpt->tau, boq);", + " cpu_printf(\"%%3ld: no move [II=%%d, tau=%%d, boq=%%d]\\n\",", + " depth, II, trpt->tau, boq);", "#endif", "#if SYNC", " /* ok if a rendez-vous fails: */", @@ -2494,18 +3965,14 @@ static char *Code2c[] = { "#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;", + " || depth >= maxdepth-1) goto Done; /* undo change from 5.2.3 */", " if ((trpt->tau&8) && !(trpt->tau&4))", " { trpt->tau &= ~(1|8);", " /* 1=timeout, 8=atomic */", - " From = now._nr_pr-1; To = BASE;", + " From = FROM_P; To = UPTO_P;", "#ifdef DEBUG", - " printf(\"%%3d: atomic step proc %%d \", depth, II+1);", - " printf(\"unexecutable\\n\");", + " cpu_printf(\"%%3ld: atomic step proc %%d unexecutable\\n\", depth, II+1);", "#endif", "#ifdef VERI", " trpt->tau |= 4; /* switch to claim */", @@ -2524,9 +3991,9 @@ static char *Code2c[] = { "#endif", " { trpt->tau |= 1;", " trpt->tau &= ~2;", - "#ifdef DEBUG", - " printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #ifdef DEBUG", + " cpu_printf(\"%%d: timeout\\n\", depth);", + " #endif", " goto Stutter;", " } }", " else", @@ -2534,18 +4001,22 @@ static char *Code2c[] = { " if ((trpt->tau&8)", " && !((trpt-1)->tau&4))", "/* blocks inside an atomic */ goto BreakOut;", - "#ifdef DEBUG", - " printf(\"%%d: req timeout\\n\",", + " #ifdef DEBUG", + " cpu_printf(\"%%d: req timeout\\n\",", " depth);", - "#endif", + " #endif", " (trpt-1)->tau |= 2; /* request */", + " #if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", + " }", + " #endif", " goto Up;", " }", "#else", - - "#ifdef DEBUG", - " printf(\"%%d: timeout\\n\", depth);", - "#endif", + " #ifdef DEBUG", + " cpu_printf(\"%%d: timeout\\n\", depth);", + " #endif", " trpt->tau |= 1;", " goto Again;", "#endif", @@ -2560,7 +4031,7 @@ static char *Code2c[] = { " { trpt->tau |= 4; /* claim stuttering */", " trpt->tau |= 128; /* stutter mark */", "#ifdef DEBUG", - " printf(\"%%d: claim stutter\\n\", depth);", + " cpu_printf(\"%%d: claim stutter\\n\", depth);", "#endif", " goto Stutter;", " }", @@ -2585,6 +4056,47 @@ static char *Code2c[] = { "Done:", " if (!(trpt->tau&8)) /* not in atomic seqs */", " {", + +"#ifndef MA", + "#if defined(FULLSTACK) || defined(CNTRSTACK)", + "#ifdef VERI", + " if (boq == -1", + " && (((trpt->tau&4) && !(trpt->tau&128))", + " || ( (trpt-1)->tau&128)))", + "#else", + " if (boq == -1)", + "#endif", + " {", + "#ifdef DEBUG2", + "#if defined(FULLSTACK)", + " printf(\"%%ld: zapping %%u (%%d)\\n\",", + " depth, trpt->ostate,", + " (trpt->ostate)?trpt->ostate->tagged:0);", + "#endif", + "#endif", + " onstack_zap();", + " }", + "#endif", +"#else", + "#ifdef VERI", + " if (boq == -1", + " && (((trpt->tau&4) && !(trpt->tau&128))", + " || ( (trpt-1)->tau&128)))", + "#else", + " if (boq == -1)", + "#endif", + " {", + "#ifdef DEBUG", + " printf(\"%%ld: zapping\\n\", depth);", + "#endif", + " onstack_zap();", + "#ifndef NOREDUCE", + " if (trpt->proviso)", + " g_store((char *) &now, vsize, 1);", + "#endif", + " }", +"#endif", + "#ifndef SAFETY", " if (_n != 0", /* we made a move */ "#ifdef VERI", @@ -2601,7 +4113,7 @@ static char *Code2c[] = { " if (fairness)", /* implies a_cycles */ " {", "#ifdef VERBOSE", - " printf(\"Consider check %%d %%d...\\n\",", + " cpu_printf(\"Consider check %%d %%d...\\n\",", " now._a_t, now._cnt[0]);", "#endif", #if 0 @@ -2624,54 +4136,23 @@ static char *Code2c[] = { " checkcycles();", " }", "#endif", -"#ifndef MA", - "#if defined(FULLSTACK) || defined(CNTRSTACK)", - "#ifdef VERI", - " if (boq == -1", - " && (((trpt->tau&4) && !(trpt->tau&128))", - " || ( (trpt-1)->tau&128)))", - "#else", - " if (boq == -1)", - "#endif", - " {", - "#ifdef DEBUG2", - "#if defined(FULLSTACK)", - " printf(\"%%d: zapping %%u (%%d)\\n\",", - " depth, trpt->ostate,", - " (trpt->ostate)?trpt->ostate->tagged:0);", - "#endif", - "#endif", - " onstack_zap();", + " }", + " if (depth > 0)", + " {", + "#if NCORE>1 && defined(FULL_TRAIL)", + " if (upto > 0)", + " { Pop_Stack_Tree();", " }", "#endif", -"#else", - "#ifdef VERI", - " if (boq == -1", - " && (((trpt->tau&4) && !(trpt->tau&128))", - " || ( (trpt-1)->tau&128)))", - "#else", - " if (boq == -1)", - "#endif", - " {", - "#ifdef DEBUG", - " printf(\"%%d: zapping\\n\", depth);", - "#endif", - " onstack_zap();", - "#ifndef NOREDUCE", - " if (trpt->proviso)", - " gstore((char *) &now, vsize, 1);", - "#endif", - " }", -"#endif", + " goto Up;", " }", - " if (depth > 0) goto Up;", "}\n", "#else", "void new_state(void) { /* place holder */ }", "#endif", /* BFS */ "", "void", - "assert(int a, char *s, int ii, int tt, Trans *t)", + "spin_assert(int a, char *s, int ii, int tt, Trans *t)", "{", " if (!a && !noasserts)", " { char bad[1024];", @@ -2688,169 +4169,214 @@ static char *Code2c[] = { "int", "Boundcheck(int x, int y, int a1, int a2, Trans *a3)", "{", - " assert((x >= 0 && x < y), \"- invalid array index\",", + " spin_assert((x >= 0 && x < y), \"- invalid array index\",", " a1, a2, a3);", " return x;", "}", "#endif", + "int do_hashgen = 0;", "void", "wrap_stats(void)", "{", " if (nShadow>0)", - " printf(\"%%8g states, stored (%%g visited)\\n\",", + " printf(\"%%9.8g states, stored (%%g visited)\\n\",", " nstates - nShadow, nstates);", " else", - " printf(\"%%8g states, stored\\n\", nstates);", + " 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(\"%%8g states, matched\\n\", truncs);", + " printf(\"%%9.8g states, matched\\n\", truncs);", "#ifdef CHECK", - " printf(\"%%8g matches within stack\\n\",truncs2);", + " printf(\"%%9.8g matches within stack\\n\",truncs2);", "#endif", " if (nShadow>0)", - " printf(\"%%8g transitions (= visited+matched)\\n\",", + " printf(\"%%9.8g transitions (= visited+matched)\\n\",", " nstates+truncs);", " else", - " printf(\"%%8g transitions (= stored+matched)\\n\",", + " printf(\"%%9.8g transitions (= stored+matched)\\n\",", " nstates+truncs);", - " printf(\"%%8g atomic steps\\n\", nlinks);", + " printf(\"%%9.8g atomic steps\\n\", nlinks);", " if (nlost) printf(\"%%g lost messages\\n\", (double) nlost);", "", "#ifndef BITSTATE", - " printf(\"hash conflicts: %%g (resolved)\\n\", hcmp);", + " #ifndef MA", + " printf(\"hash conflicts: %%9.8g (resolved)\\n\", hcmp);", + " #if !defined(AUTO_RESIZE) && !defined(BFS_PAR)", + " if (hcmp > (double) (1<<ssize))", + " { printf(\"hint: increase hashtable-size (-w) to reduce runtime\\n\");", + " }", + " #endif", + " #if defined(BFS_PAR) && defined(HC)", + " { double fp = (100. * (double) nstates)/((double) ((ulong) (1<<ssize)));", + " int fi = 0;", + " printf(\"the hash table is %%3.3g %%%% filled\", fp);", + " if (fp > 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", " printf(\"%%8g states allocated for dfs stack\\n\", ngrabs);", "#endif", - " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",", - " (double)(1<<(ssize-8)) / (double) nstates * 256.0);", - " printf(\"bits set per state: %%u (-k%%u)\\n\", hfns, hfns);", - "#if 0", -#ifndef POWOW " if (udmem)", - " printf(\"total bits available: %%8g (-M%%ld)\\n\",", - " ((double) udmem) * 8.0, udmem/(1024L*1024L));", + " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",", + " (double)(((double) udmem) * 8.0) / (double) nstates);", " else", -#endif - " printf(\"total bits available: %%8g (-w%%d)\\n\",", - " ((double) (1L << (ssize-4)) * 16.0), ssize);", - "#endif", -"#ifdef COVEST", - " /* this code requires compilation with -lm on some systems */", - " { double pow(double, double);", - " double log(double);", - " unsigned int best_k;", - " double i, n = 30000.0L;", - " double f, p, q, m, c, est = 0.0L, k = (double)hfns;", - " c = (double) nstates / n;", - " m = (double) (1<<(ssize-8)) * 256.0L / c;", - " p = 1.0L - (k / m); q = 1.0L;", - " for (i = 0.0L; i - est < n; i += 1.0L)", - " { q *= p;", - " est += pow(1.0L - q, k);", - " }", - " f = m/i;", - " est *= c;", - " i *= c;", - " /* account for loss from enhanced double hashing */", - " if (hfns > 2) est += i * pow(0.5, (double) ssize * 2.0);", - "", - " if (f < 1.134) best_k = 1;", - " else if (f < 2.348) best_k = 2;", - " else if (f < 3.644) best_k = 3;", - " else best_k = (unsigned int) (pow(3.8L,1.0L/(f+4.2L))*f*.69315L + 0.99999999L);", - "", - " if (best_k != hfns && best_k > ssize)", - " best_k = (unsigned int) 1.0 + ssize/log((double)best_k / (double)ssize + 3.0);", - "", - " if (best_k > 32)", - " best_k = 1 + (unsigned int) (32.0/log((double)best_k/35.0));", - "", - " if (est * (double) nstates < 1.0)", - " { printf(\"prob. of omissions: negligible\\n\");", - " return; /* no hints needed */", - " }", - "", - " if (best_k != hfns)", - " { printf(\"hint: repeating the search with -k%%u \", best_k);", - " printf(\"may increase accuracy\\n\");", - " } else", - " { printf(\"hint: the current setting for -k (-k%%d) \", hfns);", - " printf(\"is likely to be optimal for -w%%d\\n\", ssize);", - " }", - " if (ssize < 32)", - " { printf(\"hint: increasing -w above -w%%d \", ssize);", - " printf(\"will increase accuracy (max is -w34)\\n\");", - " printf(\"(in xspin, increase Estimated State Space Size)\\n\");", - " } }", -"#endif", + " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",", + " ((double)(((ulong)1)<<(ssize-10)) / (double) nstates) * 1024.0);", + /* the -10 and *1024 stuff is to avoid overflow */ + " printf(\"bits set per state: %%u (-k%%u)\\n\", hfns, hfns);", + " if (do_hashgen)", + " printf(\"hash polynomial used: 0x%%.8x\\n\", HASH_CONST[HASH_NR]);", + " if (s_rand != 12345)", + " printf(\"random seed used: %%u\\n\", (uint) (s_rand-1));", + "#endif", + "#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);", + " if (bfs_dsk_write >= 0) (void) close(bfs_dsk_write);", + " (void) unlink(\"pan_bfs_dsk.tmp\");", "#endif", "}", + "", "void", "wrapup(void)", - "{", - "#if defined(BITSTATE) || !defined(NOCOMP)", - " double nr1, nr2, nr3 = 0.0, nr4, nr5 = 0.0;", - "#if !defined(MA) && (defined(MEMCNT) || defined(MEMLIM))", - " int mverbose = 1;", - "#else", - " int mverbose = verbose;", + "{ double nr1, nr2, nr3 = 0.0, nr4, nr5 = 0.0;", + "#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", + " void dsk_stats(void);", + " dsk_stats();", + " #endif", + " if (search_terminated != NULL)", + " { *search_terminated |= 2; /* wrapup */", + " }", + " exit(0); /* normal termination, not an error */", + " }", "#endif", - + "#if !defined(WIN32) && !defined(WIN64)", " signal(SIGINT, SIG_DFL);", - " printf(\"(%%s)\\n\", Version);", + "#endif", + " printf(\"\\n(%%s)\\n\", SpinVersion);", " if (!done) printf(\"Warning: Search not completed\\n\");", + "#if defined(BFS_PAR) && !defined(BITSTATE)", + " if (bfs_punt > 0) printf(\"Warning: Search incomplete\\n\");", + "#endif", "#ifdef SC", " (void) unlink((const char *)stackfile);", "#endif", + "#ifdef BFS_PAR", + " printf(\" + Multi-Core (using %%d cores)\\n\", Cores);", + " #ifdef BFS_SEP_HASH", + " printf(\" + Separate Hash Tables\\n\");", + " #endif", + " #ifdef BFS_DISK", + " printf(\" + Disk storage\\n\");", + " #endif", + "#endif", + "#if NCORE>1", + " if (a_cycles)", + " { printf(\" + Multi-Core (NCORE=%%d)\\n\", NCORE);", + " } else", + " { printf(\" + Multi-Core (NCORE=%%d -z%%ld)\\n\", NCORE, z_handoff);", + " }", + "#endif", "#ifdef BFS", - " printf(\" + Using Breadth-First Search\\n\");", + " printf(\" + Breadth-First Search\\n\");", "#endif", "#ifndef NOREDUCE", " printf(\" + Partial Order Reduction\\n\");", "#endif", -#if 0 - "#ifdef Q_PROVISO", - " printf(\" + Queue Proviso\\n\");", + "#ifdef PERMUTED", + " printf(\" + Process Scheduling Permutation\\n\");", + "#endif", + "#ifdef P_REVERSE", + " printf(\" + Reverse Depth-First Search Order\\n\");", + "#endif", + " if (t_reverse)", + " printf(\" + Reverse Transition Ordering\\n\");", + "#ifdef T_RAND", + " printf(\" + Randomized Transition Ordering\\n\");", + "#endif", + "#ifdef P_RAND", + " printf(\" + Randomized Process Ordering\\n\");", + "#endif", + "#ifdef BCS", + " printf(\" + Scheduling Restriction (-L%%d)\\n\", sched_max);", + "#endif", + "#ifdef TRIX", + " printf(\" + Tree Index Compression\\n\");", "#endif", -#endif "#ifdef COLLAPSE", " printf(\" + Compression\\n\");", "#endif", "#ifdef MA", " printf(\" + Graph Encoding (-DMA=%%d)\\n\", MA);", - "#ifdef R_XPT", - " printf(\" Restarted from checkpoint %%s.xpt\\n\", Source);", - "#endif", + " #ifdef R_XPT", + " printf(\" Restarted from checkpoint %%s.xpt\\n\", PanSource);", + " #endif", "#endif", "#ifdef CHECK", - "#ifdef FULLSTACK", + " #ifdef FULLSTACK", " printf(\" + FullStack Matching\\n\");", - "#endif", - "#ifdef CNTRSTACK", + " #endif", + " #ifdef CNTRSTACK", " printf(\" + CntrStack Matching\\n\");", - "#endif", + " #endif", + "#endif", + "#ifdef PERMUTED", + " if (reversing & 2)", + " { if (p_reorder == set_permuted)", + " { printf(\" + Permuted\\n\");", + " }", + " if (p_reorder == set_reversed)", + " { printf(\" + Reversed\\n\");", + " }", + " if (p_reorder == set_rotated)", + " { printf(\" + Rotated %%d\\n\", p_rotate);", + " }", + " if (p_reorder == set_randrot)", + " { printf(\" + RandRotated\\n\");", + " } }", "#endif", "#ifdef BITSTATE", " printf(\"\\nBit statespace search for:\\n\");", "#else", - "#ifdef HC", + " #ifdef HC", " printf(\"\\nHash-Compact %%d search for:\\n\", HC);", - "#else", + " #else", " printf(\"\\nFull statespace search for:\\n\");", - "#endif", + " #endif", "#endif", "#ifdef EVENT_TRACE", "#ifdef NEGATED_TRACE", @@ -2860,7 +4386,8 @@ static char *Code2c[] = { "#endif", "#endif", "#ifdef VERI", - " printf(\"\tnever claim \t+\\n\");", + " printf(\"\tnever claim \t+\");", + " printf(\" (%%s)\\n\", procname[((Pclaim *)pptr(0))->_t]);", " printf(\"\tassertion violations\t\");", " if (noasserts)", " printf(\"- (disabled by -A flag)\\n\");", @@ -2889,7 +4416,11 @@ static char *Code2c[] = { " 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- \");", @@ -2905,9 +4436,13 @@ static char *Code2c[] = { " else", " printf(\"+\\n\\n\");", "#endif", - " printf(\"State-vector %%d byte, depth reached %%d\", ", - " hmax, mreached);", + " printf(\"State-vector %%d byte, depth reached %%ld\", hmax,", + "#if NCORE>1", + " (nr_handoffs * z_handoff) +", + "#endif", + " mreached);", " printf(\", errors: %%d\\n\", errors);", + " fflush(stdout);", "#ifdef MA", " if (done)", " { extern void dfa_stats(void);", @@ -2920,124 +4455,196 @@ static char *Code2c[] = { " wrap_stats();", "#ifdef CHECK", " printf(\"stackframes: %%d/%%d\\n\\n\", smax, svmax);", - " printf(\"stats: fa %%d, fh %%d, zh %%d, zn %%d - \",", + " printf(\"stats: fa %%ld, fh %%ld, zh %%ld, zn %%ld - \",", " Fa, Fh, Zh, Zn);", - " printf(\"check %%d holds %%d\\n\", Ccheck, Cholds);", - " printf(\"stack stats: puts %%d, probes %%d, zaps %%d\\n\",", + " printf(\"check %%ld holds %%ld\\n\", Ccheck, Cholds);", + " printf(\"stack stats: puts %%ld, probes %%ld, zaps %%ld\\n\",", " PUT, PROBE, ZAPS);", "#else", " printf(\"\\n\");", "#endif", "", - "#if defined(BITSTATE) || !defined(NOCOMP)", + "#if !defined(BITSTATE) && defined(NOCOMP)", + " if (!verbose) { goto jump_here; }", /* added 5.2.0 */ + "#endif", + "", + "#if 1", /* omitted 5.2.0: defined(BITSTATE) || !defined(NOCOMP) */ " nr1 = (nstates-nShadow)*", - " (double)(hmax+sizeof(struct H_el)-sizeof(unsigned));", - "#ifdef BFS", + " (double)(hmax+sizeof(H_el)-sizeof(unsigned));", + " #ifdef BFS", " nr2 = 0.0;", - "#else", + " #else", " nr2 = (double) ((maxdepth+3)*sizeof(Trail));", - "#endif", + " #endif", - "#ifndef BITSTATE", + " #ifndef BITSTATE", "#if !defined(MA) || defined(COLLAPSE)", - " nr3 = (double) (1L<<ssize)*sizeof(struct H_el *);", + " nr3 = (double) (ONE_L<<ssize)*sizeof(H_el *);", "#endif", - "#else", -#ifndef POWOW + " #else", " if (udmem)", " nr3 = (double) (udmem);", " else", -#endif - " nr3 = (double) (1L<<(ssize-3));", + " nr3 = (double) (ONE_L<<(ssize-3));", "#ifdef CNTRSTACK", - " nr3 += (double) (1L<<(ssize-3));", + " nr5 = (double) (ONE_L<<(ssize-3));", "#endif", "#ifdef FULLSTACK", - " nr5 = (double) (maxdepth*sizeof(struct H_el *));", + " nr5 = (double) (maxdepth*sizeof(H_el *));", "#endif", - "#endif", + " #endif", + " nr4 = (double) (svmax * (sizeof(Svtack) + hmax))", - " + (double) (smax * (sizeof(Stack) + Maxbody));", + " + (double) (smax * (sizeof(_Stack) + Maxbody * sizeof(char)));", "#ifndef MA", - " if (mverbose || memcnt < nr1+nr2+nr3+nr4+nr5)", + " if (1 /* verbose || memcnt < nr1+nr2+nr3+nr4+nr5 */)", "#endif", " { double remainder = memcnt;", " double tmp_nr = memcnt-nr3-nr4-(nr2-fragment)-nr5;", + "", + " #if NCORE>1 && !defined(SEP_STATE)", + " tmp_nr -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE;", + " #endif", " if (tmp_nr < 0.0) tmp_nr = 0.;", " printf(\"Stats on memory usage (in Megabytes):\\n\");", - " printf(\"%%-6.3f\tequivalent memory usage for states\",", - " nr1/1000000.);", + " printf(\"%%9.3f\tequivalent memory usage for states\",", + " nr1/1048576.); /* 1024*1024=1048576 */", " printf(\" (stored*(State-vector + overhead))\\n\");", - "#ifdef BITSTATE", -#ifndef POWOW + " #if NCORE>1 && !defined(WIN32) && !defined(WIN64)", + " printf(\"%%9.3f\tshared memory reserved for state storage\\n\",", + " mem_reserved/1048576.);", + " #ifdef SEP_HEAP", + " printf(\"\t\tin %%d local heaps of %%7.3f MB each\\n\",", + " NCORE, mem_reserved/(NCORE*1048576.));", + " #endif", + " printf(\"\\n\");", + " #endif", + " #ifdef BITSTATE", " if (udmem)", - " printf(\"%%-6.3f\tmemory used for hash array (-M%%ld)\\n\",", - " nr3/1000000., udmem/(1024L*1024L));", + " printf(\"%%9.3f\tmemory used for hash array (-M%%ld)\\n\",", + " nr3/1048576., udmem/(1024L*1024L));", " else", -#endif - " printf(\"%%-6.3f\tmemory used for hash array (-w%%d)\\n\",", - " nr3/1000000., ssize);", + " printf(\"%%9.3f\tmemory used for hash array (-w%%d)\\n\",", + " nr3/1048576., ssize);", " if (nr5 > 0.0)", - " printf(\"%%-6.3f\tmemory used for bit stack\\n\",", - " nr5/1000000.);", + " printf(\"%%9.3f\tmemory used for bit stack\\n\",", + " nr5/1048576.);", " remainder = remainder - nr3 - nr5;", - "#else", - " printf(\"%%-6.3f\tactual memory usage for states\",", - " tmp_nr/1000000.);", - " remainder = remainder - tmp_nr;", - " printf(\" (\");", - " if (tmp_nr > 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\",", - " sizeof(struct H_el)-sizeof(unsigned));", + " #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", + " remainder -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE;", + " printf(\"%%9.3f\tshared memory used for work-queues\\n\",", + " (GWQ_SIZE + (double) NCORE * LWQ_SIZE) /1048576.);", + " printf(\"\t\tin %%d queues of %%7.3f MB each\",", + " NCORE, (double) LWQ_SIZE /1048576.);", + " #ifndef NGQ", + " printf(\" + a global q of %%7.3f MB\\n\",", + " (double) GWQ_SIZE / 1048576.);", + " #else", + " printf(\"\\n\");", + " #endif", + " #endif", + " if (remainder - fragment > 1048576.)", + " { printf(\"%%9.3f\tother (proc and chan stacks)\\n\",", + " (remainder-fragment)/1048576.);", " }", - "#endif", - "#if !defined(MA) || defined(COLLAPSE)", - " printf(\"%%-6.3f\tmemory used for hash table (-w%%d)\\n\",", - " nr3/1000000., ssize);", - " remainder = remainder - nr3;", - "#endif", - "#endif", - "#ifndef BFS", - " printf(\"%%-6.3f\tmemory used for DFS stack (-m%%ld)\\n\",", - " nr2/1000000., maxdepth);", - " remainder = remainder - nr2;", - "#endif", - " if (remainder - fragment > 0.0)", - " printf(\"%%-6.3f\tother (proc and chan stacks)\\n\",", - " (remainder-fragment)/1000000.);", - " if (fragment > 0.0)", - " printf(\"%%-6.3f\tmemory lost to fragmentation\\n\",", - " fragment/1000000.);", - " printf(\"%%-6.3f\ttotal actual memory usage\\n\\n\",", - " memcnt/1000000.);", + " if (fragment > 1048576.)", + " { 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", + " #ifndef MA", " else", - "#endif", + " #endif", + "#endif", + + "#if !defined(BITSTATE) && defined(NOCOMP)", + "jump_here:", + "#endif", + "#ifndef MA", + " printf(\"%%9.3f\tmemory usage (Mbyte)\\n\",", + " memcnt/1048576.);", + "#endif", + "#ifdef BFS_PAR", + " bfs_report_mem();", + "#else", + " printf(\"\\n\");", "#endif", - "#ifndef MA", - " printf(\"%%-6.3f\tmemory usage (Mbyte)\\n\\n\",", - " memcnt/1000000.);", - "#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 \", ncomps[i]);", + " printf(\"%%d:%%lu \", i, ncomps[i]);", " printf(\"]\\n\");", " }", "#endif", + " #ifdef TRIX", + " if (verbose)", + " { int i;", + " printf(\"TRIX counts:\\n\");", + " printf(\" processes: \");", + " for (i = 0; i < MAXPROC; i++)", + " if (_p_count[i] != 0)", + " { printf(\"%%3d:%%ld \",", + " i, _p_count[i]);", + " }", + " printf(\"\\n channels : \");", + " for (i = 0; i < MAXQ; i++)", + " if (_c_count[i] != 0)", + " { printf(\"%%3d:%%ld \",", + " i, _c_count[i]);", + " }", + " printf(\"\\n\\n\");", + " }", + " #endif", " if ((done || verbose) && !no_rck) do_reach();", "#ifdef PEG", @@ -3053,21 +4660,90 @@ static char *Code2c[] = { "#ifdef SVDUMP", " if (vprefix > 0) close(svfd);", "#endif", + "#ifdef LOOPSTATE", + " printf(\"%%g loopstates hit\\n\", cnt_loops);", + "#endif", + "#ifdef NSUCC", + " dump_succ();", + "#endif", + "#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", " wrapup();", " pan_exit(0);", "}", + "", "/*", - " * based on Bob Jenkins hash-function from 1996", - " * see: http://www.burtleburtle.net/bob/", + " * super fast hash, based on Paul Hsieh's function", + " * http://www.azillionmonkeys.com/qed/hash.html", " */", + "#include <stdint.h>", /* for uint32_t etc */ + " #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(uchar *s, int len)", /* sets one 32-bit number, in K1 */ + "{ uint32_t h = len, 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;", "", -"#if defined(HASH64) || defined(WIN64)", - /* 64-bit Jenkins hash: http://burtleburtle.net/bob/c/lookup8.c */ + " K1 = h;", + "}", + "", + "#if WS>4", + "/* 64-bit Jenkins hash, 1997", + " * http://burtleburtle.net/bob/c/lookup8.c", + " */", "#define mix(a,b,c) \\", "{ a -= b; a -= c; a ^= (c>>43); \\", " b -= c; b -= a; b ^= (a<<9); \\", @@ -3082,66 +4758,242 @@ static char *Code2c[] = { " b -= c; b -= a; b ^= (a<<18); \\", " c -= a; c -= b; c ^= (b>>22); \\", "}", -"#else", + "#else", + "/* 32-bit Jenkins hash, 2006", + " * http://burtleburtle.net/bob/c/lookup3.c", + " */", + "#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))", + "", "#define mix(a,b,c) \\", - "{ a -= b; a -= c; a ^= (c>>13); \\", - " b -= c; b -= a; b ^= (a<<8); \\", - " c -= a; c -= b; c ^= (b>>13); \\", - " a -= b; a -= c; a ^= (c>>12); \\", - " b -= c; b -= a; b ^= (a<<16); \\", - " c -= a; c -= b; c ^= (b>>5); \\", - " a -= b; a -= c; a ^= (c>>3); \\", - " b -= c; b -= a; b ^= (a<<10); \\", - " c -= a; c -= b; c ^= (b>>15); \\", + "{ a -= c; a ^= rot(c, 4); c += b; \\", + " b -= a; b ^= rot(a, 6); a += c; \\", + " c -= b; c ^= rot(b, 8); b += a; \\", + " a -= c; a ^= rot(c,16); c += b; \\", + " b -= a; b ^= rot(a,19); a += c; \\", + " c -= b; c ^= rot(b, 4); b += a; \\", "}", -"#endif", - "void", - "d_hash(uchar *Cp, int Om) /* double bit hash - Jenkins */", - "{ unsigned long a = 0x9e3779b9, b, c = 0, len, length;", - " unsigned long *k = (unsigned long *) Cp;", "", - " length = len = (unsigned long) ((unsigned long) Om + WS-1)/WS;", + "#define final(a,b,c) \\", + "{ c ^= b; c -= rot(b,14); \\", + " a ^= c; a -= rot(c,11); \\", + " b ^= a; b -= rot(a,25); \\", + " c ^= b; c -= rot(b,16); \\", + " a ^= c; a -= rot(c,4); \\", + " b ^= a; b -= rot(a,14); \\", + " c ^= b; c -= rot(b,24); \\", + "}", + "#endif", "", + "void", + "d_hash(uchar *kb, int nbytes)", /* sets two 64-bit or 32-bit nrs, depending on WS */ + "{ uint8_t *bp;", + "#if WS>4", + " uint64_t a = 0, b, c, n;", + " const uint64_t *k = (uint64_t *) kb;", + "#else", + " uint32_t a = 0, b, c, n;", + " const uint32_t *k = (uint32_t *) kb;", + "#endif", + " n = nbytes/WS; /* nr of words */", + " /* extend to multiple of words, if needed */", + " a = WS - (nbytes %% WS);", + " if (a > 0 && a < WS)", + " { n++;", + " bp = kb + nbytes;", + " switch (a) {", + "#if WS>4", + " case 7: *bp++ = 0; /* fall thru */", + " case 6: *bp++ = 0; /* fall thru */", + " case 5: *bp++ = 0; /* fall thru */", + " case 4: *bp++ = 0; /* fall thru */", + "#endif", + " case 3: *bp++ = 0; /* fall thru */", + " case 2: *bp++ = 0; /* fall thru */", + " case 1: *bp = 0;", + " case 0: break;", + " } }", + "#if WS>4", " b = HASH_CONST[HASH_NR];", - " while (len >= 3)", + " c = 0x9e3779b97f4a7c13LL; /* arbitrary value */", + " while (n >= 3)", " { a += k[0];", " b += k[1];", " c += k[2];", " mix(a,b,c);", - " k += 3; len -= 3;", + " n -= 3;", + " k += 3;", " }", - " c += length;", - " switch (len) {", + " c += (((uint64_t) nbytes)<<3);", + " switch (n) {", " case 2: b += k[1];", " case 1: a += k[0];", + " case 0: break;", " }", " mix(a,b,c);", - " j1 = c&nmask; j3 = a&7;", /* 1st bit */ - " j2 = b&nmask; j4 = (a>>3)&7;", /* 2nd bit */ - " K1 = c; K2 = b;", /* no nmask */ + "#else", /* 32 bit version: */ + " a = c = 0xdeadbeef + (n<<2);", + " b = HASH_CONST[HASH_NR];", + " while (n > 3)", + " { a += k[0];", + " b += k[1];", + " c += k[2];", + " mix(a,b,c);", + " n -= 3;", + " k += 3;", + " }", + " switch (n) { ", + " case 3: c += k[2];", + " case 2: b += k[1];", + " case 1: a += k[0];", + " final(a,b,c);", + " case 0: break;", + " }", + "#endif", + " 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;", "}", + "", + "#if defined(MURMUR) && (WS==8)", + "/* public-domain, 64-bit MurmurHash3, by Austin Appleby */", + "/* https://code.google.com/p/smhasher/wiki/MurmurHash3 */", "void", - "s_hash(uchar *cp, int om)", - "{ d_hash(cp, om); /* sets K1 and K2 */", + "m_hash(uchar *v, int len)", + "{ uint8_t *bp, *data = (uint8_t*) v;", + " int i, nblocks = len / 16;", + "", + " uint64_t h1 = HASH_CONST[HASH_NR];", + " uint64_t h2 = 0x9e3779b97f4a7c13LL;", + "", + " uint64_t c1 = 0x87c37b91114253d5;", + " uint64_t c2 = 0x4cf5ad432745937f;", + "", + " uint64_t *blocks = (uint64_t *)(data);", + "", + " /* guarantee a multiple of 16 bytes */", + " i = 16 - (len %% 16);", + " if (i > 0 && i < 16)", + " { nblocks++;", + " bp = v + len;", + " switch (i) {", + " case 15: *bp++ = 0; /* fall thru */", + " case 14: *bp++ = 0;", + " case 13: *bp++ = 0;", + " case 12: *bp++ = 0;", + " case 11: *bp++ = 0;", + " case 10: *bp++ = 0;", + " case 9: *bp++ = 0;", + " case 8: *bp++ = 0;", + " case 7: *bp++ = 0;", + " case 6: *bp++ = 0;", + " case 5: *bp++ = 0;", + " case 4: *bp++ = 0;", + " case 3: *bp++ = 0;", + " case 2: *bp++ = 0;", + " case 1: *bp = 0;", + " case 0: break;", + " } }", + "", + " for (i = 0; i < nblocks; i++)", + " { uint64_t k1 = blocks[i*2];", + " uint64_t k2 = blocks[i*2+1];", + "", + " k1 *= c1;", + " k1 = (k1 << 31) | (k1 >> 33);", + " k1 *= c2;", + " h1 ^= k1;", + "", + " h1 = (h1 << 27) | (h1 >> 37);", + " h1 += h2;", + " h1 = h1 * 5 + 0x52dce729;", + "", + " k2 *= c2;", + " k2 = (k2 << 33) | (k2 >> 31);", + " k2 *= c1;", + " h2 ^= k2;", + "", + " h2 = (h2 << 31) | (h2 >> 33);", + " h2 += h1;", + " h2 = h2 * 5 + 0x38495ab5;", + " }", + "", + " uint8_t *tail = (uint8_t*)(data + (nblocks * 16));", + "", + " uint64_t k1 = 0;", + " uint64_t k2 = 0;", + "", + " switch(len & 15) {", + " case 15: k2 ^= ((uint64_t) tail[14]) << 48; break;", + " case 14: k2 ^= ((uint64_t) tail[13]) << 40; break;", + " case 13: k2 ^= ((uint64_t) tail[12]) << 32; break;", + " case 12: k2 ^= ((uint64_t) tail[11]) << 24; break;", + " case 11: k2 ^= ((uint64_t) tail[10]) << 16; break;", + " case 10: k2 ^= ((uint64_t) tail[ 9]) << 8; break;", + " case 9: k2 ^= ((uint64_t) tail[ 8]) << 0; break;", + " k2 *= c2;", + " k2 = (k2 << 33) | (k2 >> 31);", + " k2 *= c1;", + " h2 ^= k2; break;", + " case 8: k1 ^= ((uint64_t) tail[7]) << 56; break;", + " case 7: k1 ^= ((uint64_t) tail[6]) << 48; break;", + " case 6: k1 ^= ((uint64_t) tail[5]) << 40; break;", + " case 5: k1 ^= ((uint64_t) tail[4]) << 32; break;", + " case 4: k1 ^= ((uint64_t) tail[3]) << 24; break;", + " case 3: k1 ^= ((uint64_t) tail[2]) << 16; break;", + " case 2: k1 ^= ((uint64_t) tail[1]) << 8; break;", + " case 1: k1 ^= ((uint64_t) tail[0]) << 0; break;", + " k1 *= c1;", + " k1 = (k1 << 31) | (k1 >> 33);", + " k1 *= c2;", + " h1 ^= k1;", + " };", + "", + " h1 ^= len; h2 ^= len;", + " h1 += h2;", + " h2 += h1;", + " h1 ^= h1 >> 33;", + " h1 *= 0xff51afd7ed558ccd;", + " h1 ^= h1 >> 33;", + " h1 *= 0xc4ceb9fe1a85ec53;", + " h1 ^= h1 >> 33;", + " h2 ^= h2 >> 33;", + " h2 *= 0xff51afd7ed558ccd;", + " h2 ^= h2 >> 33;", + " h2 *= 0xc4ceb9fe1a85ec53;", + " h2 ^= h2 >> 33;", + " h1 += h2;", + " h2 += h1;", + "", + " j1_spin = h1&nmask; j3_spin = (h1>>48)&7;", + " j2_spin = h2&nmask; j4_spin = (h2>>48)&7;", + " K1 = h1; K2 = h2;", + "}", + "#endif", + "", + "void", + "s_hash(uchar *cp, int om)", /* uses either d_sfh (1x32bit), or d_hash (2x64bit) */ + "{", /* depending on ssize ie the -w parameter */ + " hasher(cp, om); /* sets K1 */", "#ifdef BITSTATE", " if (S_Tab == H_tab)", /* state stack in bitstate search */ - " j1 = K1 %% omaxdepth;", + " j1_spin = K1 %% omaxdepth;", " else", - "#endif", /* if (S_Tab != H_Tab) */ - " if (ssize < 8*WS)", - " j1 = K1&mask;", - " else", - " j1 = K1;", + "#endif", + " if (ssize < 8*WS)", + " j1_spin = K1&mask;", + " else", + " j1_spin = K1;", "}", "#ifndef RANDSTOR", "int *prerand;", "void", "inirand(void)", "{ int i;", - " srand(123); /* fixed startpoint */", + " srand(s_rand+HASH_NR);", /* inirand */ " prerand = (int *) emalloc((omaxdepth+3)*sizeof(int));", " for (i = 0; i < omaxdepth+3; i++)", - " prerand[i] = rand();", + " { prerand[i] = rand();", + " }", "}", "int", "pan_rand(void)", @@ -3150,28 +5002,271 @@ static char *Code2c[] = { "}", "#endif", "", + "void", + "set_masks(void)", + "{", + " if (WS == 4 && ssize >= 32)", + " { mask = 0xffffffff;", + "#ifdef BITSTATE", + " switch (ssize) {", + " case 34: nmask = (mask>>1); break;", + " case 33: nmask = (mask>>2); break;", + " default: nmask = (mask>>3); break;", + " }", + "#else", + " nmask = mask;", + "#endif", + " } else if (WS == 8)", + " { mask = ((ONE_L<<ssize)-1); /* hash init */", + "#ifdef BITSTATE", + " nmask = mask>>3;", + "#else", + " nmask = mask;", + "#endif", + " } else if (WS != 4)", + " { fprintf(stderr, \"pan: wordsize %%ld not supported\\n\", (long int) WS);", + " exit(1);", + " } else /* WS == 4 and ssize < 32 */", + " { mask = ((ONE_L<<ssize)-1); /* hash init */", + " nmask = (mask>>3);", + " }", + "}", + "", + "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", + "#if NCORE>1", + " #error cannot combine AUTO_RESIZE with NCORE>1", + "#endif", + "static long reclaim_size;", + "static char *reclaim_mem;", + "static H_el **N_tab;", + "void", + "reverse_capture(H_el *p)", + "{ if (!p) return;", + " reverse_capture(p->nxt);", + " /* last element of list moves first */", + " /* to preserve list-order */", + " j2_spin = p->m_K1;", + " if (ssize < 8*WS) /* probably always true */", + " { j2_spin &= mask;", + " }", + " 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 */", + " }", + "", + " ssize += 2; /* 4x size @htable ssize */", + "", + " printf(\"pan: resizing hashtable to -w%%d.. \", ssize);", + "", + " N_tab = (H_el **) emalloc((ONE_L<<ssize)*sizeof(H_el *));", + " set_masks(); /* they changed */", + "", + " for (j1_spin = 0; j1_spin < (ONE_L << (ssize - 2)); j1_spin++)", + " { reverse_capture(H_tab[j1_spin]);", + " }", + " reclaim_mem = (char *) H_tab;", + " reclaim_size = (ONE_L << (ssize - 2));", + " H_tab = N_tab;", + "", + " printf(\" done\\n\");", + "}", + "#endif", + "#if defined(ZAPH) && defined(BITSTATE)", + "void", + "zap_hashtable(void)", + "{ cpu_printf(\"pan: resetting hashtable\\n\");", + " if (udmem)", + " { memset(SS, 0, udmem);", + " } else", + " { memset(SS, 0, ONE_L<<(ssize-3));", + " }", + "}", + "#endif", + "", + "#if NCLAIMS>1", + "int", + "find_claim(char *s)", + "{ int i, j;", + " for (i = 0; strncmp(procname[i], \":np_:\", 5) != 0; i++)", + " { if (strcmp(s, procname[i]) == 0)", + " { for (j = 0; j < NCLAIMS; j++)", + " { if (spin_c_typ[j] == i)", + " { return j;", + " } }", + " break;", + " } }", + " printf(\"pan: error: cannot find claim '%%s'\\n\", s);", + " exit(1);", + " return -1; /* unreachable */", + "}", + "#endif", + "", + "#if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + "int /* to avoid having to include <math.h> and compile with -lm */", + "blog2(int n) /* n >= 1 */", + "{ int m=1, r=2;", + " if (n == 1) { return 0; }", + " if (n == 2) { return 1; }", + " while (n > r) { m++; r *= 2; }", + " return m;", + "}", + "#endif", + "", + "uint pp[33];", + "", + "uint ", + "mul(uint a, uint b, uint p)", + "{ int c = 0;", + " while (a)", + " { if (a&1)", + " { a ^= 1;", + " c ^= b;", + " }", + " a = (a>>1);", + " if (b & 0x80000000)", + " { b += b;", + " b ^= p;", + " } else", + " { b += b;", + " } }", + " return c;", + "}", + "", + "uint", + "ppow(int n, uint p)", + "{ uint t = 1; int i;", + " for (i = 0; i < 32; i++)", + " { if (n & (1<<i))", + " { t = mul(t, pp[i], p);", + " } }", + " return t;", + "}", + "", + "void", + "hashgen(void) /* courtesy Jim Reeds, 1995 */", + "{ uint x, y, p; int i, cnt;", + " int ff[5] = { 3, 5, 17, 257, 65537 };", + " int nn[5];", + "", + " srand(s_rand); /* was: srandom(s_rand) */", + " nn[0] = ff[1]*ff[2]*ff[3]*ff[4];", + " nn[1] = ff[0]*ff[2]*ff[3]*ff[4];", + " nn[2] = ff[0]*ff[1]*ff[3]*ff[4];", + " nn[3] = ff[0]*ff[1]*ff[2]*ff[4];", + " nn[4] = ff[0]*ff[1]*ff[2]*ff[3];", + " for (cnt = 0; cnt < 5000; cnt++)", + " { x = 2;", + " p = ((rand()<<13)^rand()) | 1; /* used random() before */", + " pp[0] = x;", + " for (i = 0; i < 32; i++)", + " { pp[i+1] = mul(pp[i], pp[i], p);", + " }", + " if (pp[32] == x)", + " { for (i = 0; i < 5; i++)", + " { y = ppow(nn[i], p);", + " if (y == 1)", + " { break;", + " } }", + " if (y != 1)", + " { HASH_CONST[0] = p;", /* 32 bit */ + " if (verbose)", + " { printf(\"polynomial: 0x%%.8x (%%d tries)\\n\",", + " p, cnt);", + " }", + " return;", /* success */ + " } } }", + " fprintf(efd, \"pan: could not find a polynomial in %%d tries\\n\", cnt);", + " fprintf(efd, \"pan: try a different seed with -RSn\\n\");", + " exit(1);", + "}", + "", "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))", + " { printf(\"spin: error, the version of spin \");", + " printf(\"that generated this pan.c assumed a different \");", + " printf(\"wordsize (%%d iso %%d)\\n\", G_long, (int) sizeof(long));", + " exit(1);", + " }", + "", + "#if defined(T_RAND) && (T_RAND>0)", + " s_rand = T_RAND;", /* so that -RS can override */ + "#elif defined(P_RAND) && (P_RAND>0)", + " s_rand = P_RAND;", + "#endif", + "", + "#ifdef PUTPID", + " { char *ptr = strrchr(argv[0], '/');", + " if (ptr == NULL)", + " { ptr = argv[0];", + " } else", + " { ptr++;", + " }", + " progname = emalloc(strlen(ptr));", + " strcpy(progname, ptr);", + " /* printf(\"progname: %%s\\n\", progname); */", + " }", + "#endif", + "", "#ifdef BITSTATE", - " bstore = bstore_reg; /* default */", + " b_store = bstore_reg; /* default */", + "#endif", + "#if NCORE>1", + " { int i, j;", + " strcpy(o_cmdline, \"\");", + " for (j = 1; j < argc; j++)", + " { strcat(o_cmdline, argv[j]);", + " strcat(o_cmdline, \" \");", + " }", + " /* printf(\"Command Line: %%s\\n\", o_cmdline); */", + " if (strlen(o_cmdline) >= sizeof(o_cmdline))", + " { Uerror(\"option list too long\");", + " } }", "#endif", " while (argc > 1 && argv[1][0] == '-')", " { switch (argv[1][1]) {", "#ifndef SAFETY", - "#ifdef NP", - " case 'a': fprintf(efd, \"error: -a disabled\");", - " usage(efd); break;", - "#else", + " #ifdef NP", + " case 'a': fprintf(efd, \"warning: -a is disabled by -DNP, ignored\");", + " 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 0<N<256\\n\");", + " exit(1);", + " } }", + " break;", + " #endif", "#endif", " case 'A': noasserts = 1; break;", " case 'b': bounded = 1; break;", - " case 'c': upto = atoi(&argv[1][2]); break;", + "#ifdef HAS_CODE", + " #if HAS_CODE>0", + " case 'C': coltrace = 1; goto samething;", + " #endif", + "#endif", + " case 'c': upto = atoi(&argv[1][2]); break;", + " case 'D': dodot++; state_tables++; break;", " case 'd': state_tables++; break;", - " case 'e': every_error = 1; Nr_Trails = 1; break;", + " case 'e': every_error = 1; upto = 0; Nr_Trails = 1; break;", " case 'E': noends = 1; break;", "#ifdef SC", " case 'F': if (strlen(argv[1]) > 2)", @@ -3181,23 +5276,57 @@ static char *Code2c[] = { "#if !defined(SAFETY) && !defined(NOFAIR)", " case 'f': fairness = 1; break;", "#endif", - " case 'h': if (!argv[1][2]) usage(efd); else", - " HASH_NR = atoi(&argv[1][2])%%33; break;", + "#ifdef HAS_CODE", + " #if HAS_CODE>0", + " case 'g': gui = 1; goto samething;", + " #endif", + "#endif", + " case 'h':", + " if (strncmp(&argv[1][1], \"hash\", strlen(\"hash\")) == 0)", + " { do_hashgen = 1;", + " break;", + " }", + " if (!argv[1][2] || !isdigit((int) argv[1][2]))", + " { usage(efd); /* exits */", + " }", + " HASH_NR = atoi(&argv[1][2])%%(sizeof(HASH_CONST)/sizeof(uint));", + " break;", " case 'I': iterative = 2; every_error = 1; break;", - " case 'i': iterative = 1; every_error = 1; break;", + " case 'i':", + " if (strncmp(&argv[1][1], \"i_reverse\", strlen(\"i_reverse\")) == 0)", + " { reversing |= 1;", + " } else", + " { iterative = 1;", + " every_error = 1;", + " }", + " break;", " case 'J': like_java = 1; break; /* Klaus Havelund */", "#ifdef BITSTATE", " case 'k': hfns = atoi(&argv[1][2]); break;", "#endif", + "#ifdef BCS", + " case 'L':", + " sched_max = atoi(&argv[1][2]);", + " if (sched_max > 255) /* stored as one byte */", + " { fprintf(efd, \"warning: using max bound (255)\\n\");", + " sched_max = 255;", + " }", + " #ifndef NOREDUCE", + " if (sched_max == 0)", + " { fprintf(efd, \"warning: with (default) bound -L0, \");", + " fprintf(efd, \"using -DNOREDUCE performs better\\n\");", + " }", + " #endif", + " break;", + "#endif", "#ifndef SAFETY", "#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", -#ifndef POWOW "#ifdef BITSTATE", " case 'M': udmem = atoi(&argv[1][2]); break;", " case 'G': udmem = atoi(&argv[1][2]); udmem *= 1024; break;", @@ -3206,66 +5335,344 @@ static char *Code2c[] = { " fprintf(stderr, \"-M and -G affect only -DBITSTATE\\n\");", " break;", "#endif", -#endif " case 'm': maxdepth = atoi(&argv[1][2]); break;", + "#ifndef NOCLAIM", + " case 'N':", + " #if NCLAIMS>1", + " if (isdigit((int)argv[1][2]))", + " { whichclaim = atoi(&argv[1][2]);", + " } else if (isalpha((int)argv[1][2]))", + " { claimname = &argv[1][2];", + " } else if (argc > 2 && argv[2][0] != '-') /* check next arg */", + " { claimname = argv[2];", + " argc--; argv++; /* skip next arg */", + " }", + " #else", + " #if NCLAIMS==1", + " fprintf(stderr, \"warning: only one claim defined, -N ignored\\n\");", + " #else", + " fprintf(stderr, \"warning: no claims defined, -N ignored\\n\");", + " #endif", + " if (!isdigit((int)argv[1][2]) && argc > 2 && argv[2][0] != '-')", + " { argc--; argv++;", + " }", + " #endif", + "#endif", + " break;\n", " case 'n': no_rck = 1; break;", + "", + " case 'P':", + " if (!readtrail", + " && isdigit((int) argv[1][2]))", /* was argv[1][2] == '_' */ + " { int x = atoi(&argv[1][2]);", + " if (x != 0 && x != 1)", + " { fprintf(efd, \"pan: bad option -P[01], ignored\\n\");", + " }", + " if (x == 0)", + " { reversing &= ~1;", + " break;", + " }", + " if (x == 1)", + " { reversing |= 1;", + " break;", + " }", + " if (verbose)", + " fprintf(efd, \"pan: reversed *active* process creation %%s\\n\",", + " reversing&1?\"on\":\"off\");", + " break;", + " } /* else */", + "#ifdef HAS_CODE", + " #if HAS_CODE>0", + " readtrail = 1; onlyproc = atoi(&argv[1][2]);", + " if (argc > 2 && argv[2][0] != '-') /* check next arg */", + " { trailfilename = argv[2];", + " argc--; argv++; /* skip next arg */", + " }", + " #else", + " fprintf(efd, \"pan: option -P not recognized, ignored\\n\");", + " #endif", + "#else", + " fprintf(efd, \"pan: option -P not recognized, ignored\\n\");", + "#endif", + " break;", + "", + " case 'p':", + " #if !defined(BFS) && !defined(BFS_PAR)", + " #ifdef PERMUTED", + " if (strncmp(&argv[1][1], \"p_normal\", strlen(\"p_normal\")) == 0)", + " { reversing &= ~2;", + " break;", + " }", + " reversing |=2;", + " if (strncmp(&argv[1][1], \"p_permute\", strlen(\"p_permute\")) == 0)", + " { p_reorder = set_permuted;", + " break;", + " }", + " if (strncmp(&argv[1][1], \"p_rotate\", strlen(\"p_rotate\")) == 0)", + " { p_reorder = set_rotated;", + " if (isdigit((int) argv[1][9]))", + " { p_rotate = atoi(&argv[1][9]);", + " } else", + " { p_rotate = 1;", + " }", + " break;", + " }", + " if (strncmp(&argv[1][1], \"p_randrot\", strlen(\"p_randrot\")) == 0)", + " { p_reorder = set_randrot;", + " break;", + " }", + " if (strncmp(&argv[1][1], \"p_reverse\", strlen(\"p_reverse\")) == 0)", + " { p_reorder = set_reversed;", + " break;", + " }", + " #else", + " if (strncmp(&argv[1][1], \"p_permute\", strlen(\"p_permute\")) == 0", + " || strncmp(&argv[1][1], \"p_rotate\", strlen(\"p_rotate\")) == 0", + " || strncmp(&argv[1][1], \"p_randrot\", strlen(\"p_randrot\")) == 0", + " || strncmp(&argv[1][1], \"p_reverse\", strlen(\"p_reverse\")) == 0)", + " { fprintf(efd, \"option %%s required compilation with -DPERMUTED\\n\",", + " argv[1]);", + " exit(1);", + " }", + " #endif", + " #endif", "#ifdef SVDUMP", - " case 'p': vprefix = atoi(&argv[1][2]); break;", + " vprefix = atoi(&argv[1][2]);", + "#else", + " fprintf(efd, \"invalid option '%%s' -- ignored\\n\", argv[1]);", + "#endif", + " break;", + "#if NCORE==1", + " case 'Q': quota = (double) 60.0 * (double) atoi(&argv[1][2]);", + " #ifndef FREQ", + " freq /= 10.; /* for better resolution */", + " #endif", + " break;", "#endif", " case 'q': strict = 1; break;", - "#ifdef HAS_CODE", + " case 'R':", + " if (argv[1][2] == 'S') /* e.g., -RS76842 */", + " { s_rand = atoi(&argv[1][3]);", /* RS */ + " break;", + " }", + "#ifdef BITSTATE", + " Nrun = atoi(&argv[1][2]);", + " if (Nrun > 100)", + " { Nrun = 100;", + " } else if (Nrun < 1)", + " { Nrun = 1;", + " }", + "#else", + " usage(efd);", + " break;", + "#endif", " case 'r':", + " if (strncmp(&argv[1][1], \"rhash\", strlen(\"rhash\")) == 0)", + " { if (s_rand == 12345) /* default seed */", + " {", + "#if defined(WIN32) || defined(WIN64)", + " s_rand = (uint) clock();", + "#else", + " struct tms dummy_tm;", + " s_rand = (uint) times(&dummy_tm);", + "#endif", + " }", + " srand(s_rand++);", + " #ifdef PERMUTED", + " do_hashgen = 1;", /* + randomize p_rotate, p_reverse, p_permute */ + " switch (rand()%%5) {", + " case 0: p_reorder = set_permuted;", + " reversing |=2;", + " break;", + " case 1: p_reorder = set_reversed;", + " reversing |=2;", + " break;", + " /* fully randomize p_rotate: */", + " case 2: p_reorder = set_randrot;", + " reversing |=2;", + " break;", + " /* choose once, then keep p_rotate fixed: */", + " case 3: p_reorder = set_rotated;", + " p_rotate = rand()%%3;", + " reversing |=2;", + " break;", + " default: /* standard search */ break;", + " }", + " if (rand()%%2 == 0)", + " { t_reverse = 1;", + " }", + " break;", + " #else", + " fprintf(efd, \"option -rhash requires compilation with -DPERMUTED\\n\");", + " exit(1);", + " #endif", + " }", + "#if defined(HAS_CODE) && HAS_CODE>0", "samething: readtrail = 1;", - " if (isdigit(argv[1][2]))", + " if (isdigit((int)argv[1][2]))", " whichtrail = atoi(&argv[1][2]);", + " else if (argc > 2 && argv[2][0] != '-') /* check next arg */", + " { trailfilename = argv[2];", + " argc--; argv++; /* skip next arg */", + " }", + " break;", + " case 'S': silent = 1; goto samething;", + "#else", + " fprintf(efd, \"options -r is for models with embedded C code\\n\");", " break;", - " case 'P': readtrail = 1; onlyproc = atoi(&argv[1][2]); break;", - " case 'C': coltrace = 1; goto samething;", - " case 'g': gui = 1; goto samething;", - " case 'S': silent = 1; break;", "#endif", - " case 'R': Nrun = atoi(&argv[1][2]); break;", - "#ifdef BITSTATE", - " case 's': hfns = 1; break;", - "#endif", - " case 'T': TMODE = 0444; break;", - " case 't': if (argv[1][2]) tprefix = &argv[1][2]; break;", - " case 'V': printf(\"Generated by %%s\\n\", Version);", - " to_compile(); pan_exit(0); break;", - " case 'v': verbose = 1; break;", - " case 'w': ssize = atoi(&argv[1][2]); break;", + " case 'T':", + " if (isdigit((int) argv[1][2]))", /* was argv[1][2] == '_' */ + " { t_reverse = atoi(&argv[1][2]);", + " if (verbose)", + " printf(\"pan: reverse transition ordering %%s\\n\",", + " t_reverse?\"on\":\"off\");", + " break;", + " }", + " TMODE = 0444;", + " break;", + " case 't':", + " if (strncmp(&argv[1][1], \"t_reverse\", strlen(\"t_reverse\")) == 0)", + " { t_reverse = 1;", + " break;", + " }", /* i.e., a trail prefix cannot be '_reverse' */ + " if (argv[1][2])", + " { tprefix = &argv[1][2];", + " }", + " break;", + " case 'u':", + " #ifdef BFS_PAR", + " ncores = atoi(&argv[1][2]);", + " #endif", + " break;", + " case 'V': start_timer(); printf(\"Generated by %%s\\n\", SpinVersion);", + " to_compile(); pan_exit(2); break;", + " case 'v': verbose++; break;", + " case 'w': ssize = atoi(&argv[1][2]);", + " #if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + " used_w = 1;", + " #endif", + " break;", " case 'Y': signoff = 1; break;", " case 'X': efd = stdout; break;", - " default : fprintf(efd, \"saw option -%%c\\n\", argv[1][1]); usage(efd); break;", + " case 'x': exclusive = 1; break;", + " #if NCORE>1", + " /* -B ip is passthru to proxy of remote ip address: */", + " case 'B': argc--; argv++; break;", + " case 'Q': worker_pids[0] = atoi(&argv[1][2]); break;", + " /* -Un means that the nth worker should be instantiated as a proxy */", + " case 'U': proxy_pid = atoi(&argv[1][2]); break;", + " /* -W means this copy is started by a cluster-server as a remote */", + " /* this flag is passed to ./pan_proxy, which interprets it */", + " case 'W': remote_party++; break;", + " case 'Z': core_id = atoi(&argv[1][2]);", + " if (verbose)", + " { printf(\"cpu%%d: pid %%d parent %%d\\n\",", + " core_id, getpid(), worker_pids[0]);", + " }", + " break;", + " case 'z': z_handoff = atoi(&argv[1][2]); break;", + " #else", + " case 'z': break; /* ignored for single-core */", + " #endif", + " default : fprintf(efd, \"saw option -%%c\\n\",", + " argv[1][1]); usage(efd); break;", " }", " argc--; argv++;", " }", + "#if defined(BFS_PAR) && defined(BFS_SEP_HASH)", + " if (used_w == 0)", + " { if (ncores == 0) /* all cores used, by default */", + " { ssize -= blog2(BFS_MAXPROCS - 1);", + " } else", + " { ssize -= blog2(ncores);", + " } }", + "#endif", + " if (do_hashgen)", + " { hashgen();", /* placed here so that -RSn can appear after -hash */ + " }", + "#ifndef SAFETY", + " if (fairness && !a_cycles)", + " { fprintf(efd, \"error: -f requires the use of -a or -l\\n\");", + " usage(efd);", + " }", + " #if ACCEPT_LAB==0", + " if (a_cycles)", + " { fprintf(efd, \"warning: no accept labels are defined, \");", + " fprintf(efd, \"so option -a has no effect (ignored)\\n\");", + " a_cycles = 0;", + " }", + " #endif", + "#endif", + "", + "#ifdef BFS_PAR", + " uerror = bfs_uerror;", + " Uerror = bfs_Uerror;", + "#else", + " uerror = dfs_uerror;", + " Uerror = dfs_Uerror;", + "#endif", + " if (ssize <= 32) /* 6.2.0 */", + " { hasher = d_sfh;", + "#if !defined(BITSTATE) && defined(USE_TDH)", + " o_hash = o_hash32;", + "#endif", + " } else", + " { hasher = d_hash;", + "#if !defined(BITSTATE) && defined(USE_TDH)", + " o_hash = o_hash64;", + "#endif", + " }", " if (iterative && TMODE != 0666)", " { TMODE = 0666;", " fprintf(efd, \"warning: -T ignored when -i or -I is used\\n\");", " }", "#if defined(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;", - "#endif", - "#ifdef OHASH", - " fprintf(efd, \"warning: -DOHASH no longer supported (directive ignored)\\n\");", - "#endif", - "#ifdef JHASH", - " fprintf(efd, \"warning: -DJHASH no longer supported (directive ignored)\\n\");", + " TMODE = S_IREAD;", + "#endif", + "#if NCORE>1", + " store_proxy_pid = proxy_pid; /* for checks in mem_file() and someone_crashed() */", + " if (core_id != 0) { proxy_pid = 0; }", + " #ifndef SEP_STATE", + " if (core_id == 0 && a_cycles)", + " { fprintf(efd, \"hint: this search may be more efficient \");", + " fprintf(efd, \"if pan.c is compiled -DSEP_STATE\\n\");", + " }", + " #endif", + " if (z_handoff < 0)", + " { z_handoff = 20; /* conservative default - for non-liveness checks */", + " }", + "#if defined(NGQ) || defined(LWQ_FIXED)", + " LWQ_SIZE = (double) (128.*1048576.);", + "#else", + " LWQ_SIZE = (double) ( z_handoff + 2.) * (double) sizeof(SM_frame);", + /* the added margin of +2 is not really necessary */ "#endif", - "#ifdef HYBRID_HASH", - " fprintf(efd, \"warning: -DHYBRID_HASH no longer supported (directive ignored)\\n\");", + " #if NCORE>2", + " if (a_cycles)", + " { fprintf(efd, \"warning: the intended nr of cores to be used in liveness mode is 2\\n\");", + " #ifndef SEP_STATE", + " fprintf(efd, \"warning: without -DSEP_STATE there is no guarantee that all liveness violations are found\\n\");", + " #endif", + " }", /* it still works though, the later cores get states from the global q */ + " #endif", + " #ifdef HAS_HIDDEN", + " #error cannot use hidden variables when compiling multi-core", + " #endif", "#endif", - "#ifdef NOCOVEST", - " fprintf(efd, \"warning: -DNOCOVEST no longer supported (directive ignored)\\n\");", + "#if defined(T_RAND) && defined(ELSE_IN_GUARD)", + " #error cannot hide 'else' as guard in d_step, when using -DT_RAND", "#endif", "#ifdef BITSTATE", - "#ifdef BCOMP", - " fprintf(efd, \"warning: -DBCOMP no longer supported (directive ignored)\\n\");", - "#endif", " if (hfns <= 0)", " { hfns = 1;", " fprintf(efd, \"warning: using -k%%d as minimal usable value\\n\", hfns);", @@ -3278,7 +5685,7 @@ static char *Code2c[] = { " fprintf(efd, \"warning: using -w%%d as max usable value\\n\", ssize);", "/*", " * -w35 would not work: 35-3 = 32 but 1^31 is the largest", - " * power of 2 that can be represented in an unsigned long", + " * power of 2 that can be represented in an ulong", " */", " }", "#else", @@ -3297,8 +5704,8 @@ static char *Code2c[] = { " hiwater = HHH = maxdepth-10;", " DDD = HHH/2;", " if (!stackfile)", - " { stackfile = (char *) emalloc(strlen(Source)+4+1);", - " sprintf(stackfile, \"%%s._s_\", Source);", + " { stackfile = (char *) emalloc(strlen(PanSource)+4+1);", + " sprintf(stackfile, \"%%s._s_\", PanSource);", " }", " if (iterative)", " { fprintf(efd, \"error: cannot use -i or -I with -DSC\\n\");", @@ -3307,69 +5714,97 @@ static char *Code2c[] = { "#endif", "#if (defined(R_XPT) || defined(W_XPT)) && !defined(MA)", - " fprintf(efd, \"error: -D?_XPT requires -DMA\\n\");", - " exit(1);", + " #warning -DR_XPT and -DW_XPT assume -DMA (ignored)", "#endif", " if (iterative && a_cycles)", " fprintf(efd, \"warning: -i or -I work for safety properties only\\n\");", "#ifdef BFS", - "#if defined(SC)", - " fprintf(efd, \"error: -DBFS not compatible with -DSC\\n\");", - " exit(1);", + " #ifdef SC", + " #error -DBFS not compatible with -DSC", + " #endif", + " #ifdef HAS_LAST", + " #error -DBFS not compatible with _last", + " #endif", + " #ifdef HAS_STACK", + " #error cannot use c_track UnMatched with BFS", + " #endif", + " #ifdef BCS", + " #error -DBFS not compatible with -DBCS", + " #endif", + " #ifdef REACH", + " #warning -DREACH is redundant when -DBFS is used", + " #endif", "#endif", - "#if defined(HAS_LAST)", - " fprintf(efd, \"error: -DBFS not compatible with _last\\n\");", - " exit(1);", + + "#ifdef TRIX", + " #ifdef BITSTATE", + " #error cannot combine -DTRIX and -DBITSTATE", + " #endif", + " #ifdef COLLAPSE", + " #error cannot combine -DTRIX and -DCOLLAPSE", + " #endif", + " #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", - "#if defined(REACH)", - " fprintf(efd, \"warning: -DREACH redundant when -DBFS is used\\n\");", + + "#ifdef BFS_PAR", + " #ifdef NP", + " #error cannot combine -DBFS_PAR and -DNP", + " #undef NP", + " #endif", "#endif", - "#if defined(HAS_STACK)", - " fprintf(efd, \"error: cannot use UnMatched qualifier on c_track with BFS\\n\");", - " exit(1);", + + "#ifdef NOCLAIM", + " #ifdef NP", + " #warning using -DNP overrides -DNOCLAIM", + " #undef NOCLAIM", + " #endif", "#endif", + + "#ifdef BCS", + " #ifdef P_RAND", + " #error cannot combine -DBCS and -DP_RAND", + " #endif", + " #ifdef BFS", + " #error cannot combine -DBCS and -DBFS", + " #endif", "#endif", "#if defined(MERGED) && defined(PEG)", - " fprintf(efd, \"error: to allow -DPEG use: spin -o3 -a %%s\\n\", Source);", - " fprintf(efd, \" to turn off transition merge optimization\\n\");", - " pan_exit(1);", + " #error to use -DPEG use: spin -o3 -a", "#endif", - "#ifdef HC", - "#ifdef NOCOMP", - " fprintf(efd, \"error: cannot combine -DHC and -DNOCOMP\\n\");", - " pan_exit(1);", - "#endif", - "#ifdef BITSTATE", - " fprintf(efd, \"error: cannot combine -DHC and -DBITSTATE\\n\");", - " pan_exit(1);", - "#endif", + "#if defined(HC) && !defined(BFS_PAR)", + " #ifdef NOCOMP", + " #error cannot combine -DHC and -DNOCOMP", + " #endif", + " #ifdef BITSTATE", + " #error cannot combine -DHC and -DBITSTATE", + " #endif", "#endif", "#if defined(SAFETY) && defined(NP)", - " fprintf(efd, \"error: cannot combine -DNP and -DSAFETY\\n\");", - " pan_exit(1);", + " #error cannot combine -DNP and -DBFS or -DSAFETY", "#endif", "#ifdef MA", - "#ifdef BITSTATE", - " fprintf(efd, \"error: cannot combine -DMA and -DBITSTATE\\n\");", - " pan_exit(1);", - "#endif", - " if (MA <= 0)", - " { fprintf(efd, \"usage: -DMA=N with N > 0 and < VECTORSZ\\n\");", - " pan_exit(1);", - " }", + " #ifdef BITSTATE", + " #error cannot combine -DMA and -DBITSTATE", + " #endif", + " #if MA <= 0", + " #error usage: -DMA=N with N > 0 and N < VECTORSZ", + " #endif", "#endif", "#ifdef COLLAPSE", - "#if defined(BITSTATE)", - " fprintf(efd, \"error: cannot combine -DBITSTATE and -DCOLLAPSE\\n\");", - " pan_exit(1);", - "#endif", - "#if defined(NOCOMP)", - " fprintf(efd, \"error: cannot combine -DNOCOMP and -DCOLLAPSE\\n\");", - " pan_exit(1);", - "#endif", + " #ifdef BITSTATE", + " #error cannot combine -DBITSTATE and -DCOLLAPSE", + " #endif", + " #ifdef NOCOMP", + " #error cannot combine -DCOLLAPSE and -DNOCOMP", + " #endif", "#endif", " if (maxdepth <= 0 || ssize <= 1) usage(efd);", "#if SYNC>0 && !defined(NOREDUCE)", @@ -3382,202 +5817,147 @@ static char *Code2c[] = { " }", "#endif", "#if defined(REM_VARS) && !defined(NOREDUCE)", - " { fprintf(efd, \"warning: p.o. reduction not compatible with \");", - " fprintf(efd, \"remote varrefs (use -DNOREDUCE)\\n\");", - " }", + " #warning p.o. reduction not compatible with remote varrefs (use -DNOREDUCE)", "#endif", "#if defined(NOCOMP) && !defined(BITSTATE)", " if (a_cycles)", - " { fprintf(efd, \"error: -DNOCOMP voids -l and -a\\n\");", + " { fprintf(efd, \"error: use of -DNOCOMP voids -l and -a\\n\");", " pan_exit(1);", " }", "#endif", - - "#ifdef MEMLIM", /* MEMLIM setting takes precedence */ - " memlim = (double) MEMLIM * (double) (1<<20); /* size in Mbyte */", - "#else", - "#ifdef MEMCNT", - "#if MEMCNT<31", - " memlim = (double) (1<<MEMCNT);", - "#else", - " memlim = (double) (1<<30);", - " memlim *= (double) (1<<(MEMCNT-30));", - "#endif", - "#endif", - "#endif", - - "#ifndef BITSTATE", - " if (Nrun > 1) HASH_NR = Nrun - 1;", + "#ifdef MEMLIM", + " memlim = ((double) MEMLIM) * (double) (1<<20); /* size in Mbyte */", "#endif", - " if (Nrun < 1 || Nrun > 32)", - " { fprintf(efd, \"error: invalid arg for -R\\n\");", - " usage(efd);", - " }", - "#ifndef SAFETY", - " if (fairness && !a_cycles)", - " { fprintf(efd, \"error: -f requires -a or -l\\n\");", - " usage(efd);", - " }", - "#if ACCEPT_LAB==0", - " if (a_cycles)", - "#ifndef VERI", - " { fprintf(efd, \"error: no accept labels defined \");", - " fprintf(efd, \"in model (for option -a)\\n\");", - " usage(efd);", - " }", - "#else", - " { fprintf(efd, \"warning: no explicit accept labels \");", - " fprintf(efd, \"defined in model (for -a)\\n\");", - " }", - "#endif", - "#endif", + "#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", - "#if !defined(NOREDUCE)", - "#if defined(HAS_ENABLED)", - " fprintf(efd, \"error: reduced search precludes \");", - " fprintf(efd, \"use of 'enabled()'\\n\");", - " pan_exit(1);", - "#endif", - "#if defined(HAS_PCVALUE)", - " fprintf(efd, \"error: reduced search precludes \");", - " fprintf(efd, \"use of 'pcvalue()'\\n\");", - " pan_exit(1);", - "#endif", - "#if defined(HAS_BADELSE)", - " fprintf(efd, \"error: reduced search precludes \");", - " fprintf(efd, \"using 'else' combined with i/o stmnts\\n\");", - " pan_exit(1);", - "#endif", - "#if defined(HAS_LAST)", - " fprintf(efd, \"error: reduced search precludes \");", - " fprintf(efd, \"use of _last\\n\");", - " pan_exit(1);", - "#endif", + "#ifndef NOREDUCE", + " #ifdef HAS_PRIORITY", + " #warning use of priorities requires -DNOREDUCE", + " #elif HAS_ENABLED", + " #error use of enabled() requires -DNOREDUCE", + " #endif", + " #ifdef HAS_PCVALUE", + " #error use of pcvalue() requires -DNOREDUCE", + " #endif", + " #ifdef HAS_BADELSE", + " #error use of 'else' combined with i/o stmnts requires -DNOREDUCE", + " #endif", + " #if defined(HAS_LAST) && !defined(BCS)", + " #error use of _last requires -DNOREDUCE", + " #endif", "#endif", "#if SYNC>0 && !defined(NOREDUCE)", - "#ifdef HAS_UNLESS", + " #ifdef HAS_UNLESS", " fprintf(efd, \"warning: use of a rendezvous stmnts in the escape\\n\");", " fprintf(efd, \"\tof an unless clause, if present, could make p.o. reduction\\n\");", " fprintf(efd, \"\tinvalid (use -DNOREDUCE to avoid this)\\n\");", - "#ifdef BFS", - " fprintf(efd, \"\t(this type of rv is also not compatible with -DBFS)\\n\");", - "#endif", - "#endif", + " #ifdef BFS", + " fprintf(efd, \"\t(this type of rv is also not compatible with -DBFS)\\n\");", + " #endif", + " #endif", "#endif", "#if SYNC>0 && defined(BFS)", - " fprintf(efd, \"warning: use of rendezvous in BFS mode \");", - " fprintf(efd, \"does not preserve all invalid endstates\\n\");", + " 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)", - " fprintf(efd, \"warning: -i and -I need -DREACH to work accurately\\n\");", + " { fprintf(efd, \"warning: -i and -I need -DREACH to work accurately\\n\");", + " }", "#endif", "#if defined(BITSTATE) && defined(REACH)", - " fprintf(efd, \"warning: -DREACH voided by -DBITSTATE\\n\");", + " #warning -DREACH is voided by -DBITSTATE", "#endif", "#if defined(MA) && defined(REACH)", - " fprintf(efd, \"warning: -DREACH voided by -DMA\\n\");", + " #warning -DREACH is voided by -DMA", "#endif", "#if defined(FULLSTACK) && defined(CNTRSTACK)", - " fprintf(efd, \"error: cannot combine\");", - " fprintf(efd, \" -DFULLSTACK and -DCNTRSTACK\\n\");", - " pan_exit(1);", + " #error cannot combine -DFULLSTACK and -DCNTRSTACK", "#endif", "#if defined(VERI)", - "#if ACCEPT_LAB>0", - "#ifndef BFS", - " if (!a_cycles", - "#ifdef HAS_CODE", - " && !readtrail", - "#endif", - " && !state_tables)", - " { fprintf(efd, \"warning: never claim + accept labels \");", - " fprintf(efd, \"requires -a flag to fully verify\\n\");", - " }", - "#else", - " if (", - "#ifdef HAS_CODE", - " !readtrail", - "#endif", - " && !state_tables)", - " { fprintf(efd, \"warning: verification in BFS mode \");", - " fprintf(efd, \"is restricted to safety properties\\n\");", - " }", - "#endif", - "#endif", + " #if ACCEPT_LAB>0", + " #ifndef BFS", + " if (!a_cycles", + " #ifdef HAS_CODE", + " && !readtrail", + " #endif", + " #if NCORE>1", + " && core_id == 0", + " #endif", + " && !state_tables)", + " { fprintf(efd, \"warning: never claim + accept labels \");", + " fprintf(efd, \"requires -a flag to fully verify\\n\");", + " }", + " #else", + " if (verbose && !state_tables", + " #ifdef HAS_CODE", + " && !readtrail", + " #endif", + " )", + " { fprintf(efd, \"warning: verification in BFS mode \");", + " fprintf(efd, \"is restricted to safety properties\\n\");", + " }", + " #endif", + " #endif", "#endif", "#ifndef SAFETY", + " #if 0", " if (!a_cycles", - "#ifdef HAS_CODE", + " #ifdef HAS_CODE", " && !readtrail", - "#endif", - " && !state_tables)", + " #endif", + " #if NCORE>1", + " && core_id == 0", + " #endif", + " && !state_tables)", " { fprintf(efd, \"hint: this search is more efficient \");", " fprintf(efd, \"if pan.c is compiled -DSAFETY\\n\");", " }", - "#ifndef NOCOMP", + " #endif", + " #ifndef NOCOMP", " if (!a_cycles)", - " S_A = 0;", - " else", + " { S_A = 0;", + " } else", " { if (!fairness)", - " S_A = 1; /* _a_t */", - "#ifndef NOFAIR", - " else /* _a_t and _cnt[NFAIR] */", - " S_A = (&(now._cnt[0]) - (uchar *) &now) + NFAIR - 2;", + " { S_A = 1; /* _a_t */", + " #ifndef NOFAIR", + " } else /* _a_t and _cnt[NFAIR] */", + " { S_A = (&(now._cnt[0]) - (uchar *) &now) + NFAIR - 2;", " /* -2 because first two uchars in now are masked */", - "#endif", - " }", - "#endif", + " #endif", + " } }", + " #endif", "#endif", " signal(SIGINT, stopped);", - - /******************* 4.2.5 ********************/ - " if (WS == 4 && ssize >= 32)", - " { mask = 0xffffffff;", - "#ifdef BITSTATE", - " switch (ssize) {", - " case 34: nmask = (mask>>1); break;", - " case 33: nmask = (mask>>2); break;", - " default: nmask = (mask>>3); break;", - " }", - "#else", - " nmask = mask;", - "#endif", - " } else if (WS == 8)", - " { mask = ((1L<<ssize)-1); /* hash init */", - "#ifdef BITSTATE", - " nmask = mask>>3;", - "#else", - " nmask = mask;", - "#endif", - " } else if (WS != 4)", - " { fprintf(stderr, \"pan: wordsize %%ld not supported\\n\", WS);", - " exit(1);", - " } else /* WS == 4 and ssize < 32 */", - " { mask = ((1L<<ssize)-1); /* hash init */", - " nmask = (mask>>3);", - " }", - /****************** end **********************/ - - "#ifdef BFS", + " set_masks();", + "#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];", - " sprintf(nm, \"%%s.svd\", Source);", - " if ((svfd = creat(nm, 0666)) < 0)", + " sprintf(nm, \"%%s.svd\", PanSource);", + " if ((svfd = creat(nm, TMODE)) < 0)", " { fprintf(efd, \"couldn't create %%s\\n\", nm);", " vprefix = 0;", " } }", "#endif", "#ifdef RANDSTOR", - " srand(123);", + " srand(s_rand+HASH_NR);", /* main - RANDSTOR */ "#endif", "#if SYNC>0 && ASYNC==0", " set_recvs();", @@ -3591,6 +5971,7 @@ static char *Code2c[] = { "void", "usage(FILE *fd)", "{", + " fprintf(fd, \"%%s\\n\", SpinVersion);", " fprintf(fd, \"Valid Options are:\\n\");", "#ifndef SAFETY", "#ifdef NP", @@ -3606,6 +5987,7 @@ static char *Code2c[] = { " fprintf(fd, \"\t-b consider it an error to exceed the depth-limit\\n\");", " fprintf(fd, \"\t-cN stop at Nth error \");", " fprintf(fd, \"(defaults to -c1)\\n\");", + " fprintf(fd, \"\t-D print state tables in dot-format and stop\\n\");", " fprintf(fd, \"\t-d print state tables and stop\\n\");", " fprintf(fd, \"\t-e create trails for all errors\\n\");", " fprintf(fd, \"\t-E ignore invalid end states\\n\");", @@ -3615,13 +5997,18 @@ static char *Code2c[] = { "#ifndef NOFAIR", " fprintf(fd, \"\t-f add weak fairness (to -a or -l)\\n\");", "#endif", - " fprintf(fd, \"\t-hN use different hash-seed N:1..32\\n\");", + " fprintf(fd, \"\t-hN use different hash-seed N:0..499 (defaults to -h0)\\n\");", + " fprintf(fd, \"\t-hash generate a random hash-polynomial for -h0 (see also -rhash)\\n\");", + " fprintf(fd, \"\t using a seed set with -RSn (default %%u)\\n\", s_rand);", " fprintf(fd, \"\t-i search for shortest path to error\\n\");", " fprintf(fd, \"\t-I like -i, but approximate and faster\\n\");", " fprintf(fd, \"\t-J reverse eval order of nested unlesses\\n\");", "#ifdef BITSTATE", " fprintf(fd, \"\t-kN set N bits per state (defaults to 3)\\n\");", "#endif", + "#ifdef BCS", + " fprintf(fd, \"\t-LN set scheduling restriction to N (default 0)\\n\");", + "#endif", "#ifndef SAFETY", "#ifdef NP", " fprintf(fd, \"\t-l find non-progress cycles\\n\");", @@ -3631,69 +6018,83 @@ static char *Code2c[] = { " fprintf(fd, \"compilation with -DNP\\n\");", "#endif", "#endif", -#ifndef POWOW "#ifdef BITSTATE", " fprintf(fd, \"\t-MN use N Megabytes for bitstate hash array\\n\");", " fprintf(fd, \"\t-GN use N Gigabytes for bitstate hash array\\n\");", "#endif", -#endif " fprintf(fd, \"\t-mN max depth N steps (default=10k)\\n\");", + "#if NCLAIMS>1", + " fprintf(fd, \"\t-N cn -- use the claim named cn\\n\");", + " fprintf(fd, \"\t-Nn -- use claim number n\\n\");", + "#endif", " fprintf(fd, \"\t-n no listing of unreached states\\n\");", + "#ifdef PERMUTED", + " fprintf(fd, \"\t-p_permute randomize order in which processes are scheduled (see also -rhash)\\n\");", + " fprintf(fd, \"\t-p_reverse reverse order in which processes are scheduled (see also -rhash)\\n\");", + " fprintf(fd, \"\t-p_rotateN rotate by N the process scheduling order (see also -rhash)\\n\");", + "#endif", "#ifdef SVDUMP", " fprintf(fd, \"\t-pN create svfile (save N bytes per state)\\n\");", "#endif", + " fprintf(fd, \"\t-QN set time-limit on execution of N minutes\\n\");", " fprintf(fd, \"\t-q require empty chans in valid end states\\n\");", "#ifdef HAS_CODE", " fprintf(fd, \"\t-r read and execute trail - can add -v,-n,-PN,-g,-C\\n\");", + " fprintf(fd, \"\t-r trailfilename read and execute trail in file\\n\");", " fprintf(fd, \"\t-rN read and execute N-th error trail\\n\");", " fprintf(fd, \"\t-C read and execute trail - columnated output (can add -v,-n)\\n\");", - " fprintf(fd, \"\t-PN read and execute trail - restrict trail output to proc N\\n\");", + " fprintf(fd, \"\t-r -PN read and execute trail - restrict trail output to proc N\\n\");", " fprintf(fd, \"\t-g read and execute trail + msc gui support\\n\");", " fprintf(fd, \"\t-S silent replay: only user defined printfs show\\n\");", "#endif", + " fprintf(fd, \"\t-RSn use randomization seed n\\n\");", + " fprintf(fd, \"\t-rhash use random hash-polynomial and randomly choose -p_rotateN, -p_permute, or p_reverse\\n\");", "#ifdef BITSTATE", - " fprintf(fd, \"\t-RN repeat run Nx with N \");", - " fprintf(fd, \"[1..32] independent hash functions\\n\");", - " fprintf(fd, \"\t-s same as -k1 (single bit per state)\\n\");", + " fprintf(fd, \"\t-Rn run n times n: [1..100] using n \");", + " fprintf(fd, \" different hash functions\\n\");", "#endif", " fprintf(fd, \"\t-T create trail files in read-only mode\\n\");", + " fprintf(fd, \"\t-t_reverse reverse order in which transitions are explored\\n\");", " fprintf(fd, \"\t-tsuf replace .trail with .suf on trailfiles\\n\");", " fprintf(fd, \"\t-V print SPIN version number\\n\");", " fprintf(fd, \"\t-v verbose -- filenames in unreached state listing\\n\");", " fprintf(fd, \"\t-wN hashtable of 2^N entries \");", " fprintf(fd, \"(defaults to -w%%d)\\n\", ssize);", + " fprintf(fd, \"\t-x do not overwrite an existing trail file\\n\");", + "#if NCORE>1", + " fprintf(fd, \"\t-zN handoff states below depth N to 2nd cpu (multi_core)\\n\");", + "#endif", + "#ifdef HAS_CODE", + " fprintf(fd, \"\\n\toptions -r, -C, -PN, -g, and -S can optionally be followed by\\n\");", + " fprintf(fd, \"\ta filename argument, as in \'-r filename\', naming the trailfile\\n\");", + "#endif", + "#if NCORE>1", + " multi_usage(fd);", + "#endif", " exit(1);", "}", "", "char *", - "Malloc(unsigned long n)", + "Malloc(ulong n)", "{ char *tmp;", - "#if defined(MEMCNT) || defined(MEMLIM)", - " if (memcnt+ (double) n > memlim) goto err;", + "#ifdef MEMLIM", + " if (memcnt + (double) n > memlim)", + " { printf(\"pan: reached -DMEMLIM bound\\n\");", + " goto err;", + " }", "#endif", -"#if 1", " tmp = (char *) malloc(n);", " if (!tmp)", -"#else", - /* on linux machines, a large amount of memory is set aside - * for malloc, whether it is used or not - * using sbrk would make this memory arena inaccessible - * the reason for using sbrk was originally to provide a - * small additional speedup (since this memory is never released) - */ - " tmp = (char *) sbrk(n);", - " if (tmp == (char *) -1L)", -"#endif", " {", - "#if defined(MEMCNT) || defined(MEMLIM)", - "err:", + "#ifdef BFS_PAR", + " Uerror(\"out of non-shared memory\");", "#endif", " printf(\"pan: out of memory\\n\");", - "#if defined(MEMCNT) || defined(MEMLIM)", + "#ifdef MEMLIM", + "err:", " printf(\"\t%%g bytes used\\n\", memcnt);", " printf(\"\t%%g bytes more needed\\n\", (double) n);", - " printf(\"\t%%g bytes limit\\n\",", - " memlim);", + " printf(\"\t%%g bytes limit\\n\", memlim);", "#endif", "#ifdef COLLAPSE", " printf(\"hint: to reduce memory, recompile with\\n\");", @@ -3714,6 +6115,15 @@ static char *Code2c[] = { " printf(\" -DBITSTATE # supertrace, approximation\\n\");", "#endif", "#endif", + "#if NCORE>1", + " #ifdef FULL_TRAIL", + " printf(\" omit -DFULL_TRAIL or use pan -c0 to reduce memory\\n\");", + " #endif", + " #ifdef SEP_STATE", + " printf(\"hint: to reduce memory, recompile without\\n\");", + " printf(\" -DSEP_STATE # may be faster, but uses more memory\\n\");", + " #endif", + "#endif", " wrapup();", " }", " memcnt += (double) n;", @@ -3723,13 +6133,13 @@ static char *Code2c[] = { "#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);", @@ -3754,9 +6164,15 @@ static char *Code2c[] = { "}", "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)", @@ -3775,9 +6191,14 @@ static char *Code2c[] = { " trpt = getframe(depth);", "#endif", "#ifdef VERBOSE", - " printf(\"%%d State: \", depth);", + " printf(\"%%ld State: \", depth);", + "#if !defined(NOCOMP) && !defined(HC)", " for (i = 0; i < vsize; i++) printf(\"%%d%%s,\",", " ((char *)&now)[i], Mask[i]?\"*\":\"\");", + "#else", + " for (i = 0; i < vsize; i++)", + " printf(\"%%d,\", ((char *)&now)[i]);", + "#endif", " printf(\"\\n\");", "#endif", "#ifndef NOFAIR", @@ -3794,7 +6215,7 @@ static char *Code2c[] = { "#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); */", @@ -3820,10 +6241,10 @@ static char *Code2c[] = { " tt = trpt->o_tt; this = pptr(II);", " _m = do_reverse(t, II, trpt->o_m);", "#ifdef VERBOSE", - " printf(\"%%3d: proc %%d \", depth, II);", + " printf(\"%%3ld: proc %%d \", depth, II);", " printf(\"reverses %%d, %%d to %%d,\",", " t->forw, tt, t->st);", - " printf(\" %%s [abit=%%d,adepth=%%d,\", ", + " printf(\" %%s [abit=%%d,adepth=%%ld,\", ", " t->tp, now._a_t, A_depth);", " printf(\"tau=%%d,%%d] <unwind>\\n\", ", " trpt->tau, (trpt-1)->tau);", @@ -3862,14 +6283,21 @@ static char *Code2c[] = { "#endif", "static char unwinding;", "void", - "uerror(char *str)", + "dfs_uerror(char *str)", "{ static char laststr[256];", " int is_cycle;", "", " if (unwinding) return; /* 1.4.2 */", " if (strncmp(str, laststr, 254))", - " printf(\"pan: %%s (at depth %%ld)\\n\", str,", - " (depthfound==-1)?depth:depthfound);", + "#if NCORE>1", + " cpu_printf(\"pan:%%d: %%s (at depth %%ld)\\n\", errors+1, str,", + "#else", + " printf(\"pan:%%d: %%s (at depth %%ld)\\n\", errors+1, str,", + "#endif", + "#if NCORE>1", + " (nr_handoffs * z_handoff) + ", + "#endif", + " ((depthfound == -1)?depth:depthfound));", " strncpy(laststr, str, 254);", " errors++;", "#ifdef HAS_CODE", @@ -3891,13 +6319,16 @@ static char *Code2c[] = { " depth = od;", " }", "#endif", -"#ifdef BFS", + "#if NCORE>1", + " writing_trail = 1;", + "#endif", + "#ifdef BFS", " if (depth > 1) trpt--;", - " nuerror(str);", + " nuerror();", " if (depth > 1) trpt++;", -"#else", + "#else", " putrail();", -"#endif", + "#endif", "#if defined(MA) && !defined(SAFETY)", " if (strstr(str, \" cycle\"))", " { if (every_error)", @@ -3905,20 +6336,36 @@ static char *Code2c[] = { " wrapup(); /* no recovery from unwind */", " }", "#endif", + "#if NCORE>1", + " if (search_terminated != NULL)", + " { *search_terminated |= 4; /* uerror */", + " }", + " writing_trail = 0;", + "#endif", " }", " if (!is_cycle)", " { depth--; trpt--; /* undo */", " }", -"#ifndef BFS", + "#ifndef BFS", " if (iterative != 0 && maxdepth > 0)", - " { maxdepth = (iterative == 1)?(depth-1):(depth/2);", + " { if (maxdepth > depth)", + " { maxdepth = (iterative == 1)?(depth+1):(depth/2);", + " }", " warned = 1;", " printf(\"pan: reducing search depth to %%ld\\n\",", " maxdepth);", " } else", -"#endif", + "#endif", " if (errors >= upto && upto != 0)", + " {", + "#ifdef BFS_PAR", + " bfs_shutdown(\"uerror\"); /* no return */", + "#endif", + "#if NCORE>1", + " sudden_stop(\"uerror\");", + "#endif", " wrapup();", + " }", " depthfound = -1;", "}\n", "int", @@ -3930,13 +6377,14 @@ static char *Code2c[] = { " || strncmp(T->tp, \"goto :\", 6) == 0)", " return 1; /* not reported */", "", - " printf(\"\\tline %%d\", lno);", - " if (verbose)", " for (j = 0; j < sizeof(mp); j++)", " if (i >= mp[j].from && i <= mp[j].upto)", - " { printf(\", \\\"%%s\\\"\", mp[j].fnm);", + " { printf(\"\\t%%s:%%d\", mp[j].fnm, lno);", " break;", " }", + " if (j >= sizeof(mp)) /* fnm not found in list */", + " { printf(\"\\t%%s:%%d\", PanSource, lno); /* use default */", + " }", " printf(\", state %%d\", i);", " if (strcmp(T->tp, \"\") != 0)", " { char *q;", @@ -3951,45 +6399,120 @@ static char *Code2c[] = { "}\n", "void", "r_ck(uchar *which, int N, int M, short *src, S_F_MAP *mp)", - "{ int i, m=0;\n", - "#ifdef VERI", - " if (M == VERI && !verbose) return;", - "#endif", - " printf(\"unreached in proctype %%s\\n\", procname[M]);", + "{ int i, m=0;", + "", + " if ((enum btypes) Btypes[M] == N_CLAIM", + " && claimname != NULL && strcmp(claimname, procname[M]) != 0)", + " { return;", + " }", + "", + " switch ((enum btypes) Btypes[M]) {", + " case P_PROC:", + " case A_PROC:", + " printf(\"unreached in proctype %%s\\n\", procname[M]);", + " break;", + " case I_PROC:", + " printf(\"unreached in init\\n\");", + " break;", + " case E_TRACE:", + " case N_TRACE:", + " case N_CLAIM:", + " default:", + " printf(\"unreached in claim %%s\\n\", procname[M]);", + " break;", + " }", " for (i = 1; i < N; i++)", -#if 0 - " if (which[i] == 0 /* && trans[M][i] */)", -#else - " if (which[i] == 0", - " && (mapstate[M][i] == 0", - " || which[mapstate[M][i]] == 0))", -#endif - " m += xrefsrc((int) src[i], mp, M, i);", - " else", - " m++;", + " { if (which[i] == 0", + " && (mapstate[M][i] == 0", + " || which[mapstate[M][i]] == 0))", + " { m += xrefsrc((int) src[i], mp, M, i);", + " } else", + " { m++;", + " } }", " printf(\"\t(%%d of %%d states)\\n\", N-1-m, N-1);", - "}\n", + "}", + "#if NCORE>1 && !defined(SEP_STATE)", + "static long rev_trail_cnt;", + "", + "#ifdef FULL_TRAIL", + "void", + "rev_trail(int fd, volatile Stack_Tree *st_tr)", + "{ long j; char snap[64];", + "", + " if (!st_tr)", + " { return;", + " }", + " rev_trail(fd, st_tr->prv);", + "#ifdef VERBOSE", + " printf(\"%%d (%%d) LRT [%%d,%%d] -- %%9u (root %%9u)\\n\",", + " depth, rev_trail_cnt, st_tr->pr, st_tr->t_id, st_tr, stack_last[core_id]);", + "#endif", + " if (st_tr->pr != 255)", /* still needed? */ + " { sprintf(snap, \"%%ld:%%d:%%d\\n\", ", + " rev_trail_cnt++, st_tr->pr, st_tr->t_id);", + " j = strlen(snap);", + " if (write(fd, snap, j) != j)", + " { printf(\"pan: error writing trailfile\\n\");", + " close(fd);", + " wrapup();", + " return;", + " }", + " } else /* handoff point */", + " { if (a_cycles)", + " { (void) write(fd, \"-1:-1:-1\\n\", 9);", + " } }", + "}", + "#endif", /* FULL_TRAIL */ + "#endif", /* NCORE>1 */ + "", "void", "putrail(void)", - "{ int fd; long i, j;", - " Trail *trl;", + "{ int fd;", "#if defined VERI || defined(MERGED)", " char snap[64];", "#endif", - "", + "#if NCORE==1 || defined(SEP_STATE) || !defined(FULL_TRAIL)", + " long i, j;", + " Trail *trl;", + "#endif", " fd = make_trail();", " if (fd < 0) return;", "#ifdef VERI", - " sprintf(snap, \"-2:%%d:-2\\n\", VERI);", - " write(fd, snap, strlen(snap));", + " sprintf(snap, \"-2:%%d:-2\\n\", (uchar) ((P0 *)pptr(0))->_t);", + " if (write(fd, snap, strlen(snap)) < 0) return;", "#endif", "#ifdef MERGED", " sprintf(snap, \"-4:-4:-4\\n\");", - " write(fd, snap, strlen(snap));", + " if (write(fd, snap, strlen(snap)) < 0) return;", "#endif", - " for (i = 1; i <= depth; i++)", + "#ifdef PERMUTED", + " sprintf(snap, \"-5:%%d:%%d\\n\", t_reverse, reversing&2);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "", + " sprintf(snap, \"-6:%%d:%%d\\n\", p_reorder==set_permuted, p_reorder==set_reversed);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "", + " sprintf(snap, \"-7:%%d:%%d\\n\", p_reorder==set_rotated, p_rotate);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "", + " sprintf(snap, \"-8:%%d:%%d\\n\", p_reorder==set_randrot, --s_rand);", + " if (write(fd, snap, strlen(snap)) < 0) return;", + "#endif", + "#if NCORE>1 && !defined(SEP_STATE) && defined(FULL_TRAIL)", + " rev_trail_cnt = 1;", + " enter_critical(GLOBAL_LOCK);", + " rev_trail(fd, stack_last[core_id]);", + " leave_critical(GLOBAL_LOCK);", + "#else", + " i = 1; /* trail starts at position 1 */", + " #if NCORE>1 && defined(SEP_STATE)", + " if (cur_Root.m_vsize > 0) { i++; depth++; }", + " #endif", + " for ( ; i <= depth; i++)", " { if (i == depthfound+1)", - " write(fd, \"-1:-1:-1\\n\", 9);", + " { if (write(fd, \"-1:-1:-1\\n\", 9) != 9)", + " { goto notgood;", + " } }", " trl = getframe(i);", " if (!trl->o_t) continue;", " if (trl->o_pm&128) continue;", @@ -3997,12 +6520,16 @@ static char *Code2c[] = { " i, trl->pr, trl->o_t->t_id);", " j = strlen(snap);", " if (write(fd, snap, j) != j)", - " { printf(\"pan: error writing trailfile\\n\");", + " {", + "notgood: printf(\"pan: error writing trailfile\\n\");", " close(fd);", " wrapup();", - " }", - " }", + " } }", + "#endif", " close(fd);", + "#if NCORE>1", + " cpu_printf(\"pan: wrote trailfile\\n\");", + "#endif", "}\n", "void", "sv_save(void) /* push state vector onto save stack */", @@ -4022,13 +6549,16 @@ static char *Code2c[] = { "#if SYNC", " svtack->o_boq = boq;", "#endif", + "#ifdef TRIX", + " sv_populate();", + "#endif", " svtack->o_delta = vsize; /* don't compress */", " memcpy((char *)(svtack->body), (char *) &now, vsize);", "#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)", " c_stack((uchar *) &(svtack->c_stack[0]));", "#endif", "#ifdef DEBUG", - " printf(\"%%d: sv_save\\n\", depth);", + " cpu_printf(\"%%d: sv_save\\n\", depth);", "#endif", "}\n", "void", @@ -4038,7 +6568,9 @@ static char *Code2c[] = { "#if SYNC", " boq = svtack->o_boq;", "#endif", - + "#ifdef TRIX", + " re_populate();", + "#endif", "#if defined(C_States) && (HAS_TRACK==1)", "#ifdef HAS_STACK", " c_unstack((uchar *) &(svtack->c_stack[0]));", @@ -4049,78 +6581,144 @@ static char *Code2c[] = { " if (vsize != svtack->o_delta)", " Uerror(\"sv_restor\");", " if (!svtack->lst)", - " Uerror(\"error: v_restor\");", + " Uerror(\"error: sv_restor\");", " svtack = svtack->lst;", "#ifdef DEBUG", - " printf(\" sv_restor\\n\");", + " cpu_printf(\" sv_restor\\n\");", "#endif", - "}\n", + "}", + "", "void", "p_restor(int h)", - "{ int i; char *z = (char *) &now;\n", + "{ 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;", + "#else", + " char *oi;", + " #ifdef V_TRIX", + " printf(\"%%4d: p_restor %%d\\n\", depth, h);", + " #endif", + "#endif", "#ifndef XUSAFE", " p_name[h] = stack->o_name;", "#endif", - "#ifndef NOCOMP", + "#ifdef TRIX", + " vsize += sizeof(char *);", + " #ifndef BFS", + " if (processes[h] != NULL || freebodies == NULL)", + " { Uerror(\"processes error\");", + " }", + " processes[h] = freebodies;", + " freebodies = freebodies->nxt;", + " processes[h]->nxt = (TRIX_v6 *) 0;", + " processes[h]->modified = 1; /* p_restor */", + " #endif", + " processes[h]->parent_pid = stack->parent;", + " processes[h]->psize = stack->o_delta;", + " memcpy((char *)pptr(h), stack->b_ptr, stack->o_delta);", + " oi = stack->b_ptr;", + "#else", + " #if !defined(NOCOMP) && !defined(HC)", " for (i = vsize + stack->o_skip; i > vsize; i--)", " Mask[i-1] = 1; /* align */", - "#endif", + " #endif", " vsize += stack->o_skip;", " memcpy(z+vsize, stack->body, stack->o_delta);", " vsize += stack->o_delta;", - "#ifndef NOVSZ", - " now._vsz = vsize;", - "#endif", - "#ifndef NOCOMP", - " for (i = 1; i <= Air[((P0 *)pptr(h))->_t]; i++)", - " Mask[vsize - i] = 1; /* pad */", - " Mask[proc_offset[h]] = 1; /* _pid */", - "#endif", + " #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 */", + " #endif", " if (BASE > 0 && h > 0)", " ((P0 *)pptr(h))->_pid = h-BASE;", " else", " ((P0 *)pptr(h))->_pid = h;", - " i = stack->o_delqs;", + " #ifdef BFS_PAR", + " bfs_fixmask(1); /* p_restor */", + " #endif", + "#endif", " now._nr_pr += 1;", - " if (!stack->lst) /* debugging */", + "#ifndef NOVSZ", + " now._vsz = vsize;", + "#endif", + " i = stack->o_delqs;", + " if (!stack->lst)", " Uerror(\"error: p_restor\");", " stack = stack->lst;", " this = pptr(h);", " while (i-- > 0)", " q_restor();", + "#ifdef TRIX", + " re_mark_all(1); /* p_restor - all chans move up in _ids_ */", + " now._ids_[h] = oi; /* restor the original contents */", + "#endif", "}\n", "void", "q_restor(void)", - "{ char *z = (char *) &now;", - "#ifndef NOCOMP", - " int k, k_end;", - "#endif", - " q_offset[now._nr_qs] = stack->o_offset;", - " q_skip[now._nr_qs] = (uchar) stack->o_skip;", - "#ifndef XUSAFE", - " q_name[now._nr_qs] = stack->o_name;", - "#endif", + "{ int h = now._nr_qs;", + "#ifdef TRIX", + " #ifdef V_TRIX", + " printf(\"%%4d: q_restor %%d\\n\", depth, h);", + " #endif", + " vsize += sizeof(char *);", + " #ifndef BFS", + " if (channels[h] != NULL || freebodies == NULL)", + " { Uerror(\"channels error\");", + " }", + " channels[h] = freebodies;", + " freebodies = freebodies->nxt;", + " channels[h]->nxt = (TRIX_v6 *) 0;", + " channels[h]->modified = 1; /* q_restor */", + " #endif", + " channels[h]->parent_pid = stack->parent;", + " channels[h]->psize = stack->o_delta;", + " memcpy((char *)qptr(h), stack->b_ptr, stack->o_delta);", + " now._ids_[now._nr_pr + h] = stack->b_ptr;", + "#else", + " char *z = (char *) &now;", + " #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;", " memcpy(z+vsize, stack->body, stack->o_delta);", " vsize += stack->o_delta;", + "#endif", + "#ifndef XUSAFE", + " q_name[h] = stack->o_name;", + "#endif", "#ifndef NOVSZ", " now._vsz = vsize;", "#endif", " now._nr_qs += 1;", - "#ifndef NOCOMP", - " 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;", + "#ifndef TRIX", + " #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", "#endif", - " if (!stack->lst) /* debugging */", + " if (!stack->lst)", " Uerror(\"error: q_restor\");", " stack = stack->lst;", "}", @@ -4163,7 +6761,46 @@ static char *Code2c[] = { "#ifndef NOCOMP", " int o_vsize = vsize;", "#endif", - " if (h+1 != (int) now._nr_pr) return 0;\n", + " if (h+1 != (int) now._nr_pr)", + " { return 0;", + " }", + "#ifdef TRIX", + " #ifdef V_TRIX", + " printf(\"%%4d: delproc %%d -- parent %%d\\n\", depth, h, processes[h]->parent_pid);", + " if (now._nr_qs > 0)", + " printf(\" top channel: %%d -- parent %%d\\n\", now._nr_qs-1, channels[now._nr_qs-1]->parent_pid);", + " #endif", + " while (now._nr_qs > 0", + " && channels[now._nr_qs-1]->parent_pid == processes[h]->parent_pid)", + " { delq(sav);", + " i++;", + " }", + " d = processes[h]->psize;", + " if (sav)", + " { if (!stack->nxt)", + " { stack->nxt = (_Stack *) emalloc(sizeof(_Stack));", + " stack->nxt->lst = stack;", + " smax++;", + " }", + " stack = stack->nxt;", + " #ifndef XUSAFE", + " stack->o_name = p_name[h];", + " #endif", + " stack->parent = processes[h]->parent_pid;", + " stack->o_delta = d;", + " stack->o_delqs = i;", + " stack->b_ptr = now._ids_[h];", /* new 6.1 */ + " }", + " memset((char *)pptr(h), 0, d);", + " #ifndef BFS", + " processes[h]->nxt = freebodies;", + " freebodies = processes[h];", + " processes[h] = (TRIX_v6 *) 0;", + " #endif", + " vsize -= sizeof(char *);", + " now._nr_pr -= 1;", + " re_mark_all(-1); /* delproc - all chans move down in _ids_ */", + "#else", " while (now._nr_qs", " && q_offset[now._nr_qs-1] > proc_offset[h])", " { delq(sav);", @@ -4172,80 +6809,116 @@ static char *Code2c[] = { " d = vsize - proc_offset[h];", " if (sav)", " { if (!stack->nxt)", - " { stack->nxt = (Stack *)", - " emalloc(sizeof(Stack));", - " stack->nxt->body = ", - " emalloc(Maxbody*sizeof(char));", + " { stack->nxt = (_Stack *) emalloc(sizeof(_Stack));", + " stack->nxt->body = emalloc(Maxbody * sizeof(char));", " stack->nxt->lst = stack;", " smax++;", " }", " stack = stack->nxt;", " stack->o_offset = proc_offset[h];", - "#if VECTORSZ>32000", + " #if VECTORSZ>32000", " stack->o_skip = (int) proc_skip[h];", - "#else", + " #else", " stack->o_skip = (short) proc_skip[h];", - "#endif", - "#ifndef XUSAFE", + " #endif", + " #ifndef XUSAFE", " stack->o_name = p_name[h];", - "#endif", + " #endif", " stack->o_delta = d;", " stack->o_delqs = i;", " memcpy(stack->body, (char *)pptr(h), d);", " }", " vsize = proc_offset[h];", - " now._nr_pr = now._nr_pr - 1;", + " now._nr_pr -= 1;", " memset((char *)pptr(h), 0, d);", " vsize -= (int) proc_skip[h];", + " #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", " now._vsz = vsize;", "#endif", - "#ifndef NOCOMP", - " for (i = vsize; i < o_vsize; i++)", - " Mask[i] = 0; /* reset */", - "#endif", " return 1;", "}\n", "void", "delq(int sav)", "{ int h = now._nr_qs - 1;", + "#ifdef TRIX", + " int d = channels[now._nr_qs - 1]->psize;", + "#else", " int d = vsize - q_offset[now._nr_qs - 1];", + "#endif", "#ifndef NOCOMP", " int k, o_vsize = vsize;", "#endif", " if (sav)", " { if (!stack->nxt)", - " { stack->nxt = (Stack *)", - " emalloc(sizeof(Stack));", - " stack->nxt->body = ", - " emalloc(Maxbody*sizeof(char));", + " { stack->nxt = (_Stack *) emalloc(sizeof(_Stack));", + "#ifndef TRIX", + " stack->nxt->body = emalloc(Maxbody * sizeof(char));", + "#endif", " stack->nxt->lst = stack;", " smax++;", " }", " stack = stack->nxt;", + "#ifdef TRIX", + " stack->parent = channels[h]->parent_pid;", + " stack->b_ptr = now._ids_[h];", /* new 6.1 */ + "#else", " stack->o_offset = q_offset[h];", - "#if VECTORSZ>32000", + " #if VECTORSZ>32000", " stack->o_skip = (int) q_skip[h];", - "#else", + " #else", " stack->o_skip = (short) q_skip[h];", + " #endif", "#endif", - "#ifndef XUSAFE", + " #ifndef XUSAFE", " stack->o_name = q_name[h];", - "#endif", + " #endif", " stack->o_delta = d;", + "#ifndef TRIX", " memcpy(stack->body, (char *)qptr(h), d);", + "#endif", " }", + "#ifdef TRIX", + " vsize -= sizeof(char *);", + " #ifdef V_TRIX", + " printf(\"%%4d: delq %%d parent %%d\\n\", depth, h, channels[h]->parent_pid);", + " #endif", + "#else", " vsize = q_offset[h];", - " now._nr_qs = now._nr_qs - 1;", - " memset((char *)qptr(h), 0, d);", " vsize -= (int) q_skip[h];", + " #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;", + " memset((char *)qptr(h), 0, d);", + "#ifdef TRIX", + " #ifndef BFS", + " channels[h]->nxt = freebodies;", + " freebodies = channels[h];", + " channels[h] = (TRIX_v6 *) 0;", + " #endif", + "#endif", "#ifndef NOVSZ", " now._vsz = vsize;", "#endif", - "#ifndef NOCOMP", - " for (k = vsize; k < o_vsize; k++)", - " Mask[k] = 0; /* reset */", - "#endif", "}\n", "int", "qs_empty(void)", @@ -4265,7 +6938,7 @@ static char *Code2c[] = { " 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;", @@ -4273,55 +6946,54 @@ static char *Code2c[] = { "#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(\"%%d: 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", -#if 0 - " if (fairness)", - " { now._a_t &= ~2; /* pre-apply Rule 3 */", - " now._cnt[1] = 0;", /* reset both a-bit and cnt=0 */ - " /* avoid matching seed on claim stutter on this state */", - " }", -#else - " now._cnt[1] = now._cnt[0];", -#endif - "#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;", - " new_state(); /* start 2nd DFS */", + + " #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(\"%%d: cycle check returns\\n\", depth);", + " printf(\"%%ld: cycle check returns\\n\", depth);", "#endif", "#ifdef FULLSTACK", "#ifndef MA", @@ -4331,60 +7003,120 @@ static char *Code2c[] = { "#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", - "#define grab_state(n) (struct H_el *) \\", - " emalloc(sizeof(struct H_el)+n-sizeof(unsigned));", "#endif", + + "#if !defined(BFS_PAR)", + " #if defined(FULLSTACK) && defined(BITSTATE)", + "H_el *", + "grab_state(int n)", + "{ H_el *v, *last = 0;", + " if (H_tab == S_Tab)", + " { for (v = Free_list; v && ((int) v->tagged >= n); v=v->nxt)", + " { if ((int) v->tagged == n)", + " { if (last)", + " last->nxt = v->nxt;", + " else", + "gotcha: Free_list = v->nxt;", + " v->tagged = 0;", + " v->nxt = 0;", + " #ifdef COLLAPSE", + " v->ln = 0;", + " #endif", + " return v;", + " }", + " Fh++; last=v;", + " }", + " /* new: second try */", + " v = Free_list;", /* try to avoid emalloc */ + " if (v && ((int) v->tagged >= n))", + " goto gotcha;", + " ngrabs++;", + " }", + " return (H_el *) emalloc(sizeof(H_el)+n-sizeof(unsigned));", + "}", + " #else", /* !FULLSTACK || !BITSTATE */ + "#if NCORE>1", + "H_el *", + "grab_state(int n)", + "{ H_el *grab_shared(int);", + " return grab_shared(sizeof(H_el)+n-sizeof(unsigned));", + "}", + "#else", /* ! NCORE>1 */ + "#ifndef AUTO_RESIZE", + " #define grab_state(n) (H_el *) \\", + " emalloc(sizeof(H_el)+n-sizeof(ulong));", + "#else", /* AUTO_RESIZE */ + "H_el *", + "grab_state(int n)", + "{ H_el *p;", + " int cnt = sizeof(H_el)+n-sizeof(ulong);", + "#ifndef MA", + " if (reclaim_size >= cnt+WS)", + " { if ((cnt & (WS-1)) != 0) /* alignment */", + " { cnt += WS - (cnt & (WS-1));", + " }", + " p = (H_el *) reclaim_mem;", + " reclaim_mem += cnt;", + " reclaim_size -= cnt;", + " memset(p, 0, cnt);", + " } else", + "#endif", + " { p = (H_el *) emalloc(cnt);", + " }", + " return p;", + "}", + "#endif", /* AUTO_RESIZE */ + "#endif", /* NCORE>1 */ + " #endif", /* FULLSTACK && !BITSTATE */ + "#else", /* BFS_PAR */ + " extern volatile uchar *sh_pre_malloc(ulong);", + " extern volatile uchar *sh_malloc(ulong);", + " H_el *", + " grab_state(int n) /* bfs_par */", + " { volatile uchar *rval = NULL;", + " int m = sizeof(H_el) + n - sizeof(unsigned);", + "", + " if (n == 0) m = m/n;", + " #ifdef BFS_SEP_HASH", + " rval = emalloc((ulong) m);", + " #else", + " rval = sh_malloc((ulong) m);", + " #endif", + " memset((void *) rval, 0, (size_t) m);", + "", + " return (H_el *) rval;", + " }", + "#endif", /* BFS_PAR */ + "#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);", - " tmp = H_tab[j1];", + + "#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", + " tmp = H_tab[j1_spin];", " if (!tmp)", " { tmp = grab_state(n);", - " H_tab[j1] = tmp;", + " H_tab[j1_spin] = tmp;", " } else", " for ( ;; olst = tmp, tmp = tmp->nxt)", - " { m = memcmp(((char *)&(tmp->state)), v, n);", - " if (n == tmp->ln)", - " {", + " { if (n == tmp->ln)", + " { m = memcmp(((char *)&(tmp->state)), v, n);", " if (m == 0)", " goto done;", " if (m < 0)", @@ -4392,7 +7124,7 @@ static char *Code2c[] = { "Insert: ntmp = grab_state(n);", " ntmp->nxt = tmp;", " if (!olst)", - " H_tab[j1] = ntmp;", + " H_tab[j1_spin] = ntmp;", " else", " olst->nxt = ntmp;", " tmp = ntmp;", @@ -4410,15 +7142,38 @@ static char *Code2c[] = { " else if (!tmp->nxt)", " goto Append;", " }", + "#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", "#ifdef FULLSTACK", " tmp->tagged = m;", "#else", " tmp->st_id = m;", "#endif", + "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", + " tmp->m_K1 = K1;", + "#endif", " memcpy(((char *)&(tmp->state)), v, n);", " tmp->ln = n;", "done:", + + "#if NCORE>1 && !defined(SEP_STATE)", + " leave_critical(CS_ID);", + "#endif", + "#if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + "#endif", + "#ifdef FULLSTACK", " return tmp->tagged;", "#else", @@ -4430,7 +7185,7 @@ static char *Code2c[] = { "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;", @@ -4523,7 +7278,7 @@ static char *Code2c[] = { "#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;", @@ -4535,8 +7290,14 @@ static char *Code2c[] = { " 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);", @@ -4572,7 +7333,7 @@ static char *Code2c[] = { " return v - (char *)&comp_now;", "}", -"#else", +"#else", /* !COLLAPSE */ "#if !defined(NOCOMP)", "int", "compress(char *vin, int n) /* default compression */", @@ -4600,11 +7361,56 @@ static char *Code2c[] = { " char *vv = vin;", " char *v = (char *) &comp_now;", " int i;", - " for (i = 0; i < n; i++, vv++)", - " if (!Mask[i]) *v++ = *vv;", - " for (i = 0; i < WS-1; i++)", - " *v++ = 0;", - " v -= i;", + " #ifndef NO_FAST_C", /* disable faster compress */ + " int r = 0, unroll = n/8;", /* most sv are much longer */ + " if (unroll > 0)", + " { i = 0;", + " while (r++ < unroll)", + " { /* unroll 8 times, avoid ifs */", + " /* 1 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 2 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 3 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 4 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 5 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 6 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 7 */ *v = *vv++; v += 1 - Mask[i++];", + " /* 8 */ *v = *vv++; v += 1 - Mask[i++];", + " }", + " r = n - i; /* the rest, at most 7 */", + " switch (r) {", + " case 7: *v = *vv++; v += 1 - Mask[i++];", + " case 6: *v = *vv++; v += 1 - Mask[i++];", + " case 5: *v = *vv++; v += 1 - Mask[i++];", + " case 4: *v = *vv++; v += 1 - Mask[i++];", + " case 3: *v = *vv++; v += 1 - Mask[i++];", + " case 2: *v = *vv++; v += 1 - Mask[i++];", + " case 1: *v = *vv++; v += 1 - Mask[i++];", + " case 0: break;", + " }", + " n = i = v - (char *)&comp_now; /* bytes written so far */", + " r = (n+WS-1)/WS; /* in words, rounded up */", + " r *= WS; /* total bytes to fill */", + " i = r - i; /* remaining bytes */", + " switch (i) {", /* fill word */ + " case 7: *v++ = 0; /* fall thru */", + " case 6: *v++ = 0;", + " case 5: *v++ = 0;", + " case 4: *v++ = 0;", + " case 3: *v++ = 0;", + " case 2: *v++ = 0;", + " case 1: *v++ = 0;", + " case 0: break;", + " default: Uerror(\"unexpected wordsize\");", + " }", + " v -= i;", + " } else", + " #endif", + " { for (i = 0; i < n; i++, vv++)", + " if (!Mask[i]) *v++ = *vv;", + " for (i = 0; i < WS-1; i++)", + " *v++ = 0;", + " v -= i;", + " }", "#if 0", " printf(\"compress %%d -> %%d\\n\",", " n, v - (char *)&comp_now);", @@ -4613,7 +7419,7 @@ static char *Code2c[] = { "#endif", "}", "#endif", -"#endif", +"#endif", /* COLLAPSE */ "#if defined(FULLSTACK) && defined(BITSTATE)", "#if defined(MA)", "#if !defined(onstack_now)", @@ -4628,9 +7434,15 @@ static char *Code2c[] = { "#else", "void", "onstack_zap(void)", - "{ struct H_el *v, *w, *last = 0;", - " struct H_el **tmp = H_tab;", - " char *nv; int n, m;\n", + "{ 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)", + " uchar was_last = now._last;", + " now._last = 0;", + "#endif", + "", " H_tab = S_Tab;", "#ifndef NOCOMP", " nv = (char *) &comp_now;", @@ -4648,7 +7460,7 @@ static char *Code2c[] = { " s_hash((uchar *)nv, n);", "#endif", " H_tab = tmp;", - " for (v = S_Tab[j1]; v; Zh++, last=v, v=v->nxt)", + " for (v = S_Tab[j1_spin]; v; Zh++, last=v, v=v->nxt)", " { m = memcmp(&(v->state), nv, n);", " if (m == 0)", " goto Found;", @@ -4656,101 +7468,190 @@ static char *Code2c[] = { " break;", " }", "/* NotFound: */", - " Uerror(\"stack out of wack - zap\");", - " return;", + "#ifndef ZAPH", + " /* seen this happen, likely harmless in multicore */", + " if (warned == 0)", + " { /* Uerror(\"stack out of wack - zap\"); */", + " cpu_printf(\"pan: warning, stack incomplete\\n\");", + " warned = 1;", + " }", + "#endif", + " goto done;", "Found:", " ZAPS++;", " if (last)", " last->nxt = v->nxt;", " else", - " S_Tab[j1] = v->nxt;", + " S_Tab[j1_spin] = v->nxt;", " v->tagged = (unsigned) n;", "#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)", - " { v->nxt = w; /* was: v->nxt = w->nxt; */", + " { v->nxt = w;", " last->nxt = v;", " } else", " { v->nxt = Free_list;", " Free_list = v;", " }", - " return;", + " goto done;", " }", " if (!w->nxt)", " { w->nxt = v;", - " return;", + " goto done;", " } }", " Free_list = v;", - "}", - "void", - "onstack_put(void)", - "{ struct H_el **tmp = H_tab;", - " H_tab = S_Tab;", - " if (hstore((char *)&now, vsize) != 0)", - "#if defined(BITSTATE) && defined(LC)", - " printf(\"pan: warning, double stack entry\\n\");", - "#else", - " Uerror(\"cannot happen - unstack_put\");", - "#endif", - " H_tab = tmp;", - " trpt->ostate = Lstate;", - " PUT++;", - "}", - "int", - "onstack_now(void)", - "{ struct H_el *tmp;", - " struct H_el **tmp2 = H_tab;", - " char *v; int n, m = 1;\n", - " 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);", + "done:", + "#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST)", + " now._last = was_last;", "#endif", - " H_tab = tmp2;", - " for (tmp = S_Tab[j1]; tmp; Zn++, tmp = tmp->nxt)", - " { m = memcmp(((char *)&(tmp->state)),v,n);", - " if (m <= 0)", - " { Lstate = (struct H_el *) tmp;", - " break;", - " } }", - " PROBE++;", - " return (m == 0);", + " return;", "}", - "#endif", -"#endif", + "", + "#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 */ - "#ifndef BITSTATE", + "#ifdef BITSTATE", + "void init_SS(ulong);", + "", "void", - "hinit(void)", + "sinit(void)", "{", -"#ifdef MA", - "#ifdef R_XPT", - " { void r_xpoint(void);", - " r_xpoint();", + " if (udmem)", + " { udmem *= 1024L*1024L;", + " #if NCORE>1", + " if (!readtrail)", + " { init_SS((ulong) udmem);", + " } else", + " #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", " }", + "}", "#else", - " dfa_init((unsigned short) (MA+a_cycles));", - "#endif", -"#endif", -"#if !defined(MA) || defined(COLLAPSE)", - " H_tab = (struct H_el **)", - " emalloc((1L<<ssize)*sizeof(struct H_el *));", -"#endif", + " #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<<ssize)*sizeof(H_el *)));", + " #else", + " H_tab = (H_el **) emalloc((ONE_L<<ssize)*sizeof(H_el *));", + " #endif", + " }", + " #endif", + "void", + "hinit(void)", + "{", + " #ifdef MA", + " #ifdef R_XPT", + " { void r_xpoint(void);", + " r_xpoint();", + " }", + " #else", + " dfa_init((unsigned short) (MA+a_cycles));", + " #if NCORE>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<<ssize)*sizeof(H_el *));", + " #if defined(TRIX) || (defined(BFS_PAR) && defined(COLLAPSE))", + " set_H_tab(); /* need both */", + " #endif", + " } else", + " #endif", + " { set_H_tab(); /* @htable ssize */", + " }", + " #endif", /* !defined(MA) || defined(COLLAPSE) */ "}", "#endif\n", @@ -4771,13 +7672,17 @@ static char *Code2c[] = { " }", "#endif", "#ifdef SDUMP", - "#ifndef NOCOMP", " printf(\"\t State: \");", + "#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\tVector: \");", - " for (i = 0; i < n; i++) printf(\"%%d,\", v[i]);", + " for (i = 0; i < n; i++)", + " printf(\"%%d,\", v[i]);", " printf(\"\\n\");", "#endif", "}", @@ -4785,8 +7690,9 @@ static char *Code2c[] = { "#ifdef MA", "int", - "gstore(char *vin, int nin, uchar pbit)", + "g_store(char *vin, int nin, uchar pbit)", "{ int n, i;", + " int ret_val = 1;", " uchar *v;", " static uchar Info[MA+1];", "#ifndef NOCOMP", @@ -4794,22 +7700,36 @@ static char *Code2c[] = { " v = (uchar *) &comp_now;", "#else", " n = nin;", - " v = vin;", + " v = (uchar *) vin;", "#endif", " if (n >= MA)", " { printf(\"pan: error, MA too small, recompile pan.c\");", " printf(\" with -DMA=N with N>%%d\\n\", n);", " Uerror(\"aborting\");", " }", - " if (n > (int) maxgs) maxgs = (unsigned int) n;", - + " if (n > (int) maxgs)", + " { maxgs = (uint) n;", + " }", " for (i = 0; i < n; i++)", - " Info[i] = v[i];", + " { Info[i] = v[i];", + " }", " for ( ; i < MA-1; i++)", - " Info[i] = 0;", + " { Info[i] = 0;", + " }", " Info[MA-1] = pbit;", " if (a_cycles) /* place _a_t at the end */", - " { Info[MA] = Info[0]; Info[0] = 0; }", + " { Info[MA] = Info[0];", + " Info[0] = 0;", + " }", + "", + "#ifdef BFS_PAR", + " e_critical(BFS_STATE); /* bfs_par / g_store */", + "#endif", + "#if NCORE>1 && !defined(SEP_STATE)", + " enter_critical(GLOBAL_LOCK); /* crude, but necessary */", + " /* to make this mode work, also replace emalloc with grab_shared inside store MA routines */", + "#endif", + "", " if (!dfa_store(Info))", " { if (pbit == 0", " && (now._a_t&1)", @@ -4819,16 +7739,17 @@ static char *Code2c[] = { " { Info[MA-1] = 4; /* off-stack bit */", " nShadow++;", " if (!dfa_member(MA-1))", - " {", - "#ifdef VERBOSE", - " printf(\"intersected 1st dfs stack\\n\");", - "#endif", - " return 3;", + " { ret_val = 3;", + " #ifdef VERBOSE", + " printf(\"intersected 1st dfs stack\\n\");", + " #endif", + " goto done;", " } } }", - "#ifdef VERBOSE", + " ret_val = 0;", + " #ifdef VERBOSE", " printf(\"new state\\n\");", - "#endif", - " return 0; /* new state */", + " #endif", + " goto done;", " }", "#ifdef FULLSTACK", " if (pbit == 0)", @@ -4837,23 +7758,32 @@ static char *Code2c[] = { " trpt->proviso = dfa_member(MA-1);", "#endif", " Info[MA-1] = 4; /* off-stack bit */", - " if (dfa_member(MA-1)) {", - "#ifdef VERBOSE", + " if (dfa_member(MA-1))", + " { ret_val = 1; /* off-stack */", + " #ifdef VERBOSE", " printf(\"old state\\n\");", - "#endif", - " return 1; /* off-stack */", - " } else {", - "#ifdef VERBOSE", + " #endif", + " } else", + " { ret_val = 2; /* on-stack */", + " #ifdef VERBOSE", " printf(\"on-stack\\n\");", - "#endif", - " return 2; /* on-stack */", + " #endif", " }", + " goto done;", " }", "#endif", + " ret_val = 1;", "#ifdef VERBOSE", - " printf(\"old state\\n\");", + " printf(\"old state\\n\");", + "#endif", + "done:", + "#ifdef BFS_PAR", + " x_critical(BFS_STATE);", "#endif", - " return 1; /* old state */", + "#if NCORE>1 && !defined(SEP_STATE)", + " leave_critical(GLOBAL_LOCK);", + "#endif", + " return ret_val; /* old state */", "}", "#endif", @@ -4873,34 +7803,140 @@ static char *Code2c[] = { "}", "#endif", + "#ifdef TRIX", + "void", + "sv_populate(void)", + "{ int i, cnt = 0;", + " TRIX_v6 **base = processes;", + " int bound = now._nr_pr; /* MAXPROC+1; */", + "#ifdef V_TRIX", + " printf(\"%%4d: sv_populate\\n\", depth);", + "#endif", + "again:", + " for (i = 0; i < bound; i++)", + " { if (base[i] != NULL)", + " { H_el *tmp;", + " int m, n; uchar *v;", + "#ifndef BFS", + " if (base[i]->modified == 0)", + " { cnt++;", + " #ifdef V_TRIX", + " printf(\"%%4d: %%s %%d not modified\\n\",", + " depth, (base == processes)?\"proc\":\"chan\", i);", + " #endif", + " continue;", + " }", + " #ifndef V_MOD", + " base[i]->modified = 0;", + " #endif", + "#endif", + "#ifdef TRIX_RIX", + " if (base == processes)", + " { ((P0 *)pptr(i))->_pid = 0;", + " }", + "#endif", + " n = base[i]->psize;", + " v = base[i]->body;", + " s_hash(v, n); /* sets j1_spin */", + " tmp = H_tab[j1_spin];", + " if (!tmp) /* new */", + " { tmp = grab_state(n);", + " H_tab[j1_spin] = tmp;", + " m = 1; /* non-zero */", + " } else", + " { 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 */", + " { break;", + " } else if (m < 0) /* insert */", + " { ntmp = grab_state(n);", + " ntmp->nxt = tmp;", + " if (!olst)", + " H_tab[j1_spin] = ntmp;", + " else", + " olst->nxt = ntmp;", + " tmp = ntmp;", + " break;", + " } else if (!tmp->nxt) /* append */", + " { tmp->nxt = grab_state(n);", + " tmp = tmp->nxt;", + " break;", + " } } }", + " if (m != 0)", + " { memcpy((char *)&(tmp->state), v, n);", + "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", + " tmp->m_K1 = K1; /* set via s_hash */", + "#endif", + " 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 + if a process appears or disappears: always secure a full sv_populate + (channels come and go only with a process) + + only one process can disappear per step + but any nr of channels can be removed at the same time + if a process disappears, all subsequent entries + are then in the wrong place in the _ids_ list + and need to be recomputed + but we do not need to fill out with zeros + because vsize prevents them being used +#endif + " /* do the same for all channels */", + " if (base == processes)", + " { base = channels;", + " bound = now._nr_qs; /* MAXQ+1; */", + " goto again;", + " }", + "}", + "#endif\n", + "#if !defined(BFS_PAR) || (!defined(BITSTATE) && !defined(USE_TDH))", "int", - "hstore(char *vin, int nin) /* hash table storage */", - "{ struct H_el *tmp, *ntmp, *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 NOCOMP", /* defined by BITSTATE */ - "#if defined(BITSTATE) && defined(LC)", + " #endif", + " #ifdef TRIX", + " sv_populate(); /* update proc and chan ids */", + " #endif", + " #ifdef NOCOMP", /* defined by BITSTATE */ + " #if defined(BITSTATE) && defined(LC)", " if (S_Tab == H_tab)", " { v = (char *) &comp_now;", " n = compact_stack(vin, nin);", " } else", " { v = vin; n = nin;", " }", - "#else", + " #else", " v = vin; n = nin;", - "#endif", - "#else", + " #endif", + " #else", " v = (char *) &comp_now;", " #ifdef HC", - " rem_a = now._a_t;", /* 4.3.0 */ + " rem_a = now._a_t;", /* new 5.0 */ " now._a_t = 0;", /* for hashing/state matching to work right */ " #endif", - " n = compress(vin, nin);", /* with HC, this calls s_hash */ + " n = compress(vin, nin);", /* with HC, this calls s_hash -- but on vin, not on v... */ " #ifdef HC", - " now._a_t = rem_a;", /* 4.3.0 */ + " now._a_t = rem_a;", /* new 5.0 */ " #endif", + /* with HC4 -a, compress copies K1 and K2 into v[], leaving v[0] free for the a-bit */ "#ifndef SAFETY", " if (S_A)", " { v[0] = 0; /* _a_t */", @@ -4911,35 +7947,53 @@ static char *Code2c[] = { "#endif", " m = 0;", " }", - "#endif", - "#endif", - "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", + " #endif", + " #endif", + " #if !defined(HC) && !(defined(BITSTATE) && defined(LC))", " s_hash((uchar *)v, n);", - "#endif", - " tmp = H_tab[j1];", + " #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);", - " H_tab[j1] = tmp;", + " { 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 */", + " /* to collect the stats on all cpus in the wrapup */", + " #if !defined(SEP_STATE) && !defined(BITSTATE)", + " leave_critical(CS_ID);", + " #endif", + " return 1; /* allow normal termination */", + " }", + " #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++;", @@ -4948,7 +8002,7 @@ static char *Code2c[] = { "#ifndef NOFAIR", " if (S_A > NFAIR)", " { /* 0 <= now._cnt[now._a_t&1] < MAXPROC */", - " unsigned ci, bp; /* index, bit pos */", + " uint ci, bp; /* index, bit pos */", " ci = (now._cnt[now._a_t&1] / 8);", " bp = (now._cnt[now._a_t&1] - 8*ci);", " if (now._a_t&1) /* use tail-bits in _cnt */", @@ -4968,13 +8022,16 @@ static char *Code2c[] = { " /* else: wasnew == 0, i.e., old state */", "#endif", " }", - "#endif", - "#endif", + " #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)", @@ -4982,22 +8039,42 @@ static char *Code2c[] = { " {", "intersect:", "#ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", " printf(\"1st dfs-stack intersected on state %%d+\\n\",", " (int) tmp->st_id);", "#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", + " return 3;", " }", "#ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(1, (char *)&(tmp->state),n,tmp->tagged);", "#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", " 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 */", @@ -5014,41 +8091,110 @@ static char *Code2c[] = { " goto intersect;", "#endif", "#ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", " printf(\"\tStack state %%d\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(0, (char *)&(tmp->state),n,tmp->tagged);", "#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", " return 2; /* match on stack */", " }", "#else", " if (wasnew)", " {", "#ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(1, (char *)&(tmp->state), n, 0);", "#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", " return 0;", " }", "#endif", "#ifdef CHECK", + "#if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + "#endif", " printf(\"\tOld state %%d\\n\", (int) tmp->st_id);", "#endif", "#ifdef DEBUG", " dumpstate(0, (char *)&(tmp->state), n, 0);", "#endif", - "#ifdef REACH", - " if (tmp->D > depth)", - " { tmp->D = depth;", - "#ifdef CHECK", - " printf(\"\t\tReVisiting (from smaller depth)\\n\");", - "#endif", - " nstates--;", + "#if defined(BCS)", + " #ifdef CONSERVATIVE", + " if (tmp->ctx_low > trpt->sched_limit)", + " { tmp->ctx_low = trpt->sched_limit;", + " tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%%8); /* new */", + " #ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", + " printf(\"\t\tRevisit with fewer context switches\\n\");", + " #endif", + " nstates--;", + " #if defined(BFS_PAR) && !defined(BFS_SEP_HASH)", + " x_critical(BFS_ID);", + " #endif", + " #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", + " leave_critical(CS_ID);", + " #endif", + " return 0;", + " } else if ((tmp->ctx_low == trpt->sched_limit", + " && (tmp->ctx_pid[(now._last)/8] & ( 1 << ((now._last)%%8) )) == 0 ))", + " { tmp->ctx_pid[(now._last)/8] |= 1 << ((now._last)%%8); /* add */", + " #ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", + " 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", + " return 0;", + " }", + " #endif", + "#endif", + " #ifdef REACH", + " if (tmp->D > depth)", + " { tmp->D = depth;", + " #ifdef CHECK", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", + " 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", #if 0 - possible variation of iterative search for shortest counter-example (pan -i - and pan -I) suggested by Pierre Moro (for safety properties): + a possible variation of iterative search for shortest counter-example + (pan -i and pan -I) suggested by Pierre Moro (for safety properties): state revisits on shorter depths do not start until after the first counter-example is found. this assumes that the max search depth is set large enough that a first (possibly long) counter-example @@ -5056,54 +8202,86 @@ static char *Code2c[] = { if set too short, this variant can miss the counter-example, even if it would otherwise be shorter than the depth-limit. (p.m. unsure if this preserves the guarantee of finding the - shortest counter-example - so not enabled yet) - " if (errors > 0 && iterative)", /* Moro */ + shortest counter-example - so not enabled by default) + " if (errors > 0 && iterative)", /* Moro */ #endif - " return 0;", - " }", - "#endif", - "#if defined(BFS) && defined(Q_PROVISO)", - " Lstate = (struct H_el *) tmp;", - "#endif", + " return 0;", + " }", + " #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", " return 1; /* match outside stack */", " } else if (m < 0)", " { /* insert state before tmp */", " ntmp = grab_state(n);", + " #if NCORE>1", + " if (!ntmp)", + " {", + " #if !defined(SEP_STATE) && !defined(BITSTATE)", + " leave_critical(CS_ID);", + " #endif", + " return 1; /* allow normal termination */", + " }", + " #endif", " ntmp->nxt = tmp;", " if (!olst)", - " H_tab[j1] = ntmp;", + " H_tab[j1_spin] = ntmp;", " else", " olst->nxt = ntmp;", " tmp = ntmp;", " break;", " } else if (!tmp->nxt)", " { /* append after tmp */", - "#ifdef COLLAPSE", + " #ifdef COLLAPSE", "Append:", - "#endif", + " #endif", " tmp->nxt = grab_state(n);", + " #if NCORE>1", + " if (!tmp->nxt)", + " {", + " #if !defined(SEP_STATE) && !defined(BITSTATE)", + " leave_critical(CS_ID);", + " #endif", + " return 1; /* allow normal termination */", + " }", + " #endif", " tmp = tmp->nxt;", " break;", " } }", " }", - "#ifdef CHECK", + " #ifdef CHECK", " tmp->st_id = (unsigned) nstates;", + " #if NCORE>1", + " printf(\"cpu%%d: \", core_id);", + " #endif", "#ifdef BITSTATE", " printf(\" Push state %%d\\n\", ((int) nstates) - 1);", "#else", " printf(\" New state %%d\\n\", (int) nstates);", "#endif", "#endif", - "#if !defined(SAFETY) || defined(REACH)", + " #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)", " tmp->D = depth;", - "#endif", - "#ifndef SAFETY", - "#ifndef NOCOMP", + " #endif", + " #if !defined(SAFETY) && !defined(NOCOMP)", " if (S_A)", " { v[0] = V_A;", "#ifndef NOFAIR", " if (S_A > NFAIR)", - " { unsigned ci, bp; /* as above */", + " { uint ci, bp; /* as above */", " ci = (now._cnt[now._a_t&1] / 8);", " bp = (now._cnt[now._a_t&1] - 8*ci);", " if (now._a_t&1)", @@ -5114,26 +8292,409 @@ static char *Code2c[] = { " }", "#endif", " }", - "#endif", - "#endif", + " #endif", + " #if defined(AUTO_RESIZE) && !defined(BITSTATE)", + " tmp->m_K1 = K1;", + " #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);", + " dumpstate(-1, v, n, tmp->tagged);", "#endif", - " Lstate = (struct H_el *) tmp;", + " Lstate = (H_el *) tmp; /* end of h_store */", + " #else", + " #ifdef DEBUG", + " dumpstate(-1, v, n, 0);", + " #endif", + " #if NCORE>1", + " Lstate = (H_el *) tmp; /* end of h_store */", + " #endif", + " #endif", + + " #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", + + " 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<<T_ROW)", + "#define T_ROW_MASK -(1<<T_ROW)", + "#define T_FREE 0", + "#define T_STAT 1 /* status bit */", + "#ifndef T_VSZ", + " #define T_VSZ VECTORSZ/4 /* compressed vectorsize */", + "#endif", + "", + "static volatile char *ohash_sd; /* state data */", + "static volatile uint32_t *ohash_hv; /* hash values */", + "static ulong ohash_max;", + "static ulong ohash_mask;", + "", + "#if defined(USE_TDH) && defined(Q_PROVISO)", + " static volatile uchar *ohash_inq; /* open/closed flag BFS_INQ */", + "#endif", + "#ifdef HC", + " static uint32_t ohash_hc[T_HC];", + " static ulong ohash_hc_sz;", + "#endif", + "", + "void", + "init_HT(ulong x) /* USE_TDH cygwin/linux */", + "{ x = x / (ulong) sizeof(H_el *); /* room for x pointers */", + " #ifdef DEBUG", + " printf(\"prealloc x %%lu v %%d x*v %%lu\\n\",", + " x, T_VSZ, (ulong) (x * (ulong)T_VSZ));", + " #endif", + "#ifndef HC", + " if (!(x * (ulong) T_VSZ > 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", - "#ifdef DEBUG", - " dumpstate(-1, v, n, 0);", - "#endif", + " ohash_hv = (volatile uint32_t *) sh_pre_malloc(x * (ulong) sizeof(uint32_t));", + "#endif", + " ohash_mask = (((ulong)1)<<ssize)-1;", + " ohash_max = (((ulong)1)<<ssize)/100;", + "#if defined(USE_TDH) && defined(Q_PROVISO)", + " #ifdef BFS_SEP_HASH", + " ohash_inq = (uchar *) emalloc(x * (ulong) sizeof(uchar));", + " #else", + " ohash_inq = (volatile uchar *) sh_pre_malloc(x * (ulong) sizeof(uchar));", + " #endif", "#endif", - " return 0;", "}", + "", + "static int h_table_full;", + "#ifdef L_BOUND", + "void", + "bfs_mark_live(void)", + "{ int i;", + "", + " trpt->o_pm &= ~2;", + "#ifdef VERBOSE", + " bfs_printf(\"check to mark\\n\");", "#endif", - "#include TRANSITIONS", + " 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", - "do_reach(void)", - "{", + "bfs_check_live(uchar b, uchar *s)", + "{ /* assert(b>0); */", + " now._l_bnd = b-1; /* decrease bound */", + "#ifdef VERBOSE", + " bfs_printf(\"check live %%d\\n\", b);", + "#endif", + " if (b == L_bound && boq == -1)", /* never mid rv */ + " { now._l_sds = (uchar *) Lstate; /* new target */", + " } else", + " { now._l_sds = s; /* restore target */", + " if (s == (uchar *) Lstate)", + " { depthfound = depth - (BASE+1)*(L_bound - now._l_bnd - 1);", + " uerror(\"accept cycle found\");", + " depthfound = -1;", + " now._l_bnd = 0;", + " now._l_sds = (uchar *) 0;", + " } }", + "#ifdef VERBOSE", + " bfs_printf(\"set l_bound to %%d -- sds %%p\\n\", b-1, (void *) now._l_sds);", + "#endif", + "}", + "#endif", + "/* closed hashing with locality - similar to ltsmin */", + "int", + "o_store(const char *vin, int nin)", + "{ int i, seed = 0;", + " ulong hash_v, ix, ex;", + " uint32_t T_BUSY, T_DONE;", + " volatile uint32_t *t_entry;", + "#ifdef HC", + " ulong vs = ohash_hc_sz;", + "#else", + " ulong vs = (ulong) T_VSZ;", + "#endif", + "#ifdef L_BOUND", + " uchar o_bnd, *o_sds;", + "#endif", + "#ifndef STOP_ON_FULL", + " if (h_table_full)", + " { goto done;", + " }", + "#endif", + "#ifdef L_BOUND", + " if (now._l_bnd == 0)", + " { bfs_mark_live();", + " }", + " #ifdef VERBOSE", + " else", + " { bfs_printf(\"non-markable state %%d\\n\", now._l_bnd);", + " }", + " #endif", + " o_bnd = now._l_bnd;", + " o_sds = now._l_sds;", + " now._l_bnd = (o_bnd)?1:0; /* mark nested phase of bounded search */", + " now._l_sds = (uchar *) 0;", + "#endif", + "#if !defined(HC) && !defined(T_NOCOMP)", + " nin = compress((char *)vin, nin);", + " vin = (char *) &comp_now;", + "#endif", + " do { o_hash((uchar *)vin, nin, seed++);", + " hash_v = K1;", + " } while (hash_v == T_FREE || hash_v == T_STAT); /* unlikely, hash_v 0 or 1 */", + "", + " T_BUSY = ((uint32_t) hash_v & ~((uint32_t) T_STAT)); /* hash with status bit 0 */", + " T_DONE = ((uint32_t) hash_v | ((uint32_t) T_STAT)); /* hash with status bit 1 */", + "#ifdef HC", + " d_hash((uchar *)vin, nin);", /* HC */ + " ohash_hc[0] = (uint32_t) K1;", + " #if T_HC>1", + " ohash_hc[1] = (uint32_t) (K1>>32);", /* assumes ulong = 64 bits */ + " #endif", + " #if T_HC>2", + " ohash_hc[2] = (uint32_t) K2;", + " #endif", + " #if T_HC>3", + " ohash_hc[3] = (uint32_t) (K2>>32);", + " #endif", + "#endif", + " while (seed < ohash_max)", + " { ix = hash_v & ohash_mask;", + " ex = (ix & T_ROW_MASK) + T_ROW_SIZE;", + " for (i = 0; i < T_ROW_SIZE; i++)", + " { t_entry = (uint32_t *) &ohash_hv[ix];", + " if (*t_entry == T_FREE && cas(t_entry, T_FREE, T_BUSY))", + " {", + "#ifndef HC", + " memcpy((char *) &ohash_sd[ix * vs], vin, nin);", + "#else", + " memcpy((char *) &ohash_sd[ix * vs], (char *) ohash_hc, vs);", + "#endif", + "#if defined(USE_TDH) && defined(Q_PROVISO)", + " ohash_inq[ix] = (uchar) BFS_INQ;", + " Lstate = (H_el *) &ohash_inq[ix];", + "#endif", + " *t_entry = T_DONE;", + "#ifdef VERBOSE", + " #ifdef L_BOUND", + " bfs_printf(\"New state %%p [%%p]\\n\",", + " (void *) Lstate, (void *) o_sds);", + " #else", + " bfs_printf(\"New state %%p\\n\", (void *) Lstate);", + " #endif", + "#endif", + "#ifdef L_BOUND", + " if (o_bnd) { bfs_check_live(o_bnd, o_sds); }", + "#endif", + " return 0; /* New State */", + " }", + " while (*t_entry == T_BUSY)", + " { usleep(2); /* wait */", + " }", + " if (*t_entry == T_DONE /* (first) hash matches, check data */", + "#ifndef HC", + " && memcmp((char *) &ohash_sd[ix * vs], vin, nin) == 0)", + "#else", + " && memcmp((char *) &ohash_sd[ix * vs], (char *) ohash_hc, vs) == 0)", + "#endif", + " {", + "#if defined(USE_TDH) && defined(Q_PROVISO)", + " Lstate = (H_el *) &ohash_inq[ix];", + "#endif", + "#ifdef VERBOSE", + " #ifdef L_BOUND", + " bfs_printf(\"Old state %%p [%%p]\\n\",", + " (void *) Lstate, (void *) o_sds);", + " #else", + " bfs_printf(\"Old state %%p\\n\", (void *) Lstate);", + " #endif", + "#endif", + "#ifdef L_BOUND", + " if (o_bnd) { bfs_check_live(o_bnd, o_sds); }", + "#endif", + " return 1; /* Old State */", + " }", + " hcmp++; ix++;", + " ix = (ix==ex) ? ex - T_ROW_SIZE : ix;", + " }", + " /* find a new slot: */", + " do { o_hash((uchar *)vin, nin, (int) (hash_v + seed++));", + " hash_v = K1;", + " } while (hash_v == T_FREE || hash_v == T_STAT);", + " T_BUSY = ((uint32_t) hash_v & ~((uint32_t) T_STAT));", + " T_DONE = ((uint32_t) hash_v | ((uint32_t) T_STAT));", + " }", + "#ifdef STOP_ON_FULL", + " Uerror(\"hash table full\");", + " /* no return from Uerror */", + "#else", + " if (!h_table_full)", + " { h_table_full++;", + " if (who_am_i == 0)", + " { bfs_printf(\"hash table is full\\n\");", + " } }", + "done:", + " bfs_punt++; /* counts this as a lost state */", + "#endif", + "#ifdef L_BOUND", + " now._l_bnd = 0; /* no more checking */", + " now._l_sds = (uchar *) 0;", + "#endif", + " return 1; /* technically should be 0, but we want to throttle down */", + "}", + "#endif", /* USE_TDH && !WIN32 && !WIN64 */ + "#endif", /* !BITSTATE || FULLSTACK */ + "#include TRANSITIONS", 0, }; |