1219b2ee8SDavid du Colombier /***** spin: sched.c *****/
2219b2ee8SDavid du Colombier
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier */
8219b2ee8SDavid du Colombier
97dd7cddfSDavid du Colombier #include <stdlib.h>
10219b2ee8SDavid du Colombier #include "spin.h"
11219b2ee8SDavid du Colombier #include "y.tab.h"
12219b2ee8SDavid du Colombier
137dd7cddfSDavid du Colombier extern int verbose, s_trail, analyze, no_wrapup;
14*de2caf28SDavid du Colombier extern char *claimproc, *eventmap, GBuf[];
157dd7cddfSDavid du Colombier extern Ordered *all_names;
16219b2ee8SDavid du Colombier extern Symbol *Fname, *context;
177dd7cddfSDavid du Colombier extern int lineno, nr_errs, dumptab, xspin, jumpsteps, columns;
18312a1df1SDavid du Colombier extern int u_sync, Elcnt, interactive, TstOnly, cutoff;
19*de2caf28SDavid du Colombier extern short has_enabled, has_priority, has_code, replay;
20*de2caf28SDavid du Colombier extern int limited_vis, product, nclaims, old_priority_rules;
21*de2caf28SDavid du Colombier extern int old_scope_rules, scope_seq[128], scope_level, has_stdin;
22219b2ee8SDavid du Colombier
23*de2caf28SDavid du Colombier extern int pc_highest(Lextok *n);
24*de2caf28SDavid du Colombier extern void putpostlude(void);
25*de2caf28SDavid du Colombier
26*de2caf28SDavid du Colombier RunList *X_lst = (RunList *) 0;
27*de2caf28SDavid du Colombier RunList *run_lst = (RunList *) 0;
28219b2ee8SDavid du Colombier RunList *LastX = (RunList *) 0; /* previous executing proc */
29*de2caf28SDavid du Colombier ProcList *ready = (ProcList *) 0;
30219b2ee8SDavid du Colombier Element *LastStep = ZE;
31*de2caf28SDavid du Colombier int nproc=0, nstop=0, Tval=0, Priority_Sum = 0;
327dd7cddfSDavid du Colombier int Rvous=0, depth=0, nrRdy=0, MadeChoice;
337dd7cddfSDavid du Colombier short Have_claim=0, Skip_claim=0;
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier static void setlocals(RunList *);
367dd7cddfSDavid du Colombier static void setparams(RunList *, ProcList *, Lextok *);
377dd7cddfSDavid du Colombier static void talk(RunList *);
38219b2ee8SDavid du Colombier
39*de2caf28SDavid du Colombier extern char *which_mtype(const char *);
40*de2caf28SDavid du Colombier
41219b2ee8SDavid du Colombier void
runnable(ProcList * p,int weight,int noparams)427dd7cddfSDavid du Colombier runnable(ProcList *p, int weight, int noparams)
43219b2ee8SDavid du Colombier { RunList *r = (RunList *) emalloc(sizeof(RunList));
44219b2ee8SDavid du Colombier
45219b2ee8SDavid du Colombier r->n = p->n;
46219b2ee8SDavid du Colombier r->tn = p->tn;
4700d97012SDavid du Colombier r->b = p->b;
48312a1df1SDavid du Colombier r->pid = nproc++ - nstop + Skip_claim;
49*de2caf28SDavid du Colombier r->priority = weight;
50*de2caf28SDavid du Colombier p->priority = (unsigned char) weight; /* not quite the best place of course */
51312a1df1SDavid du Colombier
5200d97012SDavid du Colombier if (!noparams && ((verbose&4) || (verbose&32)))
53*de2caf28SDavid du Colombier { printf("Starting %s with pid %d",
5400d97012SDavid du Colombier p->n?p->n->name:"--", r->pid);
55*de2caf28SDavid du Colombier if (has_priority) printf(" priority %d", r->priority);
56*de2caf28SDavid du Colombier printf("\n");
57*de2caf28SDavid du Colombier }
58312a1df1SDavid du Colombier if (!p->s)
5900d97012SDavid du Colombier fatal("parsing error, no sequence %s",
6000d97012SDavid du Colombier p->n?p->n->name:"--");
61312a1df1SDavid du Colombier
62312a1df1SDavid du Colombier r->pc = huntele(p->s->frst, p->s->frst->status, -1);
637dd7cddfSDavid du Colombier r->ps = p->s;
64312a1df1SDavid du Colombier
65312a1df1SDavid du Colombier if (p->s->last)
667dd7cddfSDavid du Colombier p->s->last->status |= ENDSTATE; /* normal end state */
67312a1df1SDavid du Colombier
68*de2caf28SDavid du Colombier r->nxt = run_lst;
697dd7cddfSDavid du Colombier r->prov = p->prov;
70*de2caf28SDavid du Colombier if (weight < 1 || weight > 255)
71*de2caf28SDavid du Colombier { fatal("bad process priority, valid range: 1..255", (char *) 0);
72*de2caf28SDavid du Colombier }
7300d97012SDavid du Colombier
747dd7cddfSDavid du Colombier if (noparams) setlocals(r);
757dd7cddfSDavid du Colombier Priority_Sum += weight;
7600d97012SDavid du Colombier
77*de2caf28SDavid du Colombier run_lst = r;
78219b2ee8SDavid du Colombier }
79219b2ee8SDavid du Colombier
80219b2ee8SDavid du Colombier ProcList *
mk_rdy(Symbol * n,Lextok * p,Sequence * s,int det,Lextok * prov,enum btypes b)81*de2caf28SDavid du Colombier mk_rdy(Symbol *n, Lextok *p, Sequence *s, int det, Lextok *prov, enum btypes b)
827dd7cddfSDavid du Colombier /* n=name, p=formals, s=body det=deterministic prov=provided */
83219b2ee8SDavid du Colombier { ProcList *r = (ProcList *) emalloc(sizeof(ProcList));
84219b2ee8SDavid du Colombier Lextok *fp, *fpt; int j; extern int Npars;
85219b2ee8SDavid du Colombier
86219b2ee8SDavid du Colombier r->n = n;
87219b2ee8SDavid du Colombier r->p = p;
88219b2ee8SDavid du Colombier r->s = s;
8900d97012SDavid du Colombier r->b = b;
907dd7cddfSDavid du Colombier r->prov = prov;
91*de2caf28SDavid du Colombier r->tn = (short) nrRdy++;
92*de2caf28SDavid du Colombier n->sc = scope_seq[scope_level]; /* scope_level should be 0 */
93*de2caf28SDavid du Colombier
9400d97012SDavid du Colombier if (det != 0 && det != 1)
9500d97012SDavid du Colombier { fprintf(stderr, "spin: bad value for det (cannot happen)\n");
9600d97012SDavid du Colombier }
97*de2caf28SDavid du Colombier r->det = (unsigned char) det;
98*de2caf28SDavid du Colombier r->nxt = ready;
99*de2caf28SDavid du Colombier ready = r;
100219b2ee8SDavid du Colombier
101219b2ee8SDavid du Colombier for (fp = p, j = 0; fp; fp = fp->rgt)
102219b2ee8SDavid du Colombier for (fpt = fp->lft; fpt; fpt = fpt->rgt)
103*de2caf28SDavid du Colombier { j++; /* count # of parameters */
104*de2caf28SDavid du Colombier }
105219b2ee8SDavid du Colombier Npars = max(Npars, j);
106219b2ee8SDavid du Colombier
107*de2caf28SDavid du Colombier return ready;
108*de2caf28SDavid du Colombier }
109*de2caf28SDavid du Colombier
110*de2caf28SDavid du Colombier void
check_mtypes(Lextok * pnm,Lextok * args)111*de2caf28SDavid du Colombier check_mtypes(Lextok *pnm, Lextok *args) /* proctype name, actual params */
112*de2caf28SDavid du Colombier { ProcList *p = NULL;
113*de2caf28SDavid du Colombier Lextok *fp, *fpt, *at;
114*de2caf28SDavid du Colombier char *s, *t;
115*de2caf28SDavid du Colombier
116*de2caf28SDavid du Colombier if (pnm && pnm->sym)
117*de2caf28SDavid du Colombier { for (p = ready; p; p = p->nxt)
118*de2caf28SDavid du Colombier { if (strcmp(pnm->sym->name, p->n->name) == 0)
119*de2caf28SDavid du Colombier { /* found */
120*de2caf28SDavid du Colombier break;
121*de2caf28SDavid du Colombier } } }
122*de2caf28SDavid du Colombier
123*de2caf28SDavid du Colombier if (!p)
124*de2caf28SDavid du Colombier { fatal("cannot find proctype '%s'",
125*de2caf28SDavid du Colombier (pnm && pnm->sym)?pnm->sym->name:"?");
126*de2caf28SDavid du Colombier }
127*de2caf28SDavid du Colombier
128*de2caf28SDavid du Colombier for (fp = p->p, at = args; fp; fp = fp->rgt)
129*de2caf28SDavid du Colombier for (fpt = fp->lft; at && fpt; fpt = fpt->rgt, at = at->rgt)
130*de2caf28SDavid du Colombier {
131*de2caf28SDavid du Colombier if (fp->lft->val != MTYPE)
132*de2caf28SDavid du Colombier { continue;
133*de2caf28SDavid du Colombier }
134*de2caf28SDavid du Colombier if (!at->lft->sym)
135*de2caf28SDavid du Colombier { printf("spin:%d unrecognized mtype value\n",
136*de2caf28SDavid du Colombier pnm->ln);
137*de2caf28SDavid du Colombier continue;
138*de2caf28SDavid du Colombier }
139*de2caf28SDavid du Colombier s = "_unnamed_";
140*de2caf28SDavid du Colombier if (fp->lft->sym->mtype_name)
141*de2caf28SDavid du Colombier { t = fp->lft->sym->mtype_name->name;
142*de2caf28SDavid du Colombier } else
143*de2caf28SDavid du Colombier { t = "_unnamed_";
144*de2caf28SDavid du Colombier }
145*de2caf28SDavid du Colombier if (at->lft->ntyp != CONST)
146*de2caf28SDavid du Colombier { fatal("wrong arg type '%s'", at->lft->sym->name);
147*de2caf28SDavid du Colombier }
148*de2caf28SDavid du Colombier s = which_mtype(at->lft->sym->name);
149*de2caf28SDavid du Colombier if (s && strcmp(s, t) != 0)
150*de2caf28SDavid du Colombier { printf("spin: %s:%d, Error: '%s' is type '%s', but should be type '%s'\n",
151*de2caf28SDavid du Colombier pnm->fn->name, pnm->ln,
152*de2caf28SDavid du Colombier at->lft->sym->name, s, t);
153*de2caf28SDavid du Colombier fatal("wrong arg type '%s'", at->lft->sym->name);
154*de2caf28SDavid du Colombier } }
155219b2ee8SDavid du Colombier }
156219b2ee8SDavid du Colombier
157219b2ee8SDavid du Colombier int
find_maxel(Symbol * s)158219b2ee8SDavid du Colombier find_maxel(Symbol *s)
159219b2ee8SDavid du Colombier { ProcList *p;
160219b2ee8SDavid du Colombier
161*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
162*de2caf28SDavid du Colombier { if (p->n == s)
163*de2caf28SDavid du Colombier { return p->s->maxel++;
164*de2caf28SDavid du Colombier } }
165*de2caf28SDavid du Colombier
166219b2ee8SDavid du Colombier return Elcnt++;
167219b2ee8SDavid du Colombier }
168219b2ee8SDavid du Colombier
1697dd7cddfSDavid du Colombier static void
formdump(void)170219b2ee8SDavid du Colombier formdump(void)
171219b2ee8SDavid du Colombier { ProcList *p;
172219b2ee8SDavid du Colombier Lextok *f, *t;
173219b2ee8SDavid du Colombier int cnt;
174219b2ee8SDavid du Colombier
175*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
176219b2ee8SDavid du Colombier { if (!p->p) continue;
177219b2ee8SDavid du Colombier cnt = -1;
178219b2ee8SDavid du Colombier for (f = p->p; f; f = f->rgt) /* types */
179219b2ee8SDavid du Colombier for (t = f->lft; t; t = t->rgt) /* formals */
180219b2ee8SDavid du Colombier { if (t->ntyp != ',')
181219b2ee8SDavid du Colombier t->sym->Nid = cnt--; /* overload Nid */
182219b2ee8SDavid du Colombier else
183219b2ee8SDavid du Colombier t->lft->sym->Nid = cnt--;
184219b2ee8SDavid du Colombier }
185219b2ee8SDavid du Colombier }
186219b2ee8SDavid du Colombier }
187219b2ee8SDavid du Colombier
1887dd7cddfSDavid du Colombier void
announce(char * w)1897dd7cddfSDavid du Colombier announce(char *w)
1907dd7cddfSDavid du Colombier {
1917dd7cddfSDavid du Colombier if (columns)
192*de2caf28SDavid du Colombier { extern char GBuf[];
1937dd7cddfSDavid du Colombier extern int firstrow;
1947dd7cddfSDavid du Colombier firstrow = 1;
1957dd7cddfSDavid du Colombier if (columns == 2)
196*de2caf28SDavid du Colombier { sprintf(GBuf, "%d:%s",
197*de2caf28SDavid du Colombier run_lst->pid - Have_claim, run_lst->n->name);
198*de2caf28SDavid du Colombier pstext(run_lst->pid - Have_claim, GBuf);
1997dd7cddfSDavid du Colombier } else
200*de2caf28SDavid du Colombier { printf("proc %d = %s\n",
201*de2caf28SDavid du Colombier run_lst->pid - Have_claim, run_lst->n->name);
202*de2caf28SDavid du Colombier }
2037dd7cddfSDavid du Colombier return;
2047dd7cddfSDavid du Colombier }
205312a1df1SDavid du Colombier
2067dd7cddfSDavid du Colombier if (dumptab
2077dd7cddfSDavid du Colombier || analyze
20800d97012SDavid du Colombier || product
2097dd7cddfSDavid du Colombier || s_trail
2107dd7cddfSDavid du Colombier || !(verbose&4))
2117dd7cddfSDavid du Colombier return;
212312a1df1SDavid du Colombier
2137dd7cddfSDavid du Colombier if (w)
2147dd7cddfSDavid du Colombier printf(" 0: proc - (%s) ", w);
2157dd7cddfSDavid du Colombier else
2167dd7cddfSDavid du Colombier whoruns(1);
2177dd7cddfSDavid du Colombier printf("creates proc %2d (%s)",
218*de2caf28SDavid du Colombier run_lst->pid - Have_claim,
219*de2caf28SDavid du Colombier run_lst->n->name);
220*de2caf28SDavid du Colombier if (run_lst->priority > 1)
221*de2caf28SDavid du Colombier printf(" priority %d", run_lst->priority);
2227dd7cddfSDavid du Colombier printf("\n");
2237dd7cddfSDavid du Colombier }
224219b2ee8SDavid du Colombier
225312a1df1SDavid du Colombier #ifndef MAXP
226312a1df1SDavid du Colombier #define MAXP 255 /* matches max nr of processes in verifier */
227312a1df1SDavid du Colombier #endif
228312a1df1SDavid du Colombier
2297dd7cddfSDavid du Colombier int
enable(Lextok * m)2307dd7cddfSDavid du Colombier enable(Lextok *m)
2317dd7cddfSDavid du Colombier { ProcList *p;
2327dd7cddfSDavid du Colombier Symbol *s = m->sym; /* proctype name */
2337dd7cddfSDavid du Colombier Lextok *n = m->lft; /* actual parameters */
2347dd7cddfSDavid du Colombier
235*de2caf28SDavid du Colombier if (m->val < 1)
236*de2caf28SDavid du Colombier { m->val = 1; /* minimum priority */
237*de2caf28SDavid du Colombier }
238*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
239*de2caf28SDavid du Colombier { if (strcmp(s->name, p->n->name) == 0)
240312a1df1SDavid du Colombier { if (nproc-nstop >= MAXP)
241312a1df1SDavid du Colombier { printf("spin: too many processes (%d max)\n", MAXP);
242312a1df1SDavid du Colombier break;
243312a1df1SDavid du Colombier }
244312a1df1SDavid du Colombier runnable(p, m->val, 0);
2457dd7cddfSDavid du Colombier announce((char *) 0);
246*de2caf28SDavid du Colombier setparams(run_lst, p, n);
247*de2caf28SDavid du Colombier setlocals(run_lst); /* after setparams */
248*de2caf28SDavid du Colombier check_mtypes(m, m->lft);
249*de2caf28SDavid du Colombier return run_lst->pid - Have_claim + Skip_claim; /* effective simu pid */
250*de2caf28SDavid du Colombier } }
251219b2ee8SDavid du Colombier return 0; /* process not found */
252219b2ee8SDavid du Colombier }
253219b2ee8SDavid du Colombier
254219b2ee8SDavid du Colombier void
check_param_count(int i,Lextok * m)255f3793cddSDavid du Colombier check_param_count(int i, Lextok *m)
256f3793cddSDavid du Colombier { ProcList *p;
257f3793cddSDavid du Colombier Symbol *s = m->sym; /* proctype name */
258f3793cddSDavid du Colombier Lextok *f, *t; /* formal pars */
259f3793cddSDavid du Colombier int cnt = 0;
260f3793cddSDavid du Colombier
261*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
262f3793cddSDavid du Colombier { if (strcmp(s->name, p->n->name) == 0)
263f3793cddSDavid du Colombier { if (m->lft) /* actual param list */
264f3793cddSDavid du Colombier { lineno = m->lft->ln;
265f3793cddSDavid du Colombier Fname = m->lft->fn;
266f3793cddSDavid du Colombier }
267f3793cddSDavid du Colombier for (f = p->p; f; f = f->rgt) /* one type at a time */
268f3793cddSDavid du Colombier for (t = f->lft; t; t = t->rgt) /* count formal params */
269f3793cddSDavid du Colombier { cnt++;
270f3793cddSDavid du Colombier }
271f3793cddSDavid du Colombier if (i != cnt)
272f3793cddSDavid du Colombier { printf("spin: saw %d parameters, expected %d\n", i, cnt);
273f3793cddSDavid du Colombier non_fatal("wrong number of parameters", "");
274f3793cddSDavid du Colombier }
275f3793cddSDavid du Colombier break;
276f3793cddSDavid du Colombier } }
277f3793cddSDavid du Colombier }
278f3793cddSDavid du Colombier
279f3793cddSDavid du Colombier void
start_claim(int n)280219b2ee8SDavid du Colombier start_claim(int n)
281219b2ee8SDavid du Colombier { ProcList *p;
2827dd7cddfSDavid du Colombier RunList *r, *q = (RunList *) 0;
283219b2ee8SDavid du Colombier
284*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
28500d97012SDavid du Colombier if (p->tn == n && p->b == N_CLAIM)
2867dd7cddfSDavid du Colombier { runnable(p, 1, 1);
2877dd7cddfSDavid du Colombier goto found;
288219b2ee8SDavid du Colombier }
28900d97012SDavid du Colombier printf("spin: couldn't find claim %d (ignored)\n", n);
29000d97012SDavid du Colombier if (verbose&32)
291*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
29200d97012SDavid du Colombier printf("\t%d = %s\n", p->tn, p->n->name);
29300d97012SDavid du Colombier
2947dd7cddfSDavid du Colombier Skip_claim = 1;
2957dd7cddfSDavid du Colombier goto done;
2967dd7cddfSDavid du Colombier found:
297312a1df1SDavid du Colombier /* move claim to far end of runlist, and reassign it pid 0 */
2987dd7cddfSDavid du Colombier if (columns == 2)
299*de2caf28SDavid du Colombier { extern char GBuf[];
30000d97012SDavid du Colombier depth = 0;
301*de2caf28SDavid du Colombier sprintf(GBuf, "%d:%s", 0, p->n->name);
302*de2caf28SDavid du Colombier pstext(0, GBuf);
303*de2caf28SDavid du Colombier for (r = run_lst; r; r = r->nxt)
30400d97012SDavid du Colombier { if (r->b != N_CLAIM)
305*de2caf28SDavid du Colombier { sprintf(GBuf, "%d:%s", r->pid+1, r->n->name);
306*de2caf28SDavid du Colombier pstext(r->pid+1, GBuf);
30700d97012SDavid du Colombier } } }
308312a1df1SDavid du Colombier
309*de2caf28SDavid du Colombier if (run_lst->pid == 0) return; /* it is the first process started */
3107dd7cddfSDavid du Colombier
311*de2caf28SDavid du Colombier q = run_lst; run_lst = run_lst->nxt;
312312a1df1SDavid du Colombier q->pid = 0; q->nxt = (RunList *) 0; /* remove */
3137dd7cddfSDavid du Colombier done:
314312a1df1SDavid du Colombier Have_claim = 1;
315*de2caf28SDavid du Colombier for (r = run_lst; r; r = r->nxt)
316312a1df1SDavid du Colombier { r->pid = r->pid+Have_claim; /* adjust */
3177dd7cddfSDavid du Colombier if (!r->nxt)
3187dd7cddfSDavid du Colombier { r->nxt = q;
3197dd7cddfSDavid du Colombier break;
3207dd7cddfSDavid du Colombier } }
321312a1df1SDavid du Colombier }
322312a1df1SDavid du Colombier
323312a1df1SDavid du Colombier int
f_pid(char * n)324312a1df1SDavid du Colombier f_pid(char *n)
325312a1df1SDavid du Colombier { RunList *r;
326312a1df1SDavid du Colombier int rval = -1;
327312a1df1SDavid du Colombier
328*de2caf28SDavid du Colombier for (r = run_lst; r; r = r->nxt)
329312a1df1SDavid du Colombier if (strcmp(n, r->n->name) == 0)
330312a1df1SDavid du Colombier { if (rval >= 0)
331312a1df1SDavid du Colombier { printf("spin: remote ref to proctype %s, ", n);
332312a1df1SDavid du Colombier printf("has more than one match: %d and %d\n",
333312a1df1SDavid du Colombier rval, r->pid);
334312a1df1SDavid du Colombier } else
335312a1df1SDavid du Colombier rval = r->pid;
336312a1df1SDavid du Colombier }
337312a1df1SDavid du Colombier return rval;
338219b2ee8SDavid du Colombier }
339219b2ee8SDavid du Colombier
340219b2ee8SDavid du Colombier void
wrapup(int fini)341219b2ee8SDavid du Colombier wrapup(int fini)
342219b2ee8SDavid du Colombier {
343312a1df1SDavid du Colombier limited_vis = 0;
3447dd7cddfSDavid du Colombier if (columns)
345*de2caf28SDavid du Colombier { if (columns == 2) putpostlude();
3467dd7cddfSDavid du Colombier if (!no_wrapup)
3477dd7cddfSDavid du Colombier printf("-------------\nfinal state:\n-------------\n");
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier if (no_wrapup)
3507dd7cddfSDavid du Colombier goto short_cut;
351219b2ee8SDavid du Colombier if (nproc != nstop)
3527dd7cddfSDavid du Colombier { int ov = verbose;
353312a1df1SDavid du Colombier printf("#processes: %d\n", nproc-nstop - Have_claim + Skip_claim);
3547dd7cddfSDavid du Colombier verbose &= ~4;
355219b2ee8SDavid du Colombier dumpglobals();
3567dd7cddfSDavid du Colombier verbose = ov;
357219b2ee8SDavid du Colombier verbose &= ~1; /* no more globals */
358219b2ee8SDavid du Colombier verbose |= 32; /* add process states */
359*de2caf28SDavid du Colombier for (X_lst = run_lst; X_lst; X_lst = X_lst->nxt)
360*de2caf28SDavid du Colombier talk(X_lst);
3617dd7cddfSDavid du Colombier verbose = ov; /* restore */
362219b2ee8SDavid du Colombier }
363312a1df1SDavid du Colombier printf("%d process%s created\n",
364312a1df1SDavid du Colombier nproc - Have_claim + Skip_claim,
365312a1df1SDavid du Colombier (xspin || nproc!=1)?"es":"");
3667dd7cddfSDavid du Colombier short_cut:
367*de2caf28SDavid du Colombier if (s_trail || xspin) alldone(0); /* avoid an abort from xspin */
3687dd7cddfSDavid du Colombier if (fini) alldone(1);
369219b2ee8SDavid du Colombier }
370219b2ee8SDavid du Colombier
371219b2ee8SDavid du Colombier static char is_blocked[256];
372219b2ee8SDavid du Colombier
3737dd7cddfSDavid du Colombier static int
p_blocked(int p)374219b2ee8SDavid du Colombier p_blocked(int p)
375312a1df1SDavid du Colombier { int i, j;
376219b2ee8SDavid du Colombier
377219b2ee8SDavid du Colombier is_blocked[p%256] = 1;
378219b2ee8SDavid du Colombier for (i = j = 0; i < nproc - nstop; i++)
379219b2ee8SDavid du Colombier j += is_blocked[i];
380219b2ee8SDavid du Colombier if (j >= nproc - nstop)
381219b2ee8SDavid du Colombier { memset(is_blocked, 0, 256);
382219b2ee8SDavid du Colombier return 1;
383219b2ee8SDavid du Colombier }
384219b2ee8SDavid du Colombier return 0;
385219b2ee8SDavid du Colombier }
386219b2ee8SDavid du Colombier
3877dd7cddfSDavid du Colombier static Element *
silent_moves(Element * e)388219b2ee8SDavid du Colombier silent_moves(Element *e)
389219b2ee8SDavid du Colombier { Element *f;
390219b2ee8SDavid du Colombier
391f3793cddSDavid du Colombier if (e->n)
392219b2ee8SDavid du Colombier switch (e->n->ntyp) {
393219b2ee8SDavid du Colombier case GOTO:
394219b2ee8SDavid du Colombier if (Rvous) break;
395219b2ee8SDavid du Colombier f = get_lab(e->n, 1);
396219b2ee8SDavid du Colombier cross_dsteps(e->n, f->n);
397219b2ee8SDavid du Colombier return f; /* guard against goto cycles */
398219b2ee8SDavid du Colombier case UNLESS:
399219b2ee8SDavid du Colombier return silent_moves(e->sub->this->frst);
400219b2ee8SDavid du Colombier case NON_ATOMIC:
401219b2ee8SDavid du Colombier case ATOMIC:
402219b2ee8SDavid du Colombier case D_STEP:
403219b2ee8SDavid du Colombier e->n->sl->this->last->nxt = e->nxt;
404219b2ee8SDavid du Colombier return silent_moves(e->n->sl->this->frst);
405219b2ee8SDavid du Colombier case '.':
4067dd7cddfSDavid du Colombier return silent_moves(e->nxt);
407219b2ee8SDavid du Colombier }
408219b2ee8SDavid du Colombier return e;
409219b2ee8SDavid du Colombier }
410219b2ee8SDavid du Colombier
411*de2caf28SDavid du Colombier static int
x_can_run(void)412*de2caf28SDavid du Colombier x_can_run(void) /* the currently selected process in X_lst can run */
413*de2caf28SDavid du Colombier {
414*de2caf28SDavid du Colombier if (X_lst->prov && !eval(X_lst->prov))
415*de2caf28SDavid du Colombier {
416*de2caf28SDavid du Colombier if (0) printf("pid %d cannot run: not provided\n", X_lst->pid);
417*de2caf28SDavid du Colombier return 0;
418*de2caf28SDavid du Colombier }
419*de2caf28SDavid du Colombier if (has_priority && !old_priority_rules)
420*de2caf28SDavid du Colombier { Lextok *n = nn(ZN, CONST, ZN, ZN);
421*de2caf28SDavid du Colombier n->val = X_lst->pid;
422*de2caf28SDavid du Colombier if (0) printf("pid %d %s run (priority)\n", X_lst->pid, pc_highest(n)?"can":"cannot");
423*de2caf28SDavid du Colombier return pc_highest(n);
424*de2caf28SDavid du Colombier }
425*de2caf28SDavid du Colombier if (0) printf("pid %d can run\n", X_lst->pid);
426*de2caf28SDavid du Colombier return 1;
427*de2caf28SDavid du Colombier }
428*de2caf28SDavid du Colombier
429f3793cddSDavid du Colombier static RunList *
pickproc(RunList * Y)430f3793cddSDavid du Colombier pickproc(RunList *Y)
4317dd7cddfSDavid du Colombier { SeqList *z; Element *has_else;
4327dd7cddfSDavid du Colombier short Choices[256];
433312a1df1SDavid du Colombier int j, k, nr_else = 0;
4347dd7cddfSDavid du Colombier
4357dd7cddfSDavid du Colombier if (nproc <= nstop+1)
436*de2caf28SDavid du Colombier { X_lst = run_lst;
437f3793cddSDavid du Colombier return NULL;
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier if (!interactive || depth < jumpsteps)
440*de2caf28SDavid du Colombier { if (has_priority && !old_priority_rules) /* new 6.3.2 */
441*de2caf28SDavid du Colombier { j = Rand()%(nproc-nstop);
442*de2caf28SDavid du Colombier for (X_lst = run_lst; X_lst; X_lst = X_lst->nxt)
443*de2caf28SDavid du Colombier { if (j-- <= 0)
444*de2caf28SDavid du Colombier break;
445*de2caf28SDavid du Colombier }
446*de2caf28SDavid du Colombier if (X_lst == NULL)
447*de2caf28SDavid du Colombier { fatal("unexpected, pickproc", (char *)0);
448*de2caf28SDavid du Colombier }
449*de2caf28SDavid du Colombier j = nproc - nstop;
450*de2caf28SDavid du Colombier while (j-- > 0)
451*de2caf28SDavid du Colombier { if (x_can_run())
452*de2caf28SDavid du Colombier { Y = X_lst;
453*de2caf28SDavid du Colombier break;
454*de2caf28SDavid du Colombier }
455*de2caf28SDavid du Colombier X_lst = (X_lst->nxt)?X_lst->nxt:run_lst;
456*de2caf28SDavid du Colombier }
457*de2caf28SDavid du Colombier return Y;
458*de2caf28SDavid du Colombier }
4597dd7cddfSDavid du Colombier if (Priority_Sum < nproc-nstop)
4607dd7cddfSDavid du Colombier fatal("cannot happen - weights", (char *)0);
4617dd7cddfSDavid du Colombier j = (int) Rand()%Priority_Sum;
462f3793cddSDavid du Colombier
463*de2caf28SDavid du Colombier while (j - X_lst->priority >= 0)
464*de2caf28SDavid du Colombier { j -= X_lst->priority;
465*de2caf28SDavid du Colombier Y = X_lst;
466*de2caf28SDavid du Colombier X_lst = X_lst->nxt;
467*de2caf28SDavid du Colombier if (!X_lst) { Y = NULL; X_lst = run_lst; }
4687dd7cddfSDavid du Colombier }
469*de2caf28SDavid du Colombier
4707dd7cddfSDavid du Colombier } else
4717dd7cddfSDavid du Colombier { int only_choice = -1;
4727dd7cddfSDavid du Colombier int no_choice = 0, proc_no_ch, proc_k;
473f3793cddSDavid du Colombier
474f3793cddSDavid du Colombier Tval = 0; /* new 4.2.6 */
4757dd7cddfSDavid du Colombier try_again: printf("Select a statement\n");
476*de2caf28SDavid du Colombier try_more: for (X_lst = run_lst, k = 1; X_lst; X_lst = X_lst->nxt)
477*de2caf28SDavid du Colombier { if (X_lst->pid > 255) break;
4787dd7cddfSDavid du Colombier
479*de2caf28SDavid du Colombier Choices[X_lst->pid] = (short) k;
4807dd7cddfSDavid du Colombier
481*de2caf28SDavid du Colombier if (!X_lst->pc || !x_can_run())
482*de2caf28SDavid du Colombier { if (X_lst == run_lst)
483*de2caf28SDavid du Colombier Choices[X_lst->pid] = 0;
4847dd7cddfSDavid du Colombier continue;
4857dd7cddfSDavid du Colombier }
486*de2caf28SDavid du Colombier X_lst->pc = silent_moves(X_lst->pc);
487*de2caf28SDavid du Colombier if (!X_lst->pc->sub && X_lst->pc->n)
4887dd7cddfSDavid du Colombier { int unex;
489*de2caf28SDavid du Colombier unex = !Enabled0(X_lst->pc);
4907dd7cddfSDavid du Colombier if (unex)
4917dd7cddfSDavid du Colombier no_choice++;
4927dd7cddfSDavid du Colombier else
4937dd7cddfSDavid du Colombier only_choice = k;
4947dd7cddfSDavid du Colombier if (!xspin && unex && !(verbose&32))
4957dd7cddfSDavid du Colombier { k++;
4967dd7cddfSDavid du Colombier continue;
4977dd7cddfSDavid du Colombier }
4987dd7cddfSDavid du Colombier printf("\tchoice %d: ", k++);
499*de2caf28SDavid du Colombier p_talk(X_lst->pc, 0);
5007dd7cddfSDavid du Colombier if (unex)
5017dd7cddfSDavid du Colombier printf(" unexecutable,");
5027dd7cddfSDavid du Colombier printf(" [");
503*de2caf28SDavid du Colombier comment(stdout, X_lst->pc->n, 0);
504*de2caf28SDavid du Colombier if (X_lst->pc->esc) printf(" + Escape");
5057dd7cddfSDavid du Colombier printf("]\n");
5067dd7cddfSDavid du Colombier } else {
5077dd7cddfSDavid du Colombier has_else = ZE;
5087dd7cddfSDavid du Colombier proc_no_ch = no_choice;
5097dd7cddfSDavid du Colombier proc_k = k;
510*de2caf28SDavid du Colombier for (z = X_lst->pc->sub, j=0; z; z = z->nxt)
5117dd7cddfSDavid du Colombier { Element *y = silent_moves(z->this->frst);
5127dd7cddfSDavid du Colombier int unex;
5137dd7cddfSDavid du Colombier if (!y) continue;
5147dd7cddfSDavid du Colombier
5157dd7cddfSDavid du Colombier if (y->n->ntyp == ELSE)
5167dd7cddfSDavid du Colombier { has_else = (Rvous)?ZE:y;
5177dd7cddfSDavid du Colombier nr_else = k++;
5187dd7cddfSDavid du Colombier continue;
5197dd7cddfSDavid du Colombier }
5207dd7cddfSDavid du Colombier
5217dd7cddfSDavid du Colombier unex = !Enabled0(y);
5227dd7cddfSDavid du Colombier if (unex)
5237dd7cddfSDavid du Colombier no_choice++;
5247dd7cddfSDavid du Colombier else
5257dd7cddfSDavid du Colombier only_choice = k;
5267dd7cddfSDavid du Colombier if (!xspin && unex && !(verbose&32))
5277dd7cddfSDavid du Colombier { k++;
5287dd7cddfSDavid du Colombier continue;
5297dd7cddfSDavid du Colombier }
5307dd7cddfSDavid du Colombier printf("\tchoice %d: ", k++);
531*de2caf28SDavid du Colombier p_talk(X_lst->pc, 0);
5327dd7cddfSDavid du Colombier if (unex)
5337dd7cddfSDavid du Colombier printf(" unexecutable,");
5347dd7cddfSDavid du Colombier printf(" [");
5357dd7cddfSDavid du Colombier comment(stdout, y->n, 0);
5367dd7cddfSDavid du Colombier printf("]\n");
5377dd7cddfSDavid du Colombier }
5387dd7cddfSDavid du Colombier if (has_else)
5397dd7cddfSDavid du Colombier { if (no_choice-proc_no_ch >= (k-proc_k)-1)
5407dd7cddfSDavid du Colombier { only_choice = nr_else;
5417dd7cddfSDavid du Colombier printf("\tchoice %d: ", nr_else);
542*de2caf28SDavid du Colombier p_talk(X_lst->pc, 0);
5437dd7cddfSDavid du Colombier printf(" [else]\n");
5447dd7cddfSDavid du Colombier } else
5457dd7cddfSDavid du Colombier { no_choice++;
5467dd7cddfSDavid du Colombier printf("\tchoice %d: ", nr_else);
547*de2caf28SDavid du Colombier p_talk(X_lst->pc, 0);
5487dd7cddfSDavid du Colombier printf(" unexecutable, [else]\n");
5497dd7cddfSDavid du Colombier } }
5507dd7cddfSDavid du Colombier } }
551*de2caf28SDavid du Colombier X_lst = run_lst;
5527dd7cddfSDavid du Colombier if (k - no_choice < 2 && Tval == 0)
5537dd7cddfSDavid du Colombier { Tval = 1;
5547dd7cddfSDavid du Colombier no_choice = 0; only_choice = -1;
5557dd7cddfSDavid du Colombier goto try_more;
5567dd7cddfSDavid du Colombier }
5577dd7cddfSDavid du Colombier if (xspin)
5587dd7cddfSDavid du Colombier printf("Make Selection %d\n\n", k-1);
5597dd7cddfSDavid du Colombier else
5607dd7cddfSDavid du Colombier { if (k - no_choice < 2)
5617dd7cddfSDavid du Colombier { printf("no executable choices\n");
5627dd7cddfSDavid du Colombier alldone(0);
5637dd7cddfSDavid du Colombier }
5647dd7cddfSDavid du Colombier printf("Select [1-%d]: ", k-1);
5657dd7cddfSDavid du Colombier }
5667dd7cddfSDavid du Colombier if (!xspin && k - no_choice == 2)
5677dd7cddfSDavid du Colombier { printf("%d\n", only_choice);
5687dd7cddfSDavid du Colombier j = only_choice;
5697dd7cddfSDavid du Colombier } else
5707dd7cddfSDavid du Colombier { char buf[256];
5717dd7cddfSDavid du Colombier fflush(stdout);
57200d97012SDavid du Colombier if (scanf("%64s", buf) == 0)
57300d97012SDavid du Colombier { printf("\tno input\n");
57400d97012SDavid du Colombier goto try_again;
57500d97012SDavid du Colombier }
5767dd7cddfSDavid du Colombier j = -1;
57700d97012SDavid du Colombier if (isdigit((int) buf[0]))
5787dd7cddfSDavid du Colombier j = atoi(buf);
5797dd7cddfSDavid du Colombier else
5807dd7cddfSDavid du Colombier { if (buf[0] == 'q')
5817dd7cddfSDavid du Colombier alldone(0);
5827dd7cddfSDavid du Colombier }
5837dd7cddfSDavid du Colombier if (j < 1 || j >= k)
5847dd7cddfSDavid du Colombier { printf("\tchoice is outside range\n");
5857dd7cddfSDavid du Colombier goto try_again;
5867dd7cddfSDavid du Colombier } }
5877dd7cddfSDavid du Colombier MadeChoice = 0;
588f3793cddSDavid du Colombier Y = NULL;
589*de2caf28SDavid du Colombier for (X_lst = run_lst; X_lst; Y = X_lst, X_lst = X_lst->nxt)
590*de2caf28SDavid du Colombier { if (!X_lst->nxt
591*de2caf28SDavid du Colombier || X_lst->nxt->pid > 255
592*de2caf28SDavid du Colombier || j < Choices[X_lst->nxt->pid])
5937dd7cddfSDavid du Colombier {
594*de2caf28SDavid du Colombier MadeChoice = 1+j-Choices[X_lst->pid];
5957dd7cddfSDavid du Colombier break;
5967dd7cddfSDavid du Colombier } }
5977dd7cddfSDavid du Colombier }
598f3793cddSDavid du Colombier return Y;
5997dd7cddfSDavid du Colombier }
6007dd7cddfSDavid du Colombier
601219b2ee8SDavid du Colombier void
multi_claims(void)60200d97012SDavid du Colombier multi_claims(void)
60300d97012SDavid du Colombier { ProcList *p, *q = NULL;
60400d97012SDavid du Colombier
60500d97012SDavid du Colombier if (nclaims > 1)
60600d97012SDavid du Colombier { printf(" the model contains %d never claims:", nclaims);
607*de2caf28SDavid du Colombier for (p = ready; p; p = p->nxt)
60800d97012SDavid du Colombier { if (p->b == N_CLAIM)
60900d97012SDavid du Colombier { printf("%s%s", q?", ":" ", p->n->name);
61000d97012SDavid du Colombier q = p;
61100d97012SDavid du Colombier } }
61200d97012SDavid du Colombier printf("\n");
61300d97012SDavid du Colombier printf(" only one claim is used in a verification run\n");
614*de2caf28SDavid du Colombier printf(" choose which one with ./pan -a -N name (defaults to -N %s)\n",
61500d97012SDavid du Colombier q?q->n->name:"--");
616*de2caf28SDavid du Colombier printf(" or use e.g.: spin -search -ltl %s %s\n",
617*de2caf28SDavid du Colombier q?q->n->name:"--", Fname?Fname->name:"filename");
61800d97012SDavid du Colombier }
61900d97012SDavid du Colombier }
62000d97012SDavid du Colombier
62100d97012SDavid du Colombier void
sched(void)622219b2ee8SDavid du Colombier sched(void)
623219b2ee8SDavid du Colombier { Element *e;
624f3793cddSDavid du Colombier RunList *Y = NULL; /* previous process in run queue */
625219b2ee8SDavid du Colombier RunList *oX;
626312a1df1SDavid du Colombier int go, notbeyond = 0;
6277dd7cddfSDavid du Colombier #ifdef PC
6287dd7cddfSDavid du Colombier int bufmax = 100;
6297dd7cddfSDavid du Colombier #endif
630219b2ee8SDavid du Colombier if (dumptab)
631219b2ee8SDavid du Colombier { formdump();
632219b2ee8SDavid du Colombier symdump();
633219b2ee8SDavid du Colombier dumplabels();
634219b2ee8SDavid du Colombier return;
635219b2ee8SDavid du Colombier }
636*de2caf28SDavid du Colombier if (has_code && !analyze)
637*de2caf28SDavid du Colombier { printf("spin: warning: c_code fragments remain uninterpreted\n");
638*de2caf28SDavid du Colombier printf(" in random simulations with spin; use ./pan -r instead\n");
639*de2caf28SDavid du Colombier }
640219b2ee8SDavid du Colombier
641219b2ee8SDavid du Colombier if (has_enabled && u_sync > 0)
6427dd7cddfSDavid du Colombier { printf("spin: error, cannot use 'enabled()' in ");
6437dd7cddfSDavid du Colombier printf("models with synchronous channels.\n");
644219b2ee8SDavid du Colombier nr_errs++;
645219b2ee8SDavid du Colombier }
64600d97012SDavid du Colombier if (product)
64700d97012SDavid du Colombier { sync_product();
64800d97012SDavid du Colombier alldone(0);
64900d97012SDavid du Colombier }
650*de2caf28SDavid du Colombier if (analyze && (!replay || has_code))
651219b2ee8SDavid du Colombier { gensrc();
65200d97012SDavid du Colombier multi_claims();
653219b2ee8SDavid du Colombier return;
65400d97012SDavid du Colombier }
655*de2caf28SDavid du Colombier if (replay && !has_code)
656*de2caf28SDavid du Colombier { return;
657*de2caf28SDavid du Colombier }
65800d97012SDavid du Colombier if (s_trail)
659219b2ee8SDavid du Colombier { match_trail();
660219b2ee8SDavid du Colombier return;
661219b2ee8SDavid du Colombier }
662*de2caf28SDavid du Colombier
663219b2ee8SDavid du Colombier if (claimproc)
6647dd7cddfSDavid du Colombier printf("warning: never claim not used in random simulation\n");
6657dd7cddfSDavid du Colombier if (eventmap)
6667dd7cddfSDavid du Colombier printf("warning: trace assertion not used in random simulation\n");
667219b2ee8SDavid du Colombier
668*de2caf28SDavid du Colombier X_lst = run_lst;
669f3793cddSDavid du Colombier Y = pickproc(Y);
6707dd7cddfSDavid du Colombier
671*de2caf28SDavid du Colombier while (X_lst)
672*de2caf28SDavid du Colombier { context = X_lst->n;
673*de2caf28SDavid du Colombier if (X_lst->pc && X_lst->pc->n)
674*de2caf28SDavid du Colombier { lineno = X_lst->pc->n->ln;
675*de2caf28SDavid du Colombier Fname = X_lst->pc->n->fn;
676219b2ee8SDavid du Colombier }
677312a1df1SDavid du Colombier if (cutoff > 0 && depth >= cutoff)
678312a1df1SDavid du Colombier { printf("-------------\n");
679312a1df1SDavid du Colombier printf("depth-limit (-u%d steps) reached\n", cutoff);
680312a1df1SDavid du Colombier break;
681312a1df1SDavid du Colombier }
6827dd7cddfSDavid du Colombier #ifdef PC
6837dd7cddfSDavid du Colombier if (xspin && !interactive && --bufmax <= 0)
684312a1df1SDavid du Colombier { int c; /* avoid buffer overflow on pc's */
6857dd7cddfSDavid du Colombier printf("spin: type return to proceed\n");
6867dd7cddfSDavid du Colombier fflush(stdout);
687312a1df1SDavid du Colombier c = getc(stdin);
688312a1df1SDavid du Colombier if (c == 'q') wrapup(0);
6897dd7cddfSDavid du Colombier bufmax = 100;
6907dd7cddfSDavid du Colombier }
6917dd7cddfSDavid du Colombier #endif
692219b2ee8SDavid du Colombier depth++; LastStep = ZE;
693*de2caf28SDavid du Colombier oX = X_lst; /* a rendezvous could change it */
6947dd7cddfSDavid du Colombier go = 1;
695*de2caf28SDavid du Colombier if (X_lst->pc
696*de2caf28SDavid du Colombier && !(X_lst->pc->status & D_ATOM)
697*de2caf28SDavid du Colombier && !x_can_run())
6987dd7cddfSDavid du Colombier { if (!xspin && ((verbose&32) || (verbose&4)))
699*de2caf28SDavid du Colombier { p_talk(X_lst->pc, 1);
7007dd7cddfSDavid du Colombier printf("\t<<Not Enabled>>\n");
7017dd7cddfSDavid du Colombier }
7027dd7cddfSDavid du Colombier go = 0;
7037dd7cddfSDavid du Colombier }
704*de2caf28SDavid du Colombier if (go && (e = eval_sub(X_lst->pc)))
7057dd7cddfSDavid du Colombier { if (depth >= jumpsteps
7067dd7cddfSDavid du Colombier && ((verbose&32) || (verbose&4)))
707*de2caf28SDavid du Colombier { if (X_lst == oX)
708312a1df1SDavid du Colombier if (!(e->status & D_ATOM) || (verbose&32)) /* no talking in d_steps */
709*de2caf28SDavid du Colombier { if (!LastStep) LastStep = X_lst->pc;
710*de2caf28SDavid du Colombier /* A. Tanaka, changed order */
711*de2caf28SDavid du Colombier p_talk(LastStep, 1);
712219b2ee8SDavid du Colombier printf(" [");
713219b2ee8SDavid du Colombier comment(stdout, LastStep->n, 0);
714219b2ee8SDavid du Colombier printf("]\n");
715219b2ee8SDavid du Colombier }
716219b2ee8SDavid du Colombier if (verbose&1) dumpglobals();
717*de2caf28SDavid du Colombier if (verbose&2) dumplocal(X_lst, 0);
718312a1df1SDavid du Colombier
719312a1df1SDavid du Colombier if (!(e->status & D_ATOM))
720312a1df1SDavid du Colombier if (xspin)
721312a1df1SDavid du Colombier printf("\n");
722219b2ee8SDavid du Colombier }
723*de2caf28SDavid du Colombier if (oX != X_lst
724*de2caf28SDavid du Colombier || (X_lst->pc->status & (ATOM|D_ATOM))) /* new 5.0 */
725312a1df1SDavid du Colombier { e = silent_moves(e);
726312a1df1SDavid du Colombier notbeyond = 0;
727312a1df1SDavid du Colombier }
728*de2caf28SDavid du Colombier oX->pc = e; LastX = X_lst;
7297dd7cddfSDavid du Colombier
7307dd7cddfSDavid du Colombier if (!interactive) Tval = 0;
731219b2ee8SDavid du Colombier memset(is_blocked, 0, 256);
732219b2ee8SDavid du Colombier
733*de2caf28SDavid du Colombier if (X_lst->pc && (X_lst->pc->status & (ATOM|L_ATOM))
734*de2caf28SDavid du Colombier && (notbeyond == 0 || oX != X_lst))
735*de2caf28SDavid du Colombier { if ((X_lst->pc->status & L_ATOM))
7367dd7cddfSDavid du Colombier notbeyond = 1;
7377dd7cddfSDavid du Colombier continue; /* no process switch */
7387dd7cddfSDavid du Colombier }
739219b2ee8SDavid du Colombier } else
740219b2ee8SDavid du Colombier { depth--;
74100d97012SDavid du Colombier if (oX->pc && (oX->pc->status & D_ATOM))
74200d97012SDavid du Colombier { non_fatal("stmnt in d_step blocks", (char *)0);
74300d97012SDavid du Colombier }
744*de2caf28SDavid du Colombier if (X_lst->pc
745*de2caf28SDavid du Colombier && X_lst->pc->n
746*de2caf28SDavid du Colombier && X_lst->pc->n->ntyp == '@'
747*de2caf28SDavid du Colombier && X_lst->pid == (nproc-nstop-1))
748*de2caf28SDavid du Colombier { if (X_lst != run_lst && Y != NULL)
749*de2caf28SDavid du Colombier Y->nxt = X_lst->nxt;
750219b2ee8SDavid du Colombier else
751*de2caf28SDavid du Colombier run_lst = X_lst->nxt;
752219b2ee8SDavid du Colombier nstop++;
753*de2caf28SDavid du Colombier Priority_Sum -= X_lst->priority;
754219b2ee8SDavid du Colombier if (verbose&4)
755219b2ee8SDavid du Colombier { whoruns(1);
7567dd7cddfSDavid du Colombier dotag(stdout, "terminates\n");
757219b2ee8SDavid du Colombier }
758*de2caf28SDavid du Colombier LastX = X_lst;
7597dd7cddfSDavid du Colombier if (!interactive) Tval = 0;
760219b2ee8SDavid du Colombier if (nproc == nstop) break;
761219b2ee8SDavid du Colombier memset(is_blocked, 0, 256);
762*de2caf28SDavid du Colombier /* proc X_lst is no longer in runlist */
763*de2caf28SDavid du Colombier X_lst = (X_lst->nxt) ? X_lst->nxt : run_lst;
764219b2ee8SDavid du Colombier } else
765*de2caf28SDavid du Colombier { if (p_blocked(X_lst->pid))
766*de2caf28SDavid du Colombier { if (Tval && !has_stdin)
767*de2caf28SDavid du Colombier { break;
768*de2caf28SDavid du Colombier }
769*de2caf28SDavid du Colombier if (!Tval && depth >= jumpsteps)
770*de2caf28SDavid du Colombier { oX = X_lst;
771*de2caf28SDavid du Colombier X_lst = (RunList *) 0; /* to suppress indent */
7727dd7cddfSDavid du Colombier dotag(stdout, "timeout\n");
773*de2caf28SDavid du Colombier X_lst = oX;
774*de2caf28SDavid du Colombier Tval = 1;
775312a1df1SDavid du Colombier } } } }
77600d97012SDavid du Colombier
777*de2caf28SDavid du Colombier if (!run_lst || !X_lst) break; /* new 5.0 */
77800d97012SDavid du Colombier
779*de2caf28SDavid du Colombier Y = pickproc(X_lst);
7807dd7cddfSDavid du Colombier notbeyond = 0;
781219b2ee8SDavid du Colombier }
782219b2ee8SDavid du Colombier context = ZS;
783219b2ee8SDavid du Colombier wrapup(0);
784219b2ee8SDavid du Colombier }
785219b2ee8SDavid du Colombier
786219b2ee8SDavid du Colombier int
complete_rendez(void)787219b2ee8SDavid du Colombier complete_rendez(void)
788*de2caf28SDavid du Colombier { RunList *orun = X_lst, *tmp;
789219b2ee8SDavid du Colombier Element *s_was = LastStep;
790219b2ee8SDavid du Colombier Element *e;
7917dd7cddfSDavid du Colombier int j, ointer = interactive;
792219b2ee8SDavid du Colombier
793219b2ee8SDavid du Colombier if (s_trail)
794219b2ee8SDavid du Colombier return 1;
7957dd7cddfSDavid du Colombier if (orun->pc->status & D_ATOM)
7967dd7cddfSDavid du Colombier fatal("rv-attempt in d_step sequence", (char *)0);
797219b2ee8SDavid du Colombier Rvous = 1;
7987dd7cddfSDavid du Colombier interactive = 0;
7997dd7cddfSDavid du Colombier
8007dd7cddfSDavid du Colombier j = (int) Rand()%Priority_Sum; /* randomize start point */
801*de2caf28SDavid du Colombier X_lst = run_lst;
802*de2caf28SDavid du Colombier while (j - X_lst->priority >= 0)
803*de2caf28SDavid du Colombier { j -= X_lst->priority;
804*de2caf28SDavid du Colombier X_lst = X_lst->nxt;
805*de2caf28SDavid du Colombier if (!X_lst) X_lst = run_lst;
8067dd7cddfSDavid du Colombier }
8077dd7cddfSDavid du Colombier for (j = nproc - nstop; j > 0; j--)
808*de2caf28SDavid du Colombier { if (X_lst != orun
809*de2caf28SDavid du Colombier && (!X_lst->prov || eval(X_lst->prov))
810*de2caf28SDavid du Colombier && (e = eval_sub(X_lst->pc)))
8117dd7cddfSDavid du Colombier { if (TstOnly)
812*de2caf28SDavid du Colombier { X_lst = orun;
8137dd7cddfSDavid du Colombier Rvous = 0;
8147dd7cddfSDavid du Colombier goto out;
8157dd7cddfSDavid du Colombier }
8167dd7cddfSDavid du Colombier if ((verbose&32) || (verbose&4))
817*de2caf28SDavid du Colombier { tmp = orun; orun = X_lst; X_lst = tmp;
818*de2caf28SDavid du Colombier if (!s_was) s_was = X_lst->pc;
819219b2ee8SDavid du Colombier p_talk(s_was, 1);
820219b2ee8SDavid du Colombier printf(" [");
821219b2ee8SDavid du Colombier comment(stdout, s_was->n, 0);
822219b2ee8SDavid du Colombier printf("]\n");
823*de2caf28SDavid du Colombier tmp = orun; /* orun = X_lst; */ X_lst = tmp;
824*de2caf28SDavid du Colombier if (!LastStep) LastStep = X_lst->pc;
825219b2ee8SDavid du Colombier p_talk(LastStep, 1);
826219b2ee8SDavid du Colombier printf(" [");
827219b2ee8SDavid du Colombier comment(stdout, LastStep->n, 0);
828219b2ee8SDavid du Colombier printf("]\n");
829219b2ee8SDavid du Colombier }
8307dd7cddfSDavid du Colombier Rvous = 0; /* before silent_moves */
831*de2caf28SDavid du Colombier X_lst->pc = silent_moves(e);
8327dd7cddfSDavid du Colombier out: interactive = ointer;
833219b2ee8SDavid du Colombier return 1;
834219b2ee8SDavid du Colombier }
8357dd7cddfSDavid du Colombier
836*de2caf28SDavid du Colombier X_lst = X_lst->nxt;
837*de2caf28SDavid du Colombier if (!X_lst) X_lst = run_lst;
8387dd7cddfSDavid du Colombier }
839219b2ee8SDavid du Colombier Rvous = 0;
840*de2caf28SDavid du Colombier X_lst = orun;
8417dd7cddfSDavid du Colombier interactive = ointer;
842219b2ee8SDavid du Colombier return 0;
843219b2ee8SDavid du Colombier }
844219b2ee8SDavid du Colombier
845219b2ee8SDavid du Colombier /***** Runtime - Local Variables *****/
846219b2ee8SDavid du Colombier
8477dd7cddfSDavid du Colombier static void
addsymbol(RunList * r,Symbol * s)848219b2ee8SDavid du Colombier addsymbol(RunList *r, Symbol *s)
849219b2ee8SDavid du Colombier { Symbol *t;
850219b2ee8SDavid du Colombier int i;
851219b2ee8SDavid du Colombier
852219b2ee8SDavid du Colombier for (t = r->symtab; t; t = t->next)
85300d97012SDavid du Colombier if (strcmp(t->name, s->name) == 0
85400d97012SDavid du Colombier && (old_scope_rules
85500d97012SDavid du Colombier || strcmp((const char *)t->bscp, (const char *)s->bscp) == 0))
856219b2ee8SDavid du Colombier return; /* it's already there */
857219b2ee8SDavid du Colombier
858219b2ee8SDavid du Colombier t = (Symbol *) emalloc(sizeof(Symbol));
859219b2ee8SDavid du Colombier t->name = s->name;
860219b2ee8SDavid du Colombier t->type = s->type;
8617dd7cddfSDavid du Colombier t->hidden = s->hidden;
862*de2caf28SDavid du Colombier t->isarray = s->isarray;
8637dd7cddfSDavid du Colombier t->nbits = s->nbits;
864219b2ee8SDavid du Colombier t->nel = s->nel;
865219b2ee8SDavid du Colombier t->ini = s->ini;
866219b2ee8SDavid du Colombier t->setat = depth;
8677dd7cddfSDavid du Colombier t->context = r->n;
86800d97012SDavid du Colombier
86900d97012SDavid du Colombier t->bscp = (unsigned char *) emalloc(strlen((const char *)s->bscp)+1);
87000d97012SDavid du Colombier strcpy((char *)t->bscp, (const char *)s->bscp);
87100d97012SDavid du Colombier
872219b2ee8SDavid du Colombier if (s->type != STRUCT)
873219b2ee8SDavid du Colombier { if (s->val) /* if already initialized, copy info */
874219b2ee8SDavid du Colombier { t->val = (int *) emalloc(s->nel*sizeof(int));
875219b2ee8SDavid du Colombier for (i = 0; i < s->nel; i++)
876219b2ee8SDavid du Colombier t->val[i] = s->val[i];
877219b2ee8SDavid du Colombier } else
87800d97012SDavid du Colombier { (void) checkvar(t, 0); /* initialize it */
87900d97012SDavid du Colombier }
880219b2ee8SDavid du Colombier } else
881219b2ee8SDavid du Colombier { if (s->Sval)
882219b2ee8SDavid du Colombier fatal("saw preinitialized struct %s", s->name);
883219b2ee8SDavid du Colombier t->Slst = s->Slst;
884219b2ee8SDavid du Colombier t->Snm = s->Snm;
885219b2ee8SDavid du Colombier t->owner = s->owner;
8867dd7cddfSDavid du Colombier /* t->context = r->n; */
887219b2ee8SDavid du Colombier }
888219b2ee8SDavid du Colombier t->next = r->symtab; /* add it */
889219b2ee8SDavid du Colombier r->symtab = t;
890219b2ee8SDavid du Colombier }
891219b2ee8SDavid du Colombier
8927dd7cddfSDavid du Colombier static void
setlocals(RunList * r)8937dd7cddfSDavid du Colombier setlocals(RunList *r)
8947dd7cddfSDavid du Colombier { Ordered *walk;
8957dd7cddfSDavid du Colombier Symbol *sp;
896*de2caf28SDavid du Colombier RunList *oX = X_lst;
8977dd7cddfSDavid du Colombier
898*de2caf28SDavid du Colombier X_lst = r;
8997dd7cddfSDavid du Colombier for (walk = all_names; walk; walk = walk->next)
9007dd7cddfSDavid du Colombier { sp = walk->entry;
9017dd7cddfSDavid du Colombier if (sp
9027dd7cddfSDavid du Colombier && sp->context
9037dd7cddfSDavid du Colombier && strcmp(sp->context->name, r->n->name) == 0
9047dd7cddfSDavid du Colombier && sp->Nid >= 0
9057dd7cddfSDavid du Colombier && (sp->type == UNSIGNED
9067dd7cddfSDavid du Colombier || sp->type == BIT
9077dd7cddfSDavid du Colombier || sp->type == MTYPE
9087dd7cddfSDavid du Colombier || sp->type == BYTE
9097dd7cddfSDavid du Colombier || sp->type == CHAN
9107dd7cddfSDavid du Colombier || sp->type == SHORT
9117dd7cddfSDavid du Colombier || sp->type == INT
9127dd7cddfSDavid du Colombier || sp->type == STRUCT))
9137dd7cddfSDavid du Colombier { if (!findloc(sp))
9147dd7cddfSDavid du Colombier non_fatal("setlocals: cannot happen '%s'",
9157dd7cddfSDavid du Colombier sp->name);
9167dd7cddfSDavid du Colombier }
9177dd7cddfSDavid du Colombier }
918*de2caf28SDavid du Colombier X_lst = oX;
9197dd7cddfSDavid du Colombier }
9207dd7cddfSDavid du Colombier
9217dd7cddfSDavid du Colombier static void
oneparam(RunList * r,Lextok * t,Lextok * a,ProcList * p)922219b2ee8SDavid du Colombier oneparam(RunList *r, Lextok *t, Lextok *a, ProcList *p)
923219b2ee8SDavid du Colombier { int k; int at, ft;
924*de2caf28SDavid du Colombier RunList *oX = X_lst;
925219b2ee8SDavid du Colombier
926219b2ee8SDavid du Colombier if (!a)
927219b2ee8SDavid du Colombier fatal("missing actual parameters: '%s'", p->n->name);
92800d97012SDavid du Colombier if (t->sym->nel > 1 || t->sym->isarray)
929219b2ee8SDavid du Colombier fatal("array in parameter list, %s", t->sym->name);
930219b2ee8SDavid du Colombier k = eval(a->lft);
931219b2ee8SDavid du Colombier
932219b2ee8SDavid du Colombier at = Sym_typ(a->lft);
933*de2caf28SDavid du Colombier X_lst = r; /* switch context */
934219b2ee8SDavid du Colombier ft = Sym_typ(t);
935219b2ee8SDavid du Colombier
936219b2ee8SDavid du Colombier if (at != ft && (at == CHAN || ft == CHAN))
93700d97012SDavid du Colombier { char buf[256], tag1[64], tag2[64];
938219b2ee8SDavid du Colombier (void) sputtype(tag1, ft);
939219b2ee8SDavid du Colombier (void) sputtype(tag2, at);
9407dd7cddfSDavid du Colombier sprintf(buf, "type-clash in params of %s(..), (%s<-> %s)",
941219b2ee8SDavid du Colombier p->n->name, tag1, tag2);
942219b2ee8SDavid du Colombier non_fatal("%s", buf);
943219b2ee8SDavid du Colombier }
944219b2ee8SDavid du Colombier t->ntyp = NAME;
945219b2ee8SDavid du Colombier addsymbol(r, t->sym);
946219b2ee8SDavid du Colombier (void) setval(t, k);
947219b2ee8SDavid du Colombier
948*de2caf28SDavid du Colombier X_lst = oX;
949219b2ee8SDavid du Colombier }
950219b2ee8SDavid du Colombier
9517dd7cddfSDavid du Colombier static void
setparams(RunList * r,ProcList * p,Lextok * q)952219b2ee8SDavid du Colombier setparams(RunList *r, ProcList *p, Lextok *q)
953219b2ee8SDavid du Colombier { Lextok *f, *a; /* formal and actual pars */
954219b2ee8SDavid du Colombier Lextok *t; /* list of pars of 1 type */
955219b2ee8SDavid du Colombier
956219b2ee8SDavid du Colombier if (q)
957219b2ee8SDavid du Colombier { lineno = q->ln;
958219b2ee8SDavid du Colombier Fname = q->fn;
959219b2ee8SDavid du Colombier }
960219b2ee8SDavid du Colombier for (f = p->p, a = q; f; f = f->rgt) /* one type at a time */
961219b2ee8SDavid du Colombier for (t = f->lft; t; t = t->rgt, a = (a)?a->rgt:a)
962219b2ee8SDavid du Colombier { if (t->ntyp != ',')
963219b2ee8SDavid du Colombier oneparam(r, t, a, p); /* plain var */
964219b2ee8SDavid du Colombier else
9657dd7cddfSDavid du Colombier oneparam(r, t->lft, a, p); /* expanded struct */
966219b2ee8SDavid du Colombier }
967219b2ee8SDavid du Colombier }
968219b2ee8SDavid du Colombier
969219b2ee8SDavid du Colombier Symbol *
findloc(Symbol * s)970219b2ee8SDavid du Colombier findloc(Symbol *s)
971219b2ee8SDavid du Colombier { Symbol *r;
972219b2ee8SDavid du Colombier
973*de2caf28SDavid du Colombier if (!X_lst)
974219b2ee8SDavid du Colombier { /* fatal("error, cannot eval '%s' (no proc)", s->name); */
975219b2ee8SDavid du Colombier return ZS;
976219b2ee8SDavid du Colombier }
977*de2caf28SDavid du Colombier for (r = X_lst->symtab; r; r = r->next)
978*de2caf28SDavid du Colombier { if (strcmp(r->name, s->name) == 0
979*de2caf28SDavid du Colombier && (old_scope_rules
980*de2caf28SDavid du Colombier || strcmp((const char *)r->bscp, (const char *)s->bscp) == 0))
981*de2caf28SDavid du Colombier { break;
982*de2caf28SDavid du Colombier } }
983219b2ee8SDavid du Colombier if (!r)
984*de2caf28SDavid du Colombier { addsymbol(X_lst, s);
985*de2caf28SDavid du Colombier r = X_lst->symtab;
986219b2ee8SDavid du Colombier }
987219b2ee8SDavid du Colombier return r;
988219b2ee8SDavid du Colombier }
989219b2ee8SDavid du Colombier
990219b2ee8SDavid du Colombier int
in_bound(Symbol * r,int n)991312a1df1SDavid du Colombier in_bound(Symbol *r, int n)
992312a1df1SDavid du Colombier {
993312a1df1SDavid du Colombier if (!r) return 0;
994312a1df1SDavid du Colombier
995312a1df1SDavid du Colombier if (n >= r->nel || n < 0)
996312a1df1SDavid du Colombier { printf("spin: indexing %s[%d] - size is %d\n",
997312a1df1SDavid du Colombier r->name, n, r->nel);
998312a1df1SDavid du Colombier non_fatal("indexing array \'%s\'", r->name);
999312a1df1SDavid du Colombier return 0;
1000312a1df1SDavid du Colombier }
1001312a1df1SDavid du Colombier return 1;
1002312a1df1SDavid du Colombier }
1003312a1df1SDavid du Colombier
1004312a1df1SDavid du Colombier int
getlocal(Lextok * sn)1005219b2ee8SDavid du Colombier getlocal(Lextok *sn)
1006219b2ee8SDavid du Colombier { Symbol *r, *s = sn->sym;
1007219b2ee8SDavid du Colombier int n = eval(sn->lft);
1008219b2ee8SDavid du Colombier
1009219b2ee8SDavid du Colombier r = findloc(s);
1010219b2ee8SDavid du Colombier if (r && r->type == STRUCT)
1011219b2ee8SDavid du Colombier return Rval_struct(sn, r, 1); /* 1 = check init */
1012312a1df1SDavid du Colombier if (in_bound(r, n))
1013312a1df1SDavid du Colombier return cast_val(r->type, r->val[n], r->nbits);
1014219b2ee8SDavid du Colombier return 0;
1015219b2ee8SDavid du Colombier }
1016219b2ee8SDavid du Colombier
1017219b2ee8SDavid du Colombier int
setlocal(Lextok * p,int m)1018219b2ee8SDavid du Colombier setlocal(Lextok *p, int m)
1019219b2ee8SDavid du Colombier { Symbol *r = findloc(p->sym);
1020219b2ee8SDavid du Colombier int n = eval(p->lft);
1021219b2ee8SDavid du Colombier
1022312a1df1SDavid du Colombier if (in_bound(r, n))
1023219b2ee8SDavid du Colombier { if (r->type == STRUCT)
1024219b2ee8SDavid du Colombier (void) Lval_struct(p, r, 1, m); /* 1 = check init */
1025219b2ee8SDavid du Colombier else
1026312a1df1SDavid du Colombier {
1027312a1df1SDavid du Colombier #if 0
1028312a1df1SDavid du Colombier if (r->nbits > 0)
10297dd7cddfSDavid du Colombier m = (m & ((1<<r->nbits)-1));
10307dd7cddfSDavid du Colombier r->val[n] = m;
1031312a1df1SDavid du Colombier #else
1032312a1df1SDavid du Colombier r->val[n] = cast_val(r->type, m, r->nbits);
1033312a1df1SDavid du Colombier #endif
1034219b2ee8SDavid du Colombier r->setat = depth;
1035219b2ee8SDavid du Colombier } }
1036219b2ee8SDavid du Colombier
1037219b2ee8SDavid du Colombier return 1;
1038219b2ee8SDavid du Colombier }
1039219b2ee8SDavid du Colombier
1040219b2ee8SDavid du Colombier void
whoruns(int lnr)1041219b2ee8SDavid du Colombier whoruns(int lnr)
1042*de2caf28SDavid du Colombier { if (!X_lst) return;
1043219b2ee8SDavid du Colombier
1044219b2ee8SDavid du Colombier if (lnr) printf("%3d: ", depth);
1045219b2ee8SDavid du Colombier printf("proc ");
1046*de2caf28SDavid du Colombier if (Have_claim && X_lst->pid == 0)
1047219b2ee8SDavid du Colombier printf(" -");
1048219b2ee8SDavid du Colombier else
1049*de2caf28SDavid du Colombier printf("%2d", X_lst->pid - Have_claim);
1050*de2caf28SDavid du Colombier if (old_priority_rules)
1051*de2caf28SDavid du Colombier { printf(" (%s) ", X_lst->n->name);
1052*de2caf28SDavid du Colombier } else
1053*de2caf28SDavid du Colombier { printf(" (%s:%d) ", X_lst->n->name, X_lst->priority);
1054*de2caf28SDavid du Colombier }
1055219b2ee8SDavid du Colombier }
1056219b2ee8SDavid du Colombier
10577dd7cddfSDavid du Colombier static void
talk(RunList * r)1058219b2ee8SDavid du Colombier talk(RunList *r)
1059219b2ee8SDavid du Colombier {
10607dd7cddfSDavid du Colombier if ((verbose&32) || (verbose&4))
1061219b2ee8SDavid du Colombier { p_talk(r->pc, 1);
1062219b2ee8SDavid du Colombier printf("\n");
1063219b2ee8SDavid du Colombier if (verbose&1) dumpglobals();
1064*de2caf28SDavid du Colombier if (verbose&2) dumplocal(r, 1);
1065219b2ee8SDavid du Colombier }
1066219b2ee8SDavid du Colombier }
1067219b2ee8SDavid du Colombier
1068219b2ee8SDavid du Colombier void
p_talk(Element * e,int lnr)1069219b2ee8SDavid du Colombier p_talk(Element *e, int lnr)
10707dd7cddfSDavid du Colombier { static int lastnever = -1;
107100d97012SDavid du Colombier static char nbuf[128];
10727dd7cddfSDavid du Colombier int newnever = -1;
10737dd7cddfSDavid du Colombier
10747dd7cddfSDavid du Colombier if (e && e->n)
10757dd7cddfSDavid du Colombier newnever = e->n->ln;
10767dd7cddfSDavid du Colombier
1077*de2caf28SDavid du Colombier if (Have_claim && X_lst && X_lst->pid == 0
10787dd7cddfSDavid du Colombier && lastnever != newnever && e)
10797dd7cddfSDavid du Colombier { if (xspin)
10807dd7cddfSDavid du Colombier { printf("MSC: ~G line %d\n", newnever);
1081312a1df1SDavid du Colombier #if 0
1082312a1df1SDavid du Colombier printf("%3d: proc - (NEVER) line %d \"never\" ",
10837dd7cddfSDavid du Colombier depth, newnever);
10847dd7cddfSDavid du Colombier printf("(state 0)\t[printf('MSC: never\\\\n')]\n");
10857dd7cddfSDavid du Colombier } else
1086312a1df1SDavid du Colombier { printf("%3d: proc - (NEVER) line %d \"never\"\n",
10877dd7cddfSDavid du Colombier depth, newnever);
1088312a1df1SDavid du Colombier #endif
10897dd7cddfSDavid du Colombier }
10907dd7cddfSDavid du Colombier lastnever = newnever;
10917dd7cddfSDavid du Colombier }
10927dd7cddfSDavid du Colombier
1093219b2ee8SDavid du Colombier whoruns(lnr);
1094219b2ee8SDavid du Colombier if (e)
109500d97012SDavid du Colombier { if (e->n)
109600d97012SDavid du Colombier { char *ptr = e->n->fn->name;
109700d97012SDavid du Colombier char *qtr = nbuf;
109800d97012SDavid du Colombier while (*ptr != '\0')
109900d97012SDavid du Colombier { if (*ptr != '"')
110000d97012SDavid du Colombier { *qtr++ = *ptr;
110100d97012SDavid du Colombier }
110200d97012SDavid du Colombier ptr++;
110300d97012SDavid du Colombier }
110400d97012SDavid du Colombier *qtr = '\0';
110500d97012SDavid du Colombier } else
110600d97012SDavid du Colombier { strcpy(nbuf, "-");
110700d97012SDavid du Colombier }
110800d97012SDavid du Colombier printf("%s:%d (state %d)",
110900d97012SDavid du Colombier nbuf,
1110219b2ee8SDavid du Colombier e->n?e->n->ln:-1,
1111219b2ee8SDavid du Colombier e->seqno);
11127dd7cddfSDavid du Colombier if (!xspin
11137dd7cddfSDavid du Colombier && ((e->status&ENDSTATE) || has_lab(e, 2))) /* 2=end */
11147dd7cddfSDavid du Colombier { printf(" <valid end state>");
11157dd7cddfSDavid du Colombier }
11167dd7cddfSDavid du Colombier }
1117219b2ee8SDavid du Colombier }
1118219b2ee8SDavid du Colombier
1119219b2ee8SDavid du Colombier int
remotelab(Lextok * n)1120219b2ee8SDavid du Colombier remotelab(Lextok *n)
1121219b2ee8SDavid du Colombier { int i;
1122219b2ee8SDavid du Colombier
1123219b2ee8SDavid du Colombier lineno = n->ln;
1124219b2ee8SDavid du Colombier Fname = n->fn;
1125312a1df1SDavid du Colombier if (n->sym->type != 0 && n->sym->type != LABEL)
1126312a1df1SDavid du Colombier { printf("spin: error, type: %d\n", n->sym->type);
1127219b2ee8SDavid du Colombier fatal("not a labelname: '%s'", n->sym->name);
1128312a1df1SDavid du Colombier }
11297dd7cddfSDavid du Colombier if (n->indstep >= 0)
11307dd7cddfSDavid du Colombier { fatal("remote ref to label '%s' inside d_step",
11317dd7cddfSDavid du Colombier n->sym->name);
11327dd7cddfSDavid du Colombier }
1133*de2caf28SDavid du Colombier if ((i = find_lab(n->sym, n->lft->sym, 1)) == 0) /* remotelab */
1134*de2caf28SDavid du Colombier { fatal("unknown labelname: %s", n->sym->name);
1135*de2caf28SDavid du Colombier }
1136219b2ee8SDavid du Colombier return i;
1137219b2ee8SDavid du Colombier }
1138219b2ee8SDavid du Colombier
1139219b2ee8SDavid du Colombier int
remotevar(Lextok * n)1140219b2ee8SDavid du Colombier remotevar(Lextok *n)
1141312a1df1SDavid du Colombier { int prno, i, added=0;
1142312a1df1SDavid du Colombier RunList *Y, *oX;
1143312a1df1SDavid du Colombier Lextok *onl;
1144312a1df1SDavid du Colombier Symbol *os;
1145219b2ee8SDavid du Colombier
1146219b2ee8SDavid du Colombier lineno = n->ln;
1147219b2ee8SDavid du Colombier Fname = n->fn;
1148219b2ee8SDavid du Colombier
1149312a1df1SDavid du Colombier if (!n->lft->lft)
1150312a1df1SDavid du Colombier prno = f_pid(n->lft->sym->name);
1151312a1df1SDavid du Colombier else
1152312a1df1SDavid du Colombier { prno = eval(n->lft->lft); /* pid - can cause recursive call */
1153312a1df1SDavid du Colombier #if 0
1154312a1df1SDavid du Colombier if (n->lft->lft->ntyp == CONST) /* user-guessed pid */
1155312a1df1SDavid du Colombier #endif
1156312a1df1SDavid du Colombier { prno += Have_claim;
1157312a1df1SDavid du Colombier added = Have_claim;
1158312a1df1SDavid du Colombier } }
1159312a1df1SDavid du Colombier
1160312a1df1SDavid du Colombier if (prno < 0)
1161*de2caf28SDavid du Colombier { return 0; /* non-existing process */
1162*de2caf28SDavid du Colombier }
1163312a1df1SDavid du Colombier #if 0
1164312a1df1SDavid du Colombier i = nproc - nstop;
1165*de2caf28SDavid du Colombier for (Y = run_lst; Y; Y = Y->nxt)
1166312a1df1SDavid du Colombier { --i;
1167312a1df1SDavid du Colombier printf(" %s: i=%d, prno=%d, ->pid=%d\n", Y->n->name, i, prno, Y->pid);
1168312a1df1SDavid du Colombier }
1169312a1df1SDavid du Colombier #endif
117000d97012SDavid du Colombier i = nproc - nstop + Skip_claim; /* 6.0: added Skip_claim */
1171*de2caf28SDavid du Colombier for (Y = run_lst; Y; Y = Y->nxt)
11727dd7cddfSDavid du Colombier if (--i == prno)
1173219b2ee8SDavid du Colombier { if (strcmp(Y->n->name, n->lft->sym->name) != 0)
1174312a1df1SDavid du Colombier { printf("spin: remote reference error on '%s[%d]'\n",
1175312a1df1SDavid du Colombier n->lft->sym->name, prno-added);
11767dd7cddfSDavid du Colombier non_fatal("refers to wrong proctype '%s'", Y->n->name);
1177219b2ee8SDavid du Colombier }
1178219b2ee8SDavid du Colombier if (strcmp(n->sym->name, "_p") == 0)
11797dd7cddfSDavid du Colombier { if (Y->pc)
1180*de2caf28SDavid du Colombier { return Y->pc->seqno;
1181*de2caf28SDavid du Colombier }
11827dd7cddfSDavid du Colombier /* harmless, can only happen with -t */
11837dd7cddfSDavid du Colombier return 0;
11847dd7cddfSDavid du Colombier }
1185*de2caf28SDavid du Colombier
1186*de2caf28SDavid du Colombier /* check remote variables */
1187*de2caf28SDavid du Colombier oX = X_lst;
1188*de2caf28SDavid du Colombier X_lst = Y;
1189312a1df1SDavid du Colombier
1190312a1df1SDavid du Colombier onl = n->lft;
1191312a1df1SDavid du Colombier n->lft = n->rgt;
1192312a1df1SDavid du Colombier
1193312a1df1SDavid du Colombier os = n->sym;
1194*de2caf28SDavid du Colombier if (!n->sym->context)
1195*de2caf28SDavid du Colombier { n->sym->context = Y->n;
1196*de2caf28SDavid du Colombier }
1197*de2caf28SDavid du Colombier { int rs = old_scope_rules;
1198*de2caf28SDavid du Colombier old_scope_rules = 1; /* 6.4.0 */
1199312a1df1SDavid du Colombier n->sym = findloc(n->sym);
1200*de2caf28SDavid du Colombier old_scope_rules = rs;
1201*de2caf28SDavid du Colombier }
1202312a1df1SDavid du Colombier i = getval(n);
1203312a1df1SDavid du Colombier
1204312a1df1SDavid du Colombier n->sym = os;
1205312a1df1SDavid du Colombier n->lft = onl;
1206*de2caf28SDavid du Colombier X_lst = oX;
1207312a1df1SDavid du Colombier return i;
1208219b2ee8SDavid du Colombier }
1209312a1df1SDavid du Colombier printf("remote ref: %s[%d] ", n->lft->sym->name, prno-added);
1210219b2ee8SDavid du Colombier non_fatal("%s not found", n->sym->name);
12117dd7cddfSDavid du Colombier printf("have only:\n");
12127dd7cddfSDavid du Colombier i = nproc - nstop - 1;
1213*de2caf28SDavid du Colombier for (Y = run_lst; Y; Y = Y->nxt, i--)
12147dd7cddfSDavid du Colombier if (!strcmp(Y->n->name, n->lft->sym->name))
12157dd7cddfSDavid du Colombier printf("\t%d\t%s\n", i, Y->n->name);
1216219b2ee8SDavid du Colombier
1217219b2ee8SDavid du Colombier return 0;
1218219b2ee8SDavid du Colombier }
1219