1 /***** spin: pangen3.h *****/
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
9 static const char *Head0[] = {
10 "#if defined(BFS) && defined(REACH)",
11 " #undef REACH", /* redundant with bfs */
18 "typedef struct Trans {",
19 " short atom; /* if &2 = atomic trans; if &8 local */",
21 " short escp[HAS_UNLESS]; /* lists the escape states */",
22 " short e_trans; /* if set, this is an escp-trans */",
24 " short tpe[2]; /* class of operation (for reduction) */",
25 " short qu[6]; /* for conditional selections: qid's */",
26 " uchar ty[6]; /* ditto: type's */",
28 " short om; /* completion status of preselects */",
30 " char *tp; /* src txt of statement */",
31 " int st; /* the nextstate */",
32 " int t_id; /* transition id, unique within proc */",
33 " int forw; /* index forward transition */",
34 " int back; /* index return transition */",
35 " struct Trans *nxt;",
39 " #define qptr(x) (channels[x]->body)",
40 " #define pptr(x) (processes[x]->body)",
42 " #define qptr(x) (((uchar *)&now)+(int)q_offset[x])",
43 " #define pptr(x) (((uchar *)&now)+(int)proc_offset[x])",
44 /* " #define Pptr(x) ((proc_offset[x])?pptr(x):noptr)", */
46 "extern uchar *Pptr(int);",
47 "extern uchar *Qptr(int);",
49 "#define q_sz(x) (((Q0 *)qptr(x))->Qlen)",
53 " #undef VECTORSZ", /* backward compatibility */
56 " #define VECTORSZ 2056 /* ((MAXPROC+MAXQ+4)*sizeof(uchar *)) */",
58 " #define VECTORSZ 4112 /* the formula causes probs in preprocessing */",
62 " #define VECTORSZ 1024 /* sv size in bytes */",
66 "#define MAXPROC 255",
71 static const char *Header[] = {
86 NOREDUCE BITSTATE SAFETY MA WS>4
99 " #if !defined(SAFETY) && !defined(MA)",
100 " #define FULLSTACK", /* => NOREDUCE && !SAFETY && !MA */
104 " #if defined(SAFETY) && WS<=4",
105 " #define CNTRSTACK", /* => !NOREDUCE && BITSTATE && SAFETY && WS<=4 */
107 " #define FULLSTACK", /* => !NOREDUCE && BITSTATE && (!SAFETY || WS>4) */
110 " #define FULLSTACK", /* => !NOREDUCE && !BITSTATE */
117 " #if !defined(LC) && defined(SC)",
121 "#if defined(COLLAPSE2) || defined(COLLAPSE3) || defined(COLLAPSE4)",
122 " /* accept the above for backward compatibility */",
129 "#if defined(HC0) || defined(HC1) || defined(HC2) || defined(HC3) || defined(HC4)",
130 " #define HC 4", /* 2x32 bits */
131 "#endif", /* really only one hashcompact mode, not 5 */
133 "typedef struct _Stack { /* for queues and processes */",
134 "#if VECTORSZ>32000",
152 " char *b_ptr;", /* used in delq/q_restor and delproc/p_restor */
154 " char *body;", /* full copy of state vector in non-trix mode */
159 " struct _Stack *nxt;",
160 " struct _Stack *lst;",
162 "typedef struct Svtack { /* for complete state vector */",
163 "#if VECTORSZ>32000",
167 " short o_delta; /* current size of frame */",
168 " short m_delta; /* maximum size of frame */",
176 static const char *Header0[] = {
178 " struct Svtack *nxt;",
179 " struct Svtack *lst;",
184 static const char *Head1[] = {
185 "typedef struct State {",
188 " uchar _a_t; /* cycle detection */",
190 in _a_t: bits 0,4, and 5 =(1|16|32) are set during a 2nd dfs
191 bit 1 is used as the A-bit for fairness
192 bit 7 (128) is the proviso bit, for reduced 2nd dfs (acceptance)
195 " uchar _cnt[NFAIR]; /* counters, weak fairness */",
202 * noticed alignment problems with some Solaris
203 * compilers, if widest field isn't wordsized
206 "#if VECTORSZ<65536",
208 " unsigned short _vsz;",
214 "#ifdef HAS_LAST", /* cannot go before _cnt - see h_store() */
215 " uchar _last; /* pid executed in last step */",
218 "#if defined(BITSTATE) && defined(BCS) && defined(STORE_CTX)",
219 " uchar _ctx; /* nr of context switches so far */",
221 "#if defined(BFS_PAR) && defined(L_BOUND)",
222 " uchar _l_bnd; /* bounded liveness */",
223 " uchar *_l_sds; /* seed state */",
225 "#ifdef EVENT_TRACE",
226 " #if nstates_event<256",
229 " unsigned short _event;",
235 static const char *Addp0[] = {
236 /* addproc(....parlist... */ ")",
237 "{ int j, h = now._nr_pr;",
241 " uchar *o_this = this;\n",
243 " if (TstOnly) return (h < MAXPROC);",
245 "#ifndef NOBOUNDCHECK",
246 " /* redefine Index only within this procedure */",
248 " #define Index(x, y) Boundcheck(x, y, 0, 0, 0)",
250 " if (h >= MAXPROC)",
251 " Uerror(\"too many processes\");",
253 " printf(\"%%4d: add process %%d\\n\", depth, h);",
256 " case 0: j = sizeof(P0); break;",
260 static const char *Addp1[] = {
261 " default: Uerror(\"bad proc - addproc\");",
264 " bfs_prepmask(1); /* addproc */",
268 " vsize += sizeof(H_el *);",
271 " proc_skip[h] = WS-(vsize%%WS);",
273 " proc_skip[h] = 0;",
274 " #if !defined(NOCOMP) && !defined(HC)",
275 " for (k = vsize + (int) proc_skip[h]; k > vsize; k--)",
276 " Mask[k-1] = 1; /* align */",
278 " vsize += (int) proc_skip[h];",
279 " proc_offset[h] = vsize;",
281 " #if defined(SVDUMP) && defined(VERBOSE)",
284 " write(svfd, (uchar *) &dummy, sizeof(int)); /* mark */",
285 " write(svfd, (uchar *) &h, sizeof(int));",
286 " write(svfd, (uchar *) &n, sizeof(int));",
287 " #if VECTORSZ>32000",
288 " write(svfd, (uchar *) &proc_offset[h], sizeof(int));",
289 " write(svfd, (uchar *) &now, vprefix-4*sizeof(int)); /* padd */",
291 " write(svfd, (uchar *) &proc_offset[h], sizeof(short));",
292 " write(svfd, (uchar *) &now, vprefix-3*sizeof(int)-sizeof(short)); /* padd */",
299 "#if defined(BCS) && defined(CONSERVATIVE)",
300 " if (now._nr_pr >= CONSERVATIVE*8)",
301 " { printf(\"pan: error: too many processes -- recompile with \");",
302 " printf(\"-DCONSERVATIVE=%%d\\n\", CONSERVATIVE+1);",
306 " if (fairness && ((int) now._nr_pr + 1 >= (8*NFAIR)/2))",
307 " { printf(\"pan: error: too many processes -- current\");",
308 " printf(\" max is %%d procs (-DNFAIR=%%d)\\n\",",
309 " (8*NFAIR)/2 - 2, NFAIR);",
310 " printf(\"\\trecompile with -DNFAIR=%%d\\n\",",
315 " now._vsz = vsize;",
317 " hmax = max(hmax, vsize);",
322 " { processes[h] = freebodies;",
323 " freebodies = freebodies->nxt;",
325 " { processes[h] = (TRIX_v6 *) emalloc(sizeof(TRIX_v6));",
326 " processes[h]->body = (uchar *) emalloc(Maxbody * sizeof(char));",
328 " processes[h]->modified = 1; /* addproc */",
330 " processes[h]->psize = j;",
331 " processes[h]->parent_pid = calling_pid;",
332 " processes[h]->nxt = (TRIX_v6 *) 0;",
334 " #if !defined(NOCOMP) && !defined(HC)",
335 " for (k = 1; k <= Air[n]; k++)",
336 " Mask[vsize - k] = 1; /* pad */",
337 " Mask[vsize-j] = 1; /* _pid */",
340 " bfs_fixmask(1); /* addproc */",
342 " if (vsize >= VECTORSZ)",
343 " { printf(\"pan: error, VECTORSZ too small, recompile pan.c\");",
344 " printf(\" with -DVECTORSZ=N with N>%%d\\n\", (int) vsize);",
345 " Uerror(\"aborting\");",
349 " memset((char *)pptr(h), 0, j);",
351 " if (BASE > 0 && h > 0)",
352 " { ((P0 *)this)->_pid = h-BASE;",
354 " { ((P0 *)this)->_pid = h;",
360 static const char *Addq0[] = {
363 "addqueue(int calling_pid, int n, int is_rv)",
364 "{ int j=0, i = now._nr_qs;",
365 "#if !defined(NOCOMP) && !defined(TRIX)",
369 " Uerror(\"too many queues\");",
371 " printf(\"%%4d: add queue %%d\\n\", depth, i);",
377 static const char *Addq1[] = {
378 " default: Uerror(\"bad queue - addqueue\");",
381 " bfs_prepmask(2); /* addqueue */",
385 " vsize += sizeof(H_el *);",
388 " q_skip[i] = WS-(vsize%%WS);",
391 " #if !defined(NOCOMP) && !defined(HC)",
394 " if (is_rv) k += j;",
396 " for (k += (int) q_skip[i]; k > vsize; k--)",
399 " vsize += (int) q_skip[i];",
400 " q_offset[i] = vsize;",
403 " bfs_fixmask(2); /* addqueue */",
409 " now._vsz = vsize;",
411 " hmax = max(hmax, vsize);",
416 " { channels[i] = freebodies;",
417 " freebodies = freebodies->nxt;",
419 " { channels[i] = (TRIX_v6 *) emalloc(sizeof(TRIX_v6));",
420 " channels[i]->body = (uchar *) emalloc(Maxbody * sizeof(char));",
422 " channels[i]->modified = 1; /* addq */",
424 " channels[i]->psize = j;",
425 " channels[i]->parent_pid = calling_pid;",
426 " channels[i]->nxt = (TRIX_v6 *) 0;",
428 " if (vsize >= VECTORSZ)",
429 " Uerror(\"VECTORSZ is too small, edit pan.h\");",
432 " if (j > 0)", /* zero if there are no queues */
433 " { memset((char *)qptr(i), 0, j);",
435 " ((Q0 *)qptr(i))->_t = n;",
441 static const char *Addq11[] = {
442 "{ int j; uchar *z;\n",
447 " uerror(\"ref to uninitialized chan name (sending)\");",
448 " if (into >= (int) now._nr_qs || into < 0)",
449 " Uerror(\"qsend bad queue#\");",
450 "#if defined(TRIX) && !defined(BFS)",
451 " #ifndef TRIX_ORIG",
452 " (trpt+1)->q_bup = now._ids_[now._nr_pr+into];",
454 " printf(\"%%4d: channel %%d s save %%p from %%d\\n\",",
455 " depth, into, (trpt+1)->q_bup, now._nr_pr+into);",
458 " channels[into]->modified = 1; /* qsend */",
460 " printf(\"%%4d: channel %%d modified\\n\", depth, into);",
464 " j = ((Q0 *)qptr(into))->Qlen;",
465 " switch (((Q0 *)qptr(into))->_t) {",
469 static const char *Addq2[] = {
470 " case 0: printf(\"queue %%d was deleted\\n\", into+1);",
471 " default: Uerror(\"bad queue - qsend\");",
473 "#ifdef EVENT_TRACE",
474 " if (in_s_scope(into+1))",
475 " require('s', into);",
483 " { uerror(\"ref to uninitialized chan name (q_zero)\");",
486 " switch(((Q0 *)qptr(from))->_t) {",
490 static const char *Addq3[] = {
491 " case 0: printf(\"queue %%d was deleted\\n\", from+1);",
493 " Uerror(\"bad queue q-zero\");",
498 "{ if (q_zero(from))",
499 " { printf(\"==>> a test of the contents of a rv \");",
500 " printf(\"channel always returns FALSE\\n\");",
501 " uerror(\"error to poll rendezvous channel\");",
508 "setq_claim(int x, int m, char *s, int y, char *p)",
510 " uerror(\"x[rs] claim on uninitialized channel\");",
511 " if (x < 0 || x > MAXQ)",
512 " Uerror(\"cannot happen setq_claim\");",
516 " if (m&2) q_S_check(x, y);",
517 " if (m&1) q_R_check(x, y);",
519 "short q_sender[MAXQ+1];",
521 "q_S_check(int x, int who)",
522 "{ if (!q_sender[x])",
523 " { q_sender[x] = who+1;",
526 " { printf(\"chan %%s (%%d), \",",
528 " printf(\"sndr proc %%s (%%d)\\n\",",
529 " p_name[who], who);",
530 " uerror(\"xs chans cannot be used for rv\");",
534 " if (q_sender[x] != who+1)",
535 " { printf(\"pan: xs assertion violated: \");",
536 " printf(\"access to chan <%%s> (%%d)\\npan: by \",",
538 " if (q_sender[x] > 0 && p_name[q_sender[x]-1])",
539 " printf(\"%%s (proc %%d) and by \",",
540 " p_name[q_sender[x]-1], q_sender[x]-1);",
541 " printf(\"%%s (proc %%d)\\n\",",
542 " p_name[who], who);",
543 " uerror(\"error, partial order reduction invalid\");",
547 "short q_recver[MAXQ+1];",
549 "q_R_check(int x, int who)",
552 " printf(\"q_R_check x=%%d who=%%d\\n\", x, who);",
554 " if (!q_recver[x])",
555 " { q_recver[x] = who+1;",
558 " { printf(\"chan %%s (%%d), \",",
560 " printf(\"recv proc %%s (%%d)\\n\",",
561 " p_name[who], who);",
562 " uerror(\"xr chans cannot be used for rv\");",
566 " if (q_recver[x] != who+1)",
567 " { printf(\"pan: xr assertion violated: \");",
568 " printf(\"access to chan %%s (%%d)\\npan: \",",
570 " if (q_recver[x] > 0 && p_name[q_recver[x]-1])",
571 " printf(\"by %%s (proc %%d) and \",",
572 " p_name[q_recver[x]-1], q_recver[x]-1);",
573 " printf(\"by %%s (proc %%d)\\n\",",
574 " p_name[who], who);",
575 " uerror(\"error, partial order reduction invalid\");",
583 " uerror(\"ref to uninitialized chan name (len)\");",
584 " return ((Q0 *)qptr(x))->Qlen;",
589 " uerror(\"ref to uninitialized chan name (qfull)\");",
590 " switch(((Q0 *)qptr(from))->_t) {",
594 static const char *Addq4[] = {
595 " case 0: printf(\"queue %%d was deleted\\n\", from+1);",
597 " Uerror(\"bad queue - q_full\");",
603 "{ /* empty or full */",
604 " return !q_len(from) || q_full(from);",
609 "qrecv(int from, int slot, int fld, int done)",
613 " uerror(\"ref to uninitialized chan name (receiving)\");",
614 "#if defined(TRIX) && !defined(BFS)",
615 " #ifndef TRIX_ORIG",
616 " (trpt+1)->q_bup = now._ids_[now._nr_pr+from];",
618 " printf(\"%%4d: channel %%d r save %%p from %%d\\n\",",
619 " depth, from, (trpt+1)->q_bup, now._nr_pr+from);",
622 " channels[from]->modified = 1; /* qrecv */",
624 " printf(\"%%4d: channel %%d modified\\n\", depth, from);",
627 " if (from >= (int) now._nr_qs || from < 0)",
628 " Uerror(\"qrecv bad queue#\");",
630 "#ifdef EVENT_TRACE",
631 " if (done && (in_r_scope(from+1)))",
632 " require('r', from);",
634 " switch (((Q0 *)qptr(from))->_t) {",
638 static const char *Addq5[] = {
639 " case 0: printf(\"queue %%d was deleted\\n\", from+1);",
640 " default: Uerror(\"bad queue - qrecv\");",
648 "col_q(int i, char *z)",
651 " Q0 *ptr = (Q0 *) qptr(i);",
652 " switch (ptr->_t) {",
656 static const char *Code0[] = {
660 " memset((char *)&now, 0, sizeof(State));",
661 " vsize = (ulong) (sizeof(State) - VECTORSZ);",
663 " now._vsz = vsize;",
666 " if (VECTORSZ != sizeof(now._ids_))",
667 " { printf(\"VECTORSZ is %%d, but should be %%d in this mode\\n\",",
668 " VECTORSZ, (int) sizeof(now._ids_));",
669 " Uerror(\"VECTORSZ set incorrectly, recompile Spin (not pan.c)\");",
672 "/* optional provisioning statements, e.g. to */",
673 "/* set hidden variables, used as constants */",
681 static const char *R0[] = {
682 " Maxbody = max(Maxbody, ((int) sizeof(P%d)));",
683 " reached[%d] = reached%d;",
684 " accpstate[%d] = (uchar *) emalloc(_nstates%d);",
685 " progstate[%d] = (uchar *) emalloc(_nstates%d);",
686 " loopstate%d = loopstate[%d] = (uchar *) emalloc(_nstates%d);",
687 " stopstate[%d] = (uchar *) emalloc(_nstates%d);",
688 " visstate[%d] = (uchar *) emalloc(_nstates%d);",
689 " mapstate[%d] = (short *) emalloc(_nstates%d * sizeof(short));",
690 " stopstate[%d][_endstate%d] = 1;",
694 static const char *R00[] = {
695 " NrStates[%d] = _nstates%d;",
699 static const char *R0a[] = {
700 " retrans(%d, _nstates%d, _start%d, src_ln%d, reached%d, loopstate%d);",
704 static const char *Code1[] = {
706 " #define ACCEPT_LAB 1 /* at least 1 in np_ */",
708 " #define ACCEPT_LAB %d /* user-defined accept labels */",
712 " #warning -DMEMLIM takes precedence over -DMEMCNT",
716 " #warning using minimal value -DMEMCNT=20 (=1MB)",
717 " #define MEMLIM (1)",
721 " #define MEMLIM (1)",
725 " #error excessive value for MEMCNT",
727 " #define MEMLIM (1<<(MEMCNT-20))",
734 "#if NCORE>1 && !defined(MEMLIM)",
735 " #define MEMLIM (2048) /* need a default, using 2 GB */",
740 static const char *Code3[] = {
741 "#define PROG_LAB %d /* progress labels */",
745 static const char *R2[] = {
746 "uchar *accpstate[%d];",
747 "uchar *progstate[%d];",
748 "uchar *loopstate[%d];",
749 "uchar *reached[%d];",
750 "uchar *stopstate[%d];",
751 "uchar *visstate[%d];",
752 "short *mapstate[%d];",
754 " int NrStates[%d];",
758 static const char *R3[] = {
759 " Maxbody = max(Maxbody, ((int) sizeof(Q%d)));",
762 static const char *R4[] = {
763 " r_ck(reached%d, _nstates%d, %d, src_ln%d, src_file%d);",
766 static const char *R5[] = {
767 " case %d: j = sizeof(P%d); break;",
770 static const char *R6[] = {
774 " re_mark_all(1); /* addproc */",
777 "#ifndef NOBOUNDCHECK",
779 " #define Index(x, y) Boundcheck(x, y, II, tt, t)",
782 "#if defined(BITSTATE) && defined(COLLAPSE)",
783 " /* just to allow compilation, to generate the error */",
784 " long col_p(int i, char *z) { return 0; }",
785 " long col_q(int i, char *z) { return 0; }",
790 "col_p(int i, char *z)",
791 "{ int j, k; ulong ordinal(char *, long, short);",
793 " P0 *ptr = (P0 *) pptr(i);",
794 " switch (ptr->_t) {",
795 " case 0: j = sizeof(P0); break;",
798 static const char *R7a[] = {
799 "void\nre_mark_all(int whichway)",
802 " printf(\"%%d: re_mark_all channels %%d\\n\", depth, whichway);",
805 " for (j = 0; j < now._nr_qs; j++)",
806 " channels[j]->modified = 1; /* channel index moved */",
808 " #ifndef TRIX_ORIG",
809 " if (whichway > 0)",
810 " { for (j = now._nr_pr + now._nr_qs - 1; j >= now._nr_pr; j--)",
811 " now._ids_[j] = now._ids_[j-1];",
813 " { for (j = now._nr_pr; j < now._nr_pr + now._nr_qs; j++)",
814 " now._ids_[j] = now._ids_[j+1];",
821 static const char *R7b[] = {
824 "bfs_prepmask(int caller)",
826 "#if !defined(NOCOMP) && !defined(HC)",
827 " memcpy((char *) &tmp_msk, (const char *) Mask, sizeof(State));",
828 " Mask = (uchar *) &tmp_msk;",
830 " switch (caller) {",
831 " case 1: /* addproc */",
832 "#if VECTORSZ>32000",
833 " memcpy((char *) P_o_tmp, (const char *) proc_offset, MAXPROC*sizeof(int));",
835 " memcpy((char *) P_o_tmp, (const char *) proc_offset, MAXPROC*sizeof(short));",
837 " memcpy((char *) P_s_tmp, (const char *) proc_skip, MAXPROC*sizeof(uchar));",
838 " proc_offset = P_o_tmp;",
839 " proc_skip = (uchar *) &P_s_tmp[0];",
841 " case 2: /* addqueue */",
842 "#if VECTORSZ>32000",
843 " memcpy((char *) Q_o_tmp, (const char *) q_offset, MAXQ*sizeof(int));",
845 " memcpy((char *) Q_o_tmp, (const char *) q_offset, MAXQ*sizeof(short));",
847 " memcpy((char *) Q_s_tmp, (const char *) q_skip, MAXQ*sizeof(uchar));",
848 " q_offset = Q_o_tmp;",
849 " q_skip = (uchar *) &Q_s_tmp[0];",
851 " case 3: /* no nothing */",
853 " default: /* cannot happen */",
854 " Uerror(\"no good\");",
859 "typedef struct BFS_saves BFS_saves;",
860 "struct BFS_saves {",
865 "#if !defined(NOCOMP) && !defined(HC)",
871 "extern volatile uchar *sh_malloc(ulong);",
872 "static int bfs_runs; /* 0 before local heaps are initialized */",
875 "bfs_swoosh(BFS_saves **where, char **what, int howmuch)",
877 " for (m = *where; m; m = m->nxt)",
878 " { if (memcmp(m->m, *what, howmuch) == 0)",
882 " m = (BFS_saves *) emalloc(sizeof(BFS_saves));",
884 " { m->m = (char *) sh_malloc(howmuch);",
886 " { m->m = (char *) sh_pre_malloc(howmuch);",
888 " memcpy(m->m, *what, howmuch);",
895 "bfs_fixmask(int caller)", /* 1=addproc, 2=addqueue */
897 "#if !defined(NOCOMP) && !defined(HC)",
898 " bfs_swoosh(&bfs_save_mask, (char **) &Mask, sizeof(State));",
901 " switch (caller) {",
902 " case 1: /* addproc */",
903 " #if VECTORSZ>32000",
904 " bfs_swoosh(&bfs_save_po, (char **) &proc_offset, MAXPROC*sizeof(int));",
906 " bfs_swoosh(&bfs_save_po, (char **) &proc_offset, MAXPROC*sizeof(short));",
908 " bfs_swoosh(&bfs_save_ps, (char **) &proc_skip, MAXPROC*sizeof(uchar));",
910 " case 2: /* addqueue */",
911 " #if VECTORSZ>32000",
912 " bfs_swoosh(&bfs_save_qo, (char **) &q_offset, MAXQ*sizeof(int));",
914 " bfs_swoosh(&bfs_save_qo, (char **) &q_offset, MAXQ*sizeof(short));",
916 " bfs_swoosh(&bfs_save_qs, (char **) &q_skip, MAXQ*sizeof(uchar));",
918 " case 3: /* do nothing */",
921 " Uerror(\"double plus ungood\");",
929 static const char *R8a[] = {
930 " default: Uerror(\"bad proctype - collapse\");",
932 " if (z) x = z; else x = scratch;",
933 " y = (char *) ptr; k = proc_offset[i];",
935 "#if !defined(NOCOMP) && !defined(HC)",
936 " for ( ; j > 0; j--, y++)",
937 " if (!Mask[k++]) *x++ = *y;",
942 " for (j = 0; j < WS-1; j++)",
945 " if (z) return (long) (x - z);",
946 " return ordinal(scratch, x-scratch, (short) (2+ptr->_t));",
952 static const char *R8b[] = {
953 " default: Uerror(\"bad qtype - collapse\");",
955 " if (z) x = z; else x = scratch;",
956 " y = (char *) ptr; k = q_offset[i];",
959 " /* no need to store the empty slots at the end */",
960 " j -= (q_max[ptr->_t] - ptr->Qlen) * ((j - 2)/q_max[ptr->_t]);",
963 "#if !defined(NOCOMP) && !defined(HC)",
964 " for ( ; j > 0; j--, y++)",
965 " if (!Mask[k++]) *x++ = *y;",
970 " for (j = 0; j < WS-1; j++)",
973 " if (z) return (long) (x - z);",
974 " return ordinal(scratch, x-scratch, 1); /* chan */",
981 static const char *R12[] = {
982 "\t\tcase %d: r = ((Q%d *)z)->contents[slot].fld%d; break;",
985 const char *R13[] = {
988 "{ int _m=0, j; uchar *z;\n",
993 " uerror(\"ref to uninitialized chan (unsend)\");",
994 "#if defined(TRIX) && !defined(BFS)",
995 " #ifndef TRIX_ORIG",
996 " now._ids_[now._nr_pr+into] = trpt->q_bup;",
998 " printf(\"%%4d: channel %%d s restore %%p into %%d\\n\",",
999 " depth, into, trpt->q_bup, now._nr_pr+into);",
1002 " channels[into]->modified = 1; /* unsend */",
1004 " printf(\"%%4d: channel %%d unmodify\\n\", depth, into);",
1009 " j = ((Q0 *)z)->Qlen;",
1010 " ((Q0 *)z)->Qlen = --j;",
1011 " switch (((Q0 *)qptr(into))->_t) {",
1014 const char *R14[] = {
1015 " default: Uerror(\"bad queue - unsend\");",
1020 "unrecv(int from, int slot, int fld, int fldvar, int strt)",
1021 "{ int j; uchar *z;\n",
1023 " uerror(\"ref to uninitialized chan (unrecv)\");",
1024 "#if defined(TRIX) && !defined(BFS)",
1025 " #ifndef TRIX_ORIG",
1026 " now._ids_[now._nr_pr+from] = trpt->q_bup;",
1028 " printf(\"%%4d: channel %%d r restore %%p into %%d\\n\",",
1029 " depth, from, trpt->q_bup, now._nr_pr+from);",
1032 " channels[from]->modified = 1; /* unrecv */",
1034 " printf(\"%%4d: channel %%d unmodify\\n\", depth, from);",
1039 " j = ((Q0 *)z)->Qlen;",
1040 " if (strt) ((Q0 *)z)->Qlen = j+1;",
1041 " switch (((Q0 *)qptr(from))->_t) {",
1044 const char *R15[] = {
1045 " default: Uerror(\"bad queue - qrecv\");",
1050 static const char *Proto[] = {
1052 "/** function prototypes **/",
1053 "char *emalloc(ulong);",
1054 "char *Malloc(ulong);",
1055 "int Boundcheck(int, int, int, int, Trans *);",
1056 "int addqueue(int, int, int);",
1057 "/* int atoi(char *); */",
1058 "/* int abort(void); */",
1059 "int close(int);", /* should probably remove this */
1062 " int creat(char *, unsigned short);",
1063 " int write(int, void *, unsigned);",
1066 "int delproc(int, int);",
1067 "int endstate(void);",
1068 "int find_claim(char *);",
1069 "int h_store(char *, int);",
1070 "int pan_rand(void);",
1071 "int q_cond(short, Trans *);",
1075 "int qrecv(int, int, int, int);",
1077 "/* void *sbrk(int); */",
1078 "void spin_assert(int, char *, int, int, Trans *);",
1080 "void bfs_printf(const char *, ...);",
1081 "volatile uchar *sh_pre_malloc(ulong);",
1083 "void c_chandump(int);",
1084 "void c_globals(void);",
1085 "void c_locals(int, int);",
1086 "void checkcycles(void);",
1087 "void crack(int, int, Trans *, short *);",
1088 "void d_sfh(uchar *, int);",
1089 "void d_hash(uchar *, int);",
1090 "void m_hash(uchar *, int);",
1091 "void s_hash(uchar *, int);",
1093 "void dot_crack(int, int, Trans *);",
1094 "void do_reach(void);",
1095 "void pan_exit(int);",
1098 " void bfs_setup_mem(void);",
1101 " void sinit(void);",
1103 " void hinit(void);",
1105 "void imed(Trans *, int, int, int);",
1106 "void new_state(void);",
1107 "void p_restor(int);",
1108 "void putpeg(int, int);",
1109 "void putrail(void);",
1110 "void q_restor(void);",
1111 "void retrans(int, int, int, short *, uchar *, uchar *);",
1112 "void select_claim(int);",
1113 "void settable(void);",
1114 "void setq_claim(int, int, char *, int, char *);",
1115 "void sv_restor(void);",
1116 "void sv_save(void);",
1117 "void tagtable(int, int, int, short *, uchar *);",
1118 "void do_dfs(int, int, int, short *, uchar *, uchar *);",
1119 "void unrecv(int, int, int, int, int);",
1120 "void usage(FILE *);",
1121 "void wrap_stats(void);\n",
1123 " int g_store(char *, int, uchar);",
1125 "#if defined(FULLSTACK) && defined(BITSTATE)",
1126 " int onstack_now(void);",
1127 " void onstack_init(void);",
1128 " void onstack_put(void);",
1129 " void onstack_zap(void);",
1132 " int q_S_check(int, int);",
1133 " int q_R_check(int, int);",
1134 " uchar q_claim[MAXQ+1];",
1135 " char *q_name[MAXQ+1];",
1136 " char *p_name[MAXPROC+1];",
1139 "#ifndef NO_V_PROVISO",
1140 " #define V_PROVISO",
1142 "#if !defined(NO_RESIZE) && !defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(SPACE) && !defined(USE_TDH) && NCORE==1",
1143 " #define AUTO_RESIZE",
1146 "typedef struct Trail Trail;",
1147 "typedef struct H_el H_el;",
1151 " #ifdef FULLSTACK",
1152 " unsigned int tagged;",
1153 " #if defined(BITSTATE) && !defined(NOREDUCE) && !defined(SAFETY)",
1154 " unsigned int proviso;", /* uses just 1 bit 0/1 */
1157 " #if defined(CHECK) || (defined(COLLAPSE) && !defined(FULLSTACK))",
1160 " #if !defined(SAFETY) || defined(REACH)",
1164 " #ifndef CONSERVATIVE",
1165 " #define CONSERVATIVE 1 /* good for up to 8 processes */",
1167 " #ifdef CONSERVATIVE",
1168 " #if CONSERVATIVE <= 0 || CONSERVATIVE>32",
1169 " #error sensible values for CONSERVATIVE are 1..32 (256/8 = 32)",
1171 " uchar ctx_pid[CONSERVATIVE];", /* pids setting lowest value */
1173 " uchar ctx_low;", /* lowest nr of context switches seen so far */
1176 " /* could cost 1 extra word: 4 bytes if 32-bit and 8 bytes if 64-bit */",
1177 " #ifdef V_PROVISO",
1178 " uchar cpu_id; /* id of cpu that created the state */",
1182 " #if VECTORSZ<65536",
1183 " ushort ln;", /* length of vector */
1185 " ulong ln;", /* length of vector */
1188 " #if defined(AUTO_RESIZE) && !defined(BITSTATE)",
1195 "typedef struct BFS_Trail BFS_Trail;",
1196 "struct BFS_Trail {",
1200 " T_ID t_id;", /* could be uint, ushort, or uchar */
1206 " #undef BFS_NOTRAIL", /* just in case it was used */
1211 " #ifndef PERMUTED",
1212 " #define PERMUTED",
1217 " int st; /* current state */",
1223 " uchar pr; /* process id */",
1224 " uchar tau; /* 8 bit-flags */",
1225 " uchar o_pm; /* 8 more bit-flags */",
1228 " Meaning of bit-flags on tau and o_pm:",
1229 " tau&1 -> timeout enabled",
1230 " tau&2 -> request to enable timeout 1 level up (in claim)",
1231 " tau&4 -> current transition is a claim move",
1232 " tau&8 -> current transition is an atomic move",
1233 " tau&16 -> last move was truncated on stack",
1234 " tau&32 -> current transition is a preselected move",
1235 " tau&64 -> at least one next state is not on the stack",
1236 " tau&128 -> current transition is a stutter move",
1238 " o_pm&1 -> the current pid moved -- implements else",
1239 " o_pm&2 -> this is an acceptance state",
1240 " o_pm&4 -> this is a progress state",
1241 " o_pm&8 -> fairness alg rule 1 undo mark",
1242 " o_pm&16 -> fairness alg rule 3 undo mark",
1243 " o_pm&32 -> fairness alg rule 2 undo mark",
1244 " o_pm&64 -> the current proc applied rule2",
1245 " o_pm&128 -> a fairness, dummy move - all procs blocked",
1249 " uchar n_succ; /* nr of successor states */",
1251 " #if defined(FULLSTACK) && defined(MA) && !defined(BFS)",
1255 " uchar o_n, o_ot; /* to save locals */",
1258 " #ifdef EVENT_TRACE",
1259 " #if nstates_event<256",
1262 " unsigned short o_event;",
1267 " #if defined(T_RAND) || defined(RANDOMIZE)",
1271 " #if defined(HAS_UNLESS) && !defined(BFS)",
1272 " int e_state; /* if escape trans - state of origin */",
1274 " #if (defined(FULLSTACK) && !defined(MA)) || defined(BFS) || (NCORE>1)",
1275 " H_el *ostate; /* pointer to stored state */",
1277 /* CNTRSTACK when !NOREDUCE && BITSTATE && SAFETY && WS<=4, uses LL[] */
1278 " #if defined(CNTRSTACK) && !defined(BFS)",
1281 " Trans *o_t;", /* transition fct, next state */
1283 " #if !defined(BFS) && !defined(TRIX_ORIG)",
1289 " unsigned short sched_limit;",
1290 " unsigned char bcs; /* phase 1 or 2, or forced 4 */",
1291 " unsigned char b_pno; /* preferred pid */",
1294 " #ifdef P_RAND", /* process scheduling randomization */
1295 " unsigned char p_left; /* nr of procs left to explore */",
1296 " short p_skip; /* to find starting point in list */",
1299 " #ifdef HAS_SORTED",
1300 " short ipt;", /* insertion slot in q */
1302 " #ifdef HAS_PRIORITY",
1303 " short o_priority;",
1306 " int oval;", /* single backup value of variable */
1307 " int *ovals;", /* ptr to multiple values */
1309 "}; /* end of struct Trail */",
1311 "#ifdef BFS", /* breadth-first search */
1312 " #define Q_PROVISO",
1313 " #ifndef INLINE_REV",
1314 " #define INLINE_REV",
1317 "typedef struct SV_Hold {",
1322 " struct SV_Hold *nxt;",
1324 "#if !defined(BFS_PAR) || NRUNS>0",
1325 " typedef struct EV_Hold {",
1326 " #if !defined(BFS_PAR) || (!defined(NOCOMP) && !defined(HC) && NRUNS>0)",
1327 " char *sv; /* Mask */",
1329 " #if VECTORSZ<65536",
1330 " ushort sz; /* vsize */",
1339 " #if !defined(BFS_PAR) || (!defined(TRIX) && NRUNS>0)",
1343 " struct EV_Hold *nxt;",
1346 "typedef struct BFS_State {",
1348 " BFS_Trail *t_info;",
1354 " #if !defined(BFS_PAR) || NRUNS>0",
1357 " #if defined(Q_PROVISO) && !defined(NOREDUCE)",
1360 " #if !defined(BFS_PAR) || SYNC>0",
1366 " #ifndef BFS_PAR", /* new 6.2.4, 3 dec 2012 */
1367 " struct BFS_State *nxt;",
1374 static const char *SvMap[] = {
1377 "{ char ctd[2048], carg[128];",
1379 " strcpy(ctd, \"-DBITSTATE \");",
1381 " strcpy(ctd, \"\");",
1384 " strcat(ctd, \"-DBFS_PAR \");",
1387 " strcat(ctd, \"-DNOVSZ \");",
1390 " strcat(ctd, \"-DRHASH \");",
1393 " strcat(ctd, \"-DPERMUTED \");",
1397 " strcat(ctd, \"-DP_REVERSE \");",
1400 " strcat(ctd, \"-DT_REVERSE \");",
1404 " sprintf(carg, \"-DT_RAND=%%d \", T_RAND);",
1405 " strcat(ctd, carg);",
1407 " strcat(ctd, \"-DT_RAND \");",
1412 " sprintf(carg, \"-DP_RAND=%%d \", P_RAND);",
1413 " strcat(ctd, carg);",
1415 " strcat(ctd, \"-DP_RAND \");",
1419 " sprintf(carg, \"-DBCS=%%d \", BCS);",
1420 " strcat(ctd, carg);",
1423 " strcat(ctd, \"-DBFS \");",
1426 " sprintf(carg, \"-DMEMLIM=%%d \", MEMLIM);",
1427 " strcat(ctd, carg);",
1430 " sprintf(carg, \"-DMEMCNT=%%d \", MEMCNT);",
1431 " strcat(ctd, carg);",
1435 " strcat(ctd, \"-DNOCLAIM \");",
1438 " strcat(ctd, \"-DSAFETY \");",
1441 " strcat(ctd, \"-DNOFAIR \");",
1445 " { sprintf(carg, \"-DNFAIR=%%d \", NFAIR);",
1446 " strcat(ctd, carg);",
1452 " strcat(ctd, \"-DNOREDUCE \");",
1455 " strcat(ctd, \"-DXUSAFE \");",
1459 " strcat(ctd, \"-DNP \");",
1462 " strcat(ctd, \"-DPEG \");",
1464 "#ifdef VAR_RANGES",
1465 " strcat(ctd, \"-DVAR_RANGES \");",
1468 " strcat(ctd, \"-DHC \");",
1471 " strcat(ctd, \"-DCHECK \");",
1474 " strcat(ctd, \"-DCTL \");",
1477 " strcat(ctd, \"-DTRIX \");",
1480 " strcat(ctd, \"-DNIBIS \");",
1482 "#ifdef NOBOUNDCHECK",
1483 " strcat(ctd, \"-DNOBOUNDCHECK \");",
1486 " strcat(ctd, \"-DNOSTUTTER \");",
1489 " strcat(ctd, \"-DREACH \");",
1492 " strcat(ctd, \"-DPRINTF \");",
1495 " strcat(ctd, \"-DCOLLAPSE \");",
1498 " sprintf(carg, \"-DMA=%%d \", MA);",
1499 " strcat(ctd, carg);",
1502 " strcat(ctd, \"-DSVDUMP \");",
1504 "#if defined(VECTORSZ) && !defined(TRIX)",
1505 " if (VECTORSZ != 1024)",
1506 " { sprintf(carg, \"-DVECTORSZ=%%d \", VECTORSZ);",
1507 " strcat(ctd, carg);",
1511 " strcat(ctd, \"-DVERBOSE \");",
1514 " strcat(ctd, \"-DCHECK \");",
1517 " strcat(ctd, \"-DSDUMP \");",
1520 " sprintf(carg, \"-DNCORE=%%d \", NCORE);",
1521 " strcat(ctd, carg);",
1524 " if (VMAX != 256)",
1525 " { sprintf(carg, \"-DVMAX=%%d \", VMAX);",
1526 " strcat(ctd, carg);",
1531 " { sprintf(carg, \"-DPMAX=%%d \", PMAX);",
1532 " strcat(ctd, carg);",
1537 " { sprintf(carg, \"-DQMAX=%%d \", QMAX);",
1538 " strcat(ctd, carg);",
1541 "#ifdef SET_WQ_SIZE",
1542 " sprintf(carg, \"-DSET_WQ_SIZE=%%d \", SET_WQ_SIZE);",
1543 " strcat(ctd, carg);",
1545 " printf(\"Compiled as: cc -o pan %%span.c\\n\", ctd);",