| 1 | /***** spin: pangen1.h *****/ |
| 2 | |
| 3 | /* Copyright (c) 1989-2008 by Lucent Technologies, Bell Laboratories. */ |
| 4 | /* All Rights Reserved. This software is for educational purposes only. */ |
| 5 | /* No guarantee whatsoever is expressed or implied by the distribution of */ |
| 6 | /* this code. Permission is given to distribute this code provided that */ |
| 7 | /* this introductory message is not removed and no monies are exchanged. */ |
| 8 | /* Software written by Gerard J. Holzmann. For tool documentation see: */ |
| 9 | /* http://spinroot.com/ */ |
| 10 | /* Send all bug-reports and/or questions to: bugs@spinroot.com */ |
| 11 | /* (c) 2007: small additions for V5.0 to support multi-core verifications */ |
| 12 | |
| 13 | static char *Code2a[] = { /* the tail of procedure run() */ |
| 14 | "#if defined(VERI) && !defined(NOREDUCE) && !defined(NP)", |
| 15 | " if (!state_tables", |
| 16 | "#ifdef HAS_CODE", |
| 17 | " && !readtrail", |
| 18 | "#endif", |
| 19 | "#if NCORE>1", |
| 20 | " && core_id == 0", |
| 21 | "#endif", |
| 22 | " )", |
| 23 | " { printf(\"warning: for p.o. reduction to be valid \");", |
| 24 | " printf(\"the never claim must be stutter-invariant\\n\");", |
| 25 | " printf(\"(never claims generated from LTL \");", |
| 26 | " printf(\"formulae are stutter-invariant)\\n\");", |
| 27 | " }", |
| 28 | "#endif", |
| 29 | " UnBlock; /* disable rendez-vous */", |
| 30 | "#ifdef BITSTATE", |
| 31 | #ifndef POWOW |
| 32 | " if (udmem)", |
| 33 | " { udmem *= 1024L*1024L;", |
| 34 | " #if NCORE>1", |
| 35 | " if (!readtrail)", |
| 36 | " { void init_SS(unsigned long);", |
| 37 | " init_SS((unsigned long) udmem);", |
| 38 | " } else", |
| 39 | " #endif", |
| 40 | " SS = (uchar *) emalloc(udmem);", |
| 41 | " bstore = bstore_mod;", |
| 42 | " } else", |
| 43 | #endif |
| 44 | " #if NCORE>1", |
| 45 | " { void init_SS(unsigned long);", |
| 46 | " init_SS(ONE_L<<(ssize-3));", |
| 47 | " }", |
| 48 | " #else", |
| 49 | " SS = (uchar *) emalloc(ONE_L<<(ssize-3));", |
| 50 | " #endif", |
| 51 | "#else", /* if not BITSTATE */ |
| 52 | " hinit();", |
| 53 | "#endif", |
| 54 | "#if defined(FULLSTACK) && defined(BITSTATE)", |
| 55 | " onstack_init();", |
| 56 | "#endif", |
| 57 | "#if defined(CNTRSTACK) && !defined(BFS)", |
| 58 | " LL = (uchar *) emalloc(ONE_L<<(ssize-3));", |
| 59 | "#endif", |
| 60 | " stack = ( Stack *) emalloc(sizeof(Stack));", |
| 61 | " svtack = (Svtack *) emalloc(sizeof(Svtack));", |
| 62 | " /* a place to point for Pptr of non-running procs: */", |
| 63 | " noptr = (uchar *) emalloc(Maxbody * sizeof(char));", |
| 64 | "#ifdef SVDUMP", |
| 65 | " if (vprefix > 0)", |
| 66 | " write(svfd, (uchar *) &vprefix, sizeof(int));", |
| 67 | "#endif", |
| 68 | "#ifdef VERI", |
| 69 | " Addproc(VERI); /* never - pid = 0 */", |
| 70 | "#endif", |
| 71 | " active_procs(); /* started after never */", |
| 72 | "#ifdef EVENT_TRACE", |
| 73 | " now._event = start_event;", |
| 74 | " reached[EVENT_TRACE][start_event] = 1;", |
| 75 | "#endif", |
| 76 | |
| 77 | "#ifdef HAS_CODE", |
| 78 | " globinit();", |
| 79 | "#endif", |
| 80 | "#ifdef BITSTATE", |
| 81 | "go_again:", |
| 82 | "#endif", |
| 83 | " do_the_search();", |
| 84 | "#ifdef BITSTATE", |
| 85 | " if (--Nrun > 0 && HASH_CONST[++HASH_NR])", |
| 86 | " { printf(\"Run %%d:\\n\", HASH_NR);", |
| 87 | " wrap_stats();", |
| 88 | " printf(\"\\n\");", |
| 89 | " memset(SS, 0, ONE_L<<(ssize-3));", |
| 90 | "#ifdef CNTRSTACK", |
| 91 | " memset(LL, 0, ONE_L<<(ssize-3));", |
| 92 | "#endif", |
| 93 | "#ifdef FULLSTACK", |
| 94 | " memset((uchar *) S_Tab, 0, ", |
| 95 | " maxdepth*sizeof(struct H_el *));", |
| 96 | "#endif", |
| 97 | " nstates=nlinks=truncs=truncs2=ngrabs = 0;", |
| 98 | " nlost=nShadow=hcmp = 0;", |
| 99 | " Fa=Fh=Zh=Zn = 0;", |
| 100 | " PUT=PROBE=ZAPS=Ccheck=Cholds = 0;", |
| 101 | " goto go_again;", |
| 102 | " }", |
| 103 | "#endif", |
| 104 | "}", |
| 105 | "#ifdef HAS_PROVIDED", |
| 106 | "int provided(int, uchar, int, Trans *);", |
| 107 | "#endif", |
| 108 | |
| 109 | "#if NCORE>1", |
| 110 | "#define GLOBAL_LOCK (0)", |
| 111 | "#ifndef CS_N", |
| 112 | "#define CS_N (256*NCORE)", /* must be a power of 2 */ |
| 113 | "#endif", |
| 114 | |
| 115 | "#ifdef NGQ", /* no global queue */ |
| 116 | "#define NR_QS (NCORE)", |
| 117 | "#define CS_NR (CS_N+1) /* 2^N + 1, nr critical sections */", |
| 118 | "#define GQ_RD GLOBAL_LOCK", /* not really used in this mode */ |
| 119 | "#define GQ_WR GLOBAL_LOCK", /* but just in case... */ |
| 120 | "#define CS_ID (1 + (int) (j1 & (CS_N-1))) /* mask: 2^N - 1, zero reserved */", |
| 121 | "#define QLOCK(n) (1+n)", /* overlaps first n zones of hashtable */ |
| 122 | "#else", |
| 123 | "#define NR_QS (NCORE+1)", /* add a global queue */ |
| 124 | "#define CS_NR (CS_N+3)", /* 2 extra locks for global q */ |
| 125 | "#define GQ_RD (1)", /* read access to global q */ |
| 126 | "#define GQ_WR (2)", /* write access to global q */ |
| 127 | "#define CS_ID (3 + (int) (j1 & (CS_N-1)))", |
| 128 | "#define QLOCK(n) (3+n)",/* overlaps first n zones of hashtable */ |
| 129 | "#endif", |
| 130 | "", |
| 131 | "void e_critical(int);", |
| 132 | "void x_critical(int);", |
| 133 | "", |
| 134 | "#ifndef SEP_STATE", |
| 135 | " #define enter_critical(w) e_critical(w)", |
| 136 | " #define leave_critical(w) x_critical(w)", |
| 137 | "#else", |
| 138 | " #ifdef NGQ", |
| 139 | " #define enter_critical(w) { if (w < 1+NCORE) e_critical(w); }", |
| 140 | " #define leave_critical(w) { if (w < 1+NCORE) x_critical(w); }", |
| 141 | " #else", |
| 142 | " #define enter_critical(w) { if (w < 3+NCORE) e_critical(w); }", |
| 143 | " #define leave_critical(w) { if (w < 3+NCORE) x_critical(w); }", |
| 144 | " #endif", |
| 145 | "#endif", |
| 146 | "", |
| 147 | "int", |
| 148 | "cpu_printf(const char *fmt, ...)", /* only used with VERBOSE/CHECK/DEBUG */ |
| 149 | "{ va_list args;", |
| 150 | " enter_critical(GLOBAL_LOCK); /* printing */", |
| 151 | " printf(\"cpu%%d: \", core_id);", |
| 152 | " fflush(stdout);", |
| 153 | " va_start(args, fmt);", |
| 154 | " vprintf(fmt, args);", |
| 155 | " va_end(args);", |
| 156 | " fflush(stdout);", |
| 157 | " leave_critical(GLOBAL_LOCK);", |
| 158 | " return 1;", |
| 159 | "}", |
| 160 | "#else", |
| 161 | "int", |
| 162 | "cpu_printf(const char *fmt, ...)", |
| 163 | "{ va_list args;", |
| 164 | " va_start(args, fmt);", |
| 165 | " vprintf(fmt, args);", |
| 166 | " va_end(args);", |
| 167 | " return 1;", |
| 168 | "}", |
| 169 | "#endif", |
| 170 | |
| 171 | #ifndef PRINTF |
| 172 | "int", |
| 173 | "Printf(const char *fmt, ...)", |
| 174 | "{ /* Make sure the args to Printf", |
| 175 | " * are always evaluated (e.g., they", |
| 176 | " * could contain a run stmnt)", |
| 177 | " * but do not generate the output", |
| 178 | " * during verification runs", |
| 179 | " * unless explicitly wanted", |
| 180 | " * If this fails on your system", |
| 181 | " * compile SPIN itself -DPRINTF", |
| 182 | " * and this code is not generated", |
| 183 | " */", |
| 184 | "#ifdef HAS_CODE", |
| 185 | " if (readtrail)", |
| 186 | " { va_list args;", |
| 187 | " va_start(args, fmt);", |
| 188 | " vprintf(fmt, args);", |
| 189 | " va_end(args);", |
| 190 | " return 1;", |
| 191 | " }", |
| 192 | "#endif", |
| 193 | "#ifdef PRINTF", |
| 194 | " va_list args;", |
| 195 | " va_start(args, fmt);", |
| 196 | " vprintf(fmt, args);", |
| 197 | " va_end(args);", |
| 198 | "#endif", |
| 199 | " return 1;", |
| 200 | "}", |
| 201 | #endif |
| 202 | "extern void printm(int);", |
| 203 | |
| 204 | "#ifndef SC", |
| 205 | "#define getframe(i) &trail[i];", |
| 206 | "#else", |
| 207 | "static long HHH, DDD, hiwater;", |
| 208 | "static long CNT1, CNT2;", |
| 209 | "static int stackwrite;", |
| 210 | "static int stackread;", |
| 211 | "static Trail frameptr;", |
| 212 | "Trail *", |
| 213 | "getframe(int d)", |
| 214 | "{", |
| 215 | " if (CNT1 == CNT2)", |
| 216 | " return &trail[d];", |
| 217 | "", |
| 218 | " if (d >= (CNT1-CNT2)*DDD)", |
| 219 | " return &trail[d - (CNT1-CNT2)*DDD];", |
| 220 | "", |
| 221 | " if (!stackread", |
| 222 | " && (stackread = open(stackfile, 0)) < 0)", |
| 223 | " { printf(\"getframe: cannot open %%s\\n\", stackfile);", |
| 224 | " wrapup();", |
| 225 | " }", |
| 226 | " if (lseek(stackread, d* (off_t) sizeof(Trail), SEEK_SET) == -1", |
| 227 | " || read(stackread, &frameptr, sizeof(Trail)) != sizeof(Trail))", |
| 228 | " { printf(\"getframe: frame read error\\n\");", |
| 229 | " wrapup();", |
| 230 | " }", |
| 231 | " return &frameptr;", |
| 232 | "}", |
| 233 | "#endif", |
| 234 | |
| 235 | "#if !defined(SAFETY) && !defined(BITSTATE)", |
| 236 | "#if !defined(FULLSTACK) || defined(MA)", |
| 237 | "#define depth_of(x) A_depth /* an estimate */", |
| 238 | "#else", |
| 239 | "int", |
| 240 | "depth_of(struct H_el *s)", |
| 241 | "{ Trail *t; int d;", |
| 242 | " for (d = 0; d <= A_depth; d++)", |
| 243 | " { t = getframe(d);", |
| 244 | " if (s == t->ostate)", |
| 245 | " return d;", |
| 246 | " }", |
| 247 | " printf(\"pan: cannot happen, depth_of\\n\");", |
| 248 | " return depthfound;", |
| 249 | "}", |
| 250 | "#endif", |
| 251 | "#endif", |
| 252 | |
| 253 | "#if NCORE>1", |
| 254 | "extern void cleanup_shm(int);", |
| 255 | "volatile unsigned int *search_terminated; /* to signal early termination */", |
| 256 | /* |
| 257 | * Meaning of bitflags in search_terminated: |
| 258 | * 1 set by pan_exit |
| 259 | * 2 set by wrapup |
| 260 | * 4 set by uerror |
| 261 | * 8 set by sudden_stop -- called after someone_crashed and [Uu]error |
| 262 | * 16 set by cleanup_shm |
| 263 | * 32 set by give_up -- called on signal |
| 264 | * 64 set by proxy_exit |
| 265 | * 128 set by proxy on write port failure |
| 266 | * 256 set by proxy on someone_crashed |
| 267 | * |
| 268 | * Flags 8|32|128|256 indicate abnormal termination |
| 269 | * |
| 270 | * The flags are checked in 4 functions in the code: |
| 271 | * sudden_stop() |
| 272 | * someone_crashed() (proxy and pan version) |
| 273 | * mem_hand_off() |
| 274 | */ |
| 275 | "#endif", |
| 276 | "void", |
| 277 | "pan_exit(int val)", |
| 278 | "{ void stop_timer(void);", |
| 279 | " if (signoff)", |
| 280 | " { printf(\"--end of output--\\n\");", |
| 281 | " }", |
| 282 | "#if NCORE>1", |
| 283 | " if (search_terminated != NULL)", |
| 284 | " { *search_terminated |= 1; /* pan_exit */", |
| 285 | " }", |
| 286 | "#ifdef USE_DISK", |
| 287 | " { void dsk_stats(void);", |
| 288 | " dsk_stats();", |
| 289 | " }", |
| 290 | "#endif", |
| 291 | " if (!state_tables && !readtrail)", |
| 292 | " { cleanup_shm(1);", |
| 293 | " }", |
| 294 | "#endif", |
| 295 | " if (val == 2)", |
| 296 | " { val = 0;", |
| 297 | " } else", |
| 298 | " { stop_timer();", |
| 299 | " }", |
| 300 | " exit(val);", |
| 301 | "}", |
| 302 | |
| 303 | "#ifdef HAS_CODE", |
| 304 | "char *", |
| 305 | "transmognify(char *s)", |
| 306 | "{ char *v, *w;", |
| 307 | " static char buf[2][2048];", |
| 308 | " int i, toggle = 0;", |
| 309 | |
| 310 | " if (!s || strlen(s) > 2047) return s;", |
| 311 | " memset(buf[0], 0, 2048);", |
| 312 | " memset(buf[1], 0, 2048);", |
| 313 | " strcpy(buf[toggle], s);", |
| 314 | " while ((v = strstr(buf[toggle], \"{c_code\")))", /* assign v */ |
| 315 | " { *v = '\\0'; v++;", |
| 316 | " strcpy(buf[1-toggle], buf[toggle]);", |
| 317 | " for (w = v; *w != '}' && *w != '\\0'; w++) /* skip */;", |
| 318 | " if (*w != '}') return s;", |
| 319 | " *w = '\\0'; w++;", |
| 320 | " for (i = 0; code_lookup[i].c; i++)", |
| 321 | " if (strcmp(v, code_lookup[i].c) == 0", |
| 322 | " && strlen(v) == strlen(code_lookup[i].c))", |
| 323 | " { if (strlen(buf[1-toggle])", |
| 324 | " + strlen(code_lookup[i].t)", |
| 325 | " + strlen(w) > 2047)", |
| 326 | " return s;", |
| 327 | " strcat(buf[1-toggle], code_lookup[i].t);", |
| 328 | " break;", |
| 329 | " }", |
| 330 | " strcat(buf[1-toggle], w);", |
| 331 | " toggle = 1 - toggle;", |
| 332 | " }", |
| 333 | " buf[toggle][2047] = '\\0';", |
| 334 | " return buf[toggle];", |
| 335 | "}", |
| 336 | "#else", |
| 337 | "char * transmognify(char *s) { return s; }", |
| 338 | "#endif", |
| 339 | |
| 340 | "#ifdef HAS_CODE", |
| 341 | "void", |
| 342 | "add_src_txt(int ot, int tt)", |
| 343 | "{ Trans *t;", |
| 344 | " char *q;", |
| 345 | "", |
| 346 | " for (t = trans[ot][tt]; t; t = t->nxt)", |
| 347 | " { printf(\"\\t\\t\");", |
| 348 | |
| 349 | " q = transmognify(t->tp);", |
| 350 | " for ( ; q && *q; q++)", |
| 351 | " if (*q == '\\n')", |
| 352 | " printf(\"\\\\n\");", |
| 353 | " else", |
| 354 | " putchar(*q);", |
| 355 | " printf(\"\\n\");", |
| 356 | " }", |
| 357 | "}", |
| 358 | "void", |
| 359 | "wrap_trail(void)", |
| 360 | "{ static int wrap_in_progress = 0;", |
| 361 | " int i; short II;", |
| 362 | " P0 *z;", |
| 363 | "", |
| 364 | " if (wrap_in_progress++) return;", |
| 365 | "", |
| 366 | " printf(\"spin: trail ends after %%ld steps\\n\", depth);", |
| 367 | " if (onlyproc >= 0)", |
| 368 | " { if (onlyproc >= now._nr_pr) { pan_exit(0); }", |
| 369 | " II = onlyproc;", |
| 370 | " z = (P0 *)pptr(II);", |
| 371 | " printf(\"%%3ld:\tproc %%d (%%s) \",", |
| 372 | " depth, II, procname[z->_t]);", |
| 373 | " for (i = 0; src_all[i].src; i++)", |
| 374 | " if (src_all[i].tp == (int) z->_t)", |
| 375 | " { printf(\" line %%3d\",", |
| 376 | " src_all[i].src[z->_p]);", |
| 377 | " break;", |
| 378 | " }", |
| 379 | " printf(\" (state %%2d)\", z->_p);", |
| 380 | " if (!stopstate[z->_t][z->_p])", |
| 381 | " printf(\" (invalid end state)\");", |
| 382 | " printf(\"\\n\");", |
| 383 | " add_src_txt(z->_t, z->_p);", |
| 384 | " pan_exit(0);", |
| 385 | " }", |
| 386 | " printf(\"#processes %%d:\\n\", now._nr_pr);", |
| 387 | " if (depth < 0) depth = 0;", |
| 388 | " for (II = 0; II < now._nr_pr; II++)", |
| 389 | " { z = (P0 *)pptr(II);", |
| 390 | " printf(\"%%3ld:\tproc %%d (%%s) \",", |
| 391 | " depth, II, procname[z->_t]);", |
| 392 | " for (i = 0; src_all[i].src; i++)", |
| 393 | " if (src_all[i].tp == (int) z->_t)", |
| 394 | " { printf(\" line %%3d\",", |
| 395 | " src_all[i].src[z->_p]);", |
| 396 | " break;", |
| 397 | " }", |
| 398 | " printf(\" (state %%2d)\", z->_p);", |
| 399 | " if (!stopstate[z->_t][z->_p])", |
| 400 | " printf(\" (invalid end state)\");", |
| 401 | " printf(\"\\n\");", |
| 402 | " add_src_txt(z->_t, z->_p);", |
| 403 | " }", |
| 404 | " c_globals();", |
| 405 | " for (II = 0; II < now._nr_pr; II++)", |
| 406 | " { z = (P0 *)pptr(II);", |
| 407 | " c_locals(II, z->_t);", |
| 408 | " }", |
| 409 | "#ifdef ON_EXIT", |
| 410 | " ON_EXIT;", |
| 411 | "#endif", |
| 412 | " pan_exit(0);", |
| 413 | "}", |
| 414 | "FILE *", |
| 415 | "findtrail(void)", |
| 416 | "{ FILE *fd;", |
| 417 | " char fnm[512], *q;", |
| 418 | " char MyFile[512];", /* avoid using a non-writable string */ |
| 419 | " char MySuffix[16];", |
| 420 | " int try_core;", |
| 421 | " int candidate_files;", |
| 422 | "", |
| 423 | " if (trailfilename != NULL)", |
| 424 | " { fd = fopen(trailfilename, \"r\");", |
| 425 | " if (fd == NULL)", |
| 426 | " { printf(\"pan: cannot find %%s\\n\", trailfilename);", |
| 427 | " pan_exit(1);", |
| 428 | " } /* else */", |
| 429 | " goto success;", |
| 430 | " }", |
| 431 | "talk:", |
| 432 | " try_core = 1;", |
| 433 | " candidate_files = 0;", |
| 434 | " tprefix = \"trail\";", |
| 435 | " strcpy(MyFile, TrailFile);", |
| 436 | " do { /* see if there's more than one possible trailfile */", |
| 437 | " if (whichtrail)", |
| 438 | " { sprintf(fnm, \"%%s%%d.%%s\",", |
| 439 | " MyFile, whichtrail, tprefix);", |
| 440 | " fd = fopen(fnm, \"r\");", |
| 441 | " if (fd != NULL)", |
| 442 | " { candidate_files++;", |
| 443 | " if (verbose==100)", |
| 444 | " printf(\"trail%%d: %%s\\n\",", |
| 445 | " candidate_files, fnm);", |
| 446 | " fclose(fd);", |
| 447 | " }", |
| 448 | " if ((q = strchr(MyFile, \'.\')) != NULL)", |
| 449 | " { *q = \'\\0\';", /* e.g., strip .pml */ |
| 450 | " sprintf(fnm, \"%%s%%d.%%s\",", |
| 451 | " MyFile, whichtrail, tprefix);", |
| 452 | " *q = \'.\';", |
| 453 | " fd = fopen(fnm, \"r\");", |
| 454 | " if (fd != NULL)", |
| 455 | " { candidate_files++;", |
| 456 | " if (verbose==100)", |
| 457 | " printf(\"trail%%d: %%s\\n\",", |
| 458 | " candidate_files, fnm);", |
| 459 | " fclose(fd);", |
| 460 | " } }", |
| 461 | " } else", |
| 462 | " { sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", |
| 463 | " fd = fopen(fnm, \"r\");", |
| 464 | " if (fd != NULL)", |
| 465 | " { candidate_files++;", |
| 466 | " if (verbose==100)", |
| 467 | " printf(\"trail%%d: %%s\\n\",", |
| 468 | " candidate_files, fnm);", |
| 469 | " fclose(fd);", |
| 470 | " }", |
| 471 | " if ((q = strchr(MyFile, \'.\')) != NULL)", |
| 472 | " { *q = \'\\0\';", /* e.g., strip .pml */ |
| 473 | " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", |
| 474 | " *q = \'.\';", |
| 475 | " fd = fopen(fnm, \"r\");", |
| 476 | " if (fd != NULL)", |
| 477 | " { candidate_files++;", |
| 478 | " if (verbose==100)", |
| 479 | " printf(\"trail%%d: %%s\\n\",", |
| 480 | " candidate_files, fnm);", |
| 481 | " fclose(fd);", |
| 482 | " } } }", |
| 483 | " tprefix = MySuffix;", |
| 484 | " sprintf(tprefix, \"cpu%%d_trail\", try_core++);", |
| 485 | " } while (try_core <= NCORE);", |
| 486 | "", |
| 487 | " if (candidate_files != 1)", |
| 488 | " { if (verbose != 100)", |
| 489 | " { printf(\"error: there are %%d trail files:\\n\",", |
| 490 | " candidate_files);", |
| 491 | " verbose = 100;", |
| 492 | " goto talk;", |
| 493 | " } else", |
| 494 | " { printf(\"pan: rm or mv all except one\\n\");", |
| 495 | " exit(1);", |
| 496 | " } }", |
| 497 | |
| 498 | " try_core = 1;", |
| 499 | " strcpy(MyFile, TrailFile); /* restore */", |
| 500 | " tprefix = \"trail\";", |
| 501 | "try_again:", |
| 502 | " if (whichtrail)", |
| 503 | " { sprintf(fnm, \"%%s%%d.%%s\", MyFile, whichtrail, tprefix);", |
| 504 | " fd = fopen(fnm, \"r\");", |
| 505 | " if (fd == NULL && (q = strchr(MyFile, \'.\')))", |
| 506 | " { *q = \'\\0\';", /* e.g., strip .pml on original file */ |
| 507 | " sprintf(fnm, \"%%s%%d.%%s\",", |
| 508 | " MyFile, whichtrail, tprefix);", |
| 509 | " *q = \'.\';", |
| 510 | " fd = fopen(fnm, \"r\");", |
| 511 | " }", |
| 512 | " } else", |
| 513 | " { sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", |
| 514 | " fd = fopen(fnm, \"r\");", |
| 515 | " if (fd == NULL && (q = strchr(MyFile, \'.\')))", |
| 516 | " { *q = \'\\0\';", /* e.g., strip .pml on original file */ |
| 517 | " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", |
| 518 | " *q = \'.\';", |
| 519 | " fd = fopen(fnm, \"r\");", |
| 520 | " } }", |
| 521 | " if (fd == NULL)", |
| 522 | " { if (try_core < NCORE)", |
| 523 | " { tprefix = MySuffix;", |
| 524 | " sprintf(tprefix, \"cpu%%d_trail\", try_core++);", |
| 525 | " goto try_again;", |
| 526 | " }", |
| 527 | " printf(\"pan: cannot find trailfile %%s\\n\", fnm);", |
| 528 | " pan_exit(1);", |
| 529 | " }", |
| 530 | "success:", |
| 531 | "#if NCORE>1 && defined(SEP_STATE)", |
| 532 | " { void set_root(void); /* for partial traces from local root */", |
| 533 | " set_root();", |
| 534 | " }", |
| 535 | "#endif", |
| 536 | " return fd;", |
| 537 | "}", |
| 538 | "", |
| 539 | "uchar do_transit(Trans *, short);", |
| 540 | "", |
| 541 | "void", |
| 542 | "getrail(void)", |
| 543 | "{ FILE *fd;", |
| 544 | " char *q;", |
| 545 | " int i, t_id, lastnever=-1; short II;", |
| 546 | " Trans *t;", |
| 547 | " P0 *z;", |
| 548 | "", |
| 549 | " fd = findtrail(); /* exits if unsuccessful */", |
| 550 | " while (fscanf(fd, \"%%ld:%%d:%%d\\n\", &depth, &i, &t_id) == 3)", |
| 551 | " { if (depth == -1)", |
| 552 | " printf(\"<<<<<START OF CYCLE>>>>>\\n\");", |
| 553 | " if (depth < 0)", |
| 554 | " continue;", |
| 555 | " if (i > now._nr_pr)", |
| 556 | " { printf(\"pan: Error, proc %%d invalid pid \", i);", |
| 557 | " printf(\"transition %%d\\n\", t_id);", |
| 558 | " break;", |
| 559 | " }", |
| 560 | " II = i;", |
| 561 | " z = (P0 *)pptr(II);", |
| 562 | " for (t = trans[z->_t][z->_p]; t; t = t->nxt)", |
| 563 | " if (t->t_id == (T_ID) t_id)", |
| 564 | " break;", |
| 565 | " if (!t)", |
| 566 | " { for (i = 0; i < NrStates[z->_t]; i++)", |
| 567 | " { t = trans[z->_t][i];", |
| 568 | " if (t && t->t_id == (T_ID) t_id)", |
| 569 | " { printf(\"\\tRecovered at state %%d\\n\", i);", |
| 570 | " z->_p = i;", |
| 571 | " goto recovered;", |
| 572 | " } }", |
| 573 | " printf(\"pan: Error, proc %%d type %%d state %%d: \",", |
| 574 | " II, z->_t, z->_p);", |
| 575 | " printf(\"transition %%d not found\\n\", t_id);", |
| 576 | " printf(\"pan: list of possible transitions in this process:\\n\");", |
| 577 | " if (z->_t >= 0 && z->_t <= _NP_)", |
| 578 | " for (t = trans[z->_t][z->_p]; t; t = t->nxt)", |
| 579 | " printf(\" t_id %%d -- case %%d, [%%s]\\n\",", |
| 580 | " t->t_id, t->forw, t->tp);", |
| 581 | " break; /* pan_exit(1); */", |
| 582 | " }", |
| 583 | "recovered:", |
| 584 | " q = transmognify(t->tp);", |
| 585 | " if (gui) simvals[0] = \'\\0\';", |
| 586 | |
| 587 | " this = pptr(II);", |
| 588 | " trpt->tau |= 1;", /* timeout always possible */ |
| 589 | " if (!do_transit(t, II))", |
| 590 | " { if (onlyproc >= 0 && II != onlyproc)", |
| 591 | " goto moveon;", |
| 592 | " printf(\"pan: error, next transition UNEXECUTABLE on replay\\n\");", |
| 593 | " printf(\" most likely causes: missing c_track statements\\n\");", |
| 594 | " printf(\" or illegal side-effects in c_expr statements\\n\");", |
| 595 | " }", |
| 596 | |
| 597 | " if (onlyproc >= 0 && II != onlyproc)", |
| 598 | " goto moveon;", |
| 599 | |
| 600 | " if (verbose)", |
| 601 | " { printf(\"%%3ld: proc %%2d (%%s) \", depth, II, procname[z->_t]);", |
| 602 | |
| 603 | " for (i = 0; src_all[i].src; i++)", |
| 604 | " if (src_all[i].tp == (int) z->_t)", |
| 605 | " { printf(\" line %%3d \\\"%%s\\\" \",", |
| 606 | " src_all[i].src[z->_p], PanSource);", |
| 607 | " break;", |
| 608 | " }", |
| 609 | |
| 610 | " printf(\"(state %%d) trans {%%d,%%d} [%%s]\\n\",", |
| 611 | " z->_p, t_id, t->forw, q?q:\"\");", |
| 612 | |
| 613 | " c_globals();", |
| 614 | " for (i = 0; i < now._nr_pr; i++)", |
| 615 | " { c_locals(i, ((P0 *)pptr(i))->_t);", |
| 616 | " }", |
| 617 | " } else", |
| 618 | " if (strcmp(procname[z->_t], \":never:\") == 0)", |
| 619 | " { if (lastnever != (int) z->_p)", |
| 620 | " { for (i = 0; src_all[i].src; i++)", |
| 621 | " if (src_all[i].tp == (int) z->_t)", |
| 622 | " { printf(\"MSC: ~G %%d\\n\",", |
| 623 | " src_all[i].src[z->_p]);", |
| 624 | " break;", |
| 625 | " }", |
| 626 | " if (!src_all[i].src)", |
| 627 | " printf(\"MSC: ~R %%d\\n\", z->_p);", |
| 628 | " }", |
| 629 | " lastnever = z->_p;", |
| 630 | " goto sameas;", |
| 631 | " } else", |
| 632 | " if (strcmp(procname[z->_t], \":np_:\") != 0)", |
| 633 | " {", |
| 634 | "sameas: if (no_rck) goto moveon;", |
| 635 | " if (coltrace)", |
| 636 | " { printf(\"%%ld: \", depth);", |
| 637 | " for (i = 0; i < II; i++)", |
| 638 | " printf(\"\\t\\t\");", |
| 639 | " printf(\"%%s(%%d):\", procname[z->_t], II);", |
| 640 | " printf(\"[%%s]\\n\", q?q:\"\");", |
| 641 | " } else if (!silent)", |
| 642 | " { if (strlen(simvals) > 0) {", |
| 643 | " printf(\"%%3ld: proc %%2d (%%s)\", ", |
| 644 | " depth, II, procname[z->_t]);", |
| 645 | " for (i = 0; src_all[i].src; i++)", |
| 646 | " if (src_all[i].tp == (int) z->_t)", |
| 647 | " { printf(\" line %%3d \\\"%%s\\\" \",", |
| 648 | " src_all[i].src[z->_p], PanSource);", |
| 649 | " break;", |
| 650 | " }", |
| 651 | " printf(\"(state %%d)\t[values: %%s]\\n\", z->_p, simvals);", |
| 652 | " }", |
| 653 | " printf(\"%%3ld: proc %%2d (%%s)\", ", |
| 654 | " depth, II, procname[z->_t]);", |
| 655 | " for (i = 0; src_all[i].src; i++)", |
| 656 | " if (src_all[i].tp == (int) z->_t)", |
| 657 | " { printf(\" line %%3d \\\"%%s\\\" \",", |
| 658 | " src_all[i].src[z->_p], PanSource);", |
| 659 | " break;", |
| 660 | " }", |
| 661 | " printf(\"(state %%d)\t[%%s]\\n\", z->_p, q?q:\"\");", |
| 662 | " /* printf(\"\\n\"); */", |
| 663 | " } }", |
| 664 | "moveon: z->_p = t->st;", |
| 665 | " }", |
| 666 | " wrap_trail();", |
| 667 | "}", |
| 668 | "#endif", |
| 669 | "int", |
| 670 | "f_pid(int pt)", |
| 671 | "{ int i;", |
| 672 | " P0 *z;", |
| 673 | " for (i = 0; i < now._nr_pr; i++)", |
| 674 | " { z = (P0 *)pptr(i);", |
| 675 | " if (z->_t == (unsigned) pt)", |
| 676 | " return BASE+z->_pid;", |
| 677 | " }", |
| 678 | " return -1;", |
| 679 | "}", |
| 680 | "#ifdef VERI", |
| 681 | "void check_claim(int);", |
| 682 | "#endif", |
| 683 | "", |
| 684 | "#if !defined(HASH64) && !defined(HASH32)", |
| 685 | " #define HASH32", |
| 686 | "#endif", |
| 687 | "#if defined(HASH32) && defined(SAFETY) && !defined(SFH) && !defined(SPACE)", |
| 688 | " #define SFH", |
| 689 | "#endif", |
| 690 | "#if defined(SFH) && (defined(BITSTATE) || defined(COLLAPSE) || defined(HC) || defined(HASH64))", |
| 691 | " #undef SFH", /* need 2 hash fcts, for which Jenkins is best */ |
| 692 | "#endif", /* or a 64 bit hash, which we dont have for SFH */ |
| 693 | "#if defined(SFH) && !defined(NOCOMP)", |
| 694 | " #define NOCOMP /* go for speed */", |
| 695 | "#endif", |
| 696 | "#if NCORE>1 && !defined(GLOB_HEAP)", |
| 697 | " #define SEP_HEAP /* version 5.1.2 */", |
| 698 | "#endif", |
| 699 | "", |
| 700 | "#ifdef BITSTATE", |
| 701 | #ifndef POWOW |
| 702 | "int", |
| 703 | "bstore_mod(char *v, int n) /* hasharray size not a power of two */", |
| 704 | "{ unsigned long x, y;", |
| 705 | " unsigned int i = 1;", |
| 706 | "", |
| 707 | " d_hash((uchar *) v, n); /* sets j3, j4, K1, K2 */", |
| 708 | " x = K1; y = j3;", /* was K2 before 5.1.1 */ |
| 709 | " for (;;)", |
| 710 | " { if (!(SS[x%%udmem]&(1<<y))) break;", /* take the hit in speed */ |
| 711 | " if (i == hfns) {", |
| 712 | "#ifdef DEBUG", |
| 713 | " printf(\"Old bitstate\\n\");", |
| 714 | "#endif", |
| 715 | " return 1;", |
| 716 | " }", |
| 717 | " x = (x + K2 + i);", /* no mask, using mod - was K1 before 5.1.1 */ |
| 718 | " y = (y + j4) & 7;", |
| 719 | " i++;", |
| 720 | " }", |
| 721 | "#ifdef RANDSTOR", |
| 722 | " if (rand()%%100 > RANDSTOR) return 0;", |
| 723 | "#endif", |
| 724 | " for (;;)", |
| 725 | " { SS[x%%udmem] |= (1<<y);", |
| 726 | " if (i == hfns) break;", /* done */ |
| 727 | " x = (x + K2 + i);", /* no mask - was K1 before 5.1.1 */ |
| 728 | " y = (y + j4) & 7;", |
| 729 | " i++;", |
| 730 | " }", |
| 731 | "#ifdef DEBUG", |
| 732 | " printf(\"New bitstate\\n\");", |
| 733 | "#endif", |
| 734 | " if (now._a_t&1)", |
| 735 | " { nShadow++;", |
| 736 | " }", |
| 737 | " return 0;", |
| 738 | "}", |
| 739 | #endif |
| 740 | "int", |
| 741 | "bstore_reg(char *v, int n) /* extended hashing, Peter Dillinger, 2004 */", |
| 742 | "{ unsigned long x, y;", |
| 743 | " unsigned int i = 1;", |
| 744 | "", |
| 745 | " d_hash((uchar *) v, n); /* sets j1-j4 */", |
| 746 | " x = j2; y = j3;", |
| 747 | " for (;;)", |
| 748 | " { if (!(SS[x]&(1<<y))) break;", /* at least one bit not set */ |
| 749 | " if (i == hfns) {", |
| 750 | "#ifdef DEBUG", |
| 751 | " printf(\"Old bitstate\\n\");", |
| 752 | "#endif", |
| 753 | " return 1;", |
| 754 | " }", |
| 755 | " x = (x + j1 + i) & nmask;", |
| 756 | " y = (y + j4) & 7;", |
| 757 | " i++;", |
| 758 | " }", |
| 759 | "#ifdef RANDSTOR", |
| 760 | " if (rand()%%100 > RANDSTOR) return 0;", |
| 761 | "#endif", |
| 762 | " for (;;)", |
| 763 | " { SS[x] |= (1<<y);", |
| 764 | " if (i == hfns) break;", /* done */ |
| 765 | " x = (x + j1 + i) & nmask;", |
| 766 | " y = (y + j4) & 7;", |
| 767 | " i++;", |
| 768 | " }", |
| 769 | "#ifdef DEBUG", |
| 770 | " printf(\"New bitstate\\n\");", |
| 771 | "#endif", |
| 772 | " if (now._a_t&1)", |
| 773 | " { nShadow++;", |
| 774 | " }", |
| 775 | " return 0;", |
| 776 | "}", |
| 777 | "#endif", /* BITSTATE */ |
| 778 | "unsigned long TMODE = 0666; /* file permission bits for trail files */", |
| 779 | "", |
| 780 | "int trcnt=1;", |
| 781 | "char snap[64], fnm[512];", |
| 782 | "", |
| 783 | "int", |
| 784 | "make_trail(void)", |
| 785 | "{ int fd;", |
| 786 | " char *q;", |
| 787 | " char MyFile[512];", |
| 788 | " int w_flags = O_CREAT|O_WRONLY|O_TRUNC;", |
| 789 | "", |
| 790 | " if (exclusive == 1 && iterative == 0)", |
| 791 | " { w_flags |= O_EXCL;", |
| 792 | " }", |
| 793 | "", |
| 794 | " q = strrchr(TrailFile, \'/\');", |
| 795 | " if (q == NULL) q = TrailFile; else q++;", |
| 796 | " strcpy(MyFile, q); /* TrailFile is not a writable string */", |
| 797 | "", |
| 798 | " if (iterative == 0 && Nr_Trails++ > 0)", |
| 799 | " { sprintf(fnm, \"%%s%%d.%%s\",", |
| 800 | " MyFile, Nr_Trails-1, tprefix);", |
| 801 | " } else", |
| 802 | " {", |
| 803 | "#ifdef PUTPID", |
| 804 | " sprintf(fnm, \"%%s%%d.%%s\", MyFile, getpid(), tprefix);", |
| 805 | "#else", |
| 806 | " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", |
| 807 | "#endif", |
| 808 | " }", |
| 809 | #if 1 |
| 810 | " if ((fd = open(fnm, w_flags, TMODE)) < 0)", |
| 811 | #else |
| 812 | " if ((fd = creat(fnm, TMODE)) < 0)", |
| 813 | #endif |
| 814 | " { if ((q = strchr(MyFile, \'.\')))", |
| 815 | " { *q = \'\\0\';", /* strip .pml */ |
| 816 | " if (iterative == 0 && Nr_Trails-1 > 0)", |
| 817 | " sprintf(fnm, \"%%s%%d.%%s\",", |
| 818 | " MyFile, Nr_Trails-1, tprefix);", |
| 819 | " else", |
| 820 | " sprintf(fnm, \"%%s.%%s\", MyFile, tprefix);", |
| 821 | " *q = \'.\';", |
| 822 | #if 1 |
| 823 | " fd = open(fnm, w_flags, TMODE);", |
| 824 | #else |
| 825 | " fd = creat(fnm, TMODE);", |
| 826 | #endif |
| 827 | " } }", |
| 828 | " if (fd < 0)", |
| 829 | " { printf(\"pan: cannot create %%s\\n\", fnm);", |
| 830 | " perror(\"cause\");", |
| 831 | " } else", |
| 832 | " {", |
| 833 | "#if NCORE>1 && (defined(SEP_STATE) || !defined(FULL_TRAIL))", |
| 834 | " void write_root(void); ", |
| 835 | " write_root();", |
| 836 | "#else", |
| 837 | " printf(\"pan: wrote %%s\\n\", fnm);", |
| 838 | "#endif", |
| 839 | " }", |
| 840 | " return fd;", |
| 841 | "}", |
| 842 | "", |
| 843 | "#ifndef FREQ", |
| 844 | "#define FREQ (1000000)", |
| 845 | "#endif", |
| 846 | 0 |
| 847 | }; |
| 848 | |
| 849 | static char *Code2b[] = { /* breadth-first search option */ |
| 850 | "#ifdef BFS", |
| 851 | "#define Q_PROVISO", |
| 852 | "#ifndef INLINE_REV", |
| 853 | "#define INLINE_REV", |
| 854 | "#endif", |
| 855 | "", |
| 856 | "typedef struct SV_Hold {", |
| 857 | " State *sv;", |
| 858 | " int sz;", |
| 859 | " struct SV_Hold *nxt;", |
| 860 | "} SV_Hold;", |
| 861 | "", |
| 862 | "typedef struct EV_Hold {", |
| 863 | " char *sv;", /* Mask */ |
| 864 | " int sz;", /* vsize */ |
| 865 | " int nrpr;", |
| 866 | " int nrqs;", |
| 867 | " char *po;", |
| 868 | " char *qo;", |
| 869 | " char *ps, *qs;", |
| 870 | " struct EV_Hold *nxt;", |
| 871 | "} EV_Hold;", |
| 872 | "", |
| 873 | "typedef struct BFS_Trail {", |
| 874 | " Trail *frame;", |
| 875 | " SV_Hold *onow;", |
| 876 | " EV_Hold *omask;", |
| 877 | "#ifdef Q_PROVISO", |
| 878 | " struct H_el *lstate;", |
| 879 | "#endif", |
| 880 | " short boq;", |
| 881 | " struct BFS_Trail *nxt;", |
| 882 | "} BFS_Trail;", |
| 883 | "", |
| 884 | "BFS_Trail *bfs_trail, *bfs_bot, *bfs_free;", |
| 885 | "", |
| 886 | "SV_Hold *svhold, *svfree;", |
| 887 | "", |
| 888 | "#ifdef BFS_DISK", |
| 889 | "#ifndef BFS_LIMIT", |
| 890 | " #define BFS_LIMIT 100000", |
| 891 | "#endif", |
| 892 | "#ifndef BFS_DSK_LIMIT", |
| 893 | " #define BFS_DSK_LIMIT 1000000", |
| 894 | "#endif", |
| 895 | |
| 896 | "#if defined(WIN32) || defined(WIN64)", |
| 897 | " #define RFLAGS (O_RDONLY|O_BINARY)", |
| 898 | " #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC|O_BINARY)", |
| 899 | "#else", |
| 900 | " #define RFLAGS (O_RDONLY)", |
| 901 | " #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC)", |
| 902 | "#endif", |
| 903 | |
| 904 | "long bfs_size_limit;", |
| 905 | "int bfs_dsk_write = -1;", |
| 906 | "int bfs_dsk_read = -1;", |
| 907 | "long bfs_dsk_writes, bfs_dsk_reads;", |
| 908 | "int bfs_dsk_seqno_w, bfs_dsk_seqno_r;", |
| 909 | "#endif", |
| 910 | "", |
| 911 | "uchar do_reverse(Trans *, short, uchar);", |
| 912 | "void snapshot(void);", |
| 913 | "", |
| 914 | "SV_Hold *", |
| 915 | "getsv(int n)", |
| 916 | "{ SV_Hold *h = (SV_Hold *) 0, *oh;", |
| 917 | "", |
| 918 | " oh = (SV_Hold *) 0;", |
| 919 | " for (h = svfree; h; oh = h, h = h->nxt)", |
| 920 | " { if (n == h->sz)", |
| 921 | " { if (!oh)", |
| 922 | " svfree = h->nxt;", |
| 923 | " else", |
| 924 | " oh->nxt = h->nxt;", |
| 925 | " h->nxt = (SV_Hold *) 0;", |
| 926 | " break;", |
| 927 | " }", |
| 928 | " if (n < h->sz)", |
| 929 | " { h = (SV_Hold *) 0;", |
| 930 | " break;", |
| 931 | " }", |
| 932 | " /* else continue */", |
| 933 | " }", |
| 934 | "", |
| 935 | " if (!h)", |
| 936 | " { h = (SV_Hold *) emalloc(sizeof(SV_Hold));", |
| 937 | " h->sz = n;", |
| 938 | "#ifdef BFS_DISK", |
| 939 | " if (bfs_size_limit >= BFS_LIMIT)", |
| 940 | " { h->sv = (State *) 0; /* means: read disk */", |
| 941 | " bfs_dsk_writes++; /* count */", |
| 942 | " if (bfs_dsk_write < 0 /* file descriptor */", |
| 943 | " || bfs_dsk_writes%%BFS_DSK_LIMIT == 0)", |
| 944 | " { char dsk_nm[32];", |
| 945 | " if (bfs_dsk_write >= 0)", |
| 946 | " { (void) close(bfs_dsk_write);", |
| 947 | " }", |
| 948 | " sprintf(dsk_nm, \"pan_bfs_%%d.tmp\", bfs_dsk_seqno_w++);", |
| 949 | " bfs_dsk_write = open(dsk_nm, WFLAGS, 0644);", |
| 950 | " if (bfs_dsk_write < 0)", |
| 951 | " { Uerror(\"could not create tmp disk file\");", |
| 952 | " }", |
| 953 | " printf(\"pan: created disk file %%s\\n\", dsk_nm);", |
| 954 | " }", |
| 955 | " if (write(bfs_dsk_write, (char *) &now, n) != n)", |
| 956 | " { Uerror(\"aborting -- disk write failed (disk full?)\");", |
| 957 | " }", |
| 958 | " return h; /* no memcpy */", |
| 959 | " }", /* else */ |
| 960 | " bfs_size_limit++;", |
| 961 | "#endif", |
| 962 | " h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n);", |
| 963 | " }", |
| 964 | "", |
| 965 | " memcpy((char *)h->sv, (char *)&now, n);", |
| 966 | " return h;", |
| 967 | "}", |
| 968 | "", |
| 969 | "EV_Hold *", |
| 970 | "getsv_mask(int n)", |
| 971 | "{ EV_Hold *h;", |
| 972 | " static EV_Hold *kept = (EV_Hold *) 0;", |
| 973 | "", |
| 974 | " for (h = kept; h; h = h->nxt)", |
| 975 | " if (n == h->sz", |
| 976 | " && (memcmp((char *) Mask, (char *) h->sv, n) == 0)", |
| 977 | " && (now._nr_pr == h->nrpr)", |
| 978 | " && (now._nr_qs == h->nrqs)", |
| 979 | "#if VECTORSZ>32000", |
| 980 | " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(int)) == 0)", |
| 981 | " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(int)) == 0)", |
| 982 | "#else", |
| 983 | " && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(short)) == 0)", |
| 984 | " && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(short)) == 0)", |
| 985 | "#endif", |
| 986 | " && (memcmp((char *) proc_skip, (char *) h->ps, now._nr_pr * sizeof(uchar)) == 0)", |
| 987 | " && (memcmp((char *) q_skip, (char *) h->qs, now._nr_qs * sizeof(uchar)) == 0))", |
| 988 | " break;", |
| 989 | " if (!h)", |
| 990 | " { h = (EV_Hold *) emalloc(sizeof(EV_Hold));", |
| 991 | " h->sz = n;", |
| 992 | " h->nrpr = now._nr_pr;", |
| 993 | " h->nrqs = now._nr_qs;", |
| 994 | "", |
| 995 | " h->sv = (char *) emalloc(n * sizeof(char));", |
| 996 | " memcpy((char *) h->sv, (char *) Mask, n);", |
| 997 | "", |
| 998 | " if (now._nr_pr > 0)", |
| 999 | " { h->ps = (char *) emalloc(now._nr_pr * sizeof(int));", |
| 1000 | " memcpy((char *) h->ps, (char *) proc_skip, now._nr_pr * sizeof(uchar));", |
| 1001 | "#if VECTORSZ>32000", |
| 1002 | " h->po = (char *) emalloc(now._nr_pr * sizeof(int));", |
| 1003 | " memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(int));", |
| 1004 | "#else", |
| 1005 | " h->po = (char *) emalloc(now._nr_pr * sizeof(short));", |
| 1006 | " memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(short));", |
| 1007 | "#endif", |
| 1008 | " }", |
| 1009 | " if (now._nr_qs > 0)", |
| 1010 | " { h->qs = (char *) emalloc(now._nr_qs * sizeof(int));", |
| 1011 | " memcpy((char *) h->qs, (char *) q_skip, now._nr_qs * sizeof(uchar));", |
| 1012 | "#if VECTORSZ>32000", |
| 1013 | " h->qo = (char *) emalloc(now._nr_qs * sizeof(int));", |
| 1014 | " memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(int));", |
| 1015 | "#else", |
| 1016 | " h->qo = (char *) emalloc(now._nr_qs * sizeof(short));", |
| 1017 | " memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(short));", |
| 1018 | "#endif", |
| 1019 | " }", |
| 1020 | "", |
| 1021 | " h->nxt = kept;", |
| 1022 | " kept = h;", |
| 1023 | " }", |
| 1024 | " return h;", |
| 1025 | "}", |
| 1026 | "", |
| 1027 | "void", |
| 1028 | "freesv(SV_Hold *p)", |
| 1029 | "{ SV_Hold *h, *oh;", |
| 1030 | "", |
| 1031 | " oh = (SV_Hold *) 0;", |
| 1032 | " for (h = svfree; h; oh = h, h = h->nxt)", |
| 1033 | " if (h->sz >= p->sz)", |
| 1034 | " break;", |
| 1035 | "", |
| 1036 | " if (!oh)", |
| 1037 | " { p->nxt = svfree;", |
| 1038 | " svfree = p;", |
| 1039 | " } else", |
| 1040 | " { p->nxt = h;", |
| 1041 | " oh->nxt = p;", |
| 1042 | " }", |
| 1043 | "}", |
| 1044 | "", |
| 1045 | "BFS_Trail *", |
| 1046 | "get_bfs_frame(void)", |
| 1047 | "{ BFS_Trail *t;", |
| 1048 | "", |
| 1049 | " if (bfs_free)", |
| 1050 | " { t = bfs_free;", |
| 1051 | " bfs_free = bfs_free->nxt;", |
| 1052 | " t->nxt = (BFS_Trail *) 0;", |
| 1053 | " } else", |
| 1054 | " { t = (BFS_Trail *) emalloc(sizeof(BFS_Trail));", |
| 1055 | " }", |
| 1056 | " t->frame = (Trail *) emalloc(sizeof(Trail));", /* always new */ |
| 1057 | " return t;", |
| 1058 | "}", |
| 1059 | "", |
| 1060 | "void", |
| 1061 | "push_bfs(Trail *f, int d)", |
| 1062 | "{ BFS_Trail *t;", |
| 1063 | "", |
| 1064 | " t = get_bfs_frame();", |
| 1065 | " memcpy((char *)t->frame, (char *)f, sizeof(Trail));", |
| 1066 | " t->frame->o_tt = d; /* depth */", |
| 1067 | "", |
| 1068 | " t->boq = boq;", |
| 1069 | " t->onow = getsv(vsize);", |
| 1070 | " t->omask = getsv_mask(vsize);", |
| 1071 | "#if defined(FULLSTACK) && defined(Q_PROVISO)", |
| 1072 | " t->lstate = Lstate;", |
| 1073 | "#endif", |
| 1074 | " if (!bfs_bot)", |
| 1075 | " { bfs_bot = bfs_trail = t;", |
| 1076 | " } else", |
| 1077 | " { bfs_bot->nxt = t;", |
| 1078 | " bfs_bot = t;", |
| 1079 | " }", |
| 1080 | "#ifdef CHECK", |
| 1081 | " printf(\"PUSH %%u (%%d)\\n\", t->frame, d);", |
| 1082 | "#endif", |
| 1083 | "}", |
| 1084 | "", |
| 1085 | "Trail *", |
| 1086 | "pop_bfs(void)", |
| 1087 | "{ BFS_Trail *t;", |
| 1088 | "", |
| 1089 | " if (!bfs_trail)", |
| 1090 | " return (Trail *) 0;", |
| 1091 | "", |
| 1092 | " t = bfs_trail;", |
| 1093 | " bfs_trail = t->nxt;", |
| 1094 | " if (!bfs_trail)", |
| 1095 | " bfs_bot = (BFS_Trail *) 0;", |
| 1096 | "#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)", |
| 1097 | " if (t->lstate) t->lstate->tagged = 0;", |
| 1098 | "#endif", |
| 1099 | "", |
| 1100 | " t->nxt = bfs_free;", |
| 1101 | " bfs_free = t;", |
| 1102 | "", |
| 1103 | " vsize = t->onow->sz;", |
| 1104 | " boq = t->boq;", |
| 1105 | "#ifdef BFS_DISK", |
| 1106 | " if (t->onow->sv == (State *) 0)", |
| 1107 | " { char dsk_nm[32];", |
| 1108 | " bfs_dsk_reads++; /* count */", |
| 1109 | " if (bfs_dsk_read >= 0 /* file descriptor */", |
| 1110 | " && bfs_dsk_reads%%BFS_DSK_LIMIT == 0)", |
| 1111 | " { (void) close(bfs_dsk_read);", |
| 1112 | " sprintf(dsk_nm, \"pan_bfs_%%d.tmp\", bfs_dsk_seqno_r-1);", |
| 1113 | " (void) unlink(dsk_nm);", |
| 1114 | " bfs_dsk_read = -1;", |
| 1115 | " }", |
| 1116 | " if (bfs_dsk_read < 0)", |
| 1117 | " { sprintf(dsk_nm, \"pan_bfs_%%d.tmp\", bfs_dsk_seqno_r++);", |
| 1118 | " bfs_dsk_read = open(dsk_nm, RFLAGS);", |
| 1119 | " if (bfs_dsk_read < 0)", |
| 1120 | " { Uerror(\"could not open temp disk file\");", |
| 1121 | " } }", |
| 1122 | " if (read(bfs_dsk_read, (char *) &now, vsize) != vsize)", |
| 1123 | " { Uerror(\"bad bfs disk file read\");", |
| 1124 | " }", |
| 1125 | "#ifndef NOVSZ", |
| 1126 | " if (now._vsz != vsize)", |
| 1127 | " { Uerror(\"disk read vsz mismatch\");", |
| 1128 | " }", |
| 1129 | "#endif", |
| 1130 | " } else", |
| 1131 | "#endif", |
| 1132 | " memcpy((uchar *) &now, (uchar *) t->onow->sv, vsize);", |
| 1133 | " memcpy((uchar *) Mask, (uchar *) t->omask->sv, vsize);", |
| 1134 | |
| 1135 | " if (now._nr_pr > 0)", |
| 1136 | "#if VECTORSZ>32000", |
| 1137 | " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(int));", |
| 1138 | "#else", |
| 1139 | " { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(short));", |
| 1140 | "#endif", |
| 1141 | " memcpy((char *)proc_skip, (char *)t->omask->ps, now._nr_pr * sizeof(uchar));", |
| 1142 | " }", |
| 1143 | " if (now._nr_qs > 0)", |
| 1144 | "#if VECTORSZ>32000", |
| 1145 | " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(int));", |
| 1146 | "#else", |
| 1147 | " { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(short));", |
| 1148 | "#endif", |
| 1149 | " memcpy((uchar *)q_skip, (uchar *)t->omask->qs, now._nr_qs * sizeof(uchar));", |
| 1150 | " }", |
| 1151 | |
| 1152 | "#ifdef BFS_DISK", |
| 1153 | " if (t->onow->sv != (State *) 0)", |
| 1154 | "#endif", |
| 1155 | " freesv(t->onow); /* omask not freed */", |
| 1156 | "#ifdef CHECK", |
| 1157 | " printf(\"POP %%u (%%d)\\n\", t->frame, t->frame->o_tt);", |
| 1158 | "#endif", |
| 1159 | " return t->frame;", |
| 1160 | "}", |
| 1161 | "", |
| 1162 | "void", |
| 1163 | "store_state(Trail *ntrpt, int shortcut, short oboq)", |
| 1164 | "{", |
| 1165 | "#ifdef VERI", |
| 1166 | " Trans *t2 = (Trans *) 0;", |
| 1167 | " uchar ot; int tt, E_state;", |
| 1168 | " uchar o_opm = trpt->o_pm, *othis = this;", |
| 1169 | "", |
| 1170 | " if (shortcut)", |
| 1171 | " {", |
| 1172 | "#ifdef VERBOSE", |
| 1173 | " printf(\"claim: shortcut\\n\");", |
| 1174 | "#endif", |
| 1175 | " goto store_it; /* no claim move */", |
| 1176 | " }", |
| 1177 | "", |
| 1178 | " this = (((uchar *)&now)+proc_offset[0]); /* 0 = never claim */", |
| 1179 | " trpt->o_pm = 0;", /* to interpret else in never claim */ |
| 1180 | "", |
| 1181 | " tt = (int) ((P0 *)this)->_p;", |
| 1182 | " ot = (uchar) ((P0 *)this)->_t;", |
| 1183 | "", |
| 1184 | "#ifdef HAS_UNLESS", |
| 1185 | " E_state = 0;", |
| 1186 | "#endif", |
| 1187 | " for (t2 = trans[ot][tt]; t2; t2 = t2?t2->nxt:(Trans *)0)", |
| 1188 | " {", |
| 1189 | "#ifdef HAS_UNLESS", |
| 1190 | " if (E_state > 0", |
| 1191 | " && E_state != t2->e_trans)", |
| 1192 | " break;", |
| 1193 | "#endif", |
| 1194 | " if (do_transit(t2, 0))", |
| 1195 | " {", |
| 1196 | "#ifdef VERBOSE", |
| 1197 | " if (!reached[ot][t2->st])", |
| 1198 | " printf(\"depth: %%d -- claim move from %%d -> %%d\\n\",", |
| 1199 | " trpt->o_tt, ((P0 *)this)->_p, t2->st);", |
| 1200 | "#endif", |
| 1201 | "#ifdef HAS_UNLESS", |
| 1202 | " E_state = t2->e_trans;", |
| 1203 | "#endif", |
| 1204 | " if (t2->st > 0)", |
| 1205 | " { ((P0 *)this)->_p = t2->st;", |
| 1206 | " reached[ot][t2->st] = 1;", |
| 1207 | "#ifndef NOCLAIM", |
| 1208 | " check_claim(t2->st);", |
| 1209 | "#endif", |
| 1210 | " }", |
| 1211 | " if (now._nr_pr == 0) /* claim terminated */", |
| 1212 | " uerror(\"end state in claim reached\");", |
| 1213 | "", |
| 1214 | "#ifdef PEG", |
| 1215 | " peg[t2->forw]++;", |
| 1216 | "#endif", |
| 1217 | " trpt->o_pm |= 1;", |
| 1218 | " if (t2->atom&2)", /* atomic in claim */ |
| 1219 | " Uerror(\"atomic in claim not supported in BFS mode\");", |
| 1220 | "store_it:", |
| 1221 | "", |
| 1222 | "#endif", /* VERI */ |
| 1223 | "", |
| 1224 | "#ifdef BITSTATE", |
| 1225 | " if (!bstore((char *)&now, vsize))", |
| 1226 | "#else", |
| 1227 | "#ifdef MA", |
| 1228 | " if (!gstore((char *)&now, vsize, 0))", |
| 1229 | "#else", |
| 1230 | " if (!hstore((char *)&now, vsize))", |
| 1231 | "#endif", |
| 1232 | "#endif", |
| 1233 | " { static long sdone = (long) 0; long ndone;", |
| 1234 | " nstates++;", |
| 1235 | "#ifndef NOREDUCE", |
| 1236 | " trpt->tau |= 64;", /* succ definitely outside stack */ |
| 1237 | "#endif", |
| 1238 | " ndone = (unsigned long) (nstates/((double) FREQ));", |
| 1239 | " if (ndone != sdone && mreached%%10 != 0)", |
| 1240 | " { snapshot();", |
| 1241 | " sdone = ndone;", |
| 1242 | "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", |
| 1243 | " if (nstates > ((double)(1<<(ssize+1))))", |
| 1244 | " { void resize_hashtable(void);", |
| 1245 | " resize_hashtable();", |
| 1246 | " }", |
| 1247 | "#endif", |
| 1248 | " }", |
| 1249 | "#if SYNC", |
| 1250 | " if (boq != -1)", |
| 1251 | " midrv++;", |
| 1252 | " else if (oboq != -1)", |
| 1253 | " { Trail *x;", |
| 1254 | " x = (Trail *) trpt->ostate; /* pre-rv state */", |
| 1255 | " if (x) x->o_pm |= 4; /* mark success */", |
| 1256 | " }", |
| 1257 | "#endif", |
| 1258 | " push_bfs(ntrpt, trpt->o_tt+1);", |
| 1259 | " } else", |
| 1260 | " { truncs++;", |
| 1261 | |
| 1262 | "#if !defined(NOREDUCE) && defined(FULLSTACK) && defined(Q_PROVISO)", |
| 1263 | "#if !defined(BITSTATE)", |
| 1264 | " if (Lstate && Lstate->tagged) trpt->tau |= 64;", |
| 1265 | "#else", |
| 1266 | " if (trpt->tau&32)", |
| 1267 | " { BFS_Trail *tprov;", |
| 1268 | " for (tprov = bfs_trail; tprov; tprov = tprov->nxt)", |
| 1269 | " if (tprov->onow->sv != (State *) 0", |
| 1270 | " && memcmp((uchar *)&now, (uchar *)tprov->onow->sv, vsize) == 0)", |
| 1271 | " { trpt->tau |= 64;", |
| 1272 | " break; /* state is in queue */", |
| 1273 | " } }", |
| 1274 | "#endif", |
| 1275 | "#endif", |
| 1276 | " }", |
| 1277 | "#ifdef VERI", |
| 1278 | " ((P0 *)this)->_p = tt; /* reset claim */", |
| 1279 | " if (t2)", |
| 1280 | " do_reverse(t2, 0, 0);", |
| 1281 | " else", |
| 1282 | " break;", |
| 1283 | " } }", |
| 1284 | " this = othis;", |
| 1285 | " trpt->o_pm = o_opm;", |
| 1286 | "#endif", |
| 1287 | "}", |
| 1288 | "", |
| 1289 | "Trail *ntrpt;", /* 4.2.8 */ |
| 1290 | "", |
| 1291 | "void", |
| 1292 | "bfs(void)", |
| 1293 | "{ Trans *t; Trail *otrpt, *x;", |
| 1294 | " uchar _n, _m, ot, nps = 0;", |
| 1295 | " int tt, E_state;", |
| 1296 | " short II, From = (short) (now._nr_pr-1), To = BASE;", |
| 1297 | " short oboq = boq;", |
| 1298 | "", |
| 1299 | " ntrpt = (Trail *) emalloc(sizeof(Trail));", |
| 1300 | " trpt->ostate = (struct H_el *) 0;", |
| 1301 | " trpt->tau = 0;", |
| 1302 | "", |
| 1303 | " trpt->o_tt = -1;", |
| 1304 | " store_state(ntrpt, 0, oboq); /* initial state */", |
| 1305 | "", |
| 1306 | " while ((otrpt = pop_bfs())) /* also restores now */", |
| 1307 | " { memcpy((char *) trpt, (char *) otrpt, sizeof(Trail));", |
| 1308 | "#if defined(C_States) && (HAS_TRACK==1)", |
| 1309 | " c_revert((uchar *) &(now.c_state[0]));", |
| 1310 | "#endif", |
| 1311 | " if (trpt->o_pm & 4)", |
| 1312 | " {", |
| 1313 | "#ifdef VERBOSE", |
| 1314 | " printf(\"Revisit of atomic not needed (%%d)\\n\",", |
| 1315 | " trpt->o_pm);", /* at least 1 rv succeeded */ |
| 1316 | "#endif", |
| 1317 | " continue;", |
| 1318 | " }", |
| 1319 | "#ifndef NOREDUCE", |
| 1320 | " nps = 0;", |
| 1321 | "#endif", |
| 1322 | " if (trpt->o_pm == 8)", |
| 1323 | " { revrv++;", |
| 1324 | " if (trpt->tau&8)", |
| 1325 | " {", |
| 1326 | "#ifdef VERBOSE", |
| 1327 | " printf(\"Break atomic (pm:%%d,tau:%%d)\\n\",", |
| 1328 | " trpt->o_pm, trpt->tau);", |
| 1329 | "#endif", |
| 1330 | " trpt->tau &= ~8;", |
| 1331 | " }", |
| 1332 | "#ifndef NOREDUCE", |
| 1333 | " else if (trpt->tau&32)", /* was a preselected move */ |
| 1334 | " {", |
| 1335 | "#ifdef VERBOSE", |
| 1336 | " printf(\"Void preselection (pm:%%d,tau:%%d)\\n\",", |
| 1337 | " trpt->o_pm, trpt->tau);", |
| 1338 | "#endif", |
| 1339 | " trpt->tau &= ~32;", |
| 1340 | " nps = 1; /* no preselection in repeat */", |
| 1341 | " }", |
| 1342 | "#endif", |
| 1343 | " }", |
| 1344 | " trpt->o_pm &= ~(4|8);", |
| 1345 | " if (trpt->o_tt > mreached)", |
| 1346 | " { mreached = trpt->o_tt;", |
| 1347 | " if (mreached%%10 == 0)", |
| 1348 | " { snapshot();", |
| 1349 | " } }", |
| 1350 | " depth = trpt->o_tt;", |
| 1351 | |
| 1352 | " if (depth >= maxdepth)", |
| 1353 | " {", |
| 1354 | "#if SYNC", |
| 1355 | " Trail *x;", |
| 1356 | " if (boq != -1)", |
| 1357 | " { x = (Trail *) trpt->ostate;", |
| 1358 | " if (x) x->o_pm |= 4; /* not failing */", |
| 1359 | " }", |
| 1360 | "#endif", |
| 1361 | " truncs++;", |
| 1362 | " if (!warned)", |
| 1363 | " { warned = 1;", |
| 1364 | " printf(\"error: max search depth too small\\n\");", |
| 1365 | " }", |
| 1366 | " if (bounded)", |
| 1367 | " uerror(\"depth limit reached\");", |
| 1368 | " continue;", |
| 1369 | " }", |
| 1370 | |
| 1371 | /* PO */ |
| 1372 | "#ifndef NOREDUCE", |
| 1373 | " if (boq == -1 && !(trpt->tau&8) && nps == 0)", |
| 1374 | " for (II = now._nr_pr-1; II >= BASE; II -= 1)", |
| 1375 | " {", |
| 1376 | "Pickup: this = pptr(II);", |
| 1377 | " tt = (int) ((P0 *)this)->_p;", |
| 1378 | " ot = (uchar) ((P0 *)this)->_t;", |
| 1379 | " if (trans[ot][tt]->atom & 8)", /* safe */ |
| 1380 | " { t = trans[ot][tt];", |
| 1381 | " if (t->qu[0] != 0)", |
| 1382 | " { Ccheck++;", |
| 1383 | " if (!q_cond(II, t))", |
| 1384 | " continue;", |
| 1385 | " Cholds++;", |
| 1386 | " }", |
| 1387 | " From = To = II;", |
| 1388 | " trpt->tau |= 32; /* preselect marker */", |
| 1389 | "#ifdef DEBUG", |
| 1390 | " printf(\"%%3d: proc %%d PreSelected (tau=%%d)\\n\", ", |
| 1391 | " depth, II, trpt->tau);", |
| 1392 | "#endif", |
| 1393 | " goto MainLoop;", |
| 1394 | " } }", |
| 1395 | " trpt->tau &= ~32;", /* not preselected */ |
| 1396 | "#endif", |
| 1397 | /* PO */ |
| 1398 | "Repeat:", |
| 1399 | " if (trpt->tau&8) /* atomic */", |
| 1400 | " { From = To = (short ) trpt->pr;", |
| 1401 | " nlinks++;", |
| 1402 | " } else", |
| 1403 | " { From = now._nr_pr-1;", |
| 1404 | " To = BASE;", |
| 1405 | " }", |
| 1406 | "MainLoop:", |
| 1407 | " _n = _m = 0;", |
| 1408 | " for (II = From; II >= To; II -= 1)", |
| 1409 | " {", |
| 1410 | " this = (((uchar *)&now)+proc_offset[II]);", |
| 1411 | " tt = (int) ((P0 *)this)->_p;", |
| 1412 | " ot = (uchar) ((P0 *)this)->_t;", |
| 1413 | "#if SYNC", |
| 1414 | " /* no rendezvous with same proc */", |
| 1415 | " if (boq != -1 && trpt->pr == II) continue;", |
| 1416 | "#endif", |
| 1417 | " ntrpt->pr = (uchar) II;", |
| 1418 | " ntrpt->st = tt; ", |
| 1419 | " trpt->o_pm &= ~1; /* no move yet */", |
| 1420 | "#ifdef EVENT_TRACE", |
| 1421 | " trpt->o_event = now._event;", |
| 1422 | "#endif", |
| 1423 | "#ifdef HAS_PROVIDED", |
| 1424 | " if (!provided(II, ot, tt, t)) continue;", |
| 1425 | "#endif", |
| 1426 | "#ifdef HAS_UNLESS", |
| 1427 | " E_state = 0;", |
| 1428 | "#endif", |
| 1429 | " for (t = trans[ot][tt]; t; t = t->nxt)", |
| 1430 | " {", |
| 1431 | "#ifdef HAS_UNLESS", |
| 1432 | " if (E_state > 0", |
| 1433 | " && E_state != t->e_trans)", |
| 1434 | " break;", |
| 1435 | "#endif", |
| 1436 | " ntrpt->o_t = t;", |
| 1437 | "", |
| 1438 | " oboq = boq;", |
| 1439 | "", |
| 1440 | " if (!(_m = do_transit(t, II)))", |
| 1441 | " continue;", |
| 1442 | "", |
| 1443 | " trpt->o_pm |= 1; /* we moved */", |
| 1444 | " (trpt+1)->o_m = _m; /* for unsend */", |
| 1445 | "#ifdef PEG", |
| 1446 | " peg[t->forw]++;", |
| 1447 | "#endif", |
| 1448 | "#ifdef CHECK", |
| 1449 | " printf(\"%%3d: proc %%d exec %%d, \",", |
| 1450 | " depth, II, t->forw);", |
| 1451 | " printf(\"%%d to %%d, %%s %%s %%s\",", |
| 1452 | " tt, t->st, t->tp,", |
| 1453 | " (t->atom&2)?\"atomic\":\"\",", |
| 1454 | " (boq != -1)?\"rendez-vous\":\"\");", |
| 1455 | "#ifdef HAS_UNLESS", |
| 1456 | " if (t->e_trans)", |
| 1457 | " printf(\" (escapes to state %%d)\", t->st);", |
| 1458 | "#endif", |
| 1459 | " printf(\" %%saccepting [tau=%%d]\\n\",", |
| 1460 | " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);", |
| 1461 | "#endif", |
| 1462 | "#ifdef HAS_UNLESS", |
| 1463 | " E_state = t->e_trans;", |
| 1464 | "#if SYNC>0", |
| 1465 | " if (t->e_trans > 0 && (boq != -1 /* || oboq != -1 */))", |
| 1466 | " { fprintf(efd, \"error:\tthe use of rendezvous stmnt in the escape clause\\n\");", |
| 1467 | " fprintf(efd, \"\tof an unless stmnt is not compatible with -DBFS\\n\");", |
| 1468 | " pan_exit(1);", |
| 1469 | " }", |
| 1470 | "#endif", |
| 1471 | "#endif", |
| 1472 | " if (t->st > 0) ((P0 *)this)->_p = t->st;", |
| 1473 | "", |
| 1474 | " /* ptr to pred: */ ntrpt->ostate = (struct H_el *) otrpt;", |
| 1475 | " ntrpt->st = tt;", |
| 1476 | " if (boq == -1 && (t->atom&2)) /* atomic */", |
| 1477 | " ntrpt->tau = 8; /* record for next move */", |
| 1478 | " else", |
| 1479 | " ntrpt->tau = 0;", |
| 1480 | "", |
| 1481 | " store_state(ntrpt, (boq != -1 || (t->atom&2)), oboq);", |
| 1482 | "#ifdef EVENT_TRACE", |
| 1483 | " now._event = trpt->o_event;", |
| 1484 | "#endif", |
| 1485 | "", |
| 1486 | " /* undo move and continue */", |
| 1487 | " trpt++; /* this is where ovals and ipt are set */", |
| 1488 | " do_reverse(t, II, _m); /* restore now. */", |
| 1489 | " trpt--;", |
| 1490 | "#ifdef CHECK", |
| 1491 | " #if NCORE>1", |
| 1492 | " enter_critical(GLOBAL_LOCK); /* in verbose mode only */", |
| 1493 | " printf(\"cpu%%d: \", core_id);", |
| 1494 | " #endif", |
| 1495 | |
| 1496 | " printf(\"%%3d: proc %%d \", depth, II);", |
| 1497 | " printf(\"reverses %%d, %%d to %%d,\",", |
| 1498 | " t->forw, tt, t->st);", |
| 1499 | " printf(\" %%s [abit=%%d,adepth=%%d,\",", |
| 1500 | " t->tp, now._a_t, A_depth);", |
| 1501 | " printf(\"tau=%%d,%%d]\\n\",", |
| 1502 | " trpt->tau, (trpt-1)->tau);", |
| 1503 | " #if NCORE>1", |
| 1504 | " leave_critical(GLOBAL_LOCK);", |
| 1505 | " #endif", |
| 1506 | "#endif", |
| 1507 | " reached[ot][t->st] = 1;", |
| 1508 | " reached[ot][tt] = 1;", |
| 1509 | "", |
| 1510 | " ((P0 *)this)->_p = tt;", |
| 1511 | " _n |= _m;", |
| 1512 | " } }", |
| 1513 | /* PO */ |
| 1514 | "#ifndef NOREDUCE", |
| 1515 | " /* preselected - no succ definitely outside stack */", |
| 1516 | " if ((trpt->tau&32) && !(trpt->tau&64))", |
| 1517 | " { From = now._nr_pr-1; To = BASE;", |
| 1518 | "#ifdef DEBUG", |
| 1519 | " cpu_printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", |
| 1520 | " depth, II+1, (int) _n, trpt->tau);", |
| 1521 | "#endif", |
| 1522 | " _n = 0; trpt->tau &= ~32;", |
| 1523 | " if (II >= BASE)", |
| 1524 | " goto Pickup;", |
| 1525 | " goto MainLoop;", |
| 1526 | " }", |
| 1527 | " trpt->tau &= ~(32|64);", |
| 1528 | "#endif", |
| 1529 | /* PO */ |
| 1530 | " if (_n != 0)", |
| 1531 | " continue;", |
| 1532 | "#ifdef DEBUG", |
| 1533 | " printf(\"%%3d: no move [II=%%d, tau=%%d, boq=%%d, _nr_pr=%%d]\\n\",", |
| 1534 | " depth, II, trpt->tau, boq, now._nr_pr);", |
| 1535 | "#endif", |
| 1536 | " if (boq != -1)", |
| 1537 | " { failedrv++;", |
| 1538 | " x = (Trail *) trpt->ostate; /* pre-rv state */", |
| 1539 | " if (!x) continue; /* root state */", |
| 1540 | " if ((x->tau&8) || (x->tau&32)) /* break atomic or preselect at parent */", |
| 1541 | " { x->o_pm |= 8; /* mark failure */", |
| 1542 | " this = (((uchar *)&now)+proc_offset[otrpt->pr]);", |
| 1543 | "#ifdef VERBOSE", |
| 1544 | " printf(\"\\treset state of %%d from %%d to %%d\\n\",", |
| 1545 | " otrpt->pr, ((P0 *)this)->_p, otrpt->st);", |
| 1546 | "#endif", |
| 1547 | " ((P0 *)this)->_p = otrpt->st;", |
| 1548 | " unsend(boq); /* retract rv offer */", |
| 1549 | " boq = -1;", |
| 1550 | |
| 1551 | " push_bfs(x, x->o_tt);", |
| 1552 | "#ifdef VERBOSE", |
| 1553 | " printf(\"failed rv, repush with %%d\\n\", x->o_pm);", |
| 1554 | "#endif", |
| 1555 | " }", |
| 1556 | "#ifdef VERBOSE", |
| 1557 | " else printf(\"failed rv, tau at parent: %%d\\n\", x->tau);", |
| 1558 | "#endif", |
| 1559 | " } else if (now._nr_pr > 0)", |
| 1560 | " {", |
| 1561 | " if ((trpt->tau&8)) /* atomic */", |
| 1562 | " { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */", |
| 1563 | "#ifdef DEBUG", |
| 1564 | " printf(\"%%3d: atomic step proc %%d blocks\\n\",", |
| 1565 | " depth, II+1);", |
| 1566 | "#endif", |
| 1567 | " goto Repeat;", |
| 1568 | " }", |
| 1569 | "", |
| 1570 | " if (!(trpt->tau&1)) /* didn't try timeout yet */", |
| 1571 | " { trpt->tau |= 1;", |
| 1572 | "#ifdef DEBUG", |
| 1573 | " printf(\"%%d: timeout\\n\", depth);", |
| 1574 | "#endif", |
| 1575 | " goto MainLoop;", |
| 1576 | " }", |
| 1577 | "#ifndef VERI", |
| 1578 | " if (!noends && !a_cycles && !endstate())", |
| 1579 | " uerror(\"invalid end state\");", |
| 1580 | "#endif", |
| 1581 | " } }", |
| 1582 | "}", |
| 1583 | "", |
| 1584 | "void", |
| 1585 | "putter(Trail *trpt, int fd)", |
| 1586 | "{ long j;", |
| 1587 | "", |
| 1588 | " if (!trpt) return;", |
| 1589 | "", |
| 1590 | " if (trpt != (Trail *) trpt->ostate)", |
| 1591 | " putter((Trail *) trpt->ostate, fd);", |
| 1592 | "", |
| 1593 | " if (trpt->o_t)", |
| 1594 | " { sprintf(snap, \"%%d:%%d:%%d\\n\",", |
| 1595 | " trcnt++, trpt->pr, trpt->o_t->t_id);", |
| 1596 | " j = strlen(snap);", |
| 1597 | " if (write(fd, snap, j) != j)", |
| 1598 | " { printf(\"pan: error writing %%s\\n\", fnm);", |
| 1599 | " pan_exit(1);", |
| 1600 | " } }", |
| 1601 | "}", |
| 1602 | "", |
| 1603 | "void", |
| 1604 | "nuerror(char *str)", |
| 1605 | "{ int fd = make_trail();", |
| 1606 | " int j;", |
| 1607 | "", |
| 1608 | " if (fd < 0) return;", |
| 1609 | "#ifdef VERI", |
| 1610 | " sprintf(snap, \"-2:%%d:-2\\n\", VERI);", |
| 1611 | " write(fd, snap, strlen(snap));", |
| 1612 | "#endif", |
| 1613 | "#ifdef MERGED", |
| 1614 | " sprintf(snap, \"-4:-4:-4\\n\");", |
| 1615 | " write(fd, snap, strlen(snap));", |
| 1616 | "#endif", |
| 1617 | " trcnt = 1;", |
| 1618 | " putter(trpt, fd);", |
| 1619 | " if (ntrpt->o_t)", /* 4.2.8 -- Alex example, missing last transition */ |
| 1620 | " { sprintf(snap, \"%%d:%%d:%%d\\n\",", |
| 1621 | " trcnt++, ntrpt->pr, ntrpt->o_t->t_id);", |
| 1622 | " j = strlen(snap);", |
| 1623 | " if (write(fd, snap, j) != j)", |
| 1624 | " { printf(\"pan: error writing %%s\\n\", fnm);", |
| 1625 | " pan_exit(1);", |
| 1626 | " } }", |
| 1627 | " close(fd);", |
| 1628 | " if (errors >= upto && upto != 0)", |
| 1629 | " { wrapup();", |
| 1630 | " }", |
| 1631 | "}", |
| 1632 | "#endif", /* BFS */ |
| 1633 | 0, |
| 1634 | }; |
| 1635 | |
| 1636 | static char *Code2d[] = { |
| 1637 | "clock_t start_time;", |
| 1638 | "#if NCORE>1", |
| 1639 | "clock_t crash_stamp;", |
| 1640 | "#endif", |
| 1641 | "#if !defined(WIN32) && !defined(WIN64)", |
| 1642 | "struct tms start_tm;", |
| 1643 | "#endif", |
| 1644 | "", |
| 1645 | "void", |
| 1646 | "start_timer(void)", |
| 1647 | "{", |
| 1648 | "#if defined(WIN32) || defined(WIN64)", |
| 1649 | " start_time = clock();", |
| 1650 | "#else", |
| 1651 | " start_time = times(&start_tm);", |
| 1652 | "#endif", |
| 1653 | "}", |
| 1654 | "", |
| 1655 | "void", |
| 1656 | "stop_timer(void)", |
| 1657 | "{ clock_t stop_time;", |
| 1658 | " double delta_time;", |
| 1659 | "#if !defined(WIN32) && !defined(WIN64)", |
| 1660 | " struct tms stop_tm;", |
| 1661 | " stop_time = times(&stop_tm);", |
| 1662 | " delta_time = ((double) (stop_time - start_time)) / ((double) sysconf(_SC_CLK_TCK));", |
| 1663 | "#else", |
| 1664 | " stop_time = clock();", |
| 1665 | " delta_time = ((double) (stop_time - start_time)) / ((double) CLOCKS_PER_SEC);", |
| 1666 | "#endif", |
| 1667 | " if (readtrail || delta_time < 0.00) return;", |
| 1668 | "#if NCORE>1", |
| 1669 | " if (core_id == 0 && nstates > (double) 0)", |
| 1670 | " { printf(\"\\ncpu%%d: elapsed time %%.3g seconds (%%g states visited)\\n\", core_id, delta_time, nstates);", |
| 1671 | " if (delta_time > 0.01)", |
| 1672 | " { printf(\"cpu%%d: rate %%g states/second\\n\", core_id, nstates/delta_time);", |
| 1673 | " }", |
| 1674 | " { void check_overkill(void);", |
| 1675 | " check_overkill();", |
| 1676 | " } }", |
| 1677 | "#else", |
| 1678 | " printf(\"\\npan: elapsed time %%.3g seconds\\n\", delta_time);", |
| 1679 | " if (delta_time > 0.01)", |
| 1680 | " { printf(\"pan: rate %%9.8g states/second\\n\", nstates/delta_time);", |
| 1681 | " if (verbose)", |
| 1682 | " { printf(\"pan: avg transition delay %%.5g usec\\n\",", |
| 1683 | " delta_time/(nstates+truncs));", |
| 1684 | " } }", |
| 1685 | "#endif", |
| 1686 | "}", |
| 1687 | "", |
| 1688 | "#if NCORE>1", |
| 1689 | "#ifdef T_ALERT", |
| 1690 | "double t_alerts[17];", |
| 1691 | "", |
| 1692 | "void", |
| 1693 | "crash_report(void)", |
| 1694 | "{ int i;", |
| 1695 | " printf(\"crash alert intervals:\\n\");", |
| 1696 | " for (i = 0; i < 17; i++)", |
| 1697 | " { printf(\"%%d\\t%%g\\n\", i, t_alerts[i]);", |
| 1698 | "} }", |
| 1699 | "#endif", |
| 1700 | "", |
| 1701 | "void", |
| 1702 | "crash_reset(void)", |
| 1703 | "{ /* false alarm */", |
| 1704 | " if (crash_stamp != (clock_t) 0)", |
| 1705 | " {", |
| 1706 | "#ifdef T_ALERT", |
| 1707 | " double delta_time;", |
| 1708 | " int i;", |
| 1709 | "#if defined(WIN32) || defined(WIN64)", |
| 1710 | " delta_time = ((double) (clock() - crash_stamp)) / ((double) CLOCKS_PER_SEC);", |
| 1711 | "#else", |
| 1712 | " delta_time = ((double) (times(&start_tm) - crash_stamp)) / ((double) sysconf(_SC_CLK_TCK));", |
| 1713 | "#endif", |
| 1714 | " for (i = 0; i < 16; i++)", |
| 1715 | " { if (delta_time <= (i*30))", |
| 1716 | " { t_alerts[i] = delta_time;", |
| 1717 | " break;", |
| 1718 | " } }", |
| 1719 | " if (i == 16) t_alerts[i] = delta_time;", |
| 1720 | "#endif", |
| 1721 | " if (verbose)", |
| 1722 | " printf(\"cpu%%d: crash alert off\\n\", core_id);", |
| 1723 | " }", |
| 1724 | " crash_stamp = (clock_t) 0;", |
| 1725 | "}", |
| 1726 | "", |
| 1727 | "int", |
| 1728 | "crash_test(double maxtime)", |
| 1729 | "{ double delta_time;", |
| 1730 | " if (crash_stamp == (clock_t) 0)", |
| 1731 | " { /* start timing */", |
| 1732 | "#if defined(WIN32) || defined(WIN64)", |
| 1733 | " crash_stamp = clock();", |
| 1734 | "#else", |
| 1735 | " crash_stamp = times(&start_tm);", |
| 1736 | "#endif", |
| 1737 | " if (verbose)", |
| 1738 | " { printf(\"cpu%%d: crash detection\\n\", core_id);", |
| 1739 | " }", |
| 1740 | " return 0;", |
| 1741 | " }", |
| 1742 | "#if defined(WIN32) || defined(WIN64)", |
| 1743 | " delta_time = ((double) (clock() - crash_stamp)) / ((double) CLOCKS_PER_SEC);", |
| 1744 | "#else", |
| 1745 | " delta_time = ((double) (times(&start_tm) - crash_stamp)) / ((double) sysconf(_SC_CLK_TCK));", |
| 1746 | "#endif", |
| 1747 | " return (delta_time >= maxtime);", |
| 1748 | "}", |
| 1749 | "#endif", |
| 1750 | "", |
| 1751 | "void", |
| 1752 | "do_the_search(void)", |
| 1753 | "{ int i;", |
| 1754 | " depth = mreached = 0;", |
| 1755 | " trpt = &trail[0];", |
| 1756 | "#ifdef VERI", |
| 1757 | " trpt->tau |= 4; /* the claim moves first */", |
| 1758 | "#endif", |
| 1759 | " for (i = 0; i < (int) now._nr_pr; i++)", |
| 1760 | " { P0 *ptr = (P0 *) pptr(i);", |
| 1761 | "#ifndef NP", |
| 1762 | " if (!(trpt->o_pm&2)", |
| 1763 | " && accpstate[ptr->_t][ptr->_p])", |
| 1764 | " { trpt->o_pm |= 2;", |
| 1765 | " }", |
| 1766 | "#else", |
| 1767 | " if (!(trpt->o_pm&4)", |
| 1768 | " && progstate[ptr->_t][ptr->_p])", |
| 1769 | " { trpt->o_pm |= 4;", |
| 1770 | " }", |
| 1771 | "#endif", |
| 1772 | " }", |
| 1773 | "#ifdef EVENT_TRACE", |
| 1774 | "#ifndef NP", |
| 1775 | " if (accpstate[EVENT_TRACE][now._event])", |
| 1776 | " { trpt->o_pm |= 2;", |
| 1777 | " }", |
| 1778 | "#else", |
| 1779 | " if (progstate[EVENT_TRACE][now._event])", |
| 1780 | " { trpt->o_pm |= 4;", |
| 1781 | " }", |
| 1782 | "#endif", |
| 1783 | "#endif", |
| 1784 | "#ifndef NOCOMP", |
| 1785 | " Mask[0] = Mask[1] = 1; /* _nr_pr, _nr_qs */", |
| 1786 | " if (!a_cycles)", |
| 1787 | " { i = &(now._a_t) - (uchar *) &now;", |
| 1788 | " Mask[i] = 1; /* _a_t */", |
| 1789 | " }", |
| 1790 | "#ifndef NOFAIR", |
| 1791 | " if (!fairness)", |
| 1792 | " { int j = 0;", |
| 1793 | " i = &(now._cnt[0]) - (uchar *) &now;", |
| 1794 | " while (j++ < NFAIR)", |
| 1795 | " Mask[i++] = 1; /* _cnt[] */", |
| 1796 | " }", |
| 1797 | "#endif", |
| 1798 | "#endif", |
| 1799 | "#ifndef NOFAIR", |
| 1800 | " if (fairness", |
| 1801 | " && (a_cycles && (trpt->o_pm&2)))", |
| 1802 | " { now._a_t = 2; /* set the A-bit */", |
| 1803 | " now._cnt[0] = now._nr_pr + 1;", /* NEW: +1 */ |
| 1804 | "#ifdef VERBOSE", |
| 1805 | " printf(\"%%3d: fairness Rule 1, cnt=%%d, _a_t=%%d\\n\",", |
| 1806 | " depth, now._cnt[now._a_t&1], now._a_t);", |
| 1807 | "#endif", |
| 1808 | " }", |
| 1809 | "#endif", |
| 1810 | |
| 1811 | " c_stack_start = (char *) &i; /* meant to be read-only */", |
| 1812 | |
| 1813 | "#if defined(HAS_CODE) && defined (C_INIT)", |
| 1814 | " C_INIT; /* initialization of data that must precede fork() */", |
| 1815 | " c_init_done++;", |
| 1816 | "#endif", |
| 1817 | |
| 1818 | "#if defined(C_States) && (HAS_TRACK==1)", |
| 1819 | " /* capture initial state of tracked C objects */", |
| 1820 | " c_update((uchar *) &(now.c_state[0]));", |
| 1821 | "#endif", |
| 1822 | |
| 1823 | "#ifdef HAS_CODE", |
| 1824 | " if (readtrail) getrail(); /* no return */", |
| 1825 | "#endif", |
| 1826 | " start_timer();", |
| 1827 | "#ifdef BFS", |
| 1828 | " bfs();", |
| 1829 | "#else", |
| 1830 | "#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)", |
| 1831 | " /* initial state of tracked & unmatched objects */", |
| 1832 | " c_stack((uchar *) &(svtack->c_stack[0]));", |
| 1833 | "#endif", |
| 1834 | "#ifdef RANDOMIZE", |
| 1835 | " #if RANDOMIZE>0", |
| 1836 | " srand(RANDOMIZE);", |
| 1837 | " #else", |
| 1838 | " srand(123);", |
| 1839 | " #endif", |
| 1840 | "#endif", |
| 1841 | "#if NCORE>1", |
| 1842 | " mem_get();", |
| 1843 | "#else", |
| 1844 | " new_state(); /* start 1st DFS */", |
| 1845 | "#endif", |
| 1846 | "#endif", |
| 1847 | "}", |
| 1848 | |
| 1849 | "#ifdef INLINE_REV", |
| 1850 | "uchar", |
| 1851 | "do_reverse(Trans *t, short II, uchar M)", |
| 1852 | "{ uchar _m = M;", |
| 1853 | " int tt = (int) ((P0 *)this)->_p;", |
| 1854 | "#include REVERSE_MOVES", |
| 1855 | "R999: return _m;", |
| 1856 | "}", |
| 1857 | "#endif", |
| 1858 | |
| 1859 | "#ifndef INLINE", |
| 1860 | "#ifdef EVENT_TRACE", |
| 1861 | "static char _tp = 'n'; static int _qid = 0;", |
| 1862 | "#endif", |
| 1863 | "uchar", |
| 1864 | "do_transit(Trans *t, short II)", |
| 1865 | "{ uchar _m = 0;", |
| 1866 | " int tt = (int) ((P0 *)this)->_p;", |
| 1867 | "#ifdef M_LOSS", |
| 1868 | " uchar delta_m = 0;", |
| 1869 | "#endif", |
| 1870 | "#ifdef EVENT_TRACE", |
| 1871 | " short oboq = boq;", |
| 1872 | " uchar ot = (uchar) ((P0 *)this)->_t;", |
| 1873 | " if (ot == EVENT_TRACE) boq = -1;", |
| 1874 | "#define continue { boq = oboq; return 0; }", |
| 1875 | "#else", |
| 1876 | "#define continue return 0", |
| 1877 | "#ifdef SEPARATE", |
| 1878 | " uchar ot = (uchar) ((P0 *)this)->_t;", |
| 1879 | "#endif", |
| 1880 | "#endif", |
| 1881 | "#include FORWARD_MOVES", |
| 1882 | "P999:", |
| 1883 | "#ifdef EVENT_TRACE", |
| 1884 | " if (ot == EVENT_TRACE) boq = oboq;", |
| 1885 | "#endif", |
| 1886 | " return _m;", |
| 1887 | "#undef continue", |
| 1888 | "}", |
| 1889 | |
| 1890 | "#ifdef EVENT_TRACE", |
| 1891 | "void", |
| 1892 | "require(char tp, int qid)", |
| 1893 | "{ Trans *t;", |
| 1894 | " _tp = tp; _qid = qid;", |
| 1895 | "", |
| 1896 | " if (now._event != endevent)", |
| 1897 | " for (t = trans[EVENT_TRACE][now._event]; t; t = t->nxt)", |
| 1898 | " { if (do_transit(t, EVENT_TRACE))", |
| 1899 | " { now._event = t->st;", |
| 1900 | " reached[EVENT_TRACE][t->st] = 1;", |
| 1901 | "#ifdef VERBOSE", |
| 1902 | " printf(\" event_trace move to -> %%d\\n\", t->st);", |
| 1903 | "#endif", |
| 1904 | "#ifndef BFS", |
| 1905 | "#ifndef NP", |
| 1906 | " if (accpstate[EVENT_TRACE][now._event])", |
| 1907 | " (trpt+1)->o_pm |= 2;", |
| 1908 | "#else", |
| 1909 | " if (progstate[EVENT_TRACE][now._event])", |
| 1910 | " (trpt+1)->o_pm |= 4;", |
| 1911 | "#endif", |
| 1912 | "#endif", |
| 1913 | "#ifdef NEGATED_TRACE", |
| 1914 | " if (now._event == endevent)", |
| 1915 | " {", |
| 1916 | "#ifndef BFS", |
| 1917 | " depth++; trpt++;", |
| 1918 | "#endif", |
| 1919 | " uerror(\"event_trace error (all events matched)\");", |
| 1920 | "#ifndef BFS", |
| 1921 | " trpt--; depth--;", |
| 1922 | "#endif", |
| 1923 | " break;", |
| 1924 | " }", |
| 1925 | "#endif", |
| 1926 | " for (t = t->nxt; t; t = t->nxt)", |
| 1927 | " { if (do_transit(t, EVENT_TRACE))", |
| 1928 | " Uerror(\"non-determinism in event-trace\");", |
| 1929 | " }", |
| 1930 | " return;", |
| 1931 | " }", |
| 1932 | "#ifdef VERBOSE", |
| 1933 | " else", |
| 1934 | " printf(\" event_trace miss '%%c' -- %%d, %%d, %%d\\n\",", |
| 1935 | " tp, qid, now._event, t->forw);", |
| 1936 | "#endif", |
| 1937 | " }", |
| 1938 | "#ifdef NEGATED_TRACE", |
| 1939 | " now._event = endevent; /* only 1st try will count -- fixed 4.2.6 */", |
| 1940 | "#else", |
| 1941 | "#ifndef BFS", |
| 1942 | " depth++; trpt++;", |
| 1943 | "#endif", |
| 1944 | " uerror(\"event_trace error (no matching event)\");", |
| 1945 | "#ifndef BFS", |
| 1946 | " trpt--; depth--;", |
| 1947 | "#endif", |
| 1948 | "#endif", |
| 1949 | "}", |
| 1950 | "#endif", |
| 1951 | |
| 1952 | "int", |
| 1953 | "enabled(int iam, int pid)", |
| 1954 | "{ Trans *t; uchar *othis = this;", |
| 1955 | " int res = 0; int tt; uchar ot;", |
| 1956 | "#ifdef VERI", |
| 1957 | " /* if (pid > 0) */ pid++;", |
| 1958 | "#endif", |
| 1959 | " if (pid == iam)", |
| 1960 | " Uerror(\"used: enabled(pid=thisproc)\");", |
| 1961 | " if (pid < 0 || pid >= (int) now._nr_pr)", |
| 1962 | " return 0;", |
| 1963 | " this = pptr(pid);", |
| 1964 | " TstOnly = 1;", |
| 1965 | " tt = (int) ((P0 *)this)->_p;", |
| 1966 | " ot = (uchar) ((P0 *)this)->_t;", |
| 1967 | " for (t = trans[ot][tt]; t; t = t->nxt)", |
| 1968 | " if (do_transit(t, (short) pid))", |
| 1969 | " { res = 1;", |
| 1970 | " break;", |
| 1971 | " }", |
| 1972 | " TstOnly = 0;", |
| 1973 | " this = othis;", |
| 1974 | " return res;", |
| 1975 | "}", |
| 1976 | "#endif", |
| 1977 | "void", |
| 1978 | "snap_time(void)", |
| 1979 | "{ clock_t stop_time;", |
| 1980 | " double delta_time;", |
| 1981 | "#if !defined(WIN32) && !defined(WIN64)", |
| 1982 | " struct tms stop_tm;", |
| 1983 | " stop_time = times(&stop_tm);", |
| 1984 | " delta_time = ((double) (stop_time - start_time)) / ((double) sysconf(_SC_CLK_TCK));", |
| 1985 | "#else", |
| 1986 | " stop_time = clock();", |
| 1987 | " delta_time = ((double) (stop_time - start_time)) / ((double) CLOCKS_PER_SEC);", |
| 1988 | "#endif", |
| 1989 | " if (delta_time > 0.01)", |
| 1990 | " { printf(\"t= %%6.3g \", delta_time);", |
| 1991 | " printf(\"R= %%7.0g\", nstates/delta_time);", |
| 1992 | " }", |
| 1993 | " printf(\"\\n\");", |
| 1994 | " if (quota > 0.1 && delta_time > quota)", |
| 1995 | " { printf(\"Time limit of %%6.3g minutes exceeded\\n\", quota/60.0);", |
| 1996 | "#if NCORE>1", |
| 1997 | " fflush(stdout);", |
| 1998 | " leave_critical(GLOBAL_LOCK);", |
| 1999 | " sudden_stop(\"time-limit\");", |
| 2000 | " exit(1);", |
| 2001 | "#endif", |
| 2002 | " wrapup();", |
| 2003 | " }", |
| 2004 | "}", |
| 2005 | "void", |
| 2006 | "snapshot(void)", |
| 2007 | "{", |
| 2008 | "#if NCORE>1", |
| 2009 | " enter_critical(GLOBAL_LOCK); /* snapshot */", |
| 2010 | " printf(\"cpu%%d: \", core_id);", |
| 2011 | "#endif", |
| 2012 | " printf(\"Depth= %%7ld States= %%8.3g \",", |
| 2013 | "#if NCORE>1", |
| 2014 | " (long) (nr_handoffs * z_handoff) +", |
| 2015 | "#endif", |
| 2016 | " mreached, nstates);", |
| 2017 | " printf(\"Transitions= %%8.3g \", nstates+truncs);", |
| 2018 | "#ifdef MA", |
| 2019 | " printf(\"Nodes= %%7d \", nr_states);", |
| 2020 | "#endif", |
| 2021 | " printf(\"Memory= %%9.3f\\t\", memcnt/1048576.);", |
| 2022 | " snap_time();", |
| 2023 | " fflush(stdout);", |
| 2024 | "#if NCORE>1", |
| 2025 | " leave_critical(GLOBAL_LOCK);", |
| 2026 | "#endif", |
| 2027 | "}", |
| 2028 | |
| 2029 | "#ifdef SC", |
| 2030 | "void", |
| 2031 | "stack2disk(void)", |
| 2032 | "{", |
| 2033 | " if (!stackwrite", |
| 2034 | " && (stackwrite = creat(stackfile, TMODE)) < 0)", |
| 2035 | " Uerror(\"cannot create stackfile\");", |
| 2036 | "", |
| 2037 | " if (write(stackwrite, trail, DDD*sizeof(Trail))", |
| 2038 | " != DDD*sizeof(Trail))", |
| 2039 | " Uerror(\"stackfile write error -- disk is full?\");", |
| 2040 | "", |
| 2041 | " memmove(trail, &trail[DDD], (HHH-DDD+2)*sizeof(Trail));", |
| 2042 | " memset(&trail[HHH-DDD+2], 0, (omaxdepth - HHH + DDD - 2)*sizeof(Trail));", |
| 2043 | " CNT1++;", |
| 2044 | "}", |
| 2045 | "void", |
| 2046 | "disk2stack(void)", |
| 2047 | "{ long have;", |
| 2048 | "", |
| 2049 | " CNT2++;", |
| 2050 | " memmove(&trail[DDD], trail, (HHH-DDD+2)*sizeof(Trail));", |
| 2051 | "", |
| 2052 | " if (!stackwrite", |
| 2053 | " || lseek(stackwrite, -DDD* (off_t) sizeof(Trail), SEEK_CUR) == -1)", |
| 2054 | " Uerror(\"disk2stack lseek error\");", |
| 2055 | "", |
| 2056 | " if (!stackread", |
| 2057 | " && (stackread = open(stackfile, 0)) < 0)", |
| 2058 | " Uerror(\"cannot open stackfile\");", |
| 2059 | "", |
| 2060 | " if (lseek(stackread, (CNT1-CNT2)*DDD* (off_t) sizeof(Trail), SEEK_SET) == -1)", |
| 2061 | " Uerror(\"disk2stack lseek error\");", |
| 2062 | "", |
| 2063 | " have = read(stackread, trail, DDD*sizeof(Trail));", |
| 2064 | " if (have != DDD*sizeof(Trail))", |
| 2065 | " Uerror(\"stackfile read error\");", |
| 2066 | "}", |
| 2067 | "#endif", |
| 2068 | |
| 2069 | "uchar *", |
| 2070 | "Pptr(int x)", /* as a fct, to avoid a problem with the p9 compiler */ |
| 2071 | "{ if (x < 0 || x >= MAXPROC || !proc_offset[x])", /* does not exist */ |
| 2072 | " return noptr;", |
| 2073 | " else", |
| 2074 | " return (uchar *) pptr(x);", |
| 2075 | "}", |
| 2076 | "int qs_empty(void);", |
| 2077 | |
| 2078 | "/*", |
| 2079 | " * new_state() is the main DFS search routine in the verifier", |
| 2080 | " * it has a lot of code ifdef-ed together to support", |
| 2081 | " * different search modes, which makes it quite unreadable.", |
| 2082 | " * if you are studying the code, first use the C preprocessor", |
| 2083 | " * to generate a specific version from the pan.c source,", |
| 2084 | " * e.g. by saying:", |
| 2085 | " * gcc -E -DNOREDUCE -DBITSTATE pan.c > ppan.c", |
| 2086 | " * and then study the resulting file, rather than this one", |
| 2087 | " */", |
| 2088 | "#if !defined(BFS) && (!defined(BITSTATE) || !defined(MA))", |
| 2089 | "", |
| 2090 | "#ifdef NSUCC", |
| 2091 | "int N_succ[512];", |
| 2092 | "void", |
| 2093 | "tally_succ(int cnt)", |
| 2094 | "{ if (cnt < 512) N_succ[cnt]++;", |
| 2095 | " else printf(\"tally_succ: cnt %%d exceeds range\\n\", cnt);", |
| 2096 | "}", |
| 2097 | "", |
| 2098 | "void", |
| 2099 | "dump_succ(void)", |
| 2100 | "{ int i; double sum = 0.0;", |
| 2101 | " double w_avg = 0.0;", |
| 2102 | " printf(\"Successor counts:\\n\");", |
| 2103 | " for (i = 0; i < 512; i++)", |
| 2104 | " { sum += (double) N_succ[i];", |
| 2105 | " }", |
| 2106 | " for (i = 0; i < 512; i++)", |
| 2107 | " { if (N_succ[i] > 0)", |
| 2108 | " { printf(\"%%3d\t%%10d\t(%%.4g %%%% of total)\\n\",", |
| 2109 | " i, N_succ[i], (100.0 * (double) N_succ[i])/sum);", |
| 2110 | " w_avg += (double) i * (double) N_succ[i];", |
| 2111 | " } }", |
| 2112 | " if (sum > N_succ[0])", |
| 2113 | " printf(\"mean %%.4g (without 0: %%.4g)\\n\", w_avg / sum, w_avg / (sum - (double) N_succ[0]));", |
| 2114 | "}", |
| 2115 | "#endif", |
| 2116 | "", |
| 2117 | "void", |
| 2118 | "new_state(void)", |
| 2119 | "{ Trans *t;", |
| 2120 | " uchar _n, _m, ot;", |
| 2121 | "#ifdef RANDOMIZE", |
| 2122 | " short ooi, eoi;", |
| 2123 | "#endif", |
| 2124 | "#ifdef M_LOSS", |
| 2125 | " uchar delta_m = 0;", |
| 2126 | "#endif", |
| 2127 | " short II, JJ = 0, kk;", |
| 2128 | " int tt;", |
| 2129 | "#ifdef REVERSE", |
| 2130 | " short From = BASE, To = now._nr_pr-1;", |
| 2131 | "#else", |
| 2132 | " short From = now._nr_pr-1, To = BASE;", |
| 2133 | "#endif", |
| 2134 | "Down:", |
| 2135 | "#ifdef CHECK", |
| 2136 | " cpu_printf(\"%%d: Down - %%s %%saccepting [pids %%d-%%d]\\n\",", |
| 2137 | " depth, (trpt->tau&4)?\"claim\":\"program\",", |
| 2138 | " (trpt->o_pm&2)?\"\":\"non-\", From, To);", |
| 2139 | "#endif", |
| 2140 | "#ifdef SCHED", |
| 2141 | " if (depth > 0)", |
| 2142 | " { trpt->sched_limit = (trpt-1)->sched_limit;", |
| 2143 | " } else", |
| 2144 | " { trpt->sched_limit = 0;", |
| 2145 | " }", |
| 2146 | "#endif", |
| 2147 | |
| 2148 | "#ifdef SC", |
| 2149 | " if (depth > hiwater)", |
| 2150 | " { stack2disk();", |
| 2151 | " maxdepth += DDD;", |
| 2152 | " hiwater += DDD;", |
| 2153 | " trpt -= DDD;", |
| 2154 | " if(verbose)", |
| 2155 | " printf(\"zap %%d: %%d (maxdepth now %%d)\\n\",", |
| 2156 | " CNT1, hiwater, maxdepth);", |
| 2157 | " }", |
| 2158 | "#endif", |
| 2159 | |
| 2160 | " trpt->tau &= ~(16|32|64); /* make sure these are off */", |
| 2161 | "#if defined(FULLSTACK) && defined(MA)", |
| 2162 | " trpt->proviso = 0;", |
| 2163 | "#endif", |
| 2164 | "#ifdef NSUCC", |
| 2165 | " trpt->n_succ = 0;", |
| 2166 | "#endif", |
| 2167 | "#if NCORE>1", |
| 2168 | " if (mem_hand_off())", |
| 2169 | " {", |
| 2170 | "#if SYNC", |
| 2171 | " (trpt+1)->o_n = 1; /* not a deadlock: as below */", |
| 2172 | "#endif", |
| 2173 | "#ifndef LOOPSTATE", |
| 2174 | " (trpt-1)->tau |= 16; /* worstcase guess: as below */", |
| 2175 | "#endif", |
| 2176 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 2177 | " if (upto > 0)", |
| 2178 | " { Pop_Stack_Tree();", |
| 2179 | " }", |
| 2180 | "#endif", |
| 2181 | " goto Up;", |
| 2182 | " }", |
| 2183 | "#endif", |
| 2184 | |
| 2185 | " if (depth >= maxdepth)", |
| 2186 | " { if (!warned)", |
| 2187 | " { warned = 1;", |
| 2188 | " printf(\"error: max search depth too small\\n\");", |
| 2189 | " }", |
| 2190 | " if (bounded)", |
| 2191 | " { uerror(\"depth limit reached\");", |
| 2192 | " }", |
| 2193 | " truncs++;", |
| 2194 | "#if SYNC", |
| 2195 | " (trpt+1)->o_n = 1; /* not a deadlock */", |
| 2196 | "#endif", |
| 2197 | "#ifndef LOOPSTATE", |
| 2198 | " (trpt-1)->tau |= 16; /* worstcase guess */", |
| 2199 | "#endif", |
| 2200 | |
| 2201 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 2202 | " if (upto > 0)", |
| 2203 | " { Pop_Stack_Tree();", |
| 2204 | " }", |
| 2205 | "#endif", |
| 2206 | " goto Up;", |
| 2207 | " }", |
| 2208 | "AllOver:", |
| 2209 | "#if (defined(FULLSTACK) && !defined(MA)) || NCORE>1", |
| 2210 | " /* if atomic or rv move, carry forward previous state */", |
| 2211 | " trpt->ostate = (trpt-1)->ostate;", /* was: = (struct H_el *) 0;*/ |
| 2212 | "#endif", |
| 2213 | "#ifdef VERI", |
| 2214 | " if ((trpt->tau&4) || ((trpt-1)->tau&128))", |
| 2215 | "#endif", |
| 2216 | " if (boq == -1) { /* if not mid-rv */", |
| 2217 | "#ifndef SAFETY", |
| 2218 | " /* this check should now be redundant", |
| 2219 | " * because the seed state also appears", |
| 2220 | " * on the 1st dfs stack and would be", |
| 2221 | " * matched in hstore below", |
| 2222 | " */", |
| 2223 | " if ((now._a_t&1) && depth > A_depth)", |
| 2224 | " { if (!memcmp((char *)&A_Root, ", |
| 2225 | " (char *)&now, vsize))", |
| 2226 | " {", |
| 2227 | " depthfound = A_depth;", |
| 2228 | "#ifdef CHECK", |
| 2229 | " printf(\"matches seed\\n\");", |
| 2230 | "#endif", |
| 2231 | "#ifdef NP", |
| 2232 | " uerror(\"non-progress cycle\");", |
| 2233 | "#else", |
| 2234 | " uerror(\"acceptance cycle\");", |
| 2235 | "#endif", |
| 2236 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 2237 | " if (upto > 0)", |
| 2238 | " { Pop_Stack_Tree();", |
| 2239 | " }", |
| 2240 | "#endif", |
| 2241 | " goto Up;", |
| 2242 | " }", |
| 2243 | "#ifdef CHECK", |
| 2244 | " printf(\"not seed\\n\");", |
| 2245 | "#endif", |
| 2246 | " }", |
| 2247 | "#endif", |
| 2248 | " if (!(trpt->tau&8)) /* if no atomic move */", |
| 2249 | " {", |
| 2250 | "#ifdef BITSTATE", |
| 2251 | "#ifdef CNTRSTACK", /* -> bitstate, reduced, safety */ |
| 2252 | " II = bstore((char *)&now, vsize);", |
| 2253 | " trpt->j6 = j1; trpt->j7 = j2;", |
| 2254 | " JJ = LL[j1] && LL[j2];", |
| 2255 | "#else", |
| 2256 | "#ifdef FULLSTACK", |
| 2257 | " JJ = onstack_now();", /* sets j1 */ |
| 2258 | "#else", |
| 2259 | "#ifndef NOREDUCE", |
| 2260 | " JJ = II; /* worstcase guess for p.o. */", |
| 2261 | "#endif", |
| 2262 | "#endif", |
| 2263 | " II = bstore((char *)&now, vsize);", /* sets j1-j4 */ |
| 2264 | "#endif", |
| 2265 | "#else", |
| 2266 | "#ifdef MA", |
| 2267 | " II = gstore((char *)&now, vsize, 0);", |
| 2268 | "#ifndef FULLSTACK", |
| 2269 | " JJ = II;", |
| 2270 | "#else", |
| 2271 | " JJ = (II == 2)?1:0;", |
| 2272 | "#endif", |
| 2273 | "#else", |
| 2274 | " II = hstore((char *)&now, vsize);", |
| 2275 | "#ifdef FULLSTACK", |
| 2276 | " JJ = (II == 2)?1:0;", |
| 2277 | "#endif", |
| 2278 | "#endif", |
| 2279 | "#endif", |
| 2280 | " kk = (II == 1 || II == 2);", |
| 2281 | |
| 2282 | /* II==0 new state */ |
| 2283 | /* II==1 old state */ |
| 2284 | /* II==2 on current dfs stack */ |
| 2285 | /* II==3 on 1st dfs stack */ |
| 2286 | "#ifndef SAFETY", |
| 2287 | |
| 2288 | "#if NCORE==1 || defined (SEP_STATE)", /* or else we don't know which stack its on */ |
| 2289 | " if (II == 2 && ((trpt->o_pm&2) || ((trpt-1)->o_pm&2)))", |
| 2290 | " #ifndef NOFAIR", |
| 2291 | "#if 0", |
| 2292 | " if (!fairness || ((now._a_t&1) && now._cnt[1] == 1)) /* 5.1.4 */", |
| 2293 | "#else", |
| 2294 | " if (a_cycles && !fairness) /* 5.1.6 -- example by Hirofumi Watanabe */", |
| 2295 | "#endif", |
| 2296 | " #endif", |
| 2297 | " {", |
| 2298 | " II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */", |
| 2299 | "#ifdef VERBOSE", |
| 2300 | " printf(\"state match on dfs stack\\n\");", |
| 2301 | "#endif", |
| 2302 | " goto same_case;", |
| 2303 | " }", |
| 2304 | "#endif", |
| 2305 | |
| 2306 | "#if defined(FULLSTACK) && defined(BITSTATE)", |
| 2307 | " if (!JJ && (now._a_t&1) && depth > A_depth)", |
| 2308 | " { int oj1 = j1;", |
| 2309 | " uchar o_a_t = now._a_t;", |
| 2310 | " now._a_t &= ~(1|16|32);", /* 1st stack */ |
| 2311 | " if (onstack_now())", /* changes j1 */ |
| 2312 | " { II = 3;", |
| 2313 | "#ifdef VERBOSE", |
| 2314 | " printf(\"state match on 1st dfs stack\\n\");", |
| 2315 | "#endif", |
| 2316 | " }", |
| 2317 | " now._a_t = o_a_t;", /* restore */ |
| 2318 | " j1 = oj1;", |
| 2319 | " }", |
| 2320 | "#endif", |
| 2321 | " if (II == 3 && a_cycles && (now._a_t&1))", |
| 2322 | " {", |
| 2323 | "#ifndef NOFAIR", |
| 2324 | " if (fairness && now._cnt[1] > 1) /* was != 0 */", |
| 2325 | " {", |
| 2326 | "#ifdef VERBOSE", |
| 2327 | " printf(\"\tfairness count non-zero\\n\");", |
| 2328 | "#endif", |
| 2329 | " II = 0;", /* treat as new state */ |
| 2330 | " } else", |
| 2331 | "#endif", |
| 2332 | " {", |
| 2333 | "#ifndef BITSTATE", |
| 2334 | " nShadow--;", |
| 2335 | "#endif", |
| 2336 | "same_case: if (Lstate) depthfound = Lstate->D;", |
| 2337 | "#ifdef NP", |
| 2338 | " uerror(\"non-progress cycle\");", |
| 2339 | "#else", |
| 2340 | " uerror(\"acceptance cycle\");", |
| 2341 | "#endif", |
| 2342 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 2343 | " if (upto > 0)", |
| 2344 | " { Pop_Stack_Tree();", |
| 2345 | " }", |
| 2346 | "#endif", |
| 2347 | " goto Up;", |
| 2348 | " }", |
| 2349 | " }", |
| 2350 | "#endif", |
| 2351 | |
| 2352 | "#ifndef NOREDUCE", |
| 2353 | "#ifndef SAFETY", |
| 2354 | "#if NCORE>1 && !defined(SEP_STATE) && defined(V_PROVISO)", |
| 2355 | " if (II != 0 && (!Lstate || Lstate->cpu_id < core_id))", |
| 2356 | " { (trpt-1)->tau |= 16;", /* treat as a stack state */ |
| 2357 | " }", |
| 2358 | "#endif", |
| 2359 | " if ((II && JJ) || (II == 3))", |
| 2360 | " { /* marker for liveness proviso */", |
| 2361 | "#ifndef LOOPSTATE", |
| 2362 | " (trpt-1)->tau |= 16;", /* truncated on stack */ |
| 2363 | "#endif", |
| 2364 | " truncs2++;", |
| 2365 | " }", |
| 2366 | "#else", |
| 2367 | "#if NCORE>1 && !defined(SEP_STATE) && defined(V_PROVISO)", |
| 2368 | " if (!(II != 0 && (!Lstate || Lstate->cpu_id < core_id)))", |
| 2369 | " { /* treat as stack state */", |
| 2370 | " (trpt-1)->tau |= 16;", |
| 2371 | " } else", |
| 2372 | " { /* treat as non-stack state */", |
| 2373 | " (trpt-1)->tau |= 64;", |
| 2374 | " }", |
| 2375 | "#endif", |
| 2376 | " if (!II || !JJ)", |
| 2377 | " { /* successor outside stack */", |
| 2378 | " (trpt-1)->tau |= 64;", |
| 2379 | " }", |
| 2380 | "#endif", |
| 2381 | "#endif", |
| 2382 | " if (II)", |
| 2383 | " { truncs++;", |
| 2384 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 2385 | " if (upto > 0)", |
| 2386 | " { Pop_Stack_Tree();", |
| 2387 | " if (depth == 0)", |
| 2388 | " { return;", |
| 2389 | " } }", |
| 2390 | "#endif", |
| 2391 | " goto Up;", |
| 2392 | " }", |
| 2393 | " if (!kk)", |
| 2394 | " { static long sdone = (long) 0; long ndone;", |
| 2395 | " nstates++;", |
| 2396 | "#if defined(ZAPH) && defined(BITSTATE)", |
| 2397 | " zstates += (double) hfns;", |
| 2398 | "#endif", |
| 2399 | " ndone = (unsigned long) (nstates/((double) FREQ));", |
| 2400 | " if (ndone != sdone)", |
| 2401 | " { snapshot();", |
| 2402 | " sdone = ndone;", |
| 2403 | "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", |
| 2404 | " if (nstates > ((double)(ONE_L<<(ssize+1))))", |
| 2405 | " { void resize_hashtable(void);", |
| 2406 | " resize_hashtable();", |
| 2407 | " }", |
| 2408 | "#endif", |
| 2409 | "#if defined(ZAPH) && defined(BITSTATE)", |
| 2410 | " if (zstates > ((double)(ONE_L<<(ssize-2))))", |
| 2411 | " { /* more than half the bits set */", |
| 2412 | " void zap_hashtable(void);", |
| 2413 | " zap_hashtable();", |
| 2414 | " zstates = 0;", |
| 2415 | " }", |
| 2416 | "#endif", |
| 2417 | " }", |
| 2418 | "#ifdef SVDUMP", |
| 2419 | " if (vprefix > 0)", |
| 2420 | " if (write(svfd, (uchar *) &now, vprefix) != vprefix)", |
| 2421 | " { fprintf(efd, \"writing %%s.svd failed\\n\", PanSource);", |
| 2422 | " wrapup();", |
| 2423 | " }", |
| 2424 | "#endif", |
| 2425 | "#if defined(MA) && defined(W_XPT)", |
| 2426 | " if ((unsigned long) nstates%%W_XPT == 0)", |
| 2427 | " { void w_xpoint(void);", |
| 2428 | " w_xpoint();", |
| 2429 | " }", |
| 2430 | "#endif", |
| 2431 | " }", |
| 2432 | |
| 2433 | "#if defined(FULLSTACK) || defined(CNTRSTACK)", |
| 2434 | " onstack_put();", |
| 2435 | "#ifdef DEBUG2", |
| 2436 | "#if defined(FULLSTACK) && !defined(MA)", |
| 2437 | " printf(\"%%d: putting %%u (%%d)\\n\", depth,", |
| 2438 | " trpt->ostate, ", |
| 2439 | " (trpt->ostate)?trpt->ostate->tagged:0);", |
| 2440 | "#else", |
| 2441 | " printf(\"%%d: putting\\n\", depth);", |
| 2442 | "#endif", |
| 2443 | "#endif", |
| 2444 | "#else", |
| 2445 | " #if NCORE>1", |
| 2446 | " trpt->ostate = Lstate;", |
| 2447 | " #endif", |
| 2448 | "#endif", |
| 2449 | " } }", |
| 2450 | |
| 2451 | |
| 2452 | " if (depth > mreached)", |
| 2453 | " mreached = depth;", |
| 2454 | "#ifdef VERI", |
| 2455 | " if (trpt->tau&4)", |
| 2456 | "#endif", |
| 2457 | " trpt->tau &= ~(1|2); /* timeout and -request off */", |
| 2458 | " _n = 0;", |
| 2459 | "#if SYNC", |
| 2460 | " (trpt+1)->o_n = 0;", |
| 2461 | "#endif", |
| 2462 | "#ifdef VERI", |
| 2463 | " if (now._nr_pr == 0) /* claim terminated */", |
| 2464 | " uerror(\"end state in claim reached\");", |
| 2465 | " check_claim(((P0 *)pptr(0))->_p);", |
| 2466 | "Stutter:", |
| 2467 | " if (trpt->tau&4) /* must make a claimmove */", |
| 2468 | " {", |
| 2469 | |
| 2470 | "#ifndef NOFAIR", |
| 2471 | " if ((now._a_t&2) /* A-bit set */", |
| 2472 | " && now._cnt[now._a_t&1] == 1)", |
| 2473 | " { now._a_t &= ~2;", |
| 2474 | " now._cnt[now._a_t&1] = 0;", |
| 2475 | " trpt->o_pm |= 16;", |
| 2476 | "#ifdef DEBUG", |
| 2477 | " printf(\"%%3d: fairness Rule 3.: _a_t = %%d\\n\",", |
| 2478 | " depth, now._a_t);", |
| 2479 | "#endif", |
| 2480 | " }", |
| 2481 | "#endif", |
| 2482 | |
| 2483 | " II = 0; /* never */", |
| 2484 | " goto Veri0;", |
| 2485 | " }", |
| 2486 | "#endif", |
| 2487 | "#ifndef NOREDUCE", |
| 2488 | " /* Look for a process with only safe transitions */", |
| 2489 | " /* (special rules apply in the 2nd dfs) */", |
| 2490 | " if (boq == -1 && From != To", |
| 2491 | "", |
| 2492 | "#ifdef SAFETY", |
| 2493 | " #if NCORE>1", |
| 2494 | " && (depth < z_handoff)", /* not for border states */ |
| 2495 | " #endif", |
| 2496 | " )", |
| 2497 | "#else", |
| 2498 | " #if NCORE>1", |
| 2499 | " && ((a_cycles) || (!a_cycles && depth < z_handoff))", |
| 2500 | " #endif", |
| 2501 | " && (!(now._a_t&1)", |
| 2502 | " || (a_cycles &&", |
| 2503 | " #ifndef BITSTATE", |
| 2504 | "#ifdef MA", |
| 2505 | "#ifdef VERI", |
| 2506 | " !((trpt-1)->proviso))", |
| 2507 | "#else", |
| 2508 | " !(trpt->proviso))", |
| 2509 | "#endif", |
| 2510 | "#else", |
| 2511 | "#ifdef VERI", |
| 2512 | " (trpt-1)->ostate &&", |
| 2513 | " !(((char *)&((trpt-1)->ostate->state))[0] & 128))", /* proviso bit in _a_t */ |
| 2514 | "#else", |
| 2515 | " !(((char *)&(trpt->ostate->state))[0] & 128))", |
| 2516 | "#endif", |
| 2517 | "#endif", |
| 2518 | " #else", |
| 2519 | "#ifdef VERI", |
| 2520 | " (trpt-1)->ostate &&", |
| 2521 | " (trpt-1)->ostate->proviso == 0)", |
| 2522 | "#else", |
| 2523 | " trpt->ostate->proviso == 0)", |
| 2524 | "#endif", |
| 2525 | " #endif", |
| 2526 | " ))", |
| 2527 | "#endif", /* SAFETY */ |
| 2528 | "", |
| 2529 | "#ifdef REVERSE", |
| 2530 | " for (II = From; II <= To; II++)", |
| 2531 | "#else", |
| 2532 | " for (II = From; II >= To; II--)", |
| 2533 | "#endif", |
| 2534 | " {", |
| 2535 | "Resume: /* pick up here if preselect fails */", |
| 2536 | " this = pptr(II);", |
| 2537 | " tt = (int) ((P0 *)this)->_p;", |
| 2538 | " ot = (uchar) ((P0 *)this)->_t;", |
| 2539 | " if (trans[ot][tt]->atom & 8)", |
| 2540 | " { t = trans[ot][tt];", |
| 2541 | " if (t->qu[0] != 0)", |
| 2542 | " { Ccheck++;", |
| 2543 | " if (!q_cond(II, t))", |
| 2544 | " continue;", |
| 2545 | " Cholds++;", |
| 2546 | " }", |
| 2547 | " From = To = II; /* the process preselected */", |
| 2548 | "#ifdef NIBIS", |
| 2549 | " t->om = 0;", |
| 2550 | "#endif", |
| 2551 | " trpt->tau |= 32; /* preselect marker */", |
| 2552 | "#ifdef DEBUG", |
| 2553 | "#ifdef NIBIS", |
| 2554 | " printf(\"%%3d: proc %%d Pre\", depth, II);", |
| 2555 | " printf(\"Selected (om=%%d, tau=%%d)\\n\", ", |
| 2556 | " t->om, trpt->tau);", |
| 2557 | "#else", |
| 2558 | " printf(\"%%3d: proc %%d PreSelected (tau=%%d)\\n\", ", |
| 2559 | " depth, II, trpt->tau);", |
| 2560 | "#endif", |
| 2561 | "#endif", |
| 2562 | " goto Again;", |
| 2563 | " }", |
| 2564 | " }", |
| 2565 | " trpt->tau &= ~32;", |
| 2566 | "#endif", |
| 2567 | "#if !defined(NOREDUCE) || (defined(ETIM) && !defined(VERI))", |
| 2568 | "Again:", |
| 2569 | "#endif", |
| 2570 | |
| 2571 | " /* The Main Expansion Loop over Processes */", |
| 2572 | |
| 2573 | " trpt->o_pm &= ~(8|16|32|64); /* fairness-marks */", |
| 2574 | "#ifndef NOFAIR", |
| 2575 | " if (fairness && boq == -1", |
| 2576 | "#ifdef VERI", |
| 2577 | " && (!(trpt->tau&4) && !((trpt-1)->tau&128))", |
| 2578 | "#endif", |
| 2579 | " && !(trpt->tau&8))", |
| 2580 | " { /* A_bit = 1; Cnt = N in acc states with A_bit 0 */", |
| 2581 | " if (!(now._a_t&2))", /* A-bit not set */ |
| 2582 | " {", |
| 2583 | " if (a_cycles && (trpt->o_pm&2))", |
| 2584 | " { /* Accepting state */", |
| 2585 | " now._a_t |= 2;", |
| 2586 | " now._cnt[now._a_t&1] = now._nr_pr + 1;", /* NEW +1 */ |
| 2587 | " trpt->o_pm |= 8;", |
| 2588 | "#ifdef DEBUG", |
| 2589 | " printf(\"%%3d: fairness Rule 1: cnt=%%d, _a_t=%%d\\n\",", |
| 2590 | " depth, now._cnt[now._a_t&1], now._a_t);", |
| 2591 | "#endif", |
| 2592 | " }", |
| 2593 | " } else", /* A-bit set */ |
| 2594 | " { /* A_bit = 0 when Cnt 0 */", |
| 2595 | " if (now._cnt[now._a_t&1] == 1)", |
| 2596 | " { now._a_t &= ~2;", /* reset a-bit */ |
| 2597 | " now._cnt[now._a_t&1] = 0;", |
| 2598 | " trpt->o_pm |= 16;", |
| 2599 | "#ifdef DEBUG", |
| 2600 | " printf(\"%%3d: fairness Rule 3: _a_t = %%d\\n\",", |
| 2601 | " depth, now._a_t);", |
| 2602 | "#endif", |
| 2603 | " } } }", |
| 2604 | "#endif", |
| 2605 | "", |
| 2606 | "#ifdef REVERSE", |
| 2607 | " for (II = From; II <= To; II++)", |
| 2608 | "#else", |
| 2609 | " for (II = From; II >= To; II--)", |
| 2610 | "#endif", |
| 2611 | " {", |
| 2612 | "#if SYNC", |
| 2613 | " /* no rendezvous with same proc */", |
| 2614 | " if (boq != -1 && trpt->pr == II) continue;", |
| 2615 | "#endif", |
| 2616 | "#ifdef SCHED", |
| 2617 | " /* limit max nr of interleavings */", |
| 2618 | " if (From != To", /* not a PO or atomic move */ |
| 2619 | " && depth > 0", /* there is a prior move */ |
| 2620 | " #ifdef VERI", |
| 2621 | " && II != 0", /* never claim can always move */ |
| 2622 | " #endif", |
| 2623 | " && (trpt-1)->pr != II", /* context switch */ |
| 2624 | " && trpt->sched_limit >= sched_max)", |
| 2625 | " { continue;", |
| 2626 | " }", |
| 2627 | "#endif", |
| 2628 | "#ifdef VERI", |
| 2629 | "Veri0:", |
| 2630 | "#endif", |
| 2631 | " this = pptr(II);", |
| 2632 | " tt = (int) ((P0 *)this)->_p;", |
| 2633 | " ot = (uchar) ((P0 *)this)->_t;", |
| 2634 | |
| 2635 | "#ifdef NIBIS", |
| 2636 | " /* don't repeat a previous preselected expansion */", |
| 2637 | " /* could hit this if reduction proviso was false */", |
| 2638 | " t = trans[ot][tt];", |
| 2639 | " if (!(trpt->tau&4)", /* not claim */ |
| 2640 | " && !(trpt->tau&1)", /* not timeout */ |
| 2641 | " && !(trpt->tau&32)", /* not preselected */ |
| 2642 | " && (t->atom & 8)", /* local */ |
| 2643 | " && boq == -1", /* not inside rendezvous */ |
| 2644 | " && From != To)", /* not inside atomic seq */ |
| 2645 | " { if (t->qu[0] == 0", /* unconditional */ |
| 2646 | " || q_cond(II, t))", /* true condition */ |
| 2647 | " { _m = t->om;", |
| 2648 | " if (_m>_n||(_n>3&&_m!=0)) _n=_m;", |
| 2649 | " continue; /* did it before */", |
| 2650 | " } }", |
| 2651 | "#endif", |
| 2652 | " trpt->o_pm &= ~1; /* no move in this pid yet */", |
| 2653 | "#ifdef EVENT_TRACE", |
| 2654 | " (trpt+1)->o_event = now._event;", |
| 2655 | "#endif", |
| 2656 | " /* Fairness: Cnt++ when Cnt == II */", |
| 2657 | "#ifndef NOFAIR", |
| 2658 | " trpt->o_pm &= ~64; /* didn't apply rule 2 */", |
| 2659 | " if (fairness", |
| 2660 | " && boq == -1", /* not mid rv - except rcv - NEW 3.0.8 */ |
| 2661 | " && !(trpt->o_pm&32)", /* Rule 2 not in effect */ |
| 2662 | " && (now._a_t&2)", /* A-bit is set */ |
| 2663 | " && now._cnt[now._a_t&1] == II+2)", |
| 2664 | " { now._cnt[now._a_t&1] -= 1;", |
| 2665 | "#ifdef VERI", |
| 2666 | " /* claim need not participate */", |
| 2667 | " if (II == 1)", |
| 2668 | " now._cnt[now._a_t&1] = 1;", |
| 2669 | "#endif", |
| 2670 | "#ifdef DEBUG", |
| 2671 | " printf(\"%%3d: proc %%d fairness \", depth, II);", |
| 2672 | " printf(\"Rule 2: --cnt to %%d (%%d)\\n\",", |
| 2673 | " now._cnt[now._a_t&1], now._a_t);", |
| 2674 | "#endif", |
| 2675 | " trpt->o_pm |= (32|64);", |
| 2676 | " }", |
| 2677 | "#endif", |
| 2678 | "#ifdef HAS_PROVIDED", |
| 2679 | " if (!provided(II, ot, tt, t)) continue;", |
| 2680 | "#endif", |
| 2681 | " /* check all trans of proc II - escapes first */", |
| 2682 | "#ifdef HAS_UNLESS", |
| 2683 | " trpt->e_state = 0;", |
| 2684 | "#endif", |
| 2685 | " (trpt+1)->pr = (uchar) II;", /* for uerror */ |
| 2686 | " (trpt+1)->st = tt;", |
| 2687 | |
| 2688 | "#ifdef RANDOMIZE", |
| 2689 | " for (ooi = eoi = 0, t = trans[ot][tt]; t; t = t->nxt, ooi++)", |
| 2690 | " { if (strcmp(t->tp, \"else\") == 0)", |
| 2691 | " { eoi++;", |
| 2692 | " break;", |
| 2693 | " } }", |
| 2694 | " if (eoi > 0)", |
| 2695 | " { t = trans[ot][tt];", |
| 2696 | " #ifdef VERBOSE", |
| 2697 | " printf(\"randomizer: suppressed, saw else\\n\");", |
| 2698 | " #endif", |
| 2699 | " } else", |
| 2700 | " { eoi = rand()%%ooi;", |
| 2701 | " #ifdef VERBOSE", |
| 2702 | " printf(\"randomizer: skip %%d in %%d\\n\", eoi, ooi);", |
| 2703 | " #endif", |
| 2704 | " for (t = trans[ot][tt]; t; t = t->nxt)", |
| 2705 | " if (eoi-- <= 0) break;", |
| 2706 | " }", |
| 2707 | "domore:", |
| 2708 | " for ( ; t && ooi > 0; t = t->nxt, ooi--)", |
| 2709 | "#else", /* ie dont randomize */ |
| 2710 | " for (t = trans[ot][tt]; t; t = t->nxt)", |
| 2711 | "#endif", |
| 2712 | " {", |
| 2713 | "#ifdef HAS_UNLESS", |
| 2714 | " /* exploring all transitions from", |
| 2715 | " * a single escape state suffices", |
| 2716 | " */", |
| 2717 | " if (trpt->e_state > 0", |
| 2718 | " && trpt->e_state != t->e_trans)", |
| 2719 | " {", |
| 2720 | "#ifdef DEBUG", |
| 2721 | " printf(\"skip 2nd escape %%d (did %%d before)\\n\",", |
| 2722 | " t->e_trans, trpt->e_state);", |
| 2723 | "#endif", |
| 2724 | " break;", |
| 2725 | " }", |
| 2726 | "#endif", |
| 2727 | " (trpt+1)->o_t = t;", /* for uerror */ |
| 2728 | "#ifdef INLINE", |
| 2729 | "#include FORWARD_MOVES", |
| 2730 | "P999: /* jumps here when move succeeds */", |
| 2731 | "#else", |
| 2732 | " if (!(_m = do_transit(t, II))) continue;", |
| 2733 | "#endif", |
| 2734 | "#ifdef SCHED", |
| 2735 | " if (depth > 0", |
| 2736 | " #ifdef VERI", |
| 2737 | " && II != 0", |
| 2738 | " #endif", |
| 2739 | " && (trpt-1)->pr != II)", |
| 2740 | " { trpt->sched_limit = 1 + (trpt-1)->sched_limit;", |
| 2741 | " }", |
| 2742 | "#endif", |
| 2743 | " if (boq == -1)", |
| 2744 | "#ifdef CTL", |
| 2745 | " /* for branching-time, can accept reduction only if */", |
| 2746 | " /* the persistent set contains just 1 transition */", |
| 2747 | " { if ((trpt->tau&32) && (trpt->o_pm&1))", |
| 2748 | " trpt->tau |= 16;", /* CTL */ |
| 2749 | " trpt->o_pm |= 1; /* we moved */", |
| 2750 | " }", |
| 2751 | "#else", |
| 2752 | " trpt->o_pm |= 1; /* we moved */", |
| 2753 | "#endif", |
| 2754 | |
| 2755 | "#ifdef LOOPSTATE", |
| 2756 | " if (loopstate[ot][tt])", |
| 2757 | " {", |
| 2758 | "#ifdef VERBOSE", |
| 2759 | " printf(\"exiting from loopstate:\\n\");", |
| 2760 | "#endif", |
| 2761 | " trpt->tau |= 16;", /* exiting loopstate */ |
| 2762 | " cnt_loops++;", |
| 2763 | " }", |
| 2764 | "#endif", |
| 2765 | |
| 2766 | "#ifdef PEG", |
| 2767 | " peg[t->forw]++;", |
| 2768 | "#endif", |
| 2769 | "#if defined(VERBOSE) || defined(CHECK)", |
| 2770 | "#if defined(SVDUMP)", |
| 2771 | " cpu_printf(\"%%3d: proc %%d exec %%d \\n\", depth, II, t->t_id);", |
| 2772 | "#else", |
| 2773 | " cpu_printf(\"%%3d: proc %%d exec %%d, %%d to %%d, %%s %%s %%s %%saccepting [tau=%%d]\\n\", ", |
| 2774 | " depth, II, t->forw, tt, t->st, t->tp,", |
| 2775 | " (t->atom&2)?\"atomic\":\"\",", |
| 2776 | " (boq != -1)?\"rendez-vous\":\"\",", |
| 2777 | " (trpt->o_pm&2)?\"\":\"non-\", trpt->tau);", |
| 2778 | "#ifdef HAS_UNLESS", |
| 2779 | " if (t->e_trans)", |
| 2780 | " cpu_printf(\"\\t(escape to state %%d)\\n\", t->st);", |
| 2781 | "#endif", |
| 2782 | "#endif", |
| 2783 | "#ifdef RANDOMIZE", |
| 2784 | " cpu_printf(\"\\t(randomizer %%d)\\n\", ooi);", |
| 2785 | "#endif", |
| 2786 | "#endif", |
| 2787 | |
| 2788 | "#ifdef HAS_LAST", |
| 2789 | "#ifdef VERI", |
| 2790 | " if (II != 0)", |
| 2791 | "#endif", |
| 2792 | " now._last = II - BASE;", |
| 2793 | "#endif", |
| 2794 | "#ifdef HAS_UNLESS", |
| 2795 | " trpt->e_state = t->e_trans;", |
| 2796 | "#endif", |
| 2797 | |
| 2798 | " depth++; trpt++;", |
| 2799 | " trpt->pr = (uchar) II;", |
| 2800 | " trpt->st = tt;", |
| 2801 | " trpt->o_pm &= ~(2|4);", |
| 2802 | " if (t->st > 0)", |
| 2803 | " { ((P0 *)this)->_p = t->st;", |
| 2804 | "/* moved down reached[ot][t->st] = 1; */", |
| 2805 | " }", |
| 2806 | "#ifndef SAFETY", |
| 2807 | " if (a_cycles)", |
| 2808 | " {", |
| 2809 | "#if (ACCEPT_LAB>0 && !defined(NP)) || (PROG_LAB>0 && defined(HAS_NP))", |
| 2810 | " int ii;", |
| 2811 | "#endif", |
| 2812 | "#define P__Q ((P0 *)pptr(ii))", |
| 2813 | "#if ACCEPT_LAB>0", |
| 2814 | "#ifdef NP", |
| 2815 | " /* state 1 of np_ claim is accepting */", |
| 2816 | " if (((P0 *)pptr(0))->_p == 1)", |
| 2817 | " trpt->o_pm |= 2;", |
| 2818 | "#else", |
| 2819 | " for (ii = 0; ii < (int) now._nr_pr; ii++)", |
| 2820 | " { if (accpstate[P__Q->_t][P__Q->_p])", |
| 2821 | " { trpt->o_pm |= 2;", |
| 2822 | " break;", |
| 2823 | " } }", |
| 2824 | "#endif", |
| 2825 | "#endif", |
| 2826 | "#if defined(HAS_NP) && PROG_LAB>0", |
| 2827 | " for (ii = 0; ii < (int) now._nr_pr; ii++)", |
| 2828 | " { if (progstate[P__Q->_t][P__Q->_p])", |
| 2829 | " { trpt->o_pm |= 4;", |
| 2830 | " break;", |
| 2831 | " } }", |
| 2832 | "#endif", |
| 2833 | "#undef P__Q", |
| 2834 | " }", |
| 2835 | "#endif", |
| 2836 | " trpt->o_t = t; trpt->o_n = _n;", |
| 2837 | " trpt->o_ot = ot; trpt->o_tt = tt;", |
| 2838 | " trpt->o_To = To; trpt->o_m = _m;", |
| 2839 | " trpt->tau = 0;", |
| 2840 | "#ifdef RANDOMIZE", |
| 2841 | " trpt->oo_i = ooi;", |
| 2842 | "#endif", |
| 2843 | " if (boq != -1 || (t->atom&2))", |
| 2844 | " { trpt->tau |= 8;", |
| 2845 | "#ifdef VERI", |
| 2846 | " /* atomic sequence in claim */", |
| 2847 | " if((trpt-1)->tau&4)", |
| 2848 | " trpt->tau |= 4;", |
| 2849 | " else", |
| 2850 | " trpt->tau &= ~4;", |
| 2851 | " } else", |
| 2852 | " { if ((trpt-1)->tau&4)", |
| 2853 | " trpt->tau &= ~4;", |
| 2854 | " else", |
| 2855 | " trpt->tau |= 4;", |
| 2856 | " }", |
| 2857 | " /* if claim allowed timeout, so */", |
| 2858 | " /* does the next program-step: */", |
| 2859 | " if (((trpt-1)->tau&1) && !(trpt->tau&4))", |
| 2860 | " trpt->tau |= 1;", |
| 2861 | "#else", |
| 2862 | " } else", |
| 2863 | " trpt->tau &= ~8;", |
| 2864 | "#endif", |
| 2865 | " if (boq == -1 && (t->atom&2))", |
| 2866 | " { From = To = II; nlinks++;", |
| 2867 | " } else", |
| 2868 | "#ifdef REVERSE", |
| 2869 | " { From = BASE; To = now._nr_pr-1;", |
| 2870 | "#else", |
| 2871 | " { From = now._nr_pr-1; To = BASE;", |
| 2872 | "#endif", |
| 2873 | " }", |
| 2874 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 2875 | " if (upto > 0)", |
| 2876 | " { Push_Stack_Tree(II, t->t_id);", |
| 2877 | " }", |
| 2878 | "#endif", |
| 2879 | " goto Down; /* pseudo-recursion */", |
| 2880 | "Up:", |
| 2881 | "#ifdef CHECK", |
| 2882 | " cpu_printf(\"%%d: Up - %%s\\n\", depth,", |
| 2883 | " (trpt->tau&4)?\"claim\":\"program\");", |
| 2884 | "#endif", |
| 2885 | "#if NCORE>1", |
| 2886 | " iam_alive();", |
| 2887 | " #ifdef USE_DISK", |
| 2888 | " mem_drain();", |
| 2889 | " #endif", |
| 2890 | "#endif", |
| 2891 | "#if defined(MA) || NCORE>1", |
| 2892 | " if (depth <= 0) return;", |
| 2893 | " /* e.g., if first state is old, after a restart */", |
| 2894 | "#endif", |
| 2895 | |
| 2896 | "#ifdef SC", |
| 2897 | " if (CNT1 > CNT2", |
| 2898 | " && depth < hiwater - (HHH-DDD) + 2)", |
| 2899 | " {", |
| 2900 | " trpt += DDD;", |
| 2901 | " disk2stack();", |
| 2902 | " maxdepth -= DDD;", |
| 2903 | " hiwater -= DDD;", |
| 2904 | " if(verbose)", |
| 2905 | " printf(\"unzap %%d: %%d\\n\", CNT2, hiwater);", |
| 2906 | " }", |
| 2907 | "#endif", |
| 2908 | |
| 2909 | "#ifndef NOFAIR", |
| 2910 | " if (trpt->o_pm&128) /* fairness alg */", |
| 2911 | " { now._cnt[now._a_t&1] = trpt->bup.oval;", |
| 2912 | " _n = 1; trpt->o_pm &= ~128;", |
| 2913 | " depth--; trpt--;", |
| 2914 | "#if defined(VERBOSE) || defined(CHECK)", |
| 2915 | " printf(\"%%3d: reversed fairness default move\\n\", depth);", |
| 2916 | "#endif", |
| 2917 | " goto Q999;", |
| 2918 | " }", |
| 2919 | "#endif", |
| 2920 | |
| 2921 | "#ifdef HAS_LAST", |
| 2922 | "#ifdef VERI", |
| 2923 | " { int d; Trail *trl;", |
| 2924 | " now._last = 0;", |
| 2925 | " for (d = 1; d < depth; d++)", |
| 2926 | " { trl = getframe(depth-d); /* was (trpt-d) */", |
| 2927 | " if (trl->pr != 0)", |
| 2928 | " { now._last = trl->pr - BASE;", |
| 2929 | " break;", |
| 2930 | " } } }", |
| 2931 | "#else", |
| 2932 | " now._last = (depth<1)?0:(trpt-1)->pr;", |
| 2933 | "#endif", |
| 2934 | "#endif", |
| 2935 | "#ifdef EVENT_TRACE", |
| 2936 | " now._event = trpt->o_event;", |
| 2937 | "#endif", |
| 2938 | "#ifndef SAFETY", |
| 2939 | " if ((now._a_t&1) && depth <= A_depth)", |
| 2940 | " return; /* to checkcycles() */", |
| 2941 | "#endif", |
| 2942 | " t = trpt->o_t; _n = trpt->o_n;", |
| 2943 | " ot = trpt->o_ot; II = trpt->pr;", |
| 2944 | " tt = trpt->o_tt; this = pptr(II);", |
| 2945 | " To = trpt->o_To; _m = trpt->o_m;", |
| 2946 | "#ifdef RANDOMIZE", |
| 2947 | " ooi = trpt->oo_i;", |
| 2948 | "#endif", |
| 2949 | "#ifdef INLINE_REV", |
| 2950 | " _m = do_reverse(t, II, _m);", |
| 2951 | "#else", |
| 2952 | "#include REVERSE_MOVES", |
| 2953 | "R999: /* jumps here when done */", |
| 2954 | "#endif", |
| 2955 | |
| 2956 | "#ifdef VERBOSE", |
| 2957 | " cpu_printf(\"%%3d: proc %%d reverses %%d, %%d to %%d\\n\",", |
| 2958 | " depth, II, t->forw, tt, t->st);", |
| 2959 | " cpu_printf(\"\\t%%s [abit=%%d,adepth=%%d,tau=%%d,%%d]\\n\", ", |
| 2960 | " t->tp, now._a_t, A_depth, trpt->tau, (trpt-1)->tau);", |
| 2961 | "#endif", |
| 2962 | "#ifndef NOREDUCE", |
| 2963 | " /* pass the proviso tags */", |
| 2964 | " if ((trpt->tau&8) /* rv or atomic */", |
| 2965 | " && (trpt->tau&16))", |
| 2966 | " (trpt-1)->tau |= 16;", /* pass upward */ |
| 2967 | "#ifdef SAFETY", |
| 2968 | " if ((trpt->tau&8) /* rv or atomic */", |
| 2969 | " && (trpt->tau&64))", |
| 2970 | " (trpt-1)->tau |= 64;", |
| 2971 | "#endif", |
| 2972 | "#endif", |
| 2973 | " depth--; trpt--;", |
| 2974 | "", |
| 2975 | "#ifdef NSUCC", |
| 2976 | " trpt->n_succ++;", |
| 2977 | "#endif", |
| 2978 | "#ifdef NIBIS", |
| 2979 | " (trans[ot][tt])->om = _m; /* head of list */", |
| 2980 | "#endif", |
| 2981 | |
| 2982 | " /* i.e., not set if rv fails */", |
| 2983 | " if (_m)", |
| 2984 | " {", |
| 2985 | "#if defined(VERI) && !defined(NP)", |
| 2986 | " if (II == 0 && verbose && !reached[ot][t->st])", |
| 2987 | " {", |
| 2988 | " printf(\"depth %%d: Claim reached state %%d (line %%d)\\n\",", |
| 2989 | " depth, t->st, src_claim [t->st]);", |
| 2990 | " fflush(stdout);", |
| 2991 | " }", |
| 2992 | "#endif", |
| 2993 | " reached[ot][t->st] = 1;", |
| 2994 | " reached[ot][tt] = 1;", |
| 2995 | " }", |
| 2996 | "#ifdef HAS_UNLESS", |
| 2997 | " else trpt->e_state = 0; /* undo */", |
| 2998 | "#endif", |
| 2999 | |
| 3000 | " if (_m>_n||(_n>3&&_m!=0)) _n=_m;", |
| 3001 | " ((P0 *)this)->_p = tt;", |
| 3002 | " } /* all options */", |
| 3003 | |
| 3004 | "#ifdef RANDOMIZE", |
| 3005 | " if (!t && ooi > 0)", /* means we skipped some initial options */ |
| 3006 | " { t = trans[ot][tt];", |
| 3007 | " #ifdef VERBOSE", |
| 3008 | " printf(\"randomizer: continue for %%d more\\n\", ooi);", |
| 3009 | " #endif", |
| 3010 | " goto domore;", |
| 3011 | " }", |
| 3012 | " #ifdef VERBOSE", |
| 3013 | " else", |
| 3014 | " printf(\"randomizer: done\\n\");", |
| 3015 | " #endif", |
| 3016 | "#endif", |
| 3017 | |
| 3018 | "#ifndef NOFAIR", |
| 3019 | " /* Fairness: undo Rule 2 */", |
| 3020 | " if ((trpt->o_pm&32)",/* rule 2 was applied */ |
| 3021 | " && (trpt->o_pm&64))",/* by this process II */ |
| 3022 | " { if (trpt->o_pm&1)",/* it didn't block */ |
| 3023 | " {", |
| 3024 | "#ifdef VERI", |
| 3025 | " if (now._cnt[now._a_t&1] == 1)", |
| 3026 | " now._cnt[now._a_t&1] = 2;", |
| 3027 | "#endif", |
| 3028 | " now._cnt[now._a_t&1] += 1;", |
| 3029 | "#ifdef VERBOSE", |
| 3030 | " printf(\"%%3d: proc %%d fairness \", depth, II);", |
| 3031 | " printf(\"undo Rule 2, cnt=%%d, _a_t=%%d\\n\",", |
| 3032 | " now._cnt[now._a_t&1], now._a_t);", |
| 3033 | "#endif", |
| 3034 | " trpt->o_pm &= ~(32|64);", |
| 3035 | " } else", /* process blocked */ |
| 3036 | " { if (_n > 0)", /* a prev proc didn't */ |
| 3037 | " {", /* start over */ |
| 3038 | " trpt->o_pm &= ~64;", |
| 3039 | "#ifdef REVERSE", |
| 3040 | " II = From-1;", /* after loop incr II == From */ |
| 3041 | "#else", |
| 3042 | " II = From+1;", /* after loop decr II == From */ |
| 3043 | "#endif", |
| 3044 | " } } }", |
| 3045 | "#endif", |
| 3046 | |
| 3047 | "#ifdef VERI", |
| 3048 | " if (II == 0) break; /* never claim */", |
| 3049 | "#endif", |
| 3050 | " } /* all processes */", |
| 3051 | |
| 3052 | "#ifdef NSUCC", |
| 3053 | " tally_succ(trpt->n_succ);", |
| 3054 | "#endif", |
| 3055 | |
| 3056 | "#ifdef SCHED", |
| 3057 | " if (_n == 0 /* no process could move */", |
| 3058 | " #ifdef VERI", |
| 3059 | " && II != 0", |
| 3060 | " #endif", |
| 3061 | " && depth > 0", |
| 3062 | " && trpt->sched_limit >= sched_max)", |
| 3063 | " { _n = 1; /* not a deadlock */", |
| 3064 | " }", |
| 3065 | "#endif", |
| 3066 | |
| 3067 | "#ifndef NOFAIR", |
| 3068 | " /* Fairness: undo Rule 2 */", |
| 3069 | " if (trpt->o_pm&32) /* remains if proc blocked */", |
| 3070 | " {", |
| 3071 | "#ifdef VERI", |
| 3072 | " if (now._cnt[now._a_t&1] == 1)", |
| 3073 | " now._cnt[now._a_t&1] = 2;", |
| 3074 | "#endif", |
| 3075 | " now._cnt[now._a_t&1] += 1;", |
| 3076 | "#ifdef VERBOSE", |
| 3077 | " printf(\"%%3d: proc -- fairness \", depth);", |
| 3078 | " printf(\"undo Rule 2, cnt=%%d, _a_t=%%d\\n\",", |
| 3079 | " now._cnt[now._a_t&1], now._a_t);", |
| 3080 | "#endif", |
| 3081 | " trpt->o_pm &= ~32;", |
| 3082 | " }", |
| 3083 | "#ifndef NP", |
| 3084 | /* 12/97 non-progress cycles cannot be created |
| 3085 | * by stuttering extension, here or elsewhere |
| 3086 | */ |
| 3087 | " if (fairness", |
| 3088 | " && _n == 0 /* nobody moved */", |
| 3089 | "#ifdef VERI", |
| 3090 | " && !(trpt->tau&4) /* in program move */", |
| 3091 | "#endif", |
| 3092 | " && !(trpt->tau&8) /* not an atomic one */", |
| 3093 | "#ifdef OTIM", |
| 3094 | " && ((trpt->tau&1) || endstate())", |
| 3095 | "#else", |
| 3096 | "#ifdef ETIM", |
| 3097 | " && (trpt->tau&1) /* already tried timeout */", |
| 3098 | "#endif", |
| 3099 | "#endif", |
| 3100 | "#ifndef NOREDUCE", |
| 3101 | " /* see below */", |
| 3102 | " && !((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", |
| 3103 | "#endif", |
| 3104 | " && now._cnt[now._a_t&1] > 0) /* needed more procs */", |
| 3105 | " { depth++; trpt++;", |
| 3106 | " trpt->o_pm |= 128 | ((trpt-1)->o_pm&(2|4));", |
| 3107 | " trpt->bup.oval = now._cnt[now._a_t&1];", |
| 3108 | " now._cnt[now._a_t&1] = 1;", |
| 3109 | "#ifdef VERI", |
| 3110 | " trpt->tau = 4;", |
| 3111 | "#else", |
| 3112 | " trpt->tau = 0;", |
| 3113 | "#endif", |
| 3114 | "#ifdef REVERSE", |
| 3115 | " From = BASE; To = now._nr_pr-1;", |
| 3116 | "#else", |
| 3117 | " From = now._nr_pr-1; To = BASE;", |
| 3118 | "#endif", |
| 3119 | "#if defined(VERBOSE) || defined(CHECK)", |
| 3120 | " printf(\"%%3d: fairness default move \", depth);", |
| 3121 | " printf(\"(all procs block)\\n\");", |
| 3122 | "#endif", |
| 3123 | " goto Down;", |
| 3124 | " }", |
| 3125 | "#endif", |
| 3126 | "Q999: /* returns here with _n>0 when done */;", |
| 3127 | |
| 3128 | " if (trpt->o_pm&8)", |
| 3129 | " { now._a_t &= ~2;", |
| 3130 | " now._cnt[now._a_t&1] = 0;", |
| 3131 | " trpt->o_pm &= ~8;", |
| 3132 | "#ifdef VERBOSE", |
| 3133 | " printf(\"%%3d: fairness undo Rule 1, _a_t=%%d\\n\",", |
| 3134 | " depth, now._a_t);", |
| 3135 | "#endif", |
| 3136 | " }", |
| 3137 | " if (trpt->o_pm&16)", |
| 3138 | " { now._a_t |= 2;", /* restore a-bit */ |
| 3139 | " now._cnt[now._a_t&1] = 1;", /* NEW: restore cnt */ |
| 3140 | " trpt->o_pm &= ~16;", |
| 3141 | "#ifdef VERBOSE", |
| 3142 | " printf(\"%%3d: fairness undo Rule 3, _a_t=%%d\\n\",", |
| 3143 | " depth, now._a_t);", |
| 3144 | "#endif", |
| 3145 | " }", |
| 3146 | "#endif", |
| 3147 | |
| 3148 | "#ifndef NOREDUCE", |
| 3149 | "#ifdef SAFETY", |
| 3150 | "#ifdef LOOPSTATE", |
| 3151 | " /* at least one move that was preselected at this */", |
| 3152 | " /* level, blocked or was a loop control flow point */", |
| 3153 | " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", |
| 3154 | "#else", |
| 3155 | " /* preselected move - no successors outside stack */", |
| 3156 | " if ((trpt->tau&32) && !(trpt->tau&64))", |
| 3157 | "#endif", |
| 3158 | "#ifdef REVERSE", |
| 3159 | " { From = BASE; To = now._nr_pr-1;", |
| 3160 | "#else", |
| 3161 | " { From = now._nr_pr-1; To = BASE;", |
| 3162 | "#endif", |
| 3163 | "#ifdef DEBUG", |
| 3164 | " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", |
| 3165 | " depth, II+1, _n, trpt->tau);", |
| 3166 | "#endif", |
| 3167 | " _n = 0; trpt->tau &= ~(16|32|64);", |
| 3168 | "#ifdef REVERSE", |
| 3169 | " if (II <= To) /* II already decremented */", |
| 3170 | "#else", |
| 3171 | " if (II >= BASE) /* II already decremented */", |
| 3172 | "#endif", |
| 3173 | " goto Resume;", |
| 3174 | " else", |
| 3175 | " goto Again;", |
| 3176 | " }", |
| 3177 | "#else", |
| 3178 | " /* at least one move that was preselected at this */", |
| 3179 | " /* level, blocked or truncated at the next level */", |
| 3180 | "/* implied: #ifdef FULLSTACK */", |
| 3181 | " if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16)))", |
| 3182 | " {", |
| 3183 | "#ifdef DEBUG", |
| 3184 | " printf(\"%%3d: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ", |
| 3185 | " depth, II+1, (int) _n, trpt->tau);", |
| 3186 | "#endif", |
| 3187 | " if (a_cycles && (trpt->tau&16))", |
| 3188 | " { if (!(now._a_t&1))", |
| 3189 | " {", |
| 3190 | "#ifdef DEBUG", |
| 3191 | " printf(\"%%3d: setting proviso bit\\n\", depth);", |
| 3192 | "#endif", |
| 3193 | "#ifndef BITSTATE", |
| 3194 | "#ifdef MA", |
| 3195 | "#ifdef VERI", |
| 3196 | " (trpt-1)->proviso = 1;", |
| 3197 | "#else", |
| 3198 | " trpt->proviso = 1;", |
| 3199 | "#endif", |
| 3200 | "#else", |
| 3201 | "#ifdef VERI", |
| 3202 | " if ((trpt-1)->ostate)", |
| 3203 | " ((char *)&((trpt-1)->ostate->state))[0] |= 128;", |
| 3204 | "#else", |
| 3205 | " ((char *)&(trpt->ostate->state))[0] |= 128;", |
| 3206 | "#endif", |
| 3207 | "#endif", |
| 3208 | "#else", |
| 3209 | "#ifdef VERI", |
| 3210 | " if ((trpt-1)->ostate)", |
| 3211 | " (trpt-1)->ostate->proviso = 1;", |
| 3212 | "#else", |
| 3213 | " trpt->ostate->proviso = 1;", |
| 3214 | "#endif", |
| 3215 | "#endif", |
| 3216 | "#ifdef REVERSE", |
| 3217 | " From = BASE; To = now._nr_pr-1;", |
| 3218 | "#else", |
| 3219 | " From = now._nr_pr-1; To = BASE;", |
| 3220 | "#endif", |
| 3221 | " _n = 0; trpt->tau &= ~(16|32|64);", |
| 3222 | " goto Again; /* do full search */", |
| 3223 | " } /* else accept reduction */", |
| 3224 | " } else", |
| 3225 | "#ifdef REVERSE", |
| 3226 | " { From = BASE; To = now._nr_pr-1;", |
| 3227 | "#else", |
| 3228 | " { From = now._nr_pr-1; To = BASE;", |
| 3229 | "#endif", |
| 3230 | " _n = 0; trpt->tau &= ~(16|32|64);", |
| 3231 | "#ifdef REVERSE", |
| 3232 | " if (II <= To) /* already decremented */", |
| 3233 | "#else", |
| 3234 | " if (II >= BASE) /* already decremented */", |
| 3235 | "#endif", |
| 3236 | " goto Resume;", |
| 3237 | " else", |
| 3238 | " goto Again;", |
| 3239 | " } }", |
| 3240 | "/* #endif */", |
| 3241 | "#endif", |
| 3242 | "#endif", |
| 3243 | |
| 3244 | " if (_n == 0 || ((trpt->tau&4) && (trpt->tau&2)))", |
| 3245 | " {", |
| 3246 | "#ifdef DEBUG", |
| 3247 | " cpu_printf(\"%%3d: no move [II=%%d, tau=%%d, boq=%%d]\\n\",", |
| 3248 | " depth, II, trpt->tau, boq);", |
| 3249 | "#endif", |
| 3250 | "#if SYNC", |
| 3251 | " /* ok if a rendez-vous fails: */", |
| 3252 | " if (boq != -1) goto Done;", |
| 3253 | "#endif", |
| 3254 | " /* ok if no procs or we're at maxdepth */", |
| 3255 | " if ((now._nr_pr == 0 && (!strict || qs_empty()))", |
| 3256 | "#ifdef OTIM", |
| 3257 | " || endstate()", |
| 3258 | "#endif", |
| 3259 | " || depth >= maxdepth-1) goto Done;", |
| 3260 | |
| 3261 | " if ((trpt->tau&8) && !(trpt->tau&4))", |
| 3262 | " { trpt->tau &= ~(1|8);", |
| 3263 | " /* 1=timeout, 8=atomic */", |
| 3264 | "#ifdef REVERSE", |
| 3265 | " From = BASE; To = now._nr_pr-1;", |
| 3266 | "#else", |
| 3267 | " From = now._nr_pr-1; To = BASE;", |
| 3268 | "#endif", |
| 3269 | "#ifdef DEBUG", |
| 3270 | " cpu_printf(\"%%3d: atomic step proc %%d unexecutable\\n\", depth, II+1);", |
| 3271 | "#endif", |
| 3272 | "#ifdef VERI", |
| 3273 | " trpt->tau |= 4; /* switch to claim */", |
| 3274 | "#endif", |
| 3275 | " goto AllOver;", |
| 3276 | " }", |
| 3277 | |
| 3278 | "#ifdef ETIM", |
| 3279 | " if (!(trpt->tau&1)) /* didn't try timeout yet */", |
| 3280 | " {", |
| 3281 | "#ifdef VERI", |
| 3282 | " if (trpt->tau&4)", |
| 3283 | " {", |
| 3284 | "#ifndef NTIM", |
| 3285 | " if (trpt->tau&2) /* requested */", |
| 3286 | "#endif", |
| 3287 | " { trpt->tau |= 1;", |
| 3288 | " trpt->tau &= ~2;", |
| 3289 | "#ifdef DEBUG", |
| 3290 | " cpu_printf(\"%%d: timeout\\n\", depth);", |
| 3291 | "#endif", |
| 3292 | " goto Stutter;", |
| 3293 | " } }", |
| 3294 | " else", |
| 3295 | " { /* only claim can enable timeout */", |
| 3296 | " if ((trpt->tau&8)", |
| 3297 | " && !((trpt-1)->tau&4))", |
| 3298 | "/* blocks inside an atomic */ goto BreakOut;", |
| 3299 | "#ifdef DEBUG", |
| 3300 | " cpu_printf(\"%%d: req timeout\\n\",", |
| 3301 | " depth);", |
| 3302 | "#endif", |
| 3303 | " (trpt-1)->tau |= 2; /* request */", |
| 3304 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 3305 | " if (upto > 0)", |
| 3306 | " { Pop_Stack_Tree();", |
| 3307 | " }", |
| 3308 | "#endif", |
| 3309 | " goto Up;", |
| 3310 | " }", |
| 3311 | "#else", |
| 3312 | |
| 3313 | "#ifdef DEBUG", |
| 3314 | " cpu_printf(\"%%d: timeout\\n\", depth);", |
| 3315 | "#endif", |
| 3316 | " trpt->tau |= 1;", |
| 3317 | " goto Again;", |
| 3318 | "#endif", |
| 3319 | " }", |
| 3320 | "#endif", |
| 3321 | |
| 3322 | /* old location of atomic block code */ |
| 3323 | "#ifdef VERI", |
| 3324 | "BreakOut:", |
| 3325 | "#ifndef NOSTUTTER", |
| 3326 | " if (!(trpt->tau&4))", |
| 3327 | " { trpt->tau |= 4; /* claim stuttering */", |
| 3328 | " trpt->tau |= 128; /* stutter mark */", |
| 3329 | "#ifdef DEBUG", |
| 3330 | " cpu_printf(\"%%d: claim stutter\\n\", depth);", |
| 3331 | "#endif", |
| 3332 | " goto Stutter;", |
| 3333 | " }", |
| 3334 | "#else", |
| 3335 | " ;", |
| 3336 | "#endif", |
| 3337 | "#else", |
| 3338 | " if (!noends && !a_cycles && !endstate())", |
| 3339 | " { depth--; trpt--; /* new 4.2.3 */", |
| 3340 | " uerror(\"invalid end state\");", |
| 3341 | " depth++; trpt++;", |
| 3342 | " }", |
| 3343 | "#ifndef NOSTUTTER", |
| 3344 | " else if (a_cycles && (trpt->o_pm&2)) /* new 4.2.4 */", |
| 3345 | " { depth--; trpt--;", |
| 3346 | " uerror(\"accept stutter\");", |
| 3347 | " depth++; trpt++;", |
| 3348 | " }", |
| 3349 | "#endif", |
| 3350 | "#endif", |
| 3351 | " }", |
| 3352 | "Done:", |
| 3353 | " if (!(trpt->tau&8)) /* not in atomic seqs */", |
| 3354 | " {", |
| 3355 | "#ifndef SAFETY", |
| 3356 | " if (_n != 0", /* we made a move */ |
| 3357 | "#ifdef VERI", |
| 3358 | " /* --after-- a program-step, i.e., */", |
| 3359 | " /* after backtracking a claim-step */", |
| 3360 | " && (trpt->tau&4)", |
| 3361 | " /* with at least one running process */", |
| 3362 | " /* unless in a stuttered accept state */", |
| 3363 | " && ((now._nr_pr > 1) || (trpt->o_pm&2))", |
| 3364 | "#endif", |
| 3365 | " && !(now._a_t&1))", /* not in 2nd DFS */ |
| 3366 | " {", |
| 3367 | "#ifndef NOFAIR", |
| 3368 | " if (fairness)", /* implies a_cycles */ |
| 3369 | " {", |
| 3370 | "#ifdef VERBOSE", |
| 3371 | " cpu_printf(\"Consider check %%d %%d...\\n\",", |
| 3372 | " now._a_t, now._cnt[0]);", |
| 3373 | "#endif", |
| 3374 | #if 0 |
| 3375 | the a-bit is set, which means that the fairness |
| 3376 | counter is running -- it was started in an accepting state. |
| 3377 | we check that the counter reached 1, which means that all |
| 3378 | processes moved least once. |
| 3379 | this means we can start the search for cycles - |
| 3380 | to be able to return to this state, we should be able to |
| 3381 | run down the counter to 1 again -- which implies a visit to |
| 3382 | the accepting state -- even though the Seed state for this |
| 3383 | search is itself not necessarily accepting |
| 3384 | #endif |
| 3385 | " if ((now._a_t&2) /* A-bit */", |
| 3386 | " && (now._cnt[0] == 1))", |
| 3387 | " checkcycles();", |
| 3388 | " } else", |
| 3389 | "#endif", |
| 3390 | " if (a_cycles && (trpt->o_pm&2))", |
| 3391 | " checkcycles();", |
| 3392 | " }", |
| 3393 | "#endif", |
| 3394 | "#ifndef MA", |
| 3395 | "#if defined(FULLSTACK) || defined(CNTRSTACK)", |
| 3396 | "#ifdef VERI", |
| 3397 | " if (boq == -1", |
| 3398 | " && (((trpt->tau&4) && !(trpt->tau&128))", |
| 3399 | " || ( (trpt-1)->tau&128)))", |
| 3400 | "#else", |
| 3401 | " if (boq == -1)", |
| 3402 | "#endif", |
| 3403 | " {", |
| 3404 | "#ifdef DEBUG2", |
| 3405 | "#if defined(FULLSTACK)", |
| 3406 | " printf(\"%%d: zapping %%u (%%d)\\n\",", |
| 3407 | " depth, trpt->ostate,", |
| 3408 | " (trpt->ostate)?trpt->ostate->tagged:0);", |
| 3409 | "#endif", |
| 3410 | "#endif", |
| 3411 | " onstack_zap();", |
| 3412 | " }", |
| 3413 | "#endif", |
| 3414 | "#else", |
| 3415 | "#ifdef VERI", |
| 3416 | " if (boq == -1", |
| 3417 | " && (((trpt->tau&4) && !(trpt->tau&128))", |
| 3418 | " || ( (trpt-1)->tau&128)))", |
| 3419 | "#else", |
| 3420 | " if (boq == -1)", |
| 3421 | "#endif", |
| 3422 | " {", |
| 3423 | "#ifdef DEBUG", |
| 3424 | " printf(\"%%d: zapping\\n\", depth);", |
| 3425 | "#endif", |
| 3426 | " onstack_zap();", |
| 3427 | "#ifndef NOREDUCE", |
| 3428 | " if (trpt->proviso)", |
| 3429 | " gstore((char *) &now, vsize, 1);", |
| 3430 | "#endif", |
| 3431 | " }", |
| 3432 | "#endif", |
| 3433 | " }", |
| 3434 | " if (depth > 0)", |
| 3435 | " {", |
| 3436 | "#if NCORE>1 && defined(FULL_TRAIL)", |
| 3437 | " if (upto > 0)", |
| 3438 | " { Pop_Stack_Tree();", |
| 3439 | " }", |
| 3440 | "#endif", |
| 3441 | " goto Up;", |
| 3442 | " }", |
| 3443 | "}\n", |
| 3444 | "#else", |
| 3445 | "void new_state(void) { /* place holder */ }", |
| 3446 | "#endif", /* BFS */ |
| 3447 | "", |
| 3448 | "void", |
| 3449 | "assert(int a, char *s, int ii, int tt, Trans *t)", |
| 3450 | "{", |
| 3451 | " if (!a && !noasserts)", |
| 3452 | " { char bad[1024];", |
| 3453 | " strcpy(bad, \"assertion violated \");", |
| 3454 | " if (strlen(s) > 1000)", |
| 3455 | " { strncpy(&bad[19], (const char *) s, 1000);", |
| 3456 | " bad[1019] = '\\0';", |
| 3457 | " } else", |
| 3458 | " strcpy(&bad[19], s);", |
| 3459 | " uerror(bad);", |
| 3460 | " }", |
| 3461 | "}", |
| 3462 | "#ifndef NOBOUNDCHECK", |
| 3463 | "int", |
| 3464 | "Boundcheck(int x, int y, int a1, int a2, Trans *a3)", |
| 3465 | "{", |
| 3466 | " assert((x >= 0 && x < y), \"- invalid array index\",", |
| 3467 | " a1, a2, a3);", |
| 3468 | " return x;", |
| 3469 | "}", |
| 3470 | "#endif", |
| 3471 | "void", |
| 3472 | "wrap_stats(void)", |
| 3473 | "{", |
| 3474 | " if (nShadow>0)", |
| 3475 | " printf(\"%%9.8g states, stored (%%g visited)\\n\",", |
| 3476 | " nstates - nShadow, nstates);", |
| 3477 | " else", |
| 3478 | " printf(\"%%9.8g states, stored\\n\", nstates);", |
| 3479 | "#ifdef BFS", |
| 3480 | "#if SYNC", |
| 3481 | " printf(\" %%8g nominal states (- rv and atomic)\\n\", nstates-midrv-nlinks+revrv);", |
| 3482 | " printf(\" %%8g rvs succeeded\\n\", midrv-failedrv);", |
| 3483 | "#else", |
| 3484 | " printf(\" %%8g nominal states (stored-atomic)\\n\", nstates-nlinks);", |
| 3485 | "#endif", |
| 3486 | "#ifdef DEBUG", |
| 3487 | " printf(\" %%8g midrv\\n\", midrv);", |
| 3488 | " printf(\" %%8g failedrv\\n\", failedrv);", |
| 3489 | " printf(\" %%8g revrv\\n\", revrv);", |
| 3490 | "#endif", |
| 3491 | "#endif", |
| 3492 | " printf(\"%%9.8g states, matched\\n\", truncs);", |
| 3493 | "#ifdef CHECK", |
| 3494 | " printf(\"%%9.8g matches within stack\\n\",truncs2);", |
| 3495 | "#endif", |
| 3496 | " if (nShadow>0)", |
| 3497 | " printf(\"%%9.8g transitions (= visited+matched)\\n\",", |
| 3498 | " nstates+truncs);", |
| 3499 | " else", |
| 3500 | " printf(\"%%9.8g transitions (= stored+matched)\\n\",", |
| 3501 | " nstates+truncs);", |
| 3502 | " printf(\"%%9.8g atomic steps\\n\", nlinks);", |
| 3503 | " if (nlost) printf(\"%%g lost messages\\n\", (double) nlost);", |
| 3504 | "", |
| 3505 | "#ifndef BITSTATE", |
| 3506 | " printf(\"hash conflicts: %%9.8g (resolved)\\n\", hcmp);", |
| 3507 | " #ifndef AUTO_RESIZE", |
| 3508 | " if (hcmp > (double) (1<<ssize))", |
| 3509 | " { printf(\"hint: increase hashtable-size (-w) to reduce runtime\\n\");", |
| 3510 | " } /* in multi-core: also reduces lock delays on access to hashtable */", |
| 3511 | " #endif", |
| 3512 | "#else", |
| 3513 | "#ifdef CHECK", |
| 3514 | " printf(\"%%8g states allocated for dfs stack\\n\", ngrabs);", |
| 3515 | "#endif", |
| 3516 | " if (udmem)", |
| 3517 | " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",", |
| 3518 | " (double)(((double) udmem) * 8.0) / (double) nstates);", |
| 3519 | " else", |
| 3520 | " printf(\"\\nhash factor: %%4g (best if > 100.)\\n\\n\",", |
| 3521 | " (double)(1<<(ssize-8)) / (double) nstates * 256.0);", |
| 3522 | " printf(\"bits set per state: %%u (-k%%u)\\n\", hfns, hfns);", |
| 3523 | " #if 0", |
| 3524 | #ifndef POWOW |
| 3525 | " if (udmem)", |
| 3526 | " { printf(\"total bits available: %%8g (-M%%ld)\\n\",", |
| 3527 | " ((double) udmem) * 8.0, udmem/(1024L*1024L));", |
| 3528 | " } else", |
| 3529 | #endif |
| 3530 | " printf(\"total bits available: %%8g (-w%%d)\\n\",", |
| 3531 | " ((double) (ONE_L << (ssize-4)) * 16.0), ssize);", |
| 3532 | " #endif", |
| 3533 | "#endif", |
| 3534 | "#ifdef BFS_DISK", |
| 3535 | " printf(\"bfs disk reads: %%ld writes %%ld -- diff %%ld\\n\",", |
| 3536 | " bfs_dsk_reads, bfs_dsk_writes, bfs_dsk_writes-bfs_dsk_reads);", |
| 3537 | " if (bfs_dsk_read >= 0) (void) close(bfs_dsk_read);", |
| 3538 | " if (bfs_dsk_write >= 0) (void) close(bfs_dsk_write);", |
| 3539 | " (void) unlink(\"pan_bfs_dsk.tmp\");", |
| 3540 | "#endif", |
| 3541 | "}", |
| 3542 | "", |
| 3543 | "void", |
| 3544 | "wrapup(void)", |
| 3545 | "{", |
| 3546 | "#if defined(BITSTATE) || !defined(NOCOMP)", |
| 3547 | " double nr1, nr2, nr3 = 0.0, nr4, nr5 = 0.0;", |
| 3548 | " #if !defined(MA) && (defined(MEMCNT) || defined(MEMLIM))", |
| 3549 | " int mverbose = 1;", |
| 3550 | " #else", |
| 3551 | " int mverbose = verbose;", |
| 3552 | " #endif", |
| 3553 | "#endif", |
| 3554 | "#if NCORE>1", |
| 3555 | " if (verbose) cpu_printf(\"wrapup -- %%d error(s)\\n\", errors);", |
| 3556 | " if (core_id != 0)", |
| 3557 | " {", |
| 3558 | "#ifdef USE_DISK", |
| 3559 | " void dsk_stats(void);", |
| 3560 | " dsk_stats();", |
| 3561 | "#endif", |
| 3562 | " if (search_terminated != NULL)", |
| 3563 | " { *search_terminated |= 2; /* wrapup */", |
| 3564 | " }", |
| 3565 | " exit(0); /* normal termination, not an error */", |
| 3566 | " }", |
| 3567 | "#endif", |
| 3568 | "#if !defined(WIN32) && !defined(WIN64)", |
| 3569 | " signal(SIGINT, SIG_DFL);", |
| 3570 | "#endif", |
| 3571 | " printf(\"\\n(%%s)\\n\", SpinVersion);", |
| 3572 | " if (!done) printf(\"Warning: Search not completed\\n\");", |
| 3573 | "#ifdef SC", |
| 3574 | " (void) unlink((const char *)stackfile);", |
| 3575 | "#endif", |
| 3576 | "#if NCORE>1", |
| 3577 | " if (a_cycles)", |
| 3578 | " { printf(\" + Multi-Core (NCORE=%%d)\\n\", NCORE);", |
| 3579 | " } else", |
| 3580 | " { printf(\" + Multi-Core (NCORE=%%d -z%%d)\\n\", NCORE, z_handoff);", |
| 3581 | " }", |
| 3582 | "#endif", |
| 3583 | "#ifdef BFS", |
| 3584 | " printf(\" + Using Breadth-First Search\\n\");", |
| 3585 | "#endif", |
| 3586 | "#ifndef NOREDUCE", |
| 3587 | " printf(\" + Partial Order Reduction\\n\");", |
| 3588 | "#endif", |
| 3589 | "#ifdef REVERSE", |
| 3590 | " printf(\" + Reverse Depth-First Search Order\\n\");", |
| 3591 | "#endif", |
| 3592 | "#ifdef T_REVERSE", |
| 3593 | " printf(\" + Reverse Transition Ordering\\n\");", |
| 3594 | "#endif", |
| 3595 | "#ifdef RANDOMIZE", |
| 3596 | " printf(\" + Randomized Transition Ordering\\n\");", |
| 3597 | "#endif", |
| 3598 | "#ifdef SCHED", |
| 3599 | " printf(\" + Scheduling Restriction (-DSCHED=%%d)\\n\", sched_max);", |
| 3600 | "#endif", |
| 3601 | #if 0 |
| 3602 | "#ifdef Q_PROVISO", |
| 3603 | " printf(\" + Queue Proviso\\n\");", |
| 3604 | "#endif", |
| 3605 | #endif |
| 3606 | "#ifdef COLLAPSE", |
| 3607 | " printf(\" + Compression\\n\");", |
| 3608 | "#endif", |
| 3609 | "#ifdef MA", |
| 3610 | " printf(\" + Graph Encoding (-DMA=%%d)\\n\", MA);", |
| 3611 | " #ifdef R_XPT", |
| 3612 | " printf(\" Restarted from checkpoint %%s.xpt\\n\", PanSource);", |
| 3613 | " #endif", |
| 3614 | "#endif", |
| 3615 | "#ifdef CHECK", |
| 3616 | " #ifdef FULLSTACK", |
| 3617 | " printf(\" + FullStack Matching\\n\");", |
| 3618 | " #endif", |
| 3619 | " #ifdef CNTRSTACK", |
| 3620 | " printf(\" + CntrStack Matching\\n\");", |
| 3621 | " #endif", |
| 3622 | "#endif", |
| 3623 | "#ifdef BITSTATE", |
| 3624 | " printf(\"\\nBit statespace search for:\\n\");", |
| 3625 | "#else", |
| 3626 | "#ifdef HC", |
| 3627 | " printf(\"\\nHash-Compact %%d search for:\\n\", HC);", |
| 3628 | "#else", |
| 3629 | " printf(\"\\nFull statespace search for:\\n\");", |
| 3630 | "#endif", |
| 3631 | "#endif", |
| 3632 | "#ifdef EVENT_TRACE", |
| 3633 | "#ifdef NEGATED_TRACE", |
| 3634 | " printf(\"\tnotrace assertion \t+\\n\");", |
| 3635 | "#else", |
| 3636 | " printf(\"\ttrace assertion \t+\\n\");", |
| 3637 | "#endif", |
| 3638 | "#endif", |
| 3639 | "#ifdef VERI", |
| 3640 | " printf(\"\tnever claim \t+\\n\");", |
| 3641 | " printf(\"\tassertion violations\t\");", |
| 3642 | " if (noasserts)", |
| 3643 | " printf(\"- (disabled by -A flag)\\n\");", |
| 3644 | " else", |
| 3645 | " printf(\"+ (if within scope of claim)\\n\");", |
| 3646 | "#else", |
| 3647 | "#ifdef NOCLAIM", |
| 3648 | " printf(\"\tnever claim \t- (not selected)\\n\");", |
| 3649 | "#else", |
| 3650 | " printf(\"\tnever claim \t- (none specified)\\n\");", |
| 3651 | "#endif", |
| 3652 | " printf(\"\tassertion violations\t\");", |
| 3653 | " if (noasserts)", |
| 3654 | " printf(\"- (disabled by -A flag)\\n\");", |
| 3655 | " else", |
| 3656 | " printf(\"+\\n\");", |
| 3657 | "#endif", |
| 3658 | "#ifndef SAFETY", |
| 3659 | "#ifdef NP", |
| 3660 | " printf(\"\tnon-progress cycles \t\");", |
| 3661 | "#else", |
| 3662 | " printf(\"\tacceptance cycles \t\");", |
| 3663 | "#endif", |
| 3664 | " if (a_cycles)", |
| 3665 | " printf(\"+ (fairness %%sabled)\\n\",", |
| 3666 | " fairness?\"en\":\"dis\");", |
| 3667 | " else printf(\"- (not selected)\\n\");", |
| 3668 | "#else", |
| 3669 | " printf(\"\tcycle checks \t- (disabled by -DSAFETY)\\n\");", |
| 3670 | "#endif", |
| 3671 | "#ifdef VERI", |
| 3672 | " printf(\"\tinvalid end states\t- \");", |
| 3673 | " printf(\"(disabled by \");", |
| 3674 | " if (noends)", |
| 3675 | " printf(\"-E flag)\\n\\n\");", |
| 3676 | " else", |
| 3677 | " printf(\"never claim)\\n\\n\");", |
| 3678 | "#else", |
| 3679 | " printf(\"\tinvalid end states\t\");", |
| 3680 | " if (noends)", |
| 3681 | " printf(\"- (disabled by -E flag)\\n\\n\");", |
| 3682 | " else", |
| 3683 | " printf(\"+\\n\\n\");", |
| 3684 | "#endif", |
| 3685 | " printf(\"State-vector %%d byte, depth reached %%ld\", hmax,", |
| 3686 | "#if NCORE>1", |
| 3687 | " (nr_handoffs * z_handoff) +", |
| 3688 | "#endif", |
| 3689 | " mreached);", |
| 3690 | " printf(\", errors: %%d\\n\", errors);", |
| 3691 | " fflush(stdout);", |
| 3692 | "#ifdef MA", |
| 3693 | " if (done)", |
| 3694 | " { extern void dfa_stats(void);", |
| 3695 | " if (maxgs+a_cycles+2 < MA)", |
| 3696 | " printf(\"MA stats: -DMA=%%d is sufficient\\n\",", |
| 3697 | " maxgs+a_cycles+2);", |
| 3698 | " dfa_stats();", |
| 3699 | " }", |
| 3700 | "#endif", |
| 3701 | " wrap_stats();", |
| 3702 | "#ifdef CHECK", |
| 3703 | " printf(\"stackframes: %%d/%%d\\n\\n\", smax, svmax);", |
| 3704 | " printf(\"stats: fa %%d, fh %%d, zh %%d, zn %%d - \",", |
| 3705 | " Fa, Fh, Zh, Zn);", |
| 3706 | " printf(\"check %%d holds %%d\\n\", Ccheck, Cholds);", |
| 3707 | " printf(\"stack stats: puts %%d, probes %%d, zaps %%d\\n\",", |
| 3708 | " PUT, PROBE, ZAPS);", |
| 3709 | "#else", |
| 3710 | " printf(\"\\n\");", |
| 3711 | "#endif", |
| 3712 | "", |
| 3713 | "#if defined(BITSTATE) || !defined(NOCOMP)", |
| 3714 | " nr1 = (nstates-nShadow)*", |
| 3715 | " (double)(hmax+sizeof(struct H_el)-sizeof(unsigned));", |
| 3716 | "#ifdef BFS", |
| 3717 | " nr2 = 0.0;", |
| 3718 | "#else", |
| 3719 | " nr2 = (double) ((maxdepth+3)*sizeof(Trail));", |
| 3720 | "#endif", |
| 3721 | |
| 3722 | "#ifndef BITSTATE", |
| 3723 | "#if !defined(MA) || defined(COLLAPSE)", |
| 3724 | " nr3 = (double) (ONE_L<<ssize)*sizeof(struct H_el *);", |
| 3725 | "#endif", |
| 3726 | "#else", |
| 3727 | #ifndef POWOW |
| 3728 | " if (udmem)", |
| 3729 | " nr3 = (double) (udmem);", |
| 3730 | " else", |
| 3731 | #endif |
| 3732 | " nr3 = (double) (ONE_L<<(ssize-3));", |
| 3733 | "#ifdef CNTRSTACK", |
| 3734 | " nr5 = (double) (ONE_L<<(ssize-3));", |
| 3735 | "#endif", |
| 3736 | "#ifdef FULLSTACK", |
| 3737 | " nr5 = (double) (maxdepth*sizeof(struct H_el *));", |
| 3738 | "#endif", |
| 3739 | "#endif", |
| 3740 | " nr4 = (double) (svmax * (sizeof(Svtack) + hmax))", |
| 3741 | " + (double) (smax * (sizeof(Stack) + Maxbody));", |
| 3742 | "#ifndef MA", |
| 3743 | " if (mverbose || memcnt < nr1+nr2+nr3+nr4+nr5)", |
| 3744 | "#endif", |
| 3745 | " { double remainder = memcnt;", |
| 3746 | " double tmp_nr = memcnt-nr3-nr4-(nr2-fragment)-nr5;", |
| 3747 | "#if NCORE>1 && !defined(SEP_STATE)", |
| 3748 | " tmp_nr -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE;", |
| 3749 | "#endif", |
| 3750 | " if (tmp_nr < 0.0) tmp_nr = 0.;", |
| 3751 | " printf(\"Stats on memory usage (in Megabytes):\\n\");", |
| 3752 | " printf(\"%%9.3f\tequivalent memory usage for states\",", |
| 3753 | " nr1/1048576.); /* 1024*1024=1048576 */", |
| 3754 | " printf(\" (stored*(State-vector + overhead))\\n\");", |
| 3755 | " #if NCORE>1 && !defined(WIN32) && !defined(WIN64)", |
| 3756 | " printf(\"%%9.3f\tshared memory reserved for state storage\\n\",", |
| 3757 | " mem_reserved/1048576.);", |
| 3758 | " #ifdef SEP_HEAP", |
| 3759 | " printf(\"\t\tin %%d local heaps of %%7.3f MB each\\n\",", |
| 3760 | " NCORE, mem_reserved/(NCORE*1048576.));", |
| 3761 | " #endif", |
| 3762 | " printf(\"\\n\");", |
| 3763 | " #endif", |
| 3764 | "#ifdef BITSTATE", |
| 3765 | #ifndef POWOW |
| 3766 | " if (udmem)", |
| 3767 | " printf(\"%%9.3f\tmemory used for hash array (-M%%ld)\\n\",", |
| 3768 | " nr3/1048576., udmem/(1024L*1024L));", |
| 3769 | " else", |
| 3770 | #endif |
| 3771 | " printf(\"%%9.3f\tmemory used for hash array (-w%%d)\\n\",", |
| 3772 | " nr3/1048576., ssize);", |
| 3773 | " if (nr5 > 0.0)", |
| 3774 | " printf(\"%%9.3f\tmemory used for bit stack\\n\",", |
| 3775 | " nr5/1048576.);", |
| 3776 | " remainder = remainder - nr3 - nr5;", |
| 3777 | "#else", |
| 3778 | " printf(\"%%9.3f\tactual memory usage for states\",", |
| 3779 | " tmp_nr/1048576.);", |
| 3780 | " remainder -= tmp_nr;", |
| 3781 | " printf(\" (\");", |
| 3782 | " if (tmp_nr > 0.)", |
| 3783 | " { if (tmp_nr > nr1) printf(\"unsuccessful \");", |
| 3784 | " printf(\"compression: %%.2f%%%%)\\n\",", |
| 3785 | " (100.0*tmp_nr)/nr1);", |
| 3786 | " } else", |
| 3787 | " printf(\"less than 1k)\\n\");", |
| 3788 | "#ifndef MA", |
| 3789 | " if (tmp_nr > 0.)", |
| 3790 | " { printf(\" \tstate-vector as stored = %%.0f byte\",", |
| 3791 | " (tmp_nr)/(nstates-nShadow) -", |
| 3792 | " (double) (sizeof(struct H_el) - sizeof(unsigned)));", |
| 3793 | " printf(\" + %%ld byte overhead\\n\",", |
| 3794 | " (long int) sizeof(struct H_el)-sizeof(unsigned));", |
| 3795 | " }", |
| 3796 | "#endif", |
| 3797 | "#if !defined(MA) || defined(COLLAPSE)", |
| 3798 | " printf(\"%%9.3f\tmemory used for hash table (-w%%d)\\n\",", |
| 3799 | " nr3/1048576., ssize);", |
| 3800 | " remainder -= nr3;", |
| 3801 | "#endif", |
| 3802 | "#endif", |
| 3803 | "#ifndef BFS", |
| 3804 | " printf(\"%%9.3f\tmemory used for DFS stack (-m%%ld)\\n\",", |
| 3805 | " nr2/1048576., maxdepth);", |
| 3806 | " remainder -= nr2;", |
| 3807 | "#endif", |
| 3808 | "#if NCORE>1", |
| 3809 | " remainder -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE;", |
| 3810 | " printf(\"%%9.3f\tshared memory used for work-queues\\n\",", |
| 3811 | " (GWQ_SIZE + (double) NCORE * LWQ_SIZE) /1048576.);", |
| 3812 | " printf(\"\t\tin %%d queues of %%7.3f MB each\",", |
| 3813 | " NCORE, (double) LWQ_SIZE /1048576.);", |
| 3814 | " #ifndef NGQ", |
| 3815 | " printf(\" + a global q of %%7.3f MB\\n\",", |
| 3816 | " (double) GWQ_SIZE / 1048576.);", |
| 3817 | " #else", |
| 3818 | " printf(\"\\n\");", |
| 3819 | " #endif", |
| 3820 | " #endif", |
| 3821 | " if (remainder - fragment > 1048576.)", |
| 3822 | " printf(\"%%9.3f\tother (proc and chan stacks)\\n\",", |
| 3823 | " (remainder-fragment)/1048576.);", |
| 3824 | " if (fragment > 1048576.)", |
| 3825 | " printf(\"%%9.3f\tmemory lost to fragmentation\\n\",", |
| 3826 | " fragment/1048576.);", |
| 3827 | " printf(\"%%9.3f\ttotal actual memory usage\\n\\n\",", |
| 3828 | " memcnt/1048576.);", |
| 3829 | " }", |
| 3830 | "#ifndef MA", |
| 3831 | " else", |
| 3832 | "#endif", |
| 3833 | "#endif", |
| 3834 | "#ifndef MA", |
| 3835 | " printf(\"%%9.3f\tmemory usage (Mbyte)\\n\\n\",", |
| 3836 | " memcnt/1048576.);", |
| 3837 | "#endif", |
| 3838 | "#ifdef COLLAPSE", |
| 3839 | " printf(\"nr of templates: [ globals chans procs ]\\n\");", |
| 3840 | " printf(\"collapse counts: [ \");", |
| 3841 | " { int i; for (i = 0; i < 256+2; i++)", |
| 3842 | " if (ncomps[i] != 0)", |
| 3843 | " printf(\"%%d \", ncomps[i]);", |
| 3844 | " printf(\"]\\n\");", |
| 3845 | " }", |
| 3846 | "#endif", |
| 3847 | |
| 3848 | " if ((done || verbose) && !no_rck) do_reach();", |
| 3849 | "#ifdef PEG", |
| 3850 | " { int i;", |
| 3851 | " printf(\"\\nPeg Counts (transitions executed):\\n\");", |
| 3852 | " for (i = 1; i < NTRANS; i++)", |
| 3853 | " { if (peg[i]) putpeg(i, peg[i]);", |
| 3854 | " } }", |
| 3855 | "#endif", |
| 3856 | "#ifdef VAR_RANGES", |
| 3857 | " dumpranges();", |
| 3858 | "#endif", |
| 3859 | "#ifdef SVDUMP", |
| 3860 | " if (vprefix > 0) close(svfd);", |
| 3861 | "#endif", |
| 3862 | "#ifdef LOOPSTATE", |
| 3863 | " printf(\"%%g loopstates hit\\n\", cnt_loops);", |
| 3864 | "#endif", |
| 3865 | "#ifdef NSUCC", |
| 3866 | " dump_succ();", |
| 3867 | "#endif", |
| 3868 | "#if NCORE>1 && defined(T_ALERT)", |
| 3869 | " crash_report();", |
| 3870 | "#endif", |
| 3871 | " pan_exit(0);", |
| 3872 | "}\n", |
| 3873 | "void", |
| 3874 | "stopped(int arg)", |
| 3875 | "{ printf(\"Interrupted\\n\");", |
| 3876 | "#if NCORE>1", |
| 3877 | " was_interrupted = 1;", |
| 3878 | "#endif", |
| 3879 | " wrapup();", |
| 3880 | " pan_exit(0);", |
| 3881 | "}", |
| 3882 | "", |
| 3883 | "#ifdef SFH", |
| 3884 | "/*", |
| 3885 | " * super fast hash, based on Paul Hsieh's function", |
| 3886 | " * http://www.azillionmonkeys.com/qed/hash.html", |
| 3887 | " */", |
| 3888 | "#include <stdint.h>", /* for uint32_t etc */ |
| 3889 | " #undef get16bits", |
| 3890 | " #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \\", |
| 3891 | " || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)", |
| 3892 | " #define get16bits(d) (*((const uint16_t *) (d)))", |
| 3893 | " #endif", |
| 3894 | "", |
| 3895 | " #ifndef get16bits", |
| 3896 | " #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\\", |
| 3897 | " +(uint32_t)(((const uint8_t *)(d))[0]) )", |
| 3898 | " #endif", |
| 3899 | "", |
| 3900 | "void", |
| 3901 | "d_sfh(const char *s, int len)", |
| 3902 | "{ uint32_t h = len, tmp;", |
| 3903 | " int rem;", |
| 3904 | "", |
| 3905 | " rem = len & 3;", |
| 3906 | " len >>= 2;", |
| 3907 | "", |
| 3908 | " for ( ; len > 0; len--)", |
| 3909 | " { h += get16bits(s);", |
| 3910 | " tmp = (get16bits(s+2) << 11) ^ h;", |
| 3911 | " h = (h << 16) ^ tmp;", |
| 3912 | " s += 2*sizeof(uint16_t);", |
| 3913 | " h += h >> 11;", |
| 3914 | " }", |
| 3915 | " switch (rem) {", |
| 3916 | " case 3: h += get16bits(s);", |
| 3917 | " h ^= h << 16;", |
| 3918 | " h ^= s[sizeof(uint16_t)] << 18;", |
| 3919 | " h += h >> 11;", |
| 3920 | " break;", |
| 3921 | " case 2: h += get16bits(s);", |
| 3922 | " h ^= h << 11;", |
| 3923 | " h += h >> 17;", |
| 3924 | " break;", |
| 3925 | " case 1: h += *s;", |
| 3926 | " h ^= h << 10;", |
| 3927 | " h += h >> 1;", |
| 3928 | " break;", |
| 3929 | " }", |
| 3930 | " h ^= h << 3;", |
| 3931 | " h += h >> 5;", |
| 3932 | " h ^= h << 4;", |
| 3933 | " h += h >> 17;", |
| 3934 | " h ^= h << 25;", |
| 3935 | " h += h >> 6;", |
| 3936 | "", |
| 3937 | " K1 = h;", |
| 3938 | "}", |
| 3939 | "#endif", /* SFH */ |
| 3940 | "", |
| 3941 | "#include <stdint.h>", /* uint32_t etc. */ |
| 3942 | "#if defined(HASH64) || defined(WIN64)", |
| 3943 | "/* 64-bit Jenkins hash, 1997", |
| 3944 | " * http://burtleburtle.net/bob/c/lookup8.c", |
| 3945 | " */", |
| 3946 | "#define mix(a,b,c) \\", |
| 3947 | "{ a -= b; a -= c; a ^= (c>>43); \\", |
| 3948 | " b -= c; b -= a; b ^= (a<<9); \\", |
| 3949 | " c -= a; c -= b; c ^= (b>>8); \\", |
| 3950 | " a -= b; a -= c; a ^= (c>>38); \\", |
| 3951 | " b -= c; b -= a; b ^= (a<<23); \\", |
| 3952 | " c -= a; c -= b; c ^= (b>>5); \\", |
| 3953 | " a -= b; a -= c; a ^= (c>>35); \\", |
| 3954 | " b -= c; b -= a; b ^= (a<<49); \\", |
| 3955 | " c -= a; c -= b; c ^= (b>>11); \\", |
| 3956 | " a -= b; a -= c; a ^= (c>>12); \\", |
| 3957 | " b -= c; b -= a; b ^= (a<<18); \\", |
| 3958 | " c -= a; c -= b; c ^= (b>>22); \\", |
| 3959 | "}", |
| 3960 | "#else", |
| 3961 | "/* 32-bit Jenkins hash, 2006", |
| 3962 | " * http://burtleburtle.net/bob/c/lookup3.c", |
| 3963 | " */", |
| 3964 | "#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))", |
| 3965 | "", |
| 3966 | "#define mix(a,b,c) \\", |
| 3967 | "{ a -= c; a ^= rot(c, 4); c += b; \\", |
| 3968 | " b -= a; b ^= rot(a, 6); a += c; \\", |
| 3969 | " c -= b; c ^= rot(b, 8); b += a; \\", |
| 3970 | " a -= c; a ^= rot(c,16); c += b; \\", |
| 3971 | " b -= a; b ^= rot(a,19); a += c; \\", |
| 3972 | " c -= b; c ^= rot(b, 4); b += a; \\", |
| 3973 | "}", |
| 3974 | "", |
| 3975 | "#define final(a,b,c) \\", |
| 3976 | "{ c ^= b; c -= rot(b,14); \\", |
| 3977 | " a ^= c; a -= rot(c,11); \\", |
| 3978 | " b ^= a; b -= rot(a,25); \\", |
| 3979 | " c ^= b; c -= rot(b,16); \\", |
| 3980 | " a ^= c; a -= rot(c,4); \\", |
| 3981 | " b ^= a; b -= rot(a,14); \\", |
| 3982 | " c ^= b; c -= rot(b,24); \\", |
| 3983 | "}", |
| 3984 | "#endif", |
| 3985 | "", |
| 3986 | "void", |
| 3987 | "d_hash(uchar *kb, int nbytes)", |
| 3988 | "{ uint8_t *bp;", |
| 3989 | "#if defined(HASH64) || defined(WIN64)", |
| 3990 | " uint64_t a = 0, b, c, n;", |
| 3991 | " uint64_t *k = (uint64_t *) kb;", |
| 3992 | "#else", |
| 3993 | " uint32_t a, b, c, n;", |
| 3994 | " uint32_t *k = (uint32_t *) kb;", |
| 3995 | "#endif", |
| 3996 | " /* extend to multiple of words, if needed */", |
| 3997 | " n = nbytes/WS; /* nr of words */", |
| 3998 | " a = nbytes - (n*WS);", |
| 3999 | " if (a > 0)", |
| 4000 | " { n++;", |
| 4001 | " bp = kb + nbytes;", |
| 4002 | " switch (a) {", |
| 4003 | " case 3: *bp++ = 0; /* fall thru */", |
| 4004 | " case 2: *bp++ = 0; /* fall thru */", |
| 4005 | " case 1: *bp = 0;", |
| 4006 | " case 0: break;", |
| 4007 | " } }", |
| 4008 | "#if defined(HASH64) || defined(WIN64)", |
| 4009 | " b = HASH_CONST[HASH_NR];", |
| 4010 | " c = 0x9e3779b97f4a7c13LL; /* arbitrary value */", |
| 4011 | " while (n >= 3)", |
| 4012 | " { a += k[0];", |
| 4013 | " b += k[1];", |
| 4014 | " c += k[2];", |
| 4015 | " mix(a,b,c);", |
| 4016 | " n -= 3;", |
| 4017 | " k += 3;", |
| 4018 | " }", |
| 4019 | " c += (((uint64_t) nbytes)<<3);", |
| 4020 | " switch (n) {", |
| 4021 | " case 2: b += k[1];", |
| 4022 | " case 1: a += k[0];", |
| 4023 | " case 0: break;", |
| 4024 | " }", |
| 4025 | " mix(a,b,c);", |
| 4026 | "#else", /* 32 bit version: */ |
| 4027 | " a = c = 0xdeadbeef + (n<<2);", |
| 4028 | " b = HASH_CONST[HASH_NR];", |
| 4029 | " while (n > 3)", |
| 4030 | " { a += k[0];", |
| 4031 | " b += k[1];", |
| 4032 | " c += k[2];", |
| 4033 | " mix(a,b,c);", |
| 4034 | " n -= 3;", |
| 4035 | " k += 3;", |
| 4036 | " }", |
| 4037 | " switch (n) { ", |
| 4038 | " case 3: c += k[2];", |
| 4039 | " case 2: b += k[1];", |
| 4040 | " case 1: a += k[0];", |
| 4041 | " case 0: break;", |
| 4042 | " }", |
| 4043 | " final(a,b,c);", |
| 4044 | "#endif", |
| 4045 | " j1 = c&nmask; j3 = a&7; /* 1st bit */", |
| 4046 | " j2 = b&nmask; j4 = (a>>3)&7; /* 2nd bit */", |
| 4047 | " K1 = c; K2 = b;", |
| 4048 | "}", |
| 4049 | "", |
| 4050 | "void", |
| 4051 | "s_hash(uchar *cp, int om)", |
| 4052 | "{", |
| 4053 | "#if defined(SFH)", |
| 4054 | " d_sfh((const char *) cp, om); /* sets K1 */", |
| 4055 | "#else", |
| 4056 | " d_hash(cp, om); /* sets K1 etc */", |
| 4057 | "#endif", |
| 4058 | "#ifdef BITSTATE", |
| 4059 | " if (S_Tab == H_tab)", /* state stack in bitstate search */ |
| 4060 | " j1 = K1 %% omaxdepth;", |
| 4061 | " else", |
| 4062 | "#endif", /* if (S_Tab != H_Tab) */ |
| 4063 | " if (ssize < 8*WS)", |
| 4064 | " j1 = K1&mask;", |
| 4065 | " else", |
| 4066 | " j1 = K1;", |
| 4067 | "}", |
| 4068 | "#ifndef RANDSTOR", |
| 4069 | "int *prerand;", |
| 4070 | "void", |
| 4071 | "inirand(void)", |
| 4072 | "{ int i;", |
| 4073 | " srand(123); /* fixed startpoint */", |
| 4074 | " prerand = (int *) emalloc((omaxdepth+3)*sizeof(int));", |
| 4075 | " for (i = 0; i < omaxdepth+3; i++)", |
| 4076 | " prerand[i] = rand();", |
| 4077 | "}", |
| 4078 | "int", |
| 4079 | "pan_rand(void)", |
| 4080 | "{ if (!prerand) inirand();", |
| 4081 | " return prerand[depth];", |
| 4082 | "}", |
| 4083 | "#endif", |
| 4084 | "", |
| 4085 | "void", |
| 4086 | "set_masks(void) /* 4.2.5 */", |
| 4087 | "{", |
| 4088 | " if (WS == 4 && ssize >= 32)", |
| 4089 | " { mask = 0xffffffff;", |
| 4090 | "#ifdef BITSTATE", |
| 4091 | " switch (ssize) {", |
| 4092 | " case 34: nmask = (mask>>1); break;", |
| 4093 | " case 33: nmask = (mask>>2); break;", |
| 4094 | " default: nmask = (mask>>3); break;", |
| 4095 | " }", |
| 4096 | "#else", |
| 4097 | " nmask = mask;", |
| 4098 | "#endif", |
| 4099 | " } else if (WS == 8)", |
| 4100 | " { mask = ((ONE_L<<ssize)-1); /* hash init */", |
| 4101 | "#ifdef BITSTATE", |
| 4102 | " nmask = mask>>3;", |
| 4103 | "#else", |
| 4104 | " nmask = mask;", |
| 4105 | "#endif", |
| 4106 | " } else if (WS != 4)", |
| 4107 | " { fprintf(stderr, \"pan: wordsize %%ld not supported\\n\", (long int) WS);", |
| 4108 | " exit(1);", |
| 4109 | " } else /* WS == 4 and ssize < 32 */", |
| 4110 | " { mask = ((ONE_L<<ssize)-1); /* hash init */", |
| 4111 | " nmask = (mask>>3);", |
| 4112 | " }", |
| 4113 | "}", |
| 4114 | "", |
| 4115 | "static long reclaim_size;", |
| 4116 | "static char *reclaim_mem;", |
| 4117 | "#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA)", |
| 4118 | "#if NCORE>1", |
| 4119 | " #error cannot combine AUTO_RESIZE with NCORE>1 yet", |
| 4120 | "#endif", |
| 4121 | "static struct H_el **N_tab;", |
| 4122 | "void", |
| 4123 | "reverse_capture(struct H_el *p)", |
| 4124 | "{ if (!p) return;", |
| 4125 | " reverse_capture(p->nxt);", |
| 4126 | " /* last element of list moves first */", |
| 4127 | " /* to preserve list-order */", |
| 4128 | " j2 = p->m_K1;", |
| 4129 | " if (ssize < 8*WS) /* probably always true */", |
| 4130 | " { j2 &= mask;", |
| 4131 | " }", |
| 4132 | " p->nxt = N_tab[j2];", |
| 4133 | " N_tab[j2] = p;", |
| 4134 | "}", |
| 4135 | "void", |
| 4136 | "resize_hashtable(void)", |
| 4137 | "{", |
| 4138 | " if (WS == 4 && ssize >= 27 - 1)", |
| 4139 | " { return; /* canot increase further */", |
| 4140 | " }", |
| 4141 | "", |
| 4142 | " ssize += 2; /* 4x size */", |
| 4143 | "", |
| 4144 | " printf(\"pan: resizing hashtable to -w%%d.. \", ssize);", |
| 4145 | "", |
| 4146 | " N_tab = (struct H_el **)", |
| 4147 | " emalloc((ONE_L<<ssize)*sizeof(struct H_el *));", |
| 4148 | "", |
| 4149 | " set_masks(); /* they changed */", |
| 4150 | "", |
| 4151 | " for (j1 = 0; j1 < (ONE_L << (ssize - 2)); j1++)", |
| 4152 | " { reverse_capture(H_tab[j1]);", |
| 4153 | " }", |
| 4154 | " reclaim_mem = (char *) H_tab;", |
| 4155 | " reclaim_size = (ONE_L << (ssize - 2));", |
| 4156 | " H_tab = N_tab;", |
| 4157 | "", |
| 4158 | " printf(\" done\\n\");", |
| 4159 | "}", |
| 4160 | "#endif", |
| 4161 | "#if defined(ZAPH) && defined(BITSTATE)", |
| 4162 | "void", |
| 4163 | "zap_hashtable(void)", |
| 4164 | "{ cpu_printf(\"pan: resetting hashtable\\n\");", |
| 4165 | " if (udmem)", |
| 4166 | " { memset(SS, 0, udmem);", |
| 4167 | " } else", |
| 4168 | " { memset(SS, 0, ONE_L<<(ssize-3));", |
| 4169 | " }", |
| 4170 | "}", |
| 4171 | "#endif", |
| 4172 | "", |
| 4173 | "int", |
| 4174 | "main(int argc, char *argv[])", |
| 4175 | "{ void to_compile(void);\n", |
| 4176 | " efd = stderr; /* default */", |
| 4177 | "#ifdef BITSTATE", |
| 4178 | " bstore = bstore_reg; /* default */", |
| 4179 | "#endif", |
| 4180 | "#if NCORE>1", |
| 4181 | " { int i, j;", |
| 4182 | " strcpy(o_cmdline, \"\");", |
| 4183 | " for (j = 1; j < argc; j++)", |
| 4184 | " { strcat(o_cmdline, argv[j]);", |
| 4185 | " strcat(o_cmdline, \" \");", |
| 4186 | " }", |
| 4187 | " /* printf(\"Command Line: %%s\\n\", o_cmdline); */", |
| 4188 | " if (strlen(o_cmdline) >= sizeof(o_cmdline))", |
| 4189 | " { Uerror(\"option list too long\");", |
| 4190 | " } }", |
| 4191 | "#endif", |
| 4192 | " while (argc > 1 && argv[1][0] == '-')", |
| 4193 | " { switch (argv[1][1]) {", |
| 4194 | "#ifndef SAFETY", |
| 4195 | "#ifdef NP", |
| 4196 | " case 'a': fprintf(efd, \"error: -a disabled\");", |
| 4197 | " usage(efd); break;", |
| 4198 | "#else", |
| 4199 | " case 'a': a_cycles = 1; break;", |
| 4200 | "#endif", |
| 4201 | "#endif", |
| 4202 | " case 'A': noasserts = 1; break;", |
| 4203 | " case 'b': bounded = 1; break;", |
| 4204 | "#ifdef HAS_CODE", |
| 4205 | " case 'C': coltrace = 1; goto samething;", |
| 4206 | "#endif", |
| 4207 | " case 'c': upto = atoi(&argv[1][2]); break;", |
| 4208 | " case 'd': state_tables++; break;", |
| 4209 | " case 'e': every_error = 1; Nr_Trails = 1; break;", |
| 4210 | " case 'E': noends = 1; break;", |
| 4211 | "#ifdef SC", |
| 4212 | " case 'F': if (strlen(argv[1]) > 2)", |
| 4213 | " stackfile = &argv[1][2];", |
| 4214 | " break;", |
| 4215 | "#endif", |
| 4216 | "#if !defined(SAFETY) && !defined(NOFAIR)", |
| 4217 | " case 'f': fairness = 1; break;", |
| 4218 | "#endif", |
| 4219 | "#ifdef HAS_CODE", |
| 4220 | " case 'g': gui = 1; goto samething;", |
| 4221 | "#endif", |
| 4222 | " case 'h': if (!argv[1][2]) usage(efd); else", |
| 4223 | " HASH_NR = atoi(&argv[1][2])%%33; break;", |
| 4224 | " case 'I': iterative = 2; every_error = 1; break;", |
| 4225 | " case 'i': iterative = 1; every_error = 1; break;", |
| 4226 | " case 'J': like_java = 1; break; /* Klaus Havelund */", |
| 4227 | "#ifdef BITSTATE", |
| 4228 | " case 'k': hfns = atoi(&argv[1][2]); break;", |
| 4229 | "#endif", |
| 4230 | "#ifdef SCHED", |
| 4231 | " case 'L': sched_max = atoi(&argv[1][2]); break;", |
| 4232 | "#endif", |
| 4233 | "#ifndef SAFETY", |
| 4234 | "#ifdef NP", |
| 4235 | " case 'l': a_cycles = 1; break;", |
| 4236 | "#else", |
| 4237 | " case 'l': fprintf(efd, \"error: -l disabled\");", |
| 4238 | " usage(efd); break;", |
| 4239 | "#endif", |
| 4240 | "#endif", |
| 4241 | #ifndef POWOW |
| 4242 | "#ifdef BITSTATE", |
| 4243 | " case 'M': udmem = atoi(&argv[1][2]); break;", |
| 4244 | " case 'G': udmem = atoi(&argv[1][2]); udmem *= 1024; break;", |
| 4245 | "#else", |
| 4246 | " case 'M': case 'G':", |
| 4247 | " fprintf(stderr, \"-M and -G affect only -DBITSTATE\\n\");", |
| 4248 | " break;", |
| 4249 | "#endif", |
| 4250 | #endif |
| 4251 | " case 'm': maxdepth = atoi(&argv[1][2]); break;", |
| 4252 | " case 'n': no_rck = 1; break;", |
| 4253 | " case 'P': readtrail = 1; onlyproc = atoi(&argv[1][2]);", |
| 4254 | " if (argv[2][0] != '-') /* check next arg */", |
| 4255 | " { trailfilename = argv[2];", |
| 4256 | " argc--; argv++; /* skip next arg */", |
| 4257 | " }", |
| 4258 | " break;", |
| 4259 | "#ifdef SVDUMP", |
| 4260 | " case 'p': vprefix = atoi(&argv[1][2]); break;", |
| 4261 | "#endif", |
| 4262 | "#if NCORE==1", |
| 4263 | " case 'Q': quota = (double) 60.0 * (double) atoi(&argv[1][2]); break;", |
| 4264 | "#endif", |
| 4265 | " case 'q': strict = 1; break;", |
| 4266 | " case 'R': Nrun = atoi(&argv[1][2]); break;", |
| 4267 | "#ifdef HAS_CODE", |
| 4268 | " case 'r':", |
| 4269 | "samething: readtrail = 1;", |
| 4270 | " if (isdigit(argv[1][2]))", |
| 4271 | " whichtrail = atoi(&argv[1][2]);", |
| 4272 | " else if (argc > 2 && argv[2][0] != '-') /* check next arg */", |
| 4273 | " { trailfilename = argv[2];", |
| 4274 | " argc--; argv++; /* skip next arg */", |
| 4275 | " }", |
| 4276 | " break;", |
| 4277 | " case 'S': silent = 1; goto samething;", |
| 4278 | "#endif", |
| 4279 | "#ifdef BITSTATE", |
| 4280 | " case 's': hfns = 1; break;", |
| 4281 | "#endif", |
| 4282 | " case 'T': TMODE = 0444; break;", |
| 4283 | " case 't': if (argv[1][2]) tprefix = &argv[1][2]; break;", |
| 4284 | " case 'V': start_timer(); printf(\"Generated by %%s\\n\", SpinVersion);", |
| 4285 | " to_compile(); pan_exit(2); break;", |
| 4286 | " case 'v': verbose++; break;", |
| 4287 | " case 'w': ssize = atoi(&argv[1][2]); break;", |
| 4288 | " case 'Y': signoff = 1; break;", |
| 4289 | " case 'X': efd = stdout; break;", |
| 4290 | " case 'x': exclusive = 1; break;", |
| 4291 | "#if NCORE>1", |
| 4292 | " /* -B ip is passthru to proxy of remote ip address: */", |
| 4293 | " case 'B': argc--; argv++; break;", |
| 4294 | " case 'Q': worker_pids[0] = atoi(&argv[1][2]); break;", |
| 4295 | " /* -Un means that the nth worker should be instantiated as a proxy */", |
| 4296 | " case 'U': proxy_pid = atoi(&argv[1][2]); break;", |
| 4297 | " /* -W means that this copy is started by a cluster-server as a remote */", |
| 4298 | " /* this flag is passed to ./pan_proxy, which interprets it */", |
| 4299 | " case 'W': remote_party++; break;", |
| 4300 | " case 'Z': core_id = atoi(&argv[1][2]);", |
| 4301 | " if (verbose)", |
| 4302 | " { printf(\"cpu%%d: pid %%d parent %%d\\n\",", |
| 4303 | " core_id, getpid(), worker_pids[0]);", |
| 4304 | " }", |
| 4305 | " break;", |
| 4306 | " case 'z': z_handoff = atoi(&argv[1][2]); break;", |
| 4307 | "#else", |
| 4308 | " case 'z': break; /* ignored for single-core */", |
| 4309 | "#endif", |
| 4310 | " default : fprintf(efd, \"saw option -%%c\\n\", argv[1][1]); usage(efd); break;", |
| 4311 | " }", |
| 4312 | " argc--; argv++;", |
| 4313 | " }", |
| 4314 | " if (iterative && TMODE != 0666)", |
| 4315 | " { TMODE = 0666;", |
| 4316 | " fprintf(efd, \"warning: -T ignored when -i or -I is used\\n\");", |
| 4317 | " }", |
| 4318 | "#if defined(HASH32) && !defined(SFH)", |
| 4319 | " if (WS > 4)", |
| 4320 | " { fprintf(efd, \"strong warning: compiling -DHASH32 on a 64-bit machine\\n\");", |
| 4321 | " fprintf(efd, \" without -DSFH can slow down performance a lot\\n\");", |
| 4322 | " }", |
| 4323 | "#endif", |
| 4324 | "#if defined(WIN32) || defined(WIN64)", |
| 4325 | " if (TMODE == 0666)", |
| 4326 | " TMODE = _S_IWRITE | _S_IREAD;", |
| 4327 | " else", |
| 4328 | " TMODE = _S_IREAD;", |
| 4329 | "#endif", |
| 4330 | "#if NCORE>1", |
| 4331 | " store_proxy_pid = proxy_pid; /* for checks in mem_file() and someone_crashed() */", |
| 4332 | " if (core_id != 0) { proxy_pid = 0; }", |
| 4333 | " #ifndef SEP_STATE", |
| 4334 | " if (core_id == 0 && a_cycles)", |
| 4335 | " { fprintf(efd, \"hint: this search may be more efficient \");", |
| 4336 | " fprintf(efd, \"if pan.c is compiled -DSEP_STATE\\n\");", |
| 4337 | " }", |
| 4338 | " #endif", |
| 4339 | " if (z_handoff < 0)", |
| 4340 | " { z_handoff = 20; /* conservative default - for non-liveness checks */", |
| 4341 | " }", |
| 4342 | "#if defined(NGQ) || defined(LWQ_FIXED)", |
| 4343 | " LWQ_SIZE = (double) (128.*1048576.);", |
| 4344 | "#else", |
| 4345 | " LWQ_SIZE = (double) ( z_handoff + 2.) * (double) sizeof(SM_frame);", |
| 4346 | /* the added margin of +2 is not really necessary */ |
| 4347 | "#endif", |
| 4348 | " #if NCORE>2", |
| 4349 | " if (a_cycles)", |
| 4350 | " { fprintf(efd, \"warning: the intended nr of cores to be used in liveness mode is 2\\n\");", |
| 4351 | " #ifndef SEP_STATE", |
| 4352 | " fprintf(efd, \"warning: without -DSEP_STATE there is no guarantee that all liveness violations are found\\n\");", |
| 4353 | " #endif", |
| 4354 | " }", /* it still works though, the later cores get states from the global q */ |
| 4355 | " #endif", |
| 4356 | " #ifdef HAS_HIDDEN", |
| 4357 | " #error cannot use hidden variables when compiling multi-core", |
| 4358 | " #endif", |
| 4359 | "#endif", |
| 4360 | "#ifdef BITSTATE", |
| 4361 | " if (hfns <= 0)", |
| 4362 | " { hfns = 1;", |
| 4363 | " fprintf(efd, \"warning: using -k%%d as minimal usable value\\n\", hfns);", |
| 4364 | " }", |
| 4365 | "#endif", |
| 4366 | " omaxdepth = maxdepth;", |
| 4367 | "#ifdef BITSTATE", |
| 4368 | " if (WS == 4 && ssize > 34)", /* 32-bit word size */ |
| 4369 | " { ssize = 34;", |
| 4370 | " fprintf(efd, \"warning: using -w%%d as max usable value\\n\", ssize);", |
| 4371 | "/*", |
| 4372 | " * -w35 would not work: 35-3 = 32 but 1^31 is the largest", |
| 4373 | " * power of 2 that can be represented in an unsigned long", |
| 4374 | " */", |
| 4375 | " }", |
| 4376 | "#else", |
| 4377 | " if (WS == 4 && ssize > 27)", |
| 4378 | " { ssize = 27;", |
| 4379 | " fprintf(efd, \"warning: using -w%%d as max usable value\\n\", ssize);", |
| 4380 | "/*", |
| 4381 | " * for emalloc, the lookup table size multiplies by 4 for the pointers", |
| 4382 | " * the largest power of 2 that can be represented in a ulong is 1^31", |
| 4383 | " * hence the largest number of lookup table slots is 31-4 = 27", |
| 4384 | " */", |
| 4385 | " }", |
| 4386 | |
| 4387 | "#endif", |
| 4388 | "#ifdef SC", |
| 4389 | " hiwater = HHH = maxdepth-10;", |
| 4390 | " DDD = HHH/2;", |
| 4391 | " if (!stackfile)", |
| 4392 | " { stackfile = (char *) emalloc(strlen(PanSource)+4+1);", |
| 4393 | " sprintf(stackfile, \"%%s._s_\", PanSource);", |
| 4394 | " }", |
| 4395 | " if (iterative)", |
| 4396 | " { fprintf(efd, \"error: cannot use -i or -I with -DSC\\n\");", |
| 4397 | " pan_exit(1);", |
| 4398 | " }", |
| 4399 | "#endif", |
| 4400 | |
| 4401 | "#if (defined(R_XPT) || defined(W_XPT)) && !defined(MA)", |
| 4402 | " #warning -DR_XPT and -DW_XPT assume -DMA (ignored)", |
| 4403 | "#endif", |
| 4404 | |
| 4405 | " if (iterative && a_cycles)", |
| 4406 | " fprintf(efd, \"warning: -i or -I work for safety properties only\\n\");", |
| 4407 | |
| 4408 | "#ifdef BFS", |
| 4409 | " #ifdef SC", |
| 4410 | " #error -DBFS not compatible with -DSC", |
| 4411 | " #endif", |
| 4412 | " #ifdef HAS_LAST", |
| 4413 | " #error -DBFS not compatible with _last", |
| 4414 | " #endif", |
| 4415 | " #ifdef HAS_STACK", |
| 4416 | " #error cannot use c_track UnMatched with BFS", |
| 4417 | " #endif", |
| 4418 | " #ifdef REACH", |
| 4419 | " #warning -DREACH is redundant when -DBFS is used", |
| 4420 | " #endif", |
| 4421 | "#endif", |
| 4422 | "#if defined(MERGED) && defined(PEG)", |
| 4423 | " #error to use -DPEG use: spin -o3 -a", |
| 4424 | "#endif", |
| 4425 | "#ifdef HC", |
| 4426 | " #ifdef SFH", /* cannot happen -- undef-ed in this case */ |
| 4427 | " #error cannot combine -DHC and -DSFH", |
| 4428 | " /* use of NOCOMP is the real reason */", |
| 4429 | " #else", |
| 4430 | " #ifdef NOCOMP", |
| 4431 | " #error cannot combine -DHC and -DNOCOMP", |
| 4432 | " #endif", |
| 4433 | " #endif", |
| 4434 | " #ifdef BITSTATE", |
| 4435 | " #error cannot combine -DHC and -DBITSTATE", |
| 4436 | " #endif", |
| 4437 | "#endif", |
| 4438 | "#if defined(SAFETY) && defined(NP)", |
| 4439 | " #error cannot combine -DNP and -DBFS or -DSAFETY", |
| 4440 | "#endif", |
| 4441 | "#ifdef MA", |
| 4442 | " #ifdef BITSTATE", |
| 4443 | " #error cannot combine -DMA and -DBITSTATE", |
| 4444 | " #endif", |
| 4445 | " #if MA <= 0", |
| 4446 | " #error usage: -DMA=N with N > 0 and N < VECTORSZ", |
| 4447 | " #endif", |
| 4448 | "#endif", |
| 4449 | "#ifdef COLLAPSE", |
| 4450 | " #ifdef BITSTATE", |
| 4451 | " #error cannot combine -DBITSTATE and -DCOLLAPSE", |
| 4452 | " #endif", |
| 4453 | " #ifdef SFH", |
| 4454 | " #error cannot combine -DCOLLAPSE and -DSFH", |
| 4455 | " /* use of NOCOMP is the real reason */", |
| 4456 | " #else", |
| 4457 | " #ifdef NOCOMP", |
| 4458 | " #error cannot combine -DCOLLAPSE and -DNOCOMP", |
| 4459 | " #endif", |
| 4460 | " #endif", |
| 4461 | "#endif", |
| 4462 | " if (maxdepth <= 0 || ssize <= 1) usage(efd);", |
| 4463 | "#if SYNC>0 && !defined(NOREDUCE)", |
| 4464 | " if (a_cycles && fairness)", |
| 4465 | " { fprintf(efd, \"error: p.o. reduction not compatible with \");", |
| 4466 | " fprintf(efd, \"fairness (-f) in models\\n\");", |
| 4467 | " fprintf(efd, \" with rendezvous operations: \");", |
| 4468 | " fprintf(efd, \"recompile with -DNOREDUCE\\n\");", |
| 4469 | " pan_exit(1);", |
| 4470 | " }", |
| 4471 | "#endif", |
| 4472 | "#if defined(REM_VARS) && !defined(NOREDUCE)", |
| 4473 | " #warning p.o. reduction not compatible with remote varrefs (use -DNOREDUCE)", |
| 4474 | "#endif", |
| 4475 | "#if defined(NOCOMP) && !defined(BITSTATE)", |
| 4476 | " if (a_cycles)", |
| 4477 | " { fprintf(efd, \"error: use of -DNOCOMP voids -l and -a\\n\");", |
| 4478 | " pan_exit(1);", |
| 4479 | " }", |
| 4480 | "#endif", |
| 4481 | |
| 4482 | "#ifdef MEMLIM", |
| 4483 | " memlim = ((double) MEMLIM) * (double) (1<<20); /* size in Mbyte */", |
| 4484 | "#endif", |
| 4485 | |
| 4486 | "#ifndef BITSTATE", |
| 4487 | " if (Nrun > 1) HASH_NR = Nrun - 1;", |
| 4488 | "#endif", |
| 4489 | " if (Nrun < 1 || Nrun > 32)", |
| 4490 | " { fprintf(efd, \"error: invalid arg for -R\\n\");", |
| 4491 | " usage(efd);", |
| 4492 | " }", |
| 4493 | "#ifndef SAFETY", |
| 4494 | " if (fairness && !a_cycles)", |
| 4495 | " { fprintf(efd, \"error: -f requires -a or -l\\n\");", |
| 4496 | " usage(efd);", |
| 4497 | " }", |
| 4498 | " #if ACCEPT_LAB==0", |
| 4499 | " if (a_cycles)", |
| 4500 | " { fprintf(efd, \"error: no accept labels defined \");", |
| 4501 | " fprintf(efd, \"in model (for option -a)\\n\");", |
| 4502 | " usage(efd);", |
| 4503 | " }", |
| 4504 | " #endif", |
| 4505 | "#endif", |
| 4506 | "#ifndef NOREDUCE", |
| 4507 | " #ifdef HAS_ENABLED", |
| 4508 | " #error use of enabled() requires -DNOREDUCE", |
| 4509 | " #endif", |
| 4510 | " #ifdef HAS_PCVALUE", |
| 4511 | " #error use of pcvalue() requires -DNOREDUCE", |
| 4512 | " #endif", |
| 4513 | " #ifdef HAS_BADELSE", |
| 4514 | " #error use of 'else' combined with i/o stmnts requires -DNOREDUCE", |
| 4515 | " #endif", |
| 4516 | " #ifdef HAS_LAST", |
| 4517 | " #error use of _last requires -DNOREDUCE", |
| 4518 | " #endif", |
| 4519 | "#endif", |
| 4520 | |
| 4521 | "#if SYNC>0 && !defined(NOREDUCE)", |
| 4522 | " #ifdef HAS_UNLESS", |
| 4523 | " fprintf(efd, \"warning: use of a rendezvous stmnts in the escape\\n\");", |
| 4524 | " fprintf(efd, \"\tof an unless clause, if present, could make p.o. reduction\\n\");", |
| 4525 | " fprintf(efd, \"\tinvalid (use -DNOREDUCE to avoid this)\\n\");", |
| 4526 | " #ifdef BFS", |
| 4527 | " fprintf(efd, \"\t(this type of rv is also not compatible with -DBFS)\\n\");", |
| 4528 | " #endif", |
| 4529 | " #endif", |
| 4530 | "#endif", |
| 4531 | "#if SYNC>0 && defined(BFS)", |
| 4532 | " #warning use of rendezvous with BFS does not preserve all invalid endstates", |
| 4533 | "#endif", |
| 4534 | "#if !defined(REACH) && !defined(BITSTATE)", |
| 4535 | " if (iterative != 0 && a_cycles == 0)", |
| 4536 | " { fprintf(efd, \"warning: -i and -I need -DREACH to work accurately\\n\");", |
| 4537 | " }", |
| 4538 | "#endif", |
| 4539 | "#if defined(BITSTATE) && defined(REACH)", |
| 4540 | " #warning -DREACH is voided by -DBITSTATE", |
| 4541 | "#endif", |
| 4542 | "#if defined(MA) && defined(REACH)", |
| 4543 | " #warning -DREACH is voided by -DMA", |
| 4544 | "#endif", |
| 4545 | "#if defined(FULLSTACK) && defined(CNTRSTACK)", |
| 4546 | " #error cannot combine -DFULLSTACK and -DCNTRSTACK", |
| 4547 | "#endif", |
| 4548 | "#if defined(VERI)", |
| 4549 | " #if ACCEPT_LAB>0", |
| 4550 | " #ifndef BFS", |
| 4551 | " if (!a_cycles", |
| 4552 | " #ifdef HAS_CODE", |
| 4553 | " && !readtrail", |
| 4554 | " #endif", |
| 4555 | " #if NCORE>1", |
| 4556 | " && core_id == 0", |
| 4557 | " #endif", |
| 4558 | " && !state_tables)", |
| 4559 | " { fprintf(efd, \"warning: never claim + accept labels \");", |
| 4560 | " fprintf(efd, \"requires -a flag to fully verify\\n\");", |
| 4561 | " }", |
| 4562 | " #else", |
| 4563 | " if (!state_tables", |
| 4564 | " #ifdef HAS_CODE", |
| 4565 | " && !readtrail", |
| 4566 | " #endif", |
| 4567 | " )", |
| 4568 | " { fprintf(efd, \"warning: verification in BFS mode \");", |
| 4569 | " fprintf(efd, \"is restricted to safety properties\\n\");", |
| 4570 | " }", |
| 4571 | " #endif", |
| 4572 | " #endif", |
| 4573 | "#endif", |
| 4574 | "#ifndef SAFETY", |
| 4575 | " if (!a_cycles", |
| 4576 | " #ifdef HAS_CODE", |
| 4577 | " && !readtrail", |
| 4578 | " #endif", |
| 4579 | " #if NCORE>1", |
| 4580 | " && core_id == 0", |
| 4581 | " #endif", |
| 4582 | " && !state_tables)", |
| 4583 | " { fprintf(efd, \"hint: this search is more efficient \");", |
| 4584 | " fprintf(efd, \"if pan.c is compiled -DSAFETY\\n\");", |
| 4585 | " }", |
| 4586 | " #ifndef NOCOMP", |
| 4587 | " if (!a_cycles)", |
| 4588 | " { S_A = 0;", |
| 4589 | " } else", |
| 4590 | " { if (!fairness)", |
| 4591 | " { S_A = 1; /* _a_t */", |
| 4592 | " #ifndef NOFAIR", |
| 4593 | " } else /* _a_t and _cnt[NFAIR] */", |
| 4594 | " { S_A = (&(now._cnt[0]) - (uchar *) &now) + NFAIR - 2;", |
| 4595 | " /* -2 because first two uchars in now are masked */", |
| 4596 | " #endif", |
| 4597 | " } }", |
| 4598 | " #endif", |
| 4599 | "#endif", |
| 4600 | " signal(SIGINT, stopped);", |
| 4601 | " set_masks();", |
| 4602 | "#ifdef BFS", |
| 4603 | " trail = (Trail *) emalloc(6*sizeof(Trail));", |
| 4604 | " trail += 3;", |
| 4605 | "#else", |
| 4606 | " trail = (Trail *) emalloc((maxdepth+3)*sizeof(Trail));", |
| 4607 | " trail++; /* protect trpt-1 refs at depth 0 */", |
| 4608 | "#endif", |
| 4609 | "#ifdef SVDUMP", |
| 4610 | " if (vprefix > 0)", |
| 4611 | " { char nm[64];", |
| 4612 | " sprintf(nm, \"%%s.svd\", PanSource);", |
| 4613 | " if ((svfd = creat(nm, TMODE)) < 0)", |
| 4614 | " { fprintf(efd, \"couldn't create %%s\\n\", nm);", |
| 4615 | " vprefix = 0;", |
| 4616 | " } }", |
| 4617 | "#endif", |
| 4618 | "#ifdef RANDSTOR", |
| 4619 | " srand(123);", |
| 4620 | "#endif", |
| 4621 | "#if SYNC>0 && ASYNC==0", |
| 4622 | " set_recvs();", |
| 4623 | "#endif", |
| 4624 | " run();", |
| 4625 | " done = 1;", |
| 4626 | " wrapup();", |
| 4627 | " return 0;", |
| 4628 | "}", /* end of main() */ |
| 4629 | "", |
| 4630 | "void", |
| 4631 | "usage(FILE *fd)", |
| 4632 | "{", |
| 4633 | " fprintf(fd, \"%%s\\n\", SpinVersion);", |
| 4634 | " fprintf(fd, \"Valid Options are:\\n\");", |
| 4635 | "#ifndef SAFETY", |
| 4636 | "#ifdef NP", |
| 4637 | " fprintf(fd, \"\t-a -> is disabled by -DNP \");", |
| 4638 | " fprintf(fd, \"(-DNP compiles for -l only)\\n\");", |
| 4639 | "#else", |
| 4640 | " fprintf(fd, \"\t-a find acceptance cycles\\n\");", |
| 4641 | "#endif", |
| 4642 | "#else", |
| 4643 | " fprintf(fd, \"\t-a,-l,-f -> are disabled by -DSAFETY\\n\");", |
| 4644 | "#endif", |
| 4645 | " fprintf(fd, \"\t-A ignore assert() violations\\n\");", |
| 4646 | " fprintf(fd, \"\t-b consider it an error to exceed the depth-limit\\n\");", |
| 4647 | " fprintf(fd, \"\t-cN stop at Nth error \");", |
| 4648 | " fprintf(fd, \"(defaults to -c1)\\n\");", |
| 4649 | " fprintf(fd, \"\t-d print state tables and stop\\n\");", |
| 4650 | " fprintf(fd, \"\t-e create trails for all errors\\n\");", |
| 4651 | " fprintf(fd, \"\t-E ignore invalid end states\\n\");", |
| 4652 | "#ifdef SC", |
| 4653 | " fprintf(fd, \"\t-Ffile use 'file' to store disk-stack\\n\");", |
| 4654 | "#endif", |
| 4655 | "#ifndef NOFAIR", |
| 4656 | " fprintf(fd, \"\t-f add weak fairness (to -a or -l)\\n\");", |
| 4657 | "#endif", |
| 4658 | " fprintf(fd, \"\t-hN use different hash-seed N:1..32\\n\");", |
| 4659 | " fprintf(fd, \"\t-i search for shortest path to error\\n\");", |
| 4660 | " fprintf(fd, \"\t-I like -i, but approximate and faster\\n\");", |
| 4661 | " fprintf(fd, \"\t-J reverse eval order of nested unlesses\\n\");", |
| 4662 | "#ifdef BITSTATE", |
| 4663 | " fprintf(fd, \"\t-kN set N bits per state (defaults to 3)\\n\");", |
| 4664 | "#endif", |
| 4665 | "#ifdef SCHED", |
| 4666 | " fprintf(fd, \"\t-LN set scheduling restriction to N (default 10)\\n\");", |
| 4667 | "#endif", |
| 4668 | "#ifndef SAFETY", |
| 4669 | "#ifdef NP", |
| 4670 | " fprintf(fd, \"\t-l find non-progress cycles\\n\");", |
| 4671 | "#else", |
| 4672 | " fprintf(fd, \"\t-l find non-progress cycles -> \");", |
| 4673 | " fprintf(fd, \"disabled, requires \");", |
| 4674 | " fprintf(fd, \"compilation with -DNP\\n\");", |
| 4675 | "#endif", |
| 4676 | "#endif", |
| 4677 | #ifndef POWOW |
| 4678 | "#ifdef BITSTATE", |
| 4679 | " fprintf(fd, \"\t-MN use N Megabytes for bitstate hash array\\n\");", |
| 4680 | " fprintf(fd, \"\t-GN use N Gigabytes for bitstate hash array\\n\");", |
| 4681 | "#endif", |
| 4682 | #endif |
| 4683 | " fprintf(fd, \"\t-mN max depth N steps (default=10k)\\n\");", |
| 4684 | " fprintf(fd, \"\t-n no listing of unreached states\\n\");", |
| 4685 | "#ifdef SVDUMP", |
| 4686 | " fprintf(fd, \"\t-pN create svfile (save N bytes per state)\\n\");", |
| 4687 | "#endif", |
| 4688 | " fprintf(fd, \"\t-QN set time-limit on execution of N minutes\\n\");", |
| 4689 | " fprintf(fd, \"\t-q require empty chans in valid end states\\n\");", |
| 4690 | "#ifdef HAS_CODE", |
| 4691 | " fprintf(fd, \"\t-r read and execute trail - can add -v,-n,-PN,-g,-C\\n\");", |
| 4692 | " fprintf(fd, \"\t-rN read and execute N-th error trail\\n\");", |
| 4693 | " fprintf(fd, \"\t-C read and execute trail - columnated output (can add -v,-n)\\n\");", |
| 4694 | " fprintf(fd, \"\t-PN read and execute trail - restrict trail output to proc N\\n\");", |
| 4695 | " fprintf(fd, \"\t-g read and execute trail + msc gui support\\n\");", |
| 4696 | " fprintf(fd, \"\t-S silent replay: only user defined printfs show\\n\");", |
| 4697 | "#endif", |
| 4698 | "#ifdef BITSTATE", |
| 4699 | " fprintf(fd, \"\t-RN repeat run Nx with N \");", |
| 4700 | " fprintf(fd, \"[1..32] independent hash functions\\n\");", |
| 4701 | " fprintf(fd, \"\t-s same as -k1 (single bit per state)\\n\");", |
| 4702 | "#endif", |
| 4703 | " fprintf(fd, \"\t-T create trail files in read-only mode\\n\");", |
| 4704 | " fprintf(fd, \"\t-tsuf replace .trail with .suf on trailfiles\\n\");", |
| 4705 | " fprintf(fd, \"\t-V print SPIN version number\\n\");", |
| 4706 | " fprintf(fd, \"\t-v verbose -- filenames in unreached state listing\\n\");", |
| 4707 | " fprintf(fd, \"\t-wN hashtable of 2^N entries \");", |
| 4708 | " fprintf(fd, \"(defaults to -w%%d)\\n\", ssize);", |
| 4709 | " fprintf(fd, \"\t-x do not overwrite an existing trail file\\n\");", |
| 4710 | "#if NCORE>1", |
| 4711 | " fprintf(fd, \"\t-zN handoff states below depth N to 2nd cpu (multi_core)\\n\");", |
| 4712 | "#endif", |
| 4713 | "#ifdef HAS_CODE", |
| 4714 | " fprintf(fd, \"\\n\toptions -r, -C, -PN, -g, and -S can optionally be followed by\\n\");", |
| 4715 | " fprintf(fd, \"\ta filename argument, as in \'-r filename\', naming the trailfile\\n\");", |
| 4716 | "#endif", |
| 4717 | "#if NCORE>1", |
| 4718 | " multi_usage(fd);", |
| 4719 | "#endif", |
| 4720 | " exit(1);", |
| 4721 | "}", |
| 4722 | "", |
| 4723 | "char *", |
| 4724 | "Malloc(unsigned long n)", |
| 4725 | "{ char *tmp;", |
| 4726 | "#ifdef MEMLIM", |
| 4727 | " if (memcnt+ (double) n > memlim) goto err;", |
| 4728 | "#endif", |
| 4729 | "#if 1", |
| 4730 | " tmp = (char *) malloc(n);", |
| 4731 | " if (!tmp)", |
| 4732 | "#else", |
| 4733 | /* on linux machines, a large amount of memory is set aside |
| 4734 | * for malloc, whether it is used or not |
| 4735 | * using sbrk would make this memory arena inaccessible |
| 4736 | * the reason for using sbrk was originally to provide a |
| 4737 | * small additional speedup (since this memory is never released) |
| 4738 | */ |
| 4739 | " tmp = (char *) sbrk(n);", |
| 4740 | " if (tmp == (char *) -ONE_L)", |
| 4741 | "#endif", |
| 4742 | " {", |
| 4743 | "#ifdef MEMLIM", |
| 4744 | "err:", |
| 4745 | "#endif", |
| 4746 | " printf(\"pan: out of memory\\n\");", |
| 4747 | "#ifdef MEMLIM", |
| 4748 | " printf(\"\t%%g bytes used\\n\", memcnt);", |
| 4749 | " printf(\"\t%%g bytes more needed\\n\", (double) n);", |
| 4750 | " printf(\"\t%%g bytes limit\\n\",", |
| 4751 | " memlim);", |
| 4752 | "#endif", |
| 4753 | "#ifdef COLLAPSE", |
| 4754 | " printf(\"hint: to reduce memory, recompile with\\n\");", |
| 4755 | "#ifndef MA", |
| 4756 | " printf(\" -DMA=%%d # better/slower compression, or\\n\", hmax);", |
| 4757 | "#endif", |
| 4758 | " printf(\" -DBITSTATE # supertrace, approximation\\n\");", |
| 4759 | "#else", |
| 4760 | "#ifndef BITSTATE", |
| 4761 | " printf(\"hint: to reduce memory, recompile with\\n\");", |
| 4762 | "#ifndef HC", |
| 4763 | " printf(\" -DCOLLAPSE # good, fast compression, or\\n\");", |
| 4764 | "#ifndef MA", |
| 4765 | " printf(\" -DMA=%%d # better/slower compression, or\\n\", hmax);", |
| 4766 | "#endif", |
| 4767 | " printf(\" -DHC # hash-compaction, approximation\\n\");", |
| 4768 | "#endif", |
| 4769 | " printf(\" -DBITSTATE # supertrace, approximation\\n\");", |
| 4770 | "#endif", |
| 4771 | "#endif", |
| 4772 | "#if NCORE>1", |
| 4773 | " #ifdef FULL_TRAIL", |
| 4774 | " printf(\" omit -DFULL_TRAIL or use pan -c0 to reduce memory\\n\");", |
| 4775 | " #endif", |
| 4776 | " #ifdef SEP_STATE", |
| 4777 | " printf(\"hint: to reduce memory, recompile without\\n\");", |
| 4778 | " printf(\" -DSEP_STATE # may be faster, but uses more memory\\n\");", |
| 4779 | " #endif", |
| 4780 | "#endif", |
| 4781 | " wrapup();", |
| 4782 | " }", |
| 4783 | " memcnt += (double) n;", |
| 4784 | " return tmp;", |
| 4785 | "}", |
| 4786 | "", |
| 4787 | "#define CHUNK (100*VECTORSZ)", |
| 4788 | "", |
| 4789 | "char *", |
| 4790 | "emalloc(unsigned long n) /* never released or reallocated */", |
| 4791 | "{ char *tmp;", |
| 4792 | " if (n == 0)", |
| 4793 | " return (char *) NULL;", |
| 4794 | " if (n&(sizeof(void *)-1)) /* for proper alignment */", |
| 4795 | " n += sizeof(void *)-(n&(sizeof(void *)-1));", |
| 4796 | " if ((unsigned long) left < n)", /* was: (left < (long)n) */ |
| 4797 | " { grow = (n < CHUNK) ? CHUNK : n;", |
| 4798 | #if 1 |
| 4799 | " have = Malloc(grow);", |
| 4800 | #else |
| 4801 | " /* gcc's sbrk can give non-aligned result */", |
| 4802 | " grow += sizeof(void *); /* allow realignment */", |
| 4803 | " have = Malloc(grow);", |
| 4804 | " if (((unsigned) have)&(sizeof(void *)-1))", |
| 4805 | " { have += (long) (sizeof(void *) ", |
| 4806 | " - (((unsigned) have)&(sizeof(void *)-1)));", |
| 4807 | " grow -= sizeof(void *);", |
| 4808 | " }", |
| 4809 | #endif |
| 4810 | " fragment += (double) left;", |
| 4811 | " left = grow;", |
| 4812 | " }", |
| 4813 | " tmp = have;", |
| 4814 | " have += (long) n;", |
| 4815 | " left -= (long) n;", |
| 4816 | " memset(tmp, 0, n);", |
| 4817 | " return tmp;", |
| 4818 | "}", |
| 4819 | |
| 4820 | "void", |
| 4821 | "Uerror(char *str)", |
| 4822 | "{ /* always fatal */", |
| 4823 | " uerror(str);", |
| 4824 | "#if NCORE>1", |
| 4825 | " sudden_stop(\"Uerror\");", |
| 4826 | "#endif", |
| 4827 | " wrapup();", |
| 4828 | "}\n", |
| 4829 | "#if defined(MA) && !defined(SAFETY)", |
| 4830 | "int", |
| 4831 | "Unwind(void)", |
| 4832 | "{ Trans *t; uchar ot, _m; int tt; short II;", |
| 4833 | "#ifdef VERBOSE", |
| 4834 | " int i;", |
| 4835 | "#endif", |
| 4836 | " uchar oat = now._a_t;", |
| 4837 | " now._a_t &= ~(1|16|32);", |
| 4838 | " memcpy((char *) &comp_now, (char *) &now, vsize);", |
| 4839 | " now._a_t = oat;", |
| 4840 | "Up:", |
| 4841 | "#ifdef SC", |
| 4842 | " trpt = getframe(depth);", |
| 4843 | "#endif", |
| 4844 | "#ifdef VERBOSE", |
| 4845 | " printf(\"%%d State: \", depth);", |
| 4846 | " for (i = 0; i < vsize; i++) printf(\"%%d%%s,\",", |
| 4847 | " ((char *)&now)[i], Mask[i]?\"*\":\"\");", |
| 4848 | " printf(\"\\n\");", |
| 4849 | "#endif", |
| 4850 | "#ifndef NOFAIR", |
| 4851 | " if (trpt->o_pm&128) /* fairness alg */", |
| 4852 | " { now._cnt[now._a_t&1] = trpt->bup.oval;", |
| 4853 | " depth--;", |
| 4854 | "#ifdef SC", |
| 4855 | " trpt = getframe(depth);", |
| 4856 | "#else", |
| 4857 | " trpt--;", |
| 4858 | "#endif", |
| 4859 | " goto Q999;", |
| 4860 | " }", |
| 4861 | "#endif", |
| 4862 | "#ifdef HAS_LAST", |
| 4863 | "#ifdef VERI", |
| 4864 | " { int d; Trail *trl;", |
| 4865 | " now._last = 0;", |
| 4866 | " for (d = 1; d < depth; d++)", |
| 4867 | " { trl = getframe(depth-d); /* was trl = (trpt-d); */", |
| 4868 | " if (trl->pr != 0)", |
| 4869 | " { now._last = trl->pr - BASE;", |
| 4870 | " break;", |
| 4871 | " } } }", |
| 4872 | "#else", |
| 4873 | " now._last = (depth<1)?0:(trpt-1)->pr;", |
| 4874 | "#endif", |
| 4875 | "#endif", |
| 4876 | "#ifdef EVENT_TRACE", |
| 4877 | " now._event = trpt->o_event;", |
| 4878 | "#endif", |
| 4879 | " if ((now._a_t&1) && depth <= A_depth)", |
| 4880 | " { now._a_t &= ~(1|16|32);", |
| 4881 | " if (fairness) now._a_t |= 2; /* ? */", |
| 4882 | " A_depth = 0;", |
| 4883 | " goto CameFromHere; /* checkcycles() */", |
| 4884 | " }", |
| 4885 | " t = trpt->o_t;", |
| 4886 | " ot = trpt->o_ot; II = trpt->pr;", |
| 4887 | " tt = trpt->o_tt; this = pptr(II);", |
| 4888 | " _m = do_reverse(t, II, trpt->o_m);", |
| 4889 | "#ifdef VERBOSE", |
| 4890 | " printf(\"%%3d: proc %%d \", depth, II);", |
| 4891 | " printf(\"reverses %%d, %%d to %%d,\",", |
| 4892 | " t->forw, tt, t->st);", |
| 4893 | " printf(\" %%s [abit=%%d,adepth=%%d,\", ", |
| 4894 | " t->tp, now._a_t, A_depth);", |
| 4895 | " printf(\"tau=%%d,%%d] <unwind>\\n\", ", |
| 4896 | " trpt->tau, (trpt-1)->tau);", |
| 4897 | "#endif", |
| 4898 | " depth--;", |
| 4899 | "#ifdef SC", |
| 4900 | " trpt = getframe(depth);", |
| 4901 | "#else", |
| 4902 | " trpt--;", |
| 4903 | "#endif", |
| 4904 | " /* reached[ot][t->st] = 1; 3.4.13 */", |
| 4905 | " ((P0 *)this)->_p = tt;", |
| 4906 | "#ifndef NOFAIR", |
| 4907 | " if ((trpt->o_pm&32))", |
| 4908 | " {", |
| 4909 | "#ifdef VERI", |
| 4910 | " if (now._cnt[now._a_t&1] == 0)", |
| 4911 | " now._cnt[now._a_t&1] = 1;", |
| 4912 | "#endif", |
| 4913 | " now._cnt[now._a_t&1] += 1;", |
| 4914 | " }", |
| 4915 | "Q999:", |
| 4916 | " if (trpt->o_pm&8)", |
| 4917 | " { now._a_t &= ~2;", |
| 4918 | " now._cnt[now._a_t&1] = 0;", |
| 4919 | " }", |
| 4920 | " if (trpt->o_pm&16)", |
| 4921 | " now._a_t |= 2;", |
| 4922 | "#endif", |
| 4923 | "CameFromHere:", |
| 4924 | " if (memcmp((char *) &now, (char *) &comp_now, vsize) == 0)", |
| 4925 | " return depth;", |
| 4926 | " if (depth > 0) goto Up;", |
| 4927 | " return 0;", |
| 4928 | "}", |
| 4929 | "#endif", |
| 4930 | "static char unwinding;", |
| 4931 | "void", |
| 4932 | "uerror(char *str)", |
| 4933 | "{ static char laststr[256];", |
| 4934 | " int is_cycle;", |
| 4935 | "", |
| 4936 | " if (unwinding) return; /* 1.4.2 */", |
| 4937 | " if (strncmp(str, laststr, 254))", |
| 4938 | "#if NCORE>1", |
| 4939 | " cpu_printf(\"pan: %%s (at depth %%ld)\\n\", str,", |
| 4940 | "#else", |
| 4941 | " printf(\"pan: %%s (at depth %%ld)\\n\", str,", |
| 4942 | "#endif", |
| 4943 | "#if NCORE>1", |
| 4944 | " (nr_handoffs * z_handoff) + ", |
| 4945 | "#endif", |
| 4946 | " ((depthfound==-1)?depth:depthfound));", |
| 4947 | " strncpy(laststr, str, 254);", |
| 4948 | " errors++;", |
| 4949 | "#ifdef HAS_CODE", |
| 4950 | " if (readtrail) { wrap_trail(); return; }", |
| 4951 | "#endif", |
| 4952 | " is_cycle = (strstr(str, \" cycle\") != (char *) 0);", |
| 4953 | " if (!is_cycle)", |
| 4954 | " { depth++; trpt++;", /* include failed step */ |
| 4955 | " }", |
| 4956 | " if ((every_error != 0)", |
| 4957 | " || errors == upto)", |
| 4958 | " {", |
| 4959 | "#if defined(MA) && !defined(SAFETY)", |
| 4960 | " if (is_cycle)", |
| 4961 | " { int od = depth;", |
| 4962 | " unwinding = 1;", |
| 4963 | " depthfound = Unwind();", |
| 4964 | " unwinding = 0;", |
| 4965 | " depth = od;", |
| 4966 | " }", |
| 4967 | "#endif", |
| 4968 | "#if NCORE>1", |
| 4969 | " writing_trail = 1;", |
| 4970 | "#endif", |
| 4971 | "#ifdef BFS", |
| 4972 | " if (depth > 1) trpt--;", |
| 4973 | " nuerror(str);", |
| 4974 | " if (depth > 1) trpt++;", |
| 4975 | "#else", |
| 4976 | " putrail();", |
| 4977 | "#endif", |
| 4978 | "#if defined(MA) && !defined(SAFETY)", |
| 4979 | " if (strstr(str, \" cycle\"))", |
| 4980 | " { if (every_error)", |
| 4981 | " printf(\"sorry: MA writes 1 trail max\\n\");", |
| 4982 | " wrapup(); /* no recovery from unwind */", |
| 4983 | " }", |
| 4984 | "#endif", |
| 4985 | "#if NCORE>1", |
| 4986 | " if (search_terminated != NULL)", |
| 4987 | " { *search_terminated |= 4; /* uerror */", |
| 4988 | " }", |
| 4989 | " writing_trail = 0;", |
| 4990 | "#endif", |
| 4991 | " }", |
| 4992 | " if (!is_cycle)", |
| 4993 | " { depth--; trpt--; /* undo */", |
| 4994 | " }", |
| 4995 | "#ifndef BFS", |
| 4996 | " if (iterative != 0 && maxdepth > 0)", |
| 4997 | " { maxdepth = (iterative == 1)?(depth-1):(depth/2);", |
| 4998 | " warned = 1;", |
| 4999 | " printf(\"pan: reducing search depth to %%ld\\n\",", |
| 5000 | " maxdepth);", |
| 5001 | " } else", |
| 5002 | "#endif", |
| 5003 | " if (errors >= upto && upto != 0)", |
| 5004 | " {", |
| 5005 | "#if NCORE>1", |
| 5006 | " sudden_stop(\"uerror\");", |
| 5007 | "#endif", |
| 5008 | " wrapup();", |
| 5009 | " }", |
| 5010 | " depthfound = -1;", |
| 5011 | "}\n", |
| 5012 | "int", |
| 5013 | "xrefsrc(int lno, S_F_MAP *mp, int M, int i)", |
| 5014 | "{ Trans *T; int j, retval=1;", |
| 5015 | " for (T = trans[M][i]; T; T = T->nxt)", |
| 5016 | " if (T && T->tp)", |
| 5017 | " { if (strcmp(T->tp, \".(goto)\") == 0", |
| 5018 | " || strncmp(T->tp, \"goto :\", 6) == 0)", |
| 5019 | " return 1; /* not reported */", |
| 5020 | "", |
| 5021 | " printf(\"\\tline %%d\", lno);", |
| 5022 | " if (verbose)", |
| 5023 | " for (j = 0; j < sizeof(mp); j++)", |
| 5024 | " if (i >= mp[j].from && i <= mp[j].upto)", |
| 5025 | " { printf(\", \\\"%%s\\\"\", mp[j].fnm);", |
| 5026 | " break;", |
| 5027 | " }", |
| 5028 | " printf(\", state %%d\", i);", |
| 5029 | " if (strcmp(T->tp, \"\") != 0)", |
| 5030 | " { char *q;", |
| 5031 | " q = transmognify(T->tp);", |
| 5032 | " printf(\", \\\"%%s\\\"\", q?q:\"\");", |
| 5033 | " } else if (stopstate[M][i])", |
| 5034 | " printf(\", -end state-\");", |
| 5035 | " printf(\"\\n\");", |
| 5036 | " retval = 0; /* reported */", |
| 5037 | " }", |
| 5038 | " return retval;", |
| 5039 | "}\n", |
| 5040 | "void", |
| 5041 | "r_ck(uchar *which, int N, int M, short *src, S_F_MAP *mp)", |
| 5042 | "{ int i, m=0;\n", |
| 5043 | "#ifdef VERI", |
| 5044 | " if (M == VERI && !verbose) return;", |
| 5045 | "#endif", |
| 5046 | " printf(\"unreached in proctype %%s\\n\", procname[M]);", |
| 5047 | " for (i = 1; i < N; i++)", |
| 5048 | #if 0 |
| 5049 | " if (which[i] == 0 /* && trans[M][i] */)", |
| 5050 | #else |
| 5051 | " if (which[i] == 0", |
| 5052 | " && (mapstate[M][i] == 0", |
| 5053 | " || which[mapstate[M][i]] == 0))", |
| 5054 | #endif |
| 5055 | " m += xrefsrc((int) src[i], mp, M, i);", |
| 5056 | " else", |
| 5057 | " m++;", |
| 5058 | " printf(\"\t(%%d of %%d states)\\n\", N-1-m, N-1);", |
| 5059 | "}", |
| 5060 | "#if NCORE>1 && !defined(SEP_STATE)", |
| 5061 | "static long rev_trail_cnt;", |
| 5062 | "", |
| 5063 | "#ifdef FULL_TRAIL", |
| 5064 | "void", |
| 5065 | "rev_trail(int fd, volatile Stack_Tree *st_tr)", |
| 5066 | "{ long j; char snap[64];", |
| 5067 | "", |
| 5068 | " if (!st_tr)", |
| 5069 | " { return;", |
| 5070 | " }", |
| 5071 | " rev_trail(fd, st_tr->prv);", |
| 5072 | "#ifdef VERBOSE", |
| 5073 | " printf(\"%%d (%%d) LRT [%%d,%%d] -- %%9u (root %%9u)\\n\",", |
| 5074 | " depth, rev_trail_cnt, st_tr->pr, st_tr->t_id, st_tr, stack_last[core_id]);", |
| 5075 | "#endif", |
| 5076 | " if (st_tr->pr != 255)", /* still needed? */ |
| 5077 | " { sprintf(snap, \"%%ld:%%d:%%d\\n\", ", |
| 5078 | " rev_trail_cnt++, st_tr->pr, st_tr->t_id);", |
| 5079 | " j = strlen(snap);", |
| 5080 | " if (write(fd, snap, j) != j)", |
| 5081 | " { printf(\"pan: error writing trailfile\\n\");", |
| 5082 | " close(fd);", |
| 5083 | " wrapup();", |
| 5084 | " return;", |
| 5085 | " }", |
| 5086 | " } else /* handoff point */", |
| 5087 | " { if (a_cycles)", |
| 5088 | " { write(fd, \"-1:-1:-1\\n\", 9);", |
| 5089 | " } }", |
| 5090 | "}", |
| 5091 | "#endif", /* FULL_TRAIL */ |
| 5092 | "#endif", /* NCORE>1 */ |
| 5093 | "", |
| 5094 | "void", |
| 5095 | "putrail(void)", |
| 5096 | "{ int fd;", |
| 5097 | "#if defined VERI || defined(MERGED)", |
| 5098 | " char snap[64];", |
| 5099 | "#endif", |
| 5100 | "#if NCORE==1 || defined(SEP_STATE) || !defined(FULL_TRAIL)", |
| 5101 | " long i, j;", |
| 5102 | " Trail *trl;", |
| 5103 | "#endif", |
| 5104 | " fd = make_trail();", |
| 5105 | " if (fd < 0) return;", |
| 5106 | "#ifdef VERI", |
| 5107 | " sprintf(snap, \"-2:%%d:-2\\n\", VERI);", |
| 5108 | " write(fd, snap, strlen(snap));", |
| 5109 | "#endif", |
| 5110 | "#ifdef MERGED", |
| 5111 | " sprintf(snap, \"-4:-4:-4\\n\");", |
| 5112 | " write(fd, snap, strlen(snap));", |
| 5113 | "#endif", |
| 5114 | "#if NCORE>1 && !defined(SEP_STATE) && defined(FULL_TRAIL)", |
| 5115 | " rev_trail_cnt = 1;", |
| 5116 | " enter_critical(GLOBAL_LOCK);", |
| 5117 | " rev_trail(fd, stack_last[core_id]);", |
| 5118 | " leave_critical(GLOBAL_LOCK);", |
| 5119 | "#else", |
| 5120 | " i = 1; /* trail starts at position 1 */", |
| 5121 | " #if NCORE>1 && defined(SEP_STATE)", |
| 5122 | " if (cur_Root.m_vsize > 0) { i++; depth++; }", |
| 5123 | " #endif", |
| 5124 | " for ( ; i <= depth; i++)", |
| 5125 | " { if (i == depthfound+1)", |
| 5126 | " write(fd, \"-1:-1:-1\\n\", 9);", |
| 5127 | " trl = getframe(i);", |
| 5128 | " if (!trl->o_t) continue;", |
| 5129 | " if (trl->o_pm&128) continue;", |
| 5130 | " sprintf(snap, \"%%ld:%%d:%%d\\n\", ", |
| 5131 | " i, trl->pr, trl->o_t->t_id);", |
| 5132 | " j = strlen(snap);", |
| 5133 | " if (write(fd, snap, j) != j)", |
| 5134 | " { printf(\"pan: error writing trailfile\\n\");", |
| 5135 | " close(fd);", |
| 5136 | " wrapup();", |
| 5137 | " } }", |
| 5138 | "#endif", |
| 5139 | " close(fd);", |
| 5140 | "#if NCORE>1", |
| 5141 | " cpu_printf(\"pan: wrote trailfile\\n\");", |
| 5142 | "#endif", |
| 5143 | "}\n", |
| 5144 | "void", |
| 5145 | "sv_save(void) /* push state vector onto save stack */", |
| 5146 | "{ if (!svtack->nxt)", |
| 5147 | " { svtack->nxt = (Svtack *) emalloc(sizeof(Svtack));", |
| 5148 | " svtack->nxt->body = emalloc(vsize*sizeof(char));", |
| 5149 | " svtack->nxt->lst = svtack;", |
| 5150 | " svtack->nxt->m_delta = vsize;", |
| 5151 | " svmax++;", |
| 5152 | " } else if (vsize > svtack->nxt->m_delta)", |
| 5153 | " { svtack->nxt->body = emalloc(vsize*sizeof(char));", |
| 5154 | " svtack->nxt->lst = svtack;", |
| 5155 | " svtack->nxt->m_delta = vsize;", |
| 5156 | " svmax++;", |
| 5157 | " }", |
| 5158 | " svtack = svtack->nxt;", |
| 5159 | "#if SYNC", |
| 5160 | " svtack->o_boq = boq;", |
| 5161 | "#endif", |
| 5162 | " svtack->o_delta = vsize; /* don't compress */", |
| 5163 | " memcpy((char *)(svtack->body), (char *) &now, vsize);", |
| 5164 | "#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1)", |
| 5165 | " c_stack((uchar *) &(svtack->c_stack[0]));", |
| 5166 | "#endif", |
| 5167 | "#ifdef DEBUG", |
| 5168 | " cpu_printf(\"%%d: sv_save\\n\", depth);", |
| 5169 | "#endif", |
| 5170 | "}\n", |
| 5171 | "void", |
| 5172 | "sv_restor(void) /* pop state vector from save stack */", |
| 5173 | "{", |
| 5174 | " memcpy((char *)&now, svtack->body, svtack->o_delta);", |
| 5175 | "#if SYNC", |
| 5176 | " boq = svtack->o_boq;", |
| 5177 | "#endif", |
| 5178 | |
| 5179 | "#if defined(C_States) && (HAS_TRACK==1)", |
| 5180 | "#ifdef HAS_STACK", |
| 5181 | " c_unstack((uchar *) &(svtack->c_stack[0]));", |
| 5182 | "#endif", |
| 5183 | " c_revert((uchar *) &(now.c_state[0]));", |
| 5184 | "#endif", |
| 5185 | |
| 5186 | " if (vsize != svtack->o_delta)", |
| 5187 | " Uerror(\"sv_restor\");", |
| 5188 | " if (!svtack->lst)", |
| 5189 | " Uerror(\"error: v_restor\");", |
| 5190 | " svtack = svtack->lst;", |
| 5191 | "#ifdef DEBUG", |
| 5192 | " cpu_printf(\" sv_restor\\n\");", |
| 5193 | "#endif", |
| 5194 | "}\n", |
| 5195 | "void", |
| 5196 | "p_restor(int h)", |
| 5197 | "{ int i; char *z = (char *) &now;\n", |
| 5198 | " proc_offset[h] = stack->o_offset;", |
| 5199 | " proc_skip[h] = (uchar) stack->o_skip;", |
| 5200 | "#ifndef XUSAFE", |
| 5201 | " p_name[h] = stack->o_name;", |
| 5202 | "#endif", |
| 5203 | "#ifndef NOCOMP", |
| 5204 | " for (i = vsize + stack->o_skip; i > vsize; i--)", |
| 5205 | " Mask[i-1] = 1; /* align */", |
| 5206 | "#endif", |
| 5207 | " vsize += stack->o_skip;", |
| 5208 | " memcpy(z+vsize, stack->body, stack->o_delta);", |
| 5209 | " vsize += stack->o_delta;", |
| 5210 | "#ifndef NOVSZ", |
| 5211 | " now._vsz = vsize;", |
| 5212 | "#endif", |
| 5213 | "#ifndef NOCOMP", |
| 5214 | " for (i = 1; i <= Air[((P0 *)pptr(h))->_t]; i++)", |
| 5215 | " Mask[vsize - i] = 1; /* pad */", |
| 5216 | " Mask[proc_offset[h]] = 1; /* _pid */", |
| 5217 | "#endif", |
| 5218 | " if (BASE > 0 && h > 0)", |
| 5219 | " ((P0 *)pptr(h))->_pid = h-BASE;", |
| 5220 | " else", |
| 5221 | " ((P0 *)pptr(h))->_pid = h;", |
| 5222 | " i = stack->o_delqs;", |
| 5223 | " now._nr_pr += 1;", |
| 5224 | " if (!stack->lst) /* debugging */", |
| 5225 | " Uerror(\"error: p_restor\");", |
| 5226 | " stack = stack->lst;", |
| 5227 | " this = pptr(h);", |
| 5228 | " while (i-- > 0)", |
| 5229 | " q_restor();", |
| 5230 | "}\n", |
| 5231 | "void", |
| 5232 | "q_restor(void)", |
| 5233 | "{ char *z = (char *) &now;", |
| 5234 | "#ifndef NOCOMP", |
| 5235 | " int k, k_end;", |
| 5236 | "#endif", |
| 5237 | " q_offset[now._nr_qs] = stack->o_offset;", |
| 5238 | " q_skip[now._nr_qs] = (uchar) stack->o_skip;", |
| 5239 | "#ifndef XUSAFE", |
| 5240 | " q_name[now._nr_qs] = stack->o_name;", |
| 5241 | "#endif", |
| 5242 | " vsize += stack->o_skip;", |
| 5243 | " memcpy(z+vsize, stack->body, stack->o_delta);", |
| 5244 | " vsize += stack->o_delta;", |
| 5245 | "#ifndef NOVSZ", |
| 5246 | " now._vsz = vsize;", |
| 5247 | "#endif", |
| 5248 | " now._nr_qs += 1;", |
| 5249 | "#ifndef NOCOMP", |
| 5250 | " k_end = stack->o_offset;", |
| 5251 | " k = k_end - stack->o_skip;", |
| 5252 | "#if SYNC", |
| 5253 | "#ifndef BFS", |
| 5254 | " if (q_zero(now._nr_qs)) k_end += stack->o_delta;", |
| 5255 | "#endif", |
| 5256 | "#endif", |
| 5257 | " for ( ; k < k_end; k++)", |
| 5258 | " Mask[k] = 1;", |
| 5259 | "#endif", |
| 5260 | " if (!stack->lst) /* debugging */", |
| 5261 | " Uerror(\"error: q_restor\");", |
| 5262 | " stack = stack->lst;", |
| 5263 | "}", |
| 5264 | |
| 5265 | "typedef struct IntChunks {", |
| 5266 | " int *ptr;", |
| 5267 | " struct IntChunks *nxt;", |
| 5268 | "} IntChunks;", |
| 5269 | "IntChunks *filled_chunks[512];", |
| 5270 | "IntChunks *empty_chunks[512];", |
| 5271 | |
| 5272 | "int *", |
| 5273 | "grab_ints(int nr)", |
| 5274 | "{ IntChunks *z;", |
| 5275 | " if (nr >= 512) Uerror(\"cannot happen grab_int\");", |
| 5276 | " if (filled_chunks[nr])", |
| 5277 | " { z = filled_chunks[nr];", |
| 5278 | " filled_chunks[nr] = filled_chunks[nr]->nxt;", |
| 5279 | " } else ", |
| 5280 | " { z = (IntChunks *) emalloc(sizeof(IntChunks));", |
| 5281 | " z->ptr = (int *) emalloc(nr * sizeof(int));", |
| 5282 | " }", |
| 5283 | " z->nxt = empty_chunks[nr];", |
| 5284 | " empty_chunks[nr] = z;", |
| 5285 | " return z->ptr;", |
| 5286 | "}", |
| 5287 | "void", |
| 5288 | "ungrab_ints(int *p, int nr)", |
| 5289 | "{ IntChunks *z;", |
| 5290 | " if (!empty_chunks[nr]) Uerror(\"cannot happen ungrab_int\");", |
| 5291 | " z = empty_chunks[nr];", |
| 5292 | " empty_chunks[nr] = empty_chunks[nr]->nxt;", |
| 5293 | " z->ptr = p;", |
| 5294 | " z->nxt = filled_chunks[nr];", |
| 5295 | " filled_chunks[nr] = z;", |
| 5296 | "}", |
| 5297 | "int", |
| 5298 | "delproc(int sav, int h)", |
| 5299 | "{ int d, i=0;", |
| 5300 | "#ifndef NOCOMP", |
| 5301 | " int o_vsize = vsize;", |
| 5302 | "#endif", |
| 5303 | " if (h+1 != (int) now._nr_pr) return 0;\n", |
| 5304 | " while (now._nr_qs", |
| 5305 | " && q_offset[now._nr_qs-1] > proc_offset[h])", |
| 5306 | " { delq(sav);", |
| 5307 | " i++;", |
| 5308 | " }", |
| 5309 | " d = vsize - proc_offset[h];", |
| 5310 | " if (sav)", |
| 5311 | " { if (!stack->nxt)", |
| 5312 | " { stack->nxt = (Stack *)", |
| 5313 | " emalloc(sizeof(Stack));", |
| 5314 | " stack->nxt->body = ", |
| 5315 | " emalloc(Maxbody*sizeof(char));", |
| 5316 | " stack->nxt->lst = stack;", |
| 5317 | " smax++;", |
| 5318 | " }", |
| 5319 | " stack = stack->nxt;", |
| 5320 | " stack->o_offset = proc_offset[h];", |
| 5321 | "#if VECTORSZ>32000", |
| 5322 | " stack->o_skip = (int) proc_skip[h];", |
| 5323 | "#else", |
| 5324 | " stack->o_skip = (short) proc_skip[h];", |
| 5325 | "#endif", |
| 5326 | "#ifndef XUSAFE", |
| 5327 | " stack->o_name = p_name[h];", |
| 5328 | "#endif", |
| 5329 | " stack->o_delta = d;", |
| 5330 | " stack->o_delqs = i;", |
| 5331 | " memcpy(stack->body, (char *)pptr(h), d);", |
| 5332 | " }", |
| 5333 | " vsize = proc_offset[h];", |
| 5334 | " now._nr_pr = now._nr_pr - 1;", |
| 5335 | " memset((char *)pptr(h), 0, d);", |
| 5336 | " vsize -= (int) proc_skip[h];", |
| 5337 | "#ifndef NOVSZ", |
| 5338 | " now._vsz = vsize;", |
| 5339 | "#endif", |
| 5340 | "#ifndef NOCOMP", |
| 5341 | " for (i = vsize; i < o_vsize; i++)", |
| 5342 | " Mask[i] = 0; /* reset */", |
| 5343 | "#endif", |
| 5344 | " return 1;", |
| 5345 | "}\n", |
| 5346 | "void", |
| 5347 | "delq(int sav)", |
| 5348 | "{ int h = now._nr_qs - 1;", |
| 5349 | " int d = vsize - q_offset[now._nr_qs - 1];", |
| 5350 | "#ifndef NOCOMP", |
| 5351 | " int k, o_vsize = vsize;", |
| 5352 | "#endif", |
| 5353 | " if (sav)", |
| 5354 | " { if (!stack->nxt)", |
| 5355 | " { stack->nxt = (Stack *)", |
| 5356 | " emalloc(sizeof(Stack));", |
| 5357 | " stack->nxt->body = ", |
| 5358 | " emalloc(Maxbody*sizeof(char));", |
| 5359 | " stack->nxt->lst = stack;", |
| 5360 | " smax++;", |
| 5361 | " }", |
| 5362 | " stack = stack->nxt;", |
| 5363 | " stack->o_offset = q_offset[h];", |
| 5364 | "#if VECTORSZ>32000", |
| 5365 | " stack->o_skip = (int) q_skip[h];", |
| 5366 | "#else", |
| 5367 | " stack->o_skip = (short) q_skip[h];", |
| 5368 | "#endif", |
| 5369 | "#ifndef XUSAFE", |
| 5370 | " stack->o_name = q_name[h];", |
| 5371 | "#endif", |
| 5372 | " stack->o_delta = d;", |
| 5373 | " memcpy(stack->body, (char *)qptr(h), d);", |
| 5374 | " }", |
| 5375 | " vsize = q_offset[h];", |
| 5376 | " now._nr_qs = now._nr_qs - 1;", |
| 5377 | " memset((char *)qptr(h), 0, d);", |
| 5378 | " vsize -= (int) q_skip[h];", |
| 5379 | "#ifndef NOVSZ", |
| 5380 | " now._vsz = vsize;", |
| 5381 | "#endif", |
| 5382 | "#ifndef NOCOMP", |
| 5383 | " for (k = vsize; k < o_vsize; k++)", |
| 5384 | " Mask[k] = 0; /* reset */", |
| 5385 | "#endif", |
| 5386 | "}\n", |
| 5387 | "int", |
| 5388 | "qs_empty(void)", |
| 5389 | "{ int i;", |
| 5390 | " for (i = 0; i < (int) now._nr_qs; i++)", |
| 5391 | " { if (q_sz(i) > 0)", |
| 5392 | " return 0;", |
| 5393 | " }", |
| 5394 | " return 1;", |
| 5395 | "}\n", |
| 5396 | "int", |
| 5397 | "endstate(void)", |
| 5398 | "{ int i; P0 *ptr;", |
| 5399 | " for (i = BASE; i < (int) now._nr_pr; i++)", |
| 5400 | " { ptr = (P0 *) pptr(i);", |
| 5401 | " if (!stopstate[ptr->_t][ptr->_p])", |
| 5402 | " return 0;", |
| 5403 | " }", |
| 5404 | " if (strict) return qs_empty();", |
| 5405 | "#if defined(EVENT_TRACE) && !defined(OTIM)", |
| 5406 | " if (!stopstate[EVENT_TRACE][now._event] && !a_cycles)", |
| 5407 | " { printf(\"pan: event_trace not completed\\n\");", |
| 5408 | " return 0;", |
| 5409 | " }", |
| 5410 | "#endif", |
| 5411 | " return 1;", |
| 5412 | "}\n", |
| 5413 | "#ifndef SAFETY", |
| 5414 | "void", |
| 5415 | "checkcycles(void)", |
| 5416 | "{ uchar o_a_t = now._a_t;", |
| 5417 | "#ifdef SCHED", |
| 5418 | " int o_limit;", |
| 5419 | "#endif", |
| 5420 | "#ifndef NOFAIR", |
| 5421 | " uchar o_cnt = now._cnt[1];", |
| 5422 | "#endif", |
| 5423 | "#ifdef FULLSTACK", |
| 5424 | "#ifndef MA", |
| 5425 | " struct H_el *sv = trpt->ostate; /* save */", |
| 5426 | "#else", |
| 5427 | " uchar prov = trpt->proviso; /* save */", |
| 5428 | "#endif", |
| 5429 | "#endif", |
| 5430 | "#ifdef DEBUG", |
| 5431 | " { int i; uchar *v = (uchar *) &now;", |
| 5432 | " printf(\" set Seed state \");", |
| 5433 | "#ifndef NOFAIR", |
| 5434 | " if (fairness) printf(\"(cnt = %%d:%%d, nrpr=%%d) \",", |
| 5435 | " now._cnt[0], now._cnt[1], now._nr_pr);", |
| 5436 | "#endif", |
| 5437 | " /* for (i = 0; i < n; i++) printf(\"%%d,\", v[i]); */", |
| 5438 | " printf(\"\\n\");", |
| 5439 | " }", |
| 5440 | " printf(\"%%d: cycle check starts\\n\", depth);", |
| 5441 | "#endif", |
| 5442 | " now._a_t |= (1|16|32);", |
| 5443 | " /* 1 = 2nd DFS; (16|32) to help hasher */", |
| 5444 | "#ifndef NOFAIR", |
| 5445 | #if 0 |
| 5446 | " if (fairness)", |
| 5447 | " { now._a_t &= ~2; /* pre-apply Rule 3 */", |
| 5448 | " now._cnt[1] = 0;", /* reset both a-bit and cnt=0 */ |
| 5449 | " /* avoid matching seed on claim stutter on this state */", |
| 5450 | " }", |
| 5451 | #else |
| 5452 | " now._cnt[1] = now._cnt[0];", |
| 5453 | #endif |
| 5454 | "#endif", |
| 5455 | " memcpy((char *)&A_Root, (char *)&now, vsize);", |
| 5456 | " A_depth = depthfound = depth;", |
| 5457 | |
| 5458 | "#if NCORE>1", |
| 5459 | " mem_put_acc();", /* handoff accept states */ |
| 5460 | "#else", |
| 5461 | " #ifdef SCHED", |
| 5462 | " o_limit = trpt->sched_limit;", |
| 5463 | " trpt->sched_limit = 0;", |
| 5464 | " #endif", |
| 5465 | " new_state(); /* start 2nd DFS */", |
| 5466 | " #ifdef SCHED", |
| 5467 | " trpt->sched_limit = o_limit;", |
| 5468 | " #endif", |
| 5469 | "#endif", |
| 5470 | |
| 5471 | " now._a_t = o_a_t;", |
| 5472 | "#ifndef NOFAIR", |
| 5473 | " now._cnt[1] = o_cnt;", |
| 5474 | "#endif", |
| 5475 | " A_depth = 0; depthfound = -1;", |
| 5476 | "#ifdef DEBUG", |
| 5477 | " printf(\"%%d: cycle check returns\\n\", depth);", |
| 5478 | "#endif", |
| 5479 | "#ifdef FULLSTACK", |
| 5480 | "#ifndef MA", |
| 5481 | " trpt->ostate = sv; /* restore */", |
| 5482 | "#else", |
| 5483 | " trpt->proviso = prov;", |
| 5484 | "#endif", |
| 5485 | "#endif", |
| 5486 | "}", |
| 5487 | "#endif\n", |
| 5488 | "#if defined(FULLSTACK) && defined(BITSTATE)", |
| 5489 | "struct H_el *Free_list = (struct H_el *) 0;", |
| 5490 | "void", |
| 5491 | "onstack_init(void) /* to store stack states in a bitstate search */", |
| 5492 | "{ S_Tab = (struct H_el **) emalloc(maxdepth*sizeof(struct H_el *));", |
| 5493 | "}", |
| 5494 | "struct H_el *", |
| 5495 | "grab_state(int n)", |
| 5496 | "{ struct H_el *v, *last = 0;", |
| 5497 | " if (H_tab == S_Tab)", |
| 5498 | " { for (v = Free_list; v && ((int) v->tagged >= n); v=v->nxt)", |
| 5499 | " { if ((int) v->tagged == n)", |
| 5500 | " { if (last)", |
| 5501 | " last->nxt = v->nxt;", |
| 5502 | " else", |
| 5503 | "gotcha: Free_list = v->nxt;", |
| 5504 | " v->tagged = 0;", |
| 5505 | " v->nxt = 0;", |
| 5506 | "#ifdef COLLAPSE", |
| 5507 | " v->ln = 0;", |
| 5508 | "#endif", |
| 5509 | " return v;", |
| 5510 | " }", |
| 5511 | " Fh++; last=v;", |
| 5512 | " }", |
| 5513 | " /* new: second try */", |
| 5514 | " v = Free_list;", /* try to avoid emalloc */ |
| 5515 | " if (v && ((int) v->tagged >= n))", |
| 5516 | " goto gotcha;", |
| 5517 | " ngrabs++;", |
| 5518 | " }", |
| 5519 | " return (struct H_el *)", |
| 5520 | " emalloc(sizeof(struct H_el)+n-sizeof(unsigned));", |
| 5521 | "}\n", |
| 5522 | "#else", |
| 5523 | |
| 5524 | "#if NCORE>1", |
| 5525 | "struct H_el *", |
| 5526 | "grab_state(int n)", |
| 5527 | "{ struct H_el *grab_shared(int);", |
| 5528 | " return grab_shared(sizeof(struct H_el)+n-sizeof(unsigned));", |
| 5529 | "}", |
| 5530 | "#else", |
| 5531 | " #ifndef AUTO_RESIZE", |
| 5532 | " #define grab_state(n) (struct H_el *) \\", |
| 5533 | " emalloc(sizeof(struct H_el)+n-sizeof(unsigned long));", |
| 5534 | " #else", |
| 5535 | " struct H_el *", |
| 5536 | " grab_state(int n)", |
| 5537 | " { struct H_el *p;", |
| 5538 | " int cnt = sizeof(struct H_el)+n-sizeof(unsigned long);", |
| 5539 | "", |
| 5540 | " if (reclaim_size >= cnt+WS)", |
| 5541 | " { if ((cnt & (WS-1)) != 0) /* alignment */", |
| 5542 | " { cnt += WS - (cnt & (WS-1));", |
| 5543 | " }", |
| 5544 | " p = (struct H_el *) reclaim_mem;", |
| 5545 | " reclaim_mem += cnt;", |
| 5546 | " reclaim_size -= cnt;", |
| 5547 | " memset(p, 0, cnt);", |
| 5548 | " } else", |
| 5549 | " { p = (struct H_el *) emalloc(cnt);", |
| 5550 | " }", |
| 5551 | " return p;", |
| 5552 | " }", |
| 5553 | " #endif", |
| 5554 | "#endif", |
| 5555 | |
| 5556 | "#endif", |
| 5557 | "#ifdef COLLAPSE", |
| 5558 | "unsigned long", |
| 5559 | "ordinal(char *v, long n, short tp)", |
| 5560 | "{ struct H_el *tmp, *ntmp; long m;", |
| 5561 | " struct H_el *olst = (struct H_el *) 0;", |
| 5562 | " s_hash((uchar *)v, n);", |
| 5563 | |
| 5564 | "#if NCORE>1 && !defined(SEP_STATE)", |
| 5565 | " enter_critical(CS_ID); /* uses spinlock - 1..128 */", |
| 5566 | "#endif", |
| 5567 | |
| 5568 | " tmp = H_tab[j1];", |
| 5569 | " if (!tmp)", |
| 5570 | " { tmp = grab_state(n);", |
| 5571 | " H_tab[j1] = tmp;", |
| 5572 | " } else", |
| 5573 | " for ( ;; olst = tmp, tmp = tmp->nxt)", |
| 5574 | " { m = memcmp(((char *)&(tmp->state)), v, n);", |
| 5575 | " if (n == tmp->ln)", |
| 5576 | " {", |
| 5577 | " if (m == 0)", |
| 5578 | " goto done;", |
| 5579 | " if (m < 0)", |
| 5580 | " {", |
| 5581 | "Insert: ntmp = grab_state(n);", |
| 5582 | " ntmp->nxt = tmp;", |
| 5583 | " if (!olst)", |
| 5584 | " H_tab[j1] = ntmp;", |
| 5585 | " else", |
| 5586 | " olst->nxt = ntmp;", |
| 5587 | " tmp = ntmp;", |
| 5588 | " break;", |
| 5589 | " } else if (!tmp->nxt)", |
| 5590 | " {", |
| 5591 | "Append: tmp->nxt = grab_state(n);", |
| 5592 | " tmp = tmp->nxt;", |
| 5593 | " break;", |
| 5594 | " }", |
| 5595 | " continue;", |
| 5596 | " }", |
| 5597 | " if (n < tmp->ln)", |
| 5598 | " goto Insert;", |
| 5599 | " else if (!tmp->nxt)", |
| 5600 | " goto Append;", |
| 5601 | " }", |
| 5602 | " m = ++ncomps[tp];", |
| 5603 | "#ifdef FULLSTACK", |
| 5604 | " tmp->tagged = m;", |
| 5605 | "#else", |
| 5606 | " tmp->st_id = m;", |
| 5607 | "#endif", |
| 5608 | "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", |
| 5609 | " tmp->m_K1 = K1;", |
| 5610 | "#endif", |
| 5611 | " memcpy(((char *)&(tmp->state)), v, n);", |
| 5612 | " tmp->ln = n;", |
| 5613 | "done:", |
| 5614 | |
| 5615 | "#if NCORE>1 && !defined(SEP_STATE)", |
| 5616 | " leave_critical(CS_ID); /* uses spinlock */", |
| 5617 | "#endif", |
| 5618 | |
| 5619 | "#ifdef FULLSTACK", |
| 5620 | " return tmp->tagged;", |
| 5621 | "#else", |
| 5622 | " return tmp->st_id;", |
| 5623 | "#endif", |
| 5624 | "}", |
| 5625 | "", |
| 5626 | "int", |
| 5627 | "compress(char *vin, int nin) /* collapse compression */", |
| 5628 | "{ char *w, *v = (char *) &comp_now;", |
| 5629 | " int i, j;", |
| 5630 | " unsigned long n;", |
| 5631 | " static char *x;", |
| 5632 | " static uchar nbytes[513]; /* 1 + 256 + 256 */", |
| 5633 | " static unsigned short nbytelen;", |
| 5634 | " long col_q(int, char *);", |
| 5635 | " long col_p(int, char *);", |
| 5636 | "#ifndef SAFETY", |
| 5637 | " if (a_cycles)", |
| 5638 | " *v++ = now._a_t;", |
| 5639 | "#ifndef NOFAIR", |
| 5640 | " if (fairness)", |
| 5641 | " for (i = 0; i < NFAIR; i++)", |
| 5642 | " *v++ = now._cnt[i];", |
| 5643 | "#endif", |
| 5644 | "#endif", |
| 5645 | " nbytelen = 0;", |
| 5646 | |
| 5647 | "#ifndef JOINPROCS", |
| 5648 | " for (i = 0; i < (int) now._nr_pr; i++)", |
| 5649 | " { n = col_p(i, (char *) 0);", |
| 5650 | "#ifdef NOFIX", |
| 5651 | " nbytes[nbytelen] = 0;", |
| 5652 | "#else", |
| 5653 | " nbytes[nbytelen] = 1;", |
| 5654 | " *v++ = ((P0 *) pptr(i))->_t;", |
| 5655 | "#endif", |
| 5656 | " *v++ = n&255;", |
| 5657 | " if (n >= (1<<8))", |
| 5658 | " { nbytes[nbytelen]++;", |
| 5659 | " *v++ = (n>>8)&255;", |
| 5660 | " }", |
| 5661 | " if (n >= (1<<16))", |
| 5662 | " { nbytes[nbytelen]++;", |
| 5663 | " *v++ = (n>>16)&255;", |
| 5664 | " }", |
| 5665 | " if (n >= (1<<24))", |
| 5666 | " { nbytes[nbytelen]++;", |
| 5667 | " *v++ = (n>>24)&255;", |
| 5668 | " }", |
| 5669 | " nbytelen++;", |
| 5670 | " }", |
| 5671 | "#else", |
| 5672 | " x = scratch;", |
| 5673 | " for (i = 0; i < (int) now._nr_pr; i++)", |
| 5674 | " x += col_p(i, x);", |
| 5675 | " n = ordinal(scratch, x-scratch, 2); /* procs */", |
| 5676 | " *v++ = n&255;", |
| 5677 | " nbytes[nbytelen] = 0;", |
| 5678 | " if (n >= (1<<8))", |
| 5679 | " { nbytes[nbytelen]++;", |
| 5680 | " *v++ = (n>>8)&255;", |
| 5681 | " }", |
| 5682 | " if (n >= (1<<16))", |
| 5683 | " { nbytes[nbytelen]++;", |
| 5684 | " *v++ = (n>>16)&255;", |
| 5685 | " }", |
| 5686 | " if (n >= (1<<24))", |
| 5687 | " { nbytes[nbytelen]++;", |
| 5688 | " *v++ = (n>>24)&255;", |
| 5689 | " }", |
| 5690 | " nbytelen++;", |
| 5691 | "#endif", |
| 5692 | "#ifdef SEPQS", |
| 5693 | " for (i = 0; i < (int) now._nr_qs; i++)", |
| 5694 | " { n = col_q(i, (char *) 0);", |
| 5695 | " nbytes[nbytelen] = 0;", |
| 5696 | " *v++ = n&255;", |
| 5697 | " if (n >= (1<<8))", |
| 5698 | " { nbytes[nbytelen]++;", |
| 5699 | " *v++ = (n>>8)&255;", |
| 5700 | " }", |
| 5701 | " if (n >= (1<<16))", |
| 5702 | " { nbytes[nbytelen]++;", |
| 5703 | " *v++ = (n>>16)&255;", |
| 5704 | " }", |
| 5705 | " if (n >= (1<<24))", |
| 5706 | " { nbytes[nbytelen]++;", |
| 5707 | " *v++ = (n>>24)&255;", |
| 5708 | " }", |
| 5709 | " nbytelen++;", |
| 5710 | " }", |
| 5711 | "#endif", |
| 5712 | |
| 5713 | "#ifdef NOVSZ", |
| 5714 | " /* 3 = _a_t, _nr_pr, _nr_qs */", |
| 5715 | " w = (char *) &now + 3 * sizeof(uchar);", |
| 5716 | "#ifndef NOFAIR", |
| 5717 | " w += NFAIR;", |
| 5718 | "#endif", |
| 5719 | "#else", |
| 5720 | "#if VECTORSZ<65536", |
| 5721 | " w = (char *) &(now._vsz) + sizeof(unsigned short);", |
| 5722 | "#else", |
| 5723 | " w = (char *) &(now._vsz) + sizeof(unsigned long);", |
| 5724 | "#endif", |
| 5725 | "#endif", |
| 5726 | " x = scratch;", |
| 5727 | " *x++ = now._nr_pr;", |
| 5728 | " *x++ = now._nr_qs;", |
| 5729 | |
| 5730 | " if (now._nr_qs > 0 && qptr(0) < pptr(0))", |
| 5731 | " n = qptr(0) - (uchar *) w;", |
| 5732 | " else", |
| 5733 | " n = pptr(0) - (uchar *) w;", |
| 5734 | " j = w - (char *) &now;", |
| 5735 | " for (i = 0; i < (int) n; i++, w++)", |
| 5736 | " if (!Mask[j++]) *x++ = *w;", |
| 5737 | "#ifndef SEPQS", |
| 5738 | " for (i = 0; i < (int) now._nr_qs; i++)", |
| 5739 | " x += col_q(i, x);", |
| 5740 | "#endif", |
| 5741 | |
| 5742 | " x--;", |
| 5743 | " for (i = 0, j = 6; i < nbytelen; i++)", |
| 5744 | " { if (j == 6)", |
| 5745 | " { j = 0;", |
| 5746 | " *(++x) = 0;", |
| 5747 | " } else", |
| 5748 | " j += 2;", |
| 5749 | " *x |= (nbytes[i] << j);", |
| 5750 | " }", |
| 5751 | " x++;", |
| 5752 | " for (j = 0; j < WS-1; j++)", |
| 5753 | " *x++ = 0;", |
| 5754 | " x -= j; j = 0;", |
| 5755 | " n = ordinal(scratch, x-scratch, 0); /* globals */", |
| 5756 | " *v++ = n&255;", |
| 5757 | " if (n >= (1<< 8)) { *v++ = (n>> 8)&255; j++; }", |
| 5758 | " if (n >= (1<<16)) { *v++ = (n>>16)&255; j++; }", |
| 5759 | " if (n >= (1<<24)) { *v++ = (n>>24)&255; j++; }", |
| 5760 | " *v++ = j; /* add last count as a byte */", |
| 5761 | |
| 5762 | " for (i = 0; i < WS-1; i++)", |
| 5763 | " *v++ = 0;", |
| 5764 | " v -= i;", |
| 5765 | "#if 0", |
| 5766 | " printf(\"collapse %%d -> %%d\\n\",", |
| 5767 | " vsize, v - (char *)&comp_now);", |
| 5768 | "#endif", |
| 5769 | " return v - (char *)&comp_now;", |
| 5770 | "}", |
| 5771 | |
| 5772 | "#else", |
| 5773 | "#if !defined(NOCOMP)", |
| 5774 | "int", |
| 5775 | "compress(char *vin, int n) /* default compression */", |
| 5776 | "{", |
| 5777 | "#ifdef HC", |
| 5778 | " int delta = 0;", |
| 5779 | " s_hash((uchar *)vin, n); /* sets K1 and K2 */", |
| 5780 | "#ifndef SAFETY", |
| 5781 | " if (S_A)", |
| 5782 | " { delta++; /* _a_t */", |
| 5783 | "#ifndef NOFAIR", |
| 5784 | " if (S_A > NFAIR)", |
| 5785 | " delta += NFAIR; /* _cnt[] */", |
| 5786 | "#endif", |
| 5787 | " }", |
| 5788 | "#endif", |
| 5789 | " memcpy((char *) &comp_now + delta, (char *) &K1, WS);", |
| 5790 | " delta += WS;", |
| 5791 | "#if HC>0", |
| 5792 | " memcpy((char *) &comp_now + delta, (char *) &K2, HC);", |
| 5793 | " delta += HC;", |
| 5794 | "#endif", |
| 5795 | " return delta;", |
| 5796 | "#else", |
| 5797 | " char *vv = vin;", |
| 5798 | " char *v = (char *) &comp_now;", |
| 5799 | " int i;", |
| 5800 | " #ifndef NO_FAST_C", /* disable faster compress */ |
| 5801 | " int r = 0, unroll = n/8;", /* most sv are much longer */ |
| 5802 | " if (unroll > 0)", |
| 5803 | " { i = 0;", |
| 5804 | " while (r++ < unroll)", |
| 5805 | " { /* unroll 8 times, avoid ifs */", |
| 5806 | " /* 1 */ *v = *vv++;", |
| 5807 | " v += 1 - Mask[i++];", |
| 5808 | " /* 2 */ *v = *vv++;", |
| 5809 | " v += 1 - Mask[i++];", |
| 5810 | " /* 3 */ *v = *vv++;", |
| 5811 | " v += 1 - Mask[i++];", |
| 5812 | " /* 4 */ *v = *vv++;", |
| 5813 | " v += 1 - Mask[i++];", |
| 5814 | " /* 5 */ *v = *vv++;", |
| 5815 | " v += 1 - Mask[i++];", |
| 5816 | " /* 6 */ *v = *vv++;", |
| 5817 | " v += 1 - Mask[i++];", |
| 5818 | " /* 7 */ *v = *vv++;", |
| 5819 | " v += 1 - Mask[i++];", |
| 5820 | " /* 8 */ *v = *vv++;", |
| 5821 | " v += 1 - Mask[i++];", |
| 5822 | " }", |
| 5823 | " r = n - i; /* the rest, at most 7 */", |
| 5824 | " switch (r) {", |
| 5825 | " case 7: *v = *vv++; v += 1 - Mask[i++];", |
| 5826 | " case 6: *v = *vv++; v += 1 - Mask[i++];", |
| 5827 | " case 5: *v = *vv++; v += 1 - Mask[i++];", |
| 5828 | " case 4: *v = *vv++; v += 1 - Mask[i++];", |
| 5829 | " case 3: *v = *vv++; v += 1 - Mask[i++];", |
| 5830 | " case 2: *v = *vv++; v += 1 - Mask[i++];", |
| 5831 | " case 1: *v = *vv++; v += 1 - Mask[i++];", |
| 5832 | " case 0: break;", |
| 5833 | " }", |
| 5834 | " r = (n+WS-1)/WS; /* words rounded up */", |
| 5835 | " r *= WS; /* bytes */", |
| 5836 | " i = r - i; /* remainder */", |
| 5837 | " switch (i) {", /* fill word */ |
| 5838 | " case 7: *v++ = 0; /* fall thru */", |
| 5839 | " case 6: *v++ = 0;", |
| 5840 | " case 5: *v++ = 0;", |
| 5841 | " case 4: *v++ = 0;", |
| 5842 | " case 3: *v++ = 0;", |
| 5843 | " case 2: *v++ = 0;", |
| 5844 | " case 1: *v++ = 0;", |
| 5845 | " case 0: break;", |
| 5846 | " default: Uerror(\"unexpected wordsize\");", |
| 5847 | " }", |
| 5848 | " v -= i;", |
| 5849 | " } else", |
| 5850 | " #endif", |
| 5851 | " { for (i = 0; i < n; i++, vv++)", |
| 5852 | " if (!Mask[i]) *v++ = *vv;", |
| 5853 | " for (i = 0; i < WS-1; i++)", |
| 5854 | " *v++ = 0;", |
| 5855 | " v -= i;", |
| 5856 | " }", |
| 5857 | "#if 0", |
| 5858 | " printf(\"compress %%d -> %%d\\n\",", |
| 5859 | " n, v - (char *)&comp_now);", |
| 5860 | "#endif", |
| 5861 | " return v - (char *)&comp_now;", |
| 5862 | "#endif", |
| 5863 | "}", |
| 5864 | "#endif", |
| 5865 | "#endif", |
| 5866 | "#if defined(FULLSTACK) && defined(BITSTATE)", |
| 5867 | "#if defined(MA)", |
| 5868 | "#if !defined(onstack_now)", |
| 5869 | "int onstack_now(void) {}", /* to suppress compiler errors */ |
| 5870 | "#endif", |
| 5871 | "#if !defined(onstack_put)", |
| 5872 | "void onstack_put(void) {}", /* for this invalid combination */ |
| 5873 | "#endif", |
| 5874 | "#if !defined(onstack_zap)", |
| 5875 | "void onstack_zap(void) {}", /* of directives */ |
| 5876 | "#endif", |
| 5877 | "#else", |
| 5878 | "void", |
| 5879 | "onstack_zap(void)", |
| 5880 | "{ struct H_el *v, *w, *last = 0;", |
| 5881 | " struct H_el **tmp = H_tab;", |
| 5882 | " char *nv; int n, m;\n", |
| 5883 | " static char warned = 0;", |
| 5884 | "", |
| 5885 | " H_tab = S_Tab;", |
| 5886 | "#ifndef NOCOMP", |
| 5887 | " nv = (char *) &comp_now;", |
| 5888 | " n = compress((char *)&now, vsize);", |
| 5889 | "#else", |
| 5890 | "#if defined(BITSTATE) && defined(LC)", |
| 5891 | " nv = (char *) &comp_now;", |
| 5892 | " n = compact_stack((char *)&now, vsize);", |
| 5893 | "#else", |
| 5894 | " nv = (char *) &now;", |
| 5895 | " n = vsize;", |
| 5896 | "#endif", |
| 5897 | "#endif", |
| 5898 | "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", |
| 5899 | " s_hash((uchar *)nv, n);", |
| 5900 | "#endif", |
| 5901 | " H_tab = tmp;", |
| 5902 | " for (v = S_Tab[j1]; v; Zh++, last=v, v=v->nxt)", |
| 5903 | " { m = memcmp(&(v->state), nv, n);", |
| 5904 | " if (m == 0)", |
| 5905 | " goto Found;", |
| 5906 | " if (m < 0)", |
| 5907 | " break;", |
| 5908 | " }", |
| 5909 | "/* NotFound: */", |
| 5910 | "#ifndef ZAPH", |
| 5911 | " #if defined(BITSTATE) && NCORE>1", |
| 5912 | " /* seen this happen, likely harmless, but not yet understood */", |
| 5913 | " if (warned == 0)", |
| 5914 | " #endif", |
| 5915 | " { /* Uerror(\"stack out of wack - zap\"); */", |
| 5916 | " cpu_printf(\"pan: warning, stack incomplete\\n\");", |
| 5917 | " warned = 1;", |
| 5918 | " }", |
| 5919 | "#endif", |
| 5920 | " return;", |
| 5921 | "Found:", |
| 5922 | " ZAPS++;", |
| 5923 | " if (last)", |
| 5924 | " last->nxt = v->nxt;", |
| 5925 | " else", |
| 5926 | " S_Tab[j1] = v->nxt;", |
| 5927 | " v->tagged = (unsigned) n;", |
| 5928 | "#if !defined(NOREDUCE) && !defined(SAFETY)", |
| 5929 | " v->proviso = 0;", |
| 5930 | "#endif", |
| 5931 | " v->nxt = last = (struct H_el *) 0;", |
| 5932 | " for (w = Free_list; w; Fa++, last=w, w = w->nxt)", |
| 5933 | " { if ((int) w->tagged <= n)", |
| 5934 | " { if (last)", |
| 5935 | " { v->nxt = w;", |
| 5936 | " last->nxt = v;", |
| 5937 | " } else", |
| 5938 | " { v->nxt = Free_list;", |
| 5939 | " Free_list = v;", |
| 5940 | " }", |
| 5941 | " return;", |
| 5942 | " }", |
| 5943 | " if (!w->nxt)", |
| 5944 | " { w->nxt = v;", |
| 5945 | " return;", |
| 5946 | " } }", |
| 5947 | " Free_list = v;", |
| 5948 | "}", |
| 5949 | "void", |
| 5950 | "onstack_put(void)", |
| 5951 | "{ struct H_el **tmp = H_tab;", |
| 5952 | " H_tab = S_Tab;", |
| 5953 | " if (hstore((char *)&now, vsize) != 0)", |
| 5954 | "#if defined(BITSTATE) && defined(LC)", |
| 5955 | " printf(\"pan: warning, double stack entry\\n\");", |
| 5956 | "#else", |
| 5957 | " #ifndef ZAPH", |
| 5958 | " Uerror(\"cannot happen - unstack_put\");", |
| 5959 | " #endif", |
| 5960 | "#endif", |
| 5961 | " H_tab = tmp;", |
| 5962 | " trpt->ostate = Lstate;", |
| 5963 | " PUT++;", |
| 5964 | "}", |
| 5965 | "int", |
| 5966 | "onstack_now(void)", |
| 5967 | "{ struct H_el *tmp;", |
| 5968 | " struct H_el **tmp2 = H_tab;", |
| 5969 | " char *v; int n, m = 1;\n", |
| 5970 | " H_tab = S_Tab;", |
| 5971 | "#ifdef NOCOMP", |
| 5972 | "#if defined(BITSTATE) && defined(LC)", |
| 5973 | " v = (char *) &comp_now;", |
| 5974 | " n = compact_stack((char *)&now, vsize);", |
| 5975 | "#else", |
| 5976 | " v = (char *) &now;", |
| 5977 | " n = vsize;", |
| 5978 | "#endif", |
| 5979 | "#else", |
| 5980 | " v = (char *) &comp_now;", |
| 5981 | " n = compress((char *)&now, vsize);", |
| 5982 | "#endif", |
| 5983 | "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", |
| 5984 | " s_hash((uchar *)v, n);", |
| 5985 | "#endif", |
| 5986 | " H_tab = tmp2;", |
| 5987 | " for (tmp = S_Tab[j1]; tmp; Zn++, tmp = tmp->nxt)", |
| 5988 | " { m = memcmp(((char *)&(tmp->state)),v,n);", |
| 5989 | " if (m <= 0)", |
| 5990 | " { Lstate = (struct H_el *) tmp;", |
| 5991 | " break;", |
| 5992 | " } }", |
| 5993 | " PROBE++;", |
| 5994 | " return (m == 0);", |
| 5995 | "}", |
| 5996 | "#endif", |
| 5997 | "#endif", |
| 5998 | |
| 5999 | "#ifndef BITSTATE", |
| 6000 | "void", |
| 6001 | "hinit(void)", |
| 6002 | "{", |
| 6003 | " #ifdef MA", |
| 6004 | "#ifdef R_XPT", |
| 6005 | " { void r_xpoint(void);", |
| 6006 | " r_xpoint();", |
| 6007 | " }", |
| 6008 | "#else", |
| 6009 | " dfa_init((unsigned short) (MA+a_cycles));", |
| 6010 | "#if NCORE>1 && !defined(COLLAPSE)", |
| 6011 | " if (!readtrail)", |
| 6012 | " { void init_HT(unsigned long);", |
| 6013 | " init_HT(0L);", |
| 6014 | " }", |
| 6015 | "#endif", |
| 6016 | "#endif", |
| 6017 | " #endif", |
| 6018 | " #if !defined(MA) || defined(COLLAPSE)", |
| 6019 | "#if NCORE>1", |
| 6020 | " if (!readtrail)", |
| 6021 | " { void init_HT(unsigned long);", |
| 6022 | " init_HT((unsigned long) (ONE_L<<ssize)*sizeof(struct H_el *));", |
| 6023 | " } else", |
| 6024 | "#endif", |
| 6025 | " H_tab = (struct H_el **)", |
| 6026 | " emalloc((ONE_L<<ssize)*sizeof(struct H_el *));", |
| 6027 | " #endif", |
| 6028 | "}", |
| 6029 | "#endif\n", |
| 6030 | |
| 6031 | "#if !defined(BITSTATE) || defined(FULLSTACK)", |
| 6032 | |
| 6033 | "#ifdef DEBUG", |
| 6034 | "void", |
| 6035 | "dumpstate(int wasnew, char *v, int n, int tag)", |
| 6036 | "{ int i;", |
| 6037 | "#ifndef SAFETY", |
| 6038 | " if (S_A)", |
| 6039 | " { printf(\"\tstate tags %%d (%%d::%%d): \",", |
| 6040 | " V_A, wasnew, v[0]);", |
| 6041 | "#ifdef FULLSTACK", |
| 6042 | " printf(\" %%d \", tag);", |
| 6043 | "#endif", |
| 6044 | " printf(\"\\n\");", |
| 6045 | " }", |
| 6046 | "#endif", |
| 6047 | "#ifdef SDUMP", |
| 6048 | "#ifndef NOCOMP", |
| 6049 | " printf(\"\t State: \");", |
| 6050 | " for (i = 0; i < vsize; i++) printf(\"%%d%%s,\",", |
| 6051 | " ((char *)&now)[i], Mask[i]?\"*\":\"\");", |
| 6052 | "#endif", |
| 6053 | " printf(\"\\n\tVector: \");", |
| 6054 | " for (i = 0; i < n; i++) printf(\"%%d,\", v[i]);", |
| 6055 | " printf(\"\\n\");", |
| 6056 | "#endif", |
| 6057 | "}", |
| 6058 | "#endif", |
| 6059 | |
| 6060 | "#ifdef MA", |
| 6061 | "int", |
| 6062 | "gstore(char *vin, int nin, uchar pbit)", |
| 6063 | "{ int n, i;", |
| 6064 | " int ret_val = 1;", |
| 6065 | " uchar *v;", |
| 6066 | " static uchar Info[MA+1];", |
| 6067 | "#ifndef NOCOMP", |
| 6068 | " n = compress(vin, nin);", |
| 6069 | " v = (uchar *) &comp_now;", |
| 6070 | "#else", |
| 6071 | " n = nin;", |
| 6072 | " v = vin;", |
| 6073 | "#endif", |
| 6074 | " if (n >= MA)", |
| 6075 | " { printf(\"pan: error, MA too small, recompile pan.c\");", |
| 6076 | " printf(\" with -DMA=N with N>%%d\\n\", n);", |
| 6077 | " Uerror(\"aborting\");", |
| 6078 | " }", |
| 6079 | " if (n > (int) maxgs)", |
| 6080 | " { maxgs = (unsigned int) n;", |
| 6081 | " }", |
| 6082 | " for (i = 0; i < n; i++)", |
| 6083 | " { Info[i] = v[i];", |
| 6084 | " }", |
| 6085 | " for ( ; i < MA-1; i++)", |
| 6086 | " { Info[i] = 0;", |
| 6087 | " }", |
| 6088 | " Info[MA-1] = pbit;", |
| 6089 | " if (a_cycles) /* place _a_t at the end */", |
| 6090 | " { Info[MA] = Info[0];", |
| 6091 | " Info[0] = 0;", |
| 6092 | " }", |
| 6093 | "", |
| 6094 | "#if NCORE>1 && !defined(SEP_STATE)", |
| 6095 | " enter_critical(GLOBAL_LOCK); /* crude, but necessary */", |
| 6096 | " /* to make this mode work, also replace emalloc with grab_shared inside store MA routines */", |
| 6097 | "#endif", |
| 6098 | "", |
| 6099 | " if (!dfa_store(Info))", |
| 6100 | " { if (pbit == 0", |
| 6101 | " && (now._a_t&1)", |
| 6102 | " && depth > A_depth)", |
| 6103 | " { Info[MA] &= ~(1|16|32); /* _a_t */", |
| 6104 | " if (dfa_member(MA))", /* was !dfa_member(MA) */ |
| 6105 | " { Info[MA-1] = 4; /* off-stack bit */", |
| 6106 | " nShadow++;", |
| 6107 | " if (!dfa_member(MA-1))", |
| 6108 | " { ret_val = 3;", |
| 6109 | " #ifdef VERBOSE", |
| 6110 | " printf(\"intersected 1st dfs stack\\n\");", |
| 6111 | " #endif", |
| 6112 | " goto done;", |
| 6113 | " } } }", |
| 6114 | " ret_val = 0;", |
| 6115 | " #ifdef VERBOSE", |
| 6116 | " printf(\"new state\\n\");", |
| 6117 | " #endif", |
| 6118 | " goto done;", |
| 6119 | " }", |
| 6120 | "#ifdef FULLSTACK", |
| 6121 | " if (pbit == 0)", |
| 6122 | " { Info[MA-1] = 1; /* proviso bit */", |
| 6123 | "#ifndef BFS", |
| 6124 | " trpt->proviso = dfa_member(MA-1);", |
| 6125 | "#endif", |
| 6126 | " Info[MA-1] = 4; /* off-stack bit */", |
| 6127 | " if (dfa_member(MA-1))", |
| 6128 | " { ret_val = 1; /* off-stack */", |
| 6129 | " #ifdef VERBOSE", |
| 6130 | " printf(\"old state\\n\");", |
| 6131 | " #endif", |
| 6132 | " } else", |
| 6133 | " { ret_val = 2; /* on-stack */", |
| 6134 | " #ifdef VERBOSE", |
| 6135 | " printf(\"on-stack\\n\");", |
| 6136 | " #endif", |
| 6137 | " }", |
| 6138 | " goto done;", |
| 6139 | " }", |
| 6140 | "#endif", |
| 6141 | " ret_val = 1;", |
| 6142 | "#ifdef VERBOSE", |
| 6143 | " printf(\"old state\\n\");", |
| 6144 | "#endif", |
| 6145 | "done:", |
| 6146 | "#if NCORE>1 && !defined(SEP_STATE)", |
| 6147 | " leave_critical(GLOBAL_LOCK);", |
| 6148 | "#endif", |
| 6149 | " return ret_val; /* old state */", |
| 6150 | "}", |
| 6151 | "#endif", |
| 6152 | |
| 6153 | "#if defined(BITSTATE) && defined(LC)", |
| 6154 | "int", |
| 6155 | "compact_stack(char *vin, int n)", /* special case of HC4 */ |
| 6156 | "{ int delta = 0;", |
| 6157 | " s_hash((uchar *)vin, n); /* sets K1 and K2 */", |
| 6158 | "#ifndef SAFETY", |
| 6159 | " delta++; /* room for state[0] |= 128 */", |
| 6160 | "#endif", |
| 6161 | " memcpy((char *) &comp_now + delta, (char *) &K1, WS);", |
| 6162 | " delta += WS;", |
| 6163 | " memcpy((char *) &comp_now + delta, (char *) &K2, WS);", |
| 6164 | " delta += WS; /* use all available bits */", |
| 6165 | " return delta;", |
| 6166 | "}", |
| 6167 | "#endif", |
| 6168 | |
| 6169 | "int", |
| 6170 | "hstore(char *vin, int nin) /* hash table storage */", |
| 6171 | "{ struct H_el *ntmp;", |
| 6172 | " struct H_el *tmp, *olst = (struct H_el *) 0;", |
| 6173 | " char *v; int n, m=0;", |
| 6174 | "#ifdef HC", |
| 6175 | " uchar rem_a;", |
| 6176 | "#endif", |
| 6177 | "#ifdef NOCOMP", /* defined by BITSTATE */ |
| 6178 | "#if defined(BITSTATE) && defined(LC)", |
| 6179 | " if (S_Tab == H_tab)", |
| 6180 | " { v = (char *) &comp_now;", |
| 6181 | " n = compact_stack(vin, nin);", |
| 6182 | " } else", |
| 6183 | " { v = vin; n = nin;", |
| 6184 | " }", |
| 6185 | "#else", |
| 6186 | " v = vin; n = nin;", |
| 6187 | "#endif", |
| 6188 | "#else", |
| 6189 | " v = (char *) &comp_now;", |
| 6190 | " #ifdef HC", |
| 6191 | " rem_a = now._a_t;", /* new 5.0 */ |
| 6192 | " now._a_t = 0;", /* for hashing/state matching to work right */ |
| 6193 | " #endif", |
| 6194 | " n = compress(vin, nin);", /* with HC, this calls s_hash -- but on vin, not on v... */ |
| 6195 | " #ifdef HC", |
| 6196 | " now._a_t = rem_a;", /* new 5.0 */ |
| 6197 | " #endif", |
| 6198 | /* with HC4 -a, compress copies K1 and K2 into v[], leaving v[0] free for the a-bit */ |
| 6199 | "#ifndef SAFETY", |
| 6200 | " if (S_A)", |
| 6201 | " { v[0] = 0; /* _a_t */", |
| 6202 | "#ifndef NOFAIR", |
| 6203 | " if (S_A > NFAIR)", |
| 6204 | " for (m = 0; m < NFAIR; m++)", |
| 6205 | " v[m+1] = 0; /* _cnt[] */", |
| 6206 | "#endif", |
| 6207 | " m = 0;", |
| 6208 | " }", |
| 6209 | " #endif", |
| 6210 | "#endif", |
| 6211 | "#if !defined(HC) && !(defined(BITSTATE) && defined(LC))", |
| 6212 | " s_hash((uchar *)v, n);", |
| 6213 | "#endif", |
| 6214 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6215 | " enter_critical(CS_ID); /* uses spinlock */", |
| 6216 | "#endif", |
| 6217 | |
| 6218 | " tmp = H_tab[j1];", |
| 6219 | " if (!tmp)", |
| 6220 | " { tmp = grab_state(n);", |
| 6221 | "#if NCORE>1", |
| 6222 | " if (!tmp)", |
| 6223 | " { /* if we get here -- we've already issued a warning */", |
| 6224 | " /* but we want to allow the normal distributed termination */", |
| 6225 | " /* to collect the stats on all cpus in the wrapup */", |
| 6226 | " #if !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6227 | " leave_critical(CS_ID);", |
| 6228 | " #endif", |
| 6229 | " return 1; /* allow normal termination */", |
| 6230 | " }", |
| 6231 | "#endif", |
| 6232 | " H_tab[j1] = tmp;", |
| 6233 | " } else", |
| 6234 | " { for (;; hcmp++, olst = tmp, tmp = tmp->nxt)", |
| 6235 | " { /* skip the _a_t and the _cnt bytes */", |
| 6236 | "#ifdef COLLAPSE", |
| 6237 | " if (tmp->ln != 0)", |
| 6238 | " { if (!tmp->nxt) goto Append;", |
| 6239 | " continue;", |
| 6240 | " }", |
| 6241 | "#endif", |
| 6242 | " m = memcmp(((char *)&(tmp->state)) + S_A, ", |
| 6243 | " v + S_A, n - S_A);", |
| 6244 | " if (m == 0) {", |
| 6245 | "#ifdef SAFETY", |
| 6246 | "#define wasnew 0", |
| 6247 | "#else", |
| 6248 | " int wasnew = 0;", |
| 6249 | "#endif", |
| 6250 | |
| 6251 | "#ifndef SAFETY", |
| 6252 | "#ifndef NOCOMP", |
| 6253 | " if (S_A)", |
| 6254 | " { if ((((char *)&(tmp->state))[0] & V_A) != V_A)", |
| 6255 | " { wasnew = 1; nShadow++;", |
| 6256 | " ((char *)&(tmp->state))[0] |= V_A;", |
| 6257 | " }", |
| 6258 | "#ifndef NOFAIR", |
| 6259 | " if (S_A > NFAIR)", |
| 6260 | " { /* 0 <= now._cnt[now._a_t&1] < MAXPROC */", |
| 6261 | " unsigned ci, bp; /* index, bit pos */", |
| 6262 | " ci = (now._cnt[now._a_t&1] / 8);", |
| 6263 | " bp = (now._cnt[now._a_t&1] - 8*ci);", |
| 6264 | " if (now._a_t&1) /* use tail-bits in _cnt */", |
| 6265 | " { ci = (NFAIR - 1) - ci;", |
| 6266 | " bp = 7 - bp; /* bp = 0..7 */", |
| 6267 | " }", |
| 6268 | " ci++; /* skip over _a_t */", |
| 6269 | " bp = 1 << bp; /* the bit mask */", |
| 6270 | " if ((((char *)&(tmp->state))[ci] & bp)==0)", |
| 6271 | " { if (!wasnew)", |
| 6272 | " { wasnew = 1;", |
| 6273 | " nShadow++;", |
| 6274 | " }", |
| 6275 | " ((char *)&(tmp->state))[ci] |= bp;", |
| 6276 | " }", |
| 6277 | " }", |
| 6278 | " /* else: wasnew == 0, i.e., old state */", |
| 6279 | "#endif", |
| 6280 | " }", |
| 6281 | "#endif", |
| 6282 | "#endif", |
| 6283 | |
| 6284 | "#if NCORE>1", |
| 6285 | " Lstate = (struct H_el *) tmp;", |
| 6286 | "#endif", |
| 6287 | |
| 6288 | "#ifdef FULLSTACK", |
| 6289 | "#ifndef SAFETY", /* or else wasnew == 0 */ |
| 6290 | " if (wasnew)", |
| 6291 | " { Lstate = (struct H_el *) tmp;", |
| 6292 | " tmp->tagged |= V_A;", |
| 6293 | " if ((now._a_t&1)", |
| 6294 | " && (tmp->tagged&A_V)", |
| 6295 | " && depth > A_depth)", |
| 6296 | " {", |
| 6297 | "intersect:", |
| 6298 | "#ifdef CHECK", |
| 6299 | "#if NCORE>1", |
| 6300 | " printf(\"cpu%%d: \", core_id);", |
| 6301 | "#endif", |
| 6302 | " printf(\"1st dfs-stack intersected on state %%d+\\n\",", |
| 6303 | " (int) tmp->st_id);", |
| 6304 | "#endif", |
| 6305 | |
| 6306 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6307 | " leave_critical(CS_ID);", |
| 6308 | "#endif", |
| 6309 | |
| 6310 | " return 3;", |
| 6311 | " }", |
| 6312 | "#ifdef CHECK", |
| 6313 | "#if NCORE>1", |
| 6314 | " printf(\"cpu%%d: \", core_id);", |
| 6315 | "#endif", |
| 6316 | " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);", |
| 6317 | "#endif", |
| 6318 | "#ifdef DEBUG", |
| 6319 | " dumpstate(1, (char *)&(tmp->state),n,tmp->tagged);", |
| 6320 | "#endif", |
| 6321 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6322 | " leave_critical(CS_ID);", |
| 6323 | "#endif", |
| 6324 | " return 0;", |
| 6325 | " } else", |
| 6326 | "#endif", |
| 6327 | " if ((S_A)?(tmp->tagged&V_A):tmp->tagged)", |
| 6328 | " { Lstate = (struct H_el *) tmp;", |
| 6329 | "#ifndef SAFETY", |
| 6330 | " /* already on current dfs stack */", |
| 6331 | " /* but may also be on 1st dfs stack */", |
| 6332 | " if ((now._a_t&1)", |
| 6333 | " && (tmp->tagged&A_V)", |
| 6334 | |
| 6335 | " && depth > A_depth", |
| 6336 | /* new (Zhang's example) */ |
| 6337 | "#ifndef NOFAIR", |
| 6338 | " && (!fairness || now._cnt[1] <= 1)", |
| 6339 | "#endif", |
| 6340 | " )", |
| 6341 | |
| 6342 | " goto intersect;", |
| 6343 | "#endif", |
| 6344 | "#ifdef CHECK", |
| 6345 | "#if NCORE>1", |
| 6346 | " printf(\"cpu%%d: \", core_id);", |
| 6347 | "#endif", |
| 6348 | " printf(\"\tStack state %%d\\n\", (int) tmp->st_id);", |
| 6349 | "#endif", |
| 6350 | "#ifdef DEBUG", |
| 6351 | " dumpstate(0, (char *)&(tmp->state),n,tmp->tagged);", |
| 6352 | "#endif", |
| 6353 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6354 | " leave_critical(CS_ID);", |
| 6355 | "#endif", |
| 6356 | " return 2; /* match on stack */", |
| 6357 | " }", |
| 6358 | "#else", |
| 6359 | " if (wasnew)", |
| 6360 | " {", |
| 6361 | "#ifdef CHECK", |
| 6362 | "#if NCORE>1", |
| 6363 | " printf(\"cpu%%d: \", core_id);", |
| 6364 | "#endif", |
| 6365 | " printf(\"\tNew state %%d+\\n\", (int) tmp->st_id);", |
| 6366 | "#endif", |
| 6367 | "#ifdef DEBUG", |
| 6368 | " dumpstate(1, (char *)&(tmp->state), n, 0);", |
| 6369 | "#endif", |
| 6370 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6371 | " leave_critical(CS_ID);", |
| 6372 | "#endif", |
| 6373 | " return 0;", |
| 6374 | " }", |
| 6375 | "#endif", |
| 6376 | "#ifdef CHECK", |
| 6377 | "#if NCORE>1", |
| 6378 | " printf(\"cpu%%d: \", core_id);", |
| 6379 | "#endif", |
| 6380 | " printf(\"\tOld state %%d\\n\", (int) tmp->st_id);", |
| 6381 | "#endif", |
| 6382 | "#ifdef DEBUG", |
| 6383 | " dumpstate(0, (char *)&(tmp->state), n, 0);", |
| 6384 | "#endif", |
| 6385 | "#ifdef REACH", |
| 6386 | " if (tmp->D > depth)", |
| 6387 | " { tmp->D = depth;", |
| 6388 | "#ifdef CHECK", |
| 6389 | "#if NCORE>1", |
| 6390 | " printf(\"cpu%%d: \", core_id);", |
| 6391 | "#endif", |
| 6392 | " printf(\"\t\tReVisiting (from smaller depth)\\n\");", |
| 6393 | "#endif", |
| 6394 | " nstates--;", |
| 6395 | #if 0 |
| 6396 | possible variation of iterative search for shortest counter-example (pan -i |
| 6397 | and pan -I) suggested by Pierre Moro (for safety properties): |
| 6398 | state revisits on shorter depths do not start until after |
| 6399 | the first counter-example is found. this assumes that the max search |
| 6400 | depth is set large enough that a first (possibly long) counter-example |
| 6401 | can be found |
| 6402 | if set too short, this variant can miss the counter-example, even if |
| 6403 | it would otherwise be shorter than the depth-limit. |
| 6404 | (p.m. unsure if this preserves the guarantee of finding the |
| 6405 | shortest counter-example - so not enabled yet) |
| 6406 | " if (errors > 0 && iterative)", /* Moro */ |
| 6407 | #endif |
| 6408 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6409 | " leave_critical(CS_ID);", |
| 6410 | "#endif", |
| 6411 | " return 0;", |
| 6412 | " }", |
| 6413 | "#endif", |
| 6414 | "#if (defined(BFS) && defined(Q_PROVISO)) || NCORE>1", |
| 6415 | " Lstate = (struct H_el *) tmp;", |
| 6416 | "#endif", |
| 6417 | "#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6418 | " leave_critical(CS_ID);", |
| 6419 | "#endif", |
| 6420 | " return 1; /* match outside stack */", |
| 6421 | " } else if (m < 0)", |
| 6422 | " { /* insert state before tmp */", |
| 6423 | " ntmp = grab_state(n);", |
| 6424 | "#if NCORE>1", |
| 6425 | " if (!ntmp)", |
| 6426 | " {", |
| 6427 | " #if !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6428 | " leave_critical(CS_ID);", |
| 6429 | " #endif", |
| 6430 | " return 1; /* allow normal termination */", |
| 6431 | " }", |
| 6432 | "#endif", |
| 6433 | " ntmp->nxt = tmp;", |
| 6434 | " if (!olst)", |
| 6435 | " H_tab[j1] = ntmp;", |
| 6436 | " else", |
| 6437 | " olst->nxt = ntmp;", |
| 6438 | " tmp = ntmp;", |
| 6439 | " break;", |
| 6440 | " } else if (!tmp->nxt)", |
| 6441 | " { /* append after tmp */", |
| 6442 | "#ifdef COLLAPSE", |
| 6443 | "Append:", |
| 6444 | "#endif", |
| 6445 | " tmp->nxt = grab_state(n);", |
| 6446 | "#if NCORE>1", |
| 6447 | " if (!tmp->nxt)", |
| 6448 | " {", |
| 6449 | " #if !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6450 | " leave_critical(CS_ID);", |
| 6451 | " #endif", |
| 6452 | " return 1; /* allow normal termination */", |
| 6453 | " }", |
| 6454 | "#endif", |
| 6455 | " tmp = tmp->nxt;", |
| 6456 | " break;", |
| 6457 | " } }", |
| 6458 | " }", |
| 6459 | "#ifdef CHECK", |
| 6460 | " tmp->st_id = (unsigned) nstates;", |
| 6461 | "#if NCORE>1", |
| 6462 | " printf(\"cpu%%d: \", core_id);", |
| 6463 | "#endif", |
| 6464 | "#ifdef BITSTATE", |
| 6465 | " printf(\" Push state %%d\\n\", ((int) nstates) - 1);", |
| 6466 | "#else", |
| 6467 | " printf(\" New state %%d\\n\", (int) nstates);", |
| 6468 | "#endif", |
| 6469 | "#endif", |
| 6470 | "#if !defined(SAFETY) || defined(REACH)", |
| 6471 | " tmp->D = depth;", |
| 6472 | "#endif", |
| 6473 | "#ifndef SAFETY", |
| 6474 | "#ifndef NOCOMP", |
| 6475 | " if (S_A)", |
| 6476 | " { v[0] = V_A;", |
| 6477 | "#ifndef NOFAIR", |
| 6478 | " if (S_A > NFAIR)", |
| 6479 | " { unsigned ci, bp; /* as above */", |
| 6480 | " ci = (now._cnt[now._a_t&1] / 8);", |
| 6481 | " bp = (now._cnt[now._a_t&1] - 8*ci);", |
| 6482 | " if (now._a_t&1)", |
| 6483 | " { ci = (NFAIR - 1) - ci;", |
| 6484 | " bp = 7 - bp; /* bp = 0..7 */", |
| 6485 | " }", |
| 6486 | " v[1+ci] = 1 << bp;", |
| 6487 | " }", |
| 6488 | "#endif", |
| 6489 | " }", |
| 6490 | "#endif", |
| 6491 | "#endif", |
| 6492 | "#if defined(AUTO_RESIZE) && !defined(BITSTATE)", |
| 6493 | " tmp->m_K1 = K1;", |
| 6494 | "#endif", |
| 6495 | " memcpy(((char *)&(tmp->state)), v, n);", |
| 6496 | "#ifdef FULLSTACK", |
| 6497 | " tmp->tagged = (S_A)?V_A:(depth+1);", |
| 6498 | "#ifdef DEBUG", |
| 6499 | " dumpstate(-1, v, n, tmp->tagged);", |
| 6500 | "#endif", |
| 6501 | " Lstate = (struct H_el *) tmp;", |
| 6502 | "#else", |
| 6503 | " #ifdef DEBUG", |
| 6504 | " dumpstate(-1, v, n, 0);", |
| 6505 | " #endif", |
| 6506 | " #if NCORE>1", |
| 6507 | " Lstate = (struct H_el *) tmp;", |
| 6508 | " #endif", |
| 6509 | "#endif", |
| 6510 | |
| 6511 | "/* #if NCORE>1 && !defined(SEP_STATE) */", |
| 6512 | "#if NCORE>1", |
| 6513 | " #ifdef V_PROVISO", |
| 6514 | " tmp->cpu_id = core_id;", |
| 6515 | " #endif", |
| 6516 | " #if !defined(SEP_STATE) && !defined(BITSTATE)", |
| 6517 | " leave_critical(CS_ID);", |
| 6518 | " #endif", |
| 6519 | "#endif", |
| 6520 | |
| 6521 | " return 0;", |
| 6522 | "}", |
| 6523 | "#endif", |
| 6524 | "#include TRANSITIONS", |
| 6525 | "void", |
| 6526 | "do_reach(void)", |
| 6527 | "{", |
| 6528 | 0, |
| 6529 | }; |