|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include "trace.h" ! 3: #include "trace.d" ! 4: ! 5: #define DEBUG 0 ! 6: ! 7: #define BS(n) ((n) & ~(PASSED)) ! 8: ! 9: extern struct TBL *tbl; ! 10: extern struct LBT *lbt; ! 11: extern struct MBOX *mbox; ! 12: extern struct MNAME *fullname; ! 13: extern struct PROCSTACK **procstack; ! 14: ! 15: extern struct VARPARS *procpars; ! 16: extern struct TBLPARS *tblpars; ! 17: ! 18: extern struct LOCVARS *tblvars; ! 19: extern struct TBLPARS *tablpars; ! 20: ! 21: extern struct QUEUE **starter, **head, **tail; ! 22: extern struct QUEUE *s_first, *s_last; ! 23: extern struct VISIT *lastvisit; ! 24: ! 25: extern int *reftasks, *processes, *basics; ! 26: extern int *globvars, *inits, *state, *qsize; ! 27: ! 28: extern int nrtbl, nrqs, nrrefs, nrprocs, nrinit; ! 29: extern int nrvars, nrmesgs, msgbase; ! 30: extern int maxlevel, maxreached; ! 31: ! 32: extern char noshortcut, prbyq, timedd, blast, qandirty, muststore; ! 33: extern char maxxed, completed, lockplus, firstlock; ! 34: ! 35: extern long locksf, normf, loopsf; ! 36: extern double zapper; ! 37: ! 38: short lastqueue; /* the last queue addressed */ ! 39: int level = 0; ! 40: double COUNT = 0; ! 41: ! 42: char *emalloc(), *Realloc(), *Emalloc(); ! 43: ! 44: determine(m) ! 45: { ! 46: if (m >= 3*MANY) return 0; /* constant */ ! 47: else if (m >= 2*MANY) return 1; /* parameter */ ! 48: else if (m >= MANY) return 2; /* local */ ! 49: else if (m >= 0) return 3; /* global */ ! 50: else if (m < -3*MANY) return 5; /* negative number */ ! 51: else if (m <= -2) return 4; /* expression */ ! 52: else ! 53: whoops("cannot happen - determine"); ! 54: } ! 55: ! 56: convert(m, pr) ! 57: { int res, n = m; ! 58: ! 59: /* convert a pvar: global, local, parameter, or a constant */ ! 60: ! 61: switch (determine(n)) { ! 62: case 5: res = n + 3*MANY; break; ! 63: case 4: res = evalcond(-(m+2), pr); break; ! 64: case 0: res = n - 3*MANY; break; ! 65: case 1: res = wapper(m, pr); break; ! 66: case 2: n -= MANY; ! 67: if (n >= 0 && n < (int) procpars[pr].nrlvars) ! 68: res = (int) procpars[pr].lvarvals[n]; ! 69: else ! 70: whoops("reference to non-existing local var"); ! 71: break; ! 72: case 3: if (n >= 0 && n < nrvars) ! 73: res = globvars[n]; ! 74: else ! 75: whoops("reference to non-existing global var"); ! 76: break; ! 77: default: ! 78: whoops("cannot happen - convert"); /* got a parameter */ ! 79: break; ! 80: } ! 81: return res; ! 82: } ! 83: ! 84: wapper(n, pr) ! 85: { int x = n - 2*MANY; ! 86: int y; ! 87: if (x < 0 || x >= MANY) ! 88: return n; /* not a parameter */ ! 89: else ! 90: { if (x >= procpars[pr].nrvs) ! 91: whoops("unknown parameter of type pvar"); ! 92: y = (int) procpars[pr].vs[x]; ! 93: if (y >= 2*MANY && y < 3*MANY) ! 94: whoops("unresolved parameter reference"); ! 95: return y; ! 96: } ! 97: } ! 98: ! 99: mapper(n, pr) /* convert a message parameter */ ! 100: { register int x = n - MANY; ! 101: ! 102: if (x < 0 || x >= MANY) ! 103: return n; /* not a parameter */ ! 104: else ! 105: { if (x >= procpars[pr].nrms) ! 106: whoops("bad news: illegal message parameter"); ! 107: return ((int)procpars[pr].ms[x]); ! 108: } ! 109: } ! 110: ! 111: matchon(n, m, t, trial, TT, pr) ! 112: { ! 113: #if DEBUG ! 114: printf("trial %d, pr %d; ", trial, pr); ! 115: if (TT == INP || TT == OUTP) ! 116: printf("msg %s, ", fullname[n-msgbase].mname); ! 117: else ! 118: printf("code %d, ", n); ! 119: printf("q %d, tbl %d, type %d\n", m, t, TT); ! 120: #endif ! 121: ! 122: if (trial == 2) ! 123: return (TT == TMO && qsize[m] == 0); ! 124: else ! 125: { ! 126: switch (TT) { ! 127: case FCT : ! 128: case SPN : return 1; ! 129: case CND : return (evalcond(n, pr)); ! 130: case DFL : return (qsize[m] > 0 && no_other(t,head[m]->mesg,pr)); ! 131: case INP : return (qsize[m] > 0 && BS(head[m]->mesg) == n); ! 132: case TMO : return (noshortcut && qsize[m] == 0); ! 133: case OUTP: return (qsize[m] < mbox[m].limit); ! 134: default : whoops("unknown type in column head"); ! 135: } ! 136: } ! 137: } ! 138: ! 139: no_other(x, yy, pr) ! 140: { struct TBL *tmp = &(tbl[x]); ! 141: int y = BS(yy); ! 142: int j = tmp->nrcols; ! 143: int h = state[pr]; ! 144: int i; ! 145: ! 146: for (i = 0; i < j; i++) ! 147: { if (tmp->coltyp[i] == INP ! 148: && tmp->ptr[h][i].nrpils > 0 ! 149: && y == lbt[pr].mapcol[i]) ! 150: return 0; ! 151: } ! 152: return 1; ! 153: } ! 154: ! 155: send(m, to, with, pr, nst) ! 156: { struct QUEUE *tmp; ! 157: register struct QUEUE *hook = tail[to]; ! 158: int what = NONE; ! 159: ! 160: if (with != NONE) ! 161: { if ((what = convert(with, pr)) >= USED - 1 || what < 0) ! 162: { output("aborted: ", 0); ! 163: whoops("cargo too large or negative"); ! 164: } ! 165: hook->cargo = (unsigned short) ( what | USED ); ! 166: } else ! 167: hook->cargo = (unsigned short) 0; ! 168: ! 169: if (qsize[to] >= mbox[to].limit) ! 170: whoops("cannot happen - send"); ! 171: ! 172: tmp = (struct QUEUE *) emalloc(sizeof(struct QUEUE)); ! 173: tmp->last = hook; ! 174: #if TRAIL ! 175: hook->tstate[0] = (short) processes[pr]; ! 176: hook->tstate[1] = (short) nst; ! 177: #endif TRAIL ! 178: ! 179: hook->mesg = (short) m; ! 180: hook->next = tmp; ! 181: hook->s_back = s_last; ! 182: hook->s_forw = NULL; ! 183: if (s_last == NULL) ! 184: s_first = hook; ! 185: else ! 186: s_last->s_forw = hook; ! 187: ! 188: s_last = hook; ! 189: tail[to] = tmp; ! 190: qsize[to]++; ! 191: #if DEBUG ! 192: printf("\tsent %d to %d, size %d, ", m, to, qsize[to]); ! 193: printf("cargo %d [%d]\n", what, hook->cargo); ! 194: #endif ! 195: require(OUTP, m, to); ! 196: ! 197: return 1; ! 198: } ! 199: ! 200: receive(from, with, pr, ice) ! 201: struct FREEZE *ice; ! 202: { struct QUEUE *hook; ! 203: int what=NONE, wither; ! 204: ! 205: if (qsize[from] <= 0) ! 206: whoops("trying to receive from empty queue"); ! 207: ! 208: hook = head[from]; ! 209: if (hook->cargo & USED) ! 210: { what = (int) ((hook->cargo) & (~USED)); ! 211: if (with == NONE) ! 212: { fprintf(stderr, "value %d sent (msg: ", what); ! 213: putname(hook, 1); ! 214: fprintf(stderr, ") but not expected\n"); ! 215: } ! 216: else ! 217: { ice->whichvar = wither = wapper(with, pr); ! 218: if (wither >= 3*MANY || wither <= -3*MANY) ! 219: whoops("receiving into a constant..."); ! 220: if (wither < MANY) ! 221: { ice->oldvalue = globvars[wither]; ! 222: globvars[wither] = what; ! 223: } else ! 224: { int n = wither - MANY; ! 225: if (n >= 0 && n < (int) procpars[pr].nrlvars) ! 226: { ice->oldvalue = procpars[pr].lvarvals[n]; ! 227: procpars[pr].lvarvals[n] = (short) what; ! 228: } else ! 229: whoops("unknown local var"); ! 230: } ! 231: } ! 232: } else ! 233: { if (with != NONE) ! 234: { fprintf(stderr, "value %d expected (msg: ", with); ! 235: putname(hook, 1); ! 236: fprintf(stderr, ") but not sent\n"); ! 237: } ! 238: } ! 239: ! 240: hook->mesg |= PASSED; ! 241: #if DEBUG ! 242: printf("\trecv %d from queue %d, ", head[from]->mesg & (~PASSED), from); ! 243: printf("cargo %d [%d], into var %d\n", what, hook->cargo, with); ! 244: #endif ! 245: ! 246: head[from] = hook->next; ! 247: qsize[from]--; ! 248: ! 249: require(INP, (hook->mesg & (~PASSED)), from); ! 250: ! 251: return 1; ! 252: } ! 253: ! 254: unrecv(from) ! 255: { ! 256: if (head[from] == starter[from]) ! 257: whoops("unreceiving beyond initial state"); ! 258: ! 259: head[from] = head[from]->last; ! 260: head[from]->mesg &= (~PASSED); ! 261: ! 262: qsize[from]++; ! 263: } ! 264: ! 265: unsend() ! 266: { short i = lastqueue; ! 267: ! 268: if (tail[i] == starter[i]) ! 269: whoops("unsending beyond initial state"); ! 270: if ((tail[i] = tail[i]->last) != s_last) ! 271: whoops("unsend: tail not last sent message"); ! 272: ! 273: if ((s_last = s_last->s_back) != NULL) ! 274: s_last->s_forw = NULL; ! 275: else ! 276: s_first = NULL; ! 277: efree(tail[i]->next); ! 278: ! 279: qsize[i]--; ! 280: } ! 281: ! 282: output(tag, willabort) ! 283: char *tag; ! 284: { struct QUEUE *tmp; ! 285: ! 286: printf("%s", tag); ! 287: ! 288: if ((tmp = s_first) != NULL) ! 289: { formatted((struct QUEUE *) 0); ! 290: if (prbyq != 2) ! 291: do putname(tmp, 0); while ((tmp = tmp->s_forw) != NULL); ! 292: putchar('\n'); ! 293: } else ! 294: printf("null output\n"); ! 295: ! 296: if (willabort == 2 || (firstlock && willabort == 1)) ! 297: { completed = 1; ! 298: postlude(); ! 299: } ! 300: } ! 301: ! 302: putname(tmp, how) ! 303: struct QUEUE *tmp; ! 304: { int i, k = (int) (BS(tmp->mesg)) - msgbase; ! 305: char nnn[128]; ! 306: ! 307: i = strlen(fullname[k].mname); ! 308: if (tmp->mesg & PASSED) ! 309: sprintf(nnn, "%s", fullname[k].mname); ! 310: else ! 311: { sprintf(nnn, "[%s]", fullname[k].mname); ! 312: i += 2; ! 313: } ! 314: ! 315: if (tmp->cargo & USED) ! 316: sprintf(&nnn[i], "(%d),", (tmp->cargo & (~USED))); ! 317: else ! 318: sprintf(&nnn[i], ","); ! 319: ! 320: if (how) ! 321: fprintf(stderr, "%s", nnn); ! 322: else ! 323: printf("%s", nnn); ! 324: ! 325: return strlen(nnn); ! 326: } ! 327: ! 328: inendstate() ! 329: { int i, j, k; ! 330: ! 331: for (i = 0, k = nrprocs; i < nrprocs; i++) ! 332: { j = processes[i]; ! 333: if (j != basics[i] || tbl[j].endrow[state[i]] != 1) ! 334: k--; ! 335: } ! 336: return k; ! 337: } ! 338: ! 339: formatted(at) ! 340: struct QUEUE *at; ! 341: { struct QUEUE *tmp = s_first; ! 342: int i, j; extern int linecode; ! 343: ! 344: if (tmp == NULL) ! 345: return; ! 346: ! 347: switch((int) prbyq) { ! 348: case 0: break; ! 349: case 1: ! 350: for (i = 0; i < nrqs; i++) ! 351: { printf("\n\t%s = {", mbox[i].qname); ! 352: for (tmp = starter[i]; tmp != tail[i]; tmp = tmp->next) ! 353: putname(tmp, 0); ! 354: printf("}"); ! 355: } ! 356: printf("\nexecution sequence:\n\t"); ! 357: break; ! 358: case 2: putchar('\n'); ! 359: for (i = 0; i < nrqs; i++) ! 360: printf("%2d = %s\n", i, mbox[i].qname); ! 361: for (i = 0; i < nrqs; i++) ! 362: printf("\t%2d", i); ! 363: #if TRAIL ! 364: if (linecode) ! 365: printf(" \tsource"); ! 366: #endif TRAIL ! 367: putchar('\n'); ! 368: do ! 369: { if (tmp == at) ! 370: printf(" >>"); ! 371: for (i = j = whichq(BS(tmp->mesg)); i >= 0; i--) ! 372: putchar('\t'); ! 373: i = putname(tmp, 0); ! 374: #if TRAIL ! 375: if (linecode) ! 376: { for (i = 16-i; i > 0; i--) putchar(' '); ! 377: for (j = nrqs-j; j > 0; j--) putchar('\t'); ! 378: printf("%s", tbl[tmp->tstate[0]].rowname[tmp->tstate[1]]); ! 379: } ! 380: #endif TRAIL ! 381: putchar('\n'); ! 382: } while ((tmp = tmp->s_forw) != NULL); ! 383: if (at != NULL) ! 384: printf(" >>\n"); ! 385: break; ! 386: } ! 387: } ! 388: ! 389: putloop(at, aa) ! 390: struct QUEUE *at; ! 391: char aa; ! 392: { register struct QUEUE *tmp = s_first; ! 393: ! 394: if (aa) ! 395: printf("loop:\t"); ! 396: else ! 397: printf("assertion violated: "); ! 398: ! 399: if (s_first != NULL) ! 400: { formatted(at); ! 401: if (prbyq != 2) ! 402: { do ! 403: { putname(tmp, 0); ! 404: if (tmp == at) ! 405: printf("//"); ! 406: } while ((tmp = tmp->s_forw) != NULL); ! 407: printf("//\n"); ! 408: } ! 409: } else ! 410: printf("null output\n"); ! 411: } ! 412: ! 413: ppop(pr) ! 414: { struct PROCSTACK *tmp = procstack[pr]; ! 415: int i = (int) procstack[pr]->uptable; ! 416: ! 417: if (procstack[pr] == NULL) ! 418: whoops("null stack"); ! 419: ! 420: restorvarpars(tmp->varparsaved, pr); ! 421: procstack[pr] = procstack[pr]->follow; ! 422: ! 423: efree(tmp->varparsaved); ! 424: efree(tmp); ! 425: ! 426: return i; /* we're returing to this table */ ! 427: } ! 428: ! 429: ppush(pr, what, tr) ! 430: { struct PROCSTACK *tmp; ! 431: ! 432: tmp = (struct PROCSTACK *) ! 433: emalloc(sizeof(struct PROCSTACK)); ! 434: ! 435: tmp->varparsaved = (struct VARPARS *) ! 436: emalloc(sizeof(struct VARPARS)); ! 437: ! 438: savevarpars (tmp->varparsaved, pr); ! 439: ! 440: tmp->uptable = (short) what; ! 441: tmp->uptransf = (short) tr; ! 442: tmp->follow = procstack[pr]; ! 443: procstack[pr] = tmp; ! 444: } ! 445: ! 446: setlvars(to, pr) ! 447: { register int i; ! 448: short z = tblvars[to].nrlvars; ! 449: ! 450: if (z > tablpars[pr].nrlvars) ! 451: { if (tablpars[pr].nrlvars > 0) ! 452: procpars[pr].lvarvals = (short *) ! 453: Realloc(procpars[pr].lvarvals, z * sizeof(short)); ! 454: else ! 455: procpars[pr].lvarvals = (short *) ! 456: Emalloc(z * sizeof(short)); ! 457: ! 458: tablpars[pr].nrlvars = z; ! 459: } ! 460: ! 461: procpars[pr].nrlvars = z; ! 462: ! 463: for (i = 0; i < z; i++) ! 464: procpars[pr].lvarvals[i] = convert(tblvars[to].lvarvals[i], pr); ! 465: } ! 466: ! 467: setpars(from, to, pr) ! 468: struct CPARS *from; ! 469: { struct VARPARS tbuff; ! 470: register int i; ! 471: short x = tblpars[to].nrms; ! 472: short y = tblpars[to].nrvs; ! 473: ! 474: savemapped(&tbuff, from, pr); /* mapper() needs old nrms & nrvs */ ! 475: ! 476: if (x > tablpars[pr].nrms) ! 477: { if (tablpars[pr].nrms > 0) ! 478: procpars[pr].ms = (short *) ! 479: Realloc(procpars[pr].ms, x * sizeof(short)); ! 480: else ! 481: procpars[pr].ms = (short *) ! 482: Emalloc(x * sizeof(short)); ! 483: ! 484: tablpars[pr].nrms = x; ! 485: } ! 486: if (y > tablpars[pr].nrvs) ! 487: { if (tablpars[pr].nrvs > 0) ! 488: procpars[pr].vs = (short *) ! 489: Realloc(procpars[pr].vs, y * sizeof(short)); ! 490: else ! 491: procpars[pr].vs = (short *) ! 492: Emalloc(y * sizeof(short)); ! 493: ! 494: tablpars[pr].nrvs = y; ! 495: } ! 496: ! 497: procpars[pr].nrms = tbuff.nrms; ! 498: procpars[pr].nrvs = tbuff.nrvs; ! 499: ! 500: for (i = 0; i < procpars[pr].nrms; i++) ! 501: procpars[pr].ms[i] = tbuff.ms[i]; ! 502: ! 503: for (i = 0; i < procpars[pr].nrvs; i++) ! 504: procpars[pr].vs[i] = tbuff.vs[i]; ! 505: ! 506: efree(tbuff.ms); efree(tbuff.vs); ! 507: } ! 508: ! 509: #if DEBUG ! 510: showstate() ! 511: { int i, j; ! 512: printf("%2d: S:", level); ! 513: for (i = 0; i < nrprocs; i++) ! 514: printf("%d,", state[i]); ! 515: printf("M:"); ! 516: for (i = 0; i < nrprocs; i++) ! 517: printf("%d,", processes[i]); ! 518: printf("Q:"); ! 519: for (i = 0; i < nrqs; i++) ! 520: printf("%d,", qsize[i]); ! 521: printf("H:"); ! 522: for (i = 0; i < nrqs; i++) ! 523: if (qsize[i] == 0) ! 524: printf("-,"); ! 525: else ! 526: { j = (int) BS(head[i]->mesg); ! 527: printf("%s,", fullname[j-msgbase].mname); ! 528: } ! 529: printf("\tV:"); ! 530: for (i = 0; i < nrprocs; i++) ! 531: { for (j = 0; j < procpars[i].nrlvars; j++) ! 532: printf("%d ", procpars[i].lvarvals[j]); ! 533: putchar(';'); ! 534: } ! 535: putchar('\n'); ! 536: } ! 537: #endif ! 538: ! 539: retable(prc, ice) ! 540: struct FREEZE *ice; ! 541: { struct CUBE *it, *here; ! 542: int t = processes[prc]; ! 543: ! 544: if (ice->cube == NULL) ! 545: { here = ice->cube = (struct CUBE *) ! 546: emalloc(sizeof(struct CUBE)); ! 547: here->pntr = here->rtnp = NULL; ! 548: } else ! 549: { for (it = ice->cube; it->pntr != NULL; it = it->pntr) ! 550: ; ! 551: it->pntr = (struct CUBE *) ! 552: emalloc(sizeof(struct CUBE)); ! 553: it->pntr->rtnp = it; ! 554: here = it->pntr; ! 555: here->pntr = NULL; ! 556: } ! 557: here->poporpush = POP; ! 558: here->which = (short) prc; ! 559: here->procsaved = (short) t; ! 560: here->transfsaved = procstack[prc]->uptransf; ! 561: here->varparsaved = (struct VARPARS *) ! 562: emalloc(sizeof(struct VARPARS)); ! 563: ! 564: savevarpars(here->varparsaved, prc); ! 565: processes[prc] = ppop(prc); ! 566: fiddler(prc); ! 567: state[prc] = (int) here->transfsaved; ! 568: muststore = tbl[processes[prc]].labrow[state[prc]]; ! 569: } ! 570: ! 571: savevarpars(at, j) ! 572: struct VARPARS *at; ! 573: { register int i; ! 574: struct VARPARS *it; ! 575: ! 576: it = &(procpars[j]); ! 577: at->nrms = it->nrms; ! 578: at->nrvs = it->nrvs; ! 579: at->nrlvars = it->nrlvars; ! 580: ! 581: at->ms = (short *) emalloc(it->nrms * sizeof(short)); ! 582: at->vs = (short *) emalloc(it->nrvs * sizeof(short)); ! 583: at->lvarvals = (short *) emalloc(it->nrlvars * sizeof(short)); ! 584: ! 585: for (i = 0; i < at->nrms; i++) ! 586: at->ms[i] = it->ms[i]; ! 587: for (i = 0; i < at->nrvs; i++) ! 588: at->vs[i] = it->vs[i]; ! 589: for (i = 0; i < it->nrlvars; i++) ! 590: at->lvarvals[i] = it->lvarvals[i]; ! 591: } ! 592: ! 593: savemapped(at, it, j) ! 594: struct VARPARS *at; ! 595: struct CPARS *it; ! 596: { register int i; ! 597: ! 598: at->nrms = it->nrms; ! 599: at->nrvs = it->nrvs; ! 600: ! 601: at->ms = (short *) ! 602: emalloc(it->nrms * sizeof(short)); ! 603: at->vs = (short *) ! 604: emalloc(it->nrvs * sizeof(short)); ! 605: ! 606: for (i = 0; i < at->nrms; i++) ! 607: at->ms[i] = (short) mapper(it->ms[i], j); ! 608: ! 609: for (i = 0; i < at->nrvs; i++) ! 610: at->vs[i] = (short) convert(it->vs[i], j); ! 611: } ! 612: ! 613: restorvarpars(at, pr) ! 614: struct VARPARS *at; ! 615: { register int i; ! 616: ! 617: procpars[pr].nrms = at->nrms; ! 618: procpars[pr].nrvs = at->nrvs; ! 619: procpars[pr].nrlvars = at->nrlvars; ! 620: ! 621: for (i = 0; i < at->nrms; i++) ! 622: procpars[pr].ms[i] = at->ms[i]; ! 623: ! 624: for (i = 0; i < at->nrvs; i++) ! 625: procpars[pr].vs[i] = at->vs[i]; ! 626: ! 627: for (i = 0; i < at->nrlvars; i++) ! 628: procpars[pr].lvarvals[i] = at->lvarvals[i]; ! 629: ! 630: efree(at->ms); ! 631: efree(at->vs); ! 632: efree(at->lvarvals); ! 633: } ! 634: ! 635: freeze(icy) ! 636: struct FREEZE *icy; ! 637: { register int i; ! 638: struct FREEZE *ice = icy; ! 639: ! 640: ice->statsaved = (short *) emalloc(nrprocs * sizeof(short)); ! 641: ice->varsaved = (short *) emalloc(nrvars * sizeof(short)); ! 642: ! 643: ice->lastsav = lastqueue; ! 644: ice->cube = NULL; ! 645: ! 646: for (i = 0; i < nrvars; i++) ! 647: ice->varsaved[i] = (short) globvars[i]; ! 648: ! 649: for (i = 0; i < nrprocs; i++) ! 650: { ! 651: ice->statsaved[i] = (short) state[i]; ! 652: ! 653: while (tbl[processes[i]].deadrow[state[i]] && procstack[i] != NULL) ! 654: retable(i, ice); ! 655: } ! 656: } ! 657: ! 658: unfreeze(ice) ! 659: struct FREEZE *ice; ! 660: { struct CUBE *here; ! 661: register int i; ! 662: ! 663: lastqueue = ice->lastsav; ! 664: ! 665: for (i = 0; i < nrprocs; i++) ! 666: state[i] = (int) ice->statsaved[i]; ! 667: for (i = 0; i < nrvars; i++) ! 668: globvars[i] = (int) ice->varsaved[i]; ! 669: ! 670: if ((here = ice->cube) != NULL) ! 671: while (here->pntr != NULL) ! 672: here = here->pntr; ! 673: ! 674: for (; here != NULL;) ! 675: { i = (int) here->which; ! 676: if (here->poporpush == PUSH) ! 677: { processes[i] = ppop(i); ! 678: } else ! 679: { /* use cube to restore the values from before the ppop */ ! 680: ppush(i, processes[i], (int) here->transfsaved); ! 681: restorvarpars (here->varparsaved, i); ! 682: processes[i] = (int) here->procsaved; ! 683: efree(here->varparsaved); ! 684: } ! 685: efree(here); ! 686: fiddler(i); ! 687: ! 688: if (here == ice->cube) ! 689: break; ! 690: else ! 691: here = here->rtnp; ! 692: } ! 693: efree(ice->statsaved); ! 694: efree(ice->varsaved); ! 695: } ! 696: ! 697: FSE(I) ! 698: { short g, h, i, j, k, t, x, y, z, X, Y, how; ! 699: char progress = 0, internal; ! 700: struct FREEZE *delta = (struct FREEZE *) emalloc(sizeof(struct FREEZE)); ! 701: struct STATE *iam = NULL, *inloop(); ! 702: struct VISIT *ticket; ! 703: ! 704: if (level >= maxreached) ! 705: { if (maxxed && level >= maxlevel) ! 706: { efree(delta); ! 707: return; ! 708: } ! 709: if (level > maxreached) ! 710: maxreached = level; ! 711: } ! 712: freeze(delta); ! 713: ! 714: if (muststore && (iam = inloop()) == NULL) ! 715: { unfreeze(delta); ! 716: efree(delta); ! 717: return; ! 718: } ! 719: ! 720: /* ! 721: * this state has not been seen before; the state ! 722: * information has been saved in the structure ! 723: * `STATE'; queue information has been saved in the ! 724: * last `VISIT' template of this state; ! 725: * we save a pointer to this template in a local variable: ! 726: * to be able to mark the state `analyzed' when we return ! 727: * for efficiency a pointer to the last visit is kept in a global `lastvisit' ! 728: */ ! 729: ticket = lastvisit; ! 730: level++; ! 731: COUNT += (double) 1; ! 732: ! 733: /* three tries: ! 734: * 1st try accepts internal moves (no timeouts, no outputs), ! 735: * 2nd try accepts any moves except timeouts, ! 736: * 3rd try accepts only timeouts. ! 737: */ ! 738: ! 739: for (X = 0; X <= 2; X++) ! 740: { internal = 0; ! 741: for (g = 0, i = I; g < nrprocs; g++, i = (i+1)%nrprocs) ! 742: { t = processes[i]; ! 743: k = state[i]; ! 744: ! 745: if (X == 0 && tbl[t].badrow[k]) ! 746: continue; /* first try: skip fsm without receives */ ! 747: ! 748: for (j = 0; j < tbl[t].nrcols; j++) ! 749: { if ((z = tbl[t].ptr[k][j].nrpils) == 0) ! 750: continue; ! 751: ! 752: x = lbt[i].mapcol[j]; ! 753: y = lbt[i].orgcol[j]; ! 754: Y = tbl[t].coltyp[j]; ! 755: ! 756: if (matchon(x, y, t, X, Y, i)) ! 757: { for (h = 0; h < z; h++) ! 758: { how = forward(t, k, j, h, x, y, i, Y, delta); ! 759: ! 760: if (qandirty || how == 0 || how >= LV || how == TC) ! 761: internal = 1; ! 762: ! 763: progress++; ! 764: #if DEBUG ! 765: printf("\tdown - %d/%d/%d\n", t, j, h); ! 766: showstate(); ! 767: #endif ! 768: /* FSE(mbox[lastqueue].owner); */ ! 769: FSE(0); ! 770: ! 771: backup(k, how, y, i, delta); ! 772: #if DEBUG ! 773: printf("\tup - %d/%d/%d\n", t, j, h); ! 774: showstate(); ! 775: #endif ! 776: } } /* innermost loop: non-determinism */ ! 777: if (blast && progress > 0) ! 778: break; ! 779: } /* inner loop: options per process */ ! 780: if (internal) ! 781: break; ! 782: } /* outer loop: parallelism */ ! 783: if (progress) ! 784: break; /* normal exit */ ! 785: } /* outermost loop: 2 trials */ ! 786: if (progress == 0) ! 787: { ! 788: if ((k = inendstate()) == nrprocs) ! 789: { normf++; ! 790: if (assertholds()) ! 791: { if (lockplus) output("endstate: ", 0); ! 792: } else ! 793: output("assertion violated: ", 0); ! 794: } ! 795: else ! 796: { locksf++; ! 797: if (k == 0) ! 798: output("deadlock: ", 1); ! 799: else ! 800: output("partial lock: ", 1); ! 801: if (linecode) ! 802: { printf("State at time of lock:\n"); ! 803: for (i = 0; i < nrprocs; i++) ! 804: printf("\tprocess %3d: state %s\n", i, ! 805: tbl[processes[i]].rowname[state[i]]); ! 806: putchar('\n'); ! 807: } } } ! 808: ! 809: level--; ! 810: ! 811: unfreeze(delta); efree(delta); ! 812: if (iam != NULL) ! 813: { mark(iam, ticket); ! 814: if (zapper > 0 && (progress == 0 || level >= maxlevel-3)) ! 815: swiffle(iam, ticket); ! 816: } ! 817: } ! 818: ! 819: forward(tb, k, j, h, m, from, pr, TT, ice) ! 820: struct FREEZE *ice; ! 821: { int how=0, n=m; ! 822: struct ELM *at; ! 823: ! 824: ice->whichvar = NONE; ! 825: ! 826: at = &(tbl[tb].ptr[k][j].one[h]); ! 827: ! 828: switch (TT) { ! 829: case SPN: how = evalexpr(at->valtrans, pr, ice); ! 830: break; ! 831: case CND: break; /* `matchon()' already checked it */ ! 832: case FCT: m = (int) tbl[tb].calls[n].callwhat; ! 833: ppush(pr, processes[pr], (int) at->transf); ! 834: setpars(&(tbl[tb].calls[n]), reftasks[m], pr); ! 835: setlvars(reftasks[m], pr); ! 836: processes[pr] = reftasks[m]; ! 837: fiddler(pr); ! 838: state[pr] = 0; ! 839: muststore = tbl[processes[pr]].labrow[0]; ! 840: return TC; ! 841: case TMO: send(m, from, NONE, pr, at->transf); ! 842: receive(from, NONE, pr, ice); ! 843: lastqueue = (short) from; ! 844: how = TO; ! 845: break; ! 846: case DFL: ! 847: case INP: receive(from, (int) at->valtrans, pr, ice); ! 848: how = RO; ! 849: break; ! 850: case OUTP: send(m, from, (int) at->valtrans, pr, at->transf); ! 851: lastqueue = (short) from; ! 852: how |= SO; ! 853: break; ! 854: } ! 855: state[pr] = (int) at->transf; ! 856: muststore = tbl[processes[pr]].labrow[state[pr]]; ! 857: ! 858: return (how); ! 859: } ! 860: ! 861: backup(k, how, bx, i, ice) ! 862: struct FREEZE *ice; ! 863: { int u = (int) ice->whichvar; ! 864: ! 865: if (u != NONE) ! 866: { if (u >= MANY) ! 867: procpars[i].lvarvals[u-MANY] = ice->oldvalue; ! 868: else ! 869: globvars[u] = ice->oldvalue; ! 870: } ! 871: switch (how) { ! 872: case TC: u = processes[i]; ! 873: processes[i] = ppop(i); ! 874: fiddler(i); ! 875: break; ! 876: case TO: unrecv(bx); ! 877: case SO: unsend(); ! 878: peekassert(ice); ! 879: break; ! 880: case SR: unsend(); ! 881: case RO: unrecv(bx); ! 882: peekassert(ice); ! 883: default: break; ! 884: } state[i] = k; ! 885: } ! 886: ! 887: fiddler(pr) ! 888: { register int i, t = processes[pr]; ! 889: ! 890: for (i = 0; i < tbl[t].nrcols; i++) ! 891: if (tbl[t].colmap[i] >= MANY) ! 892: { lbt[pr].mapcol[i] = mapper(tbl[t].colmap[i], pr); ! 893: lbt[pr].orgcol[i] = whichq(lbt[pr].mapcol[i]); ! 894: } else ! 895: { lbt[pr].mapcol[i] = tbl[t].colmap[i]; ! 896: lbt[pr].orgcol[i] = tbl[t].colorg[i]; ! 897: } ! 898: ! 899: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.