xref: /plan9/sys/src/cmd/spin/sched.c (revision 00d970127b9d44d2b22f4f656717a212dec1f1d2)
1219b2ee8SDavid du Colombier /***** spin: sched.c *****/
2219b2ee8SDavid du Colombier 
3312a1df1SDavid du Colombier /* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories.     */
47dd7cddfSDavid du Colombier /* All Rights Reserved.  This software is for educational purposes only.  */
5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6312a1df1SDavid du Colombier /* this code.  Permission is given to distribute this code provided that  */
7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged.  */
8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann.  For tool documentation see:   */
9312a1df1SDavid du Colombier /*             http://spinroot.com/                                       */
10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com            */
11219b2ee8SDavid du Colombier 
127dd7cddfSDavid du Colombier #include <stdlib.h>
13219b2ee8SDavid du Colombier #include "spin.h"
14219b2ee8SDavid du Colombier #include "y.tab.h"
15219b2ee8SDavid du Colombier 
167dd7cddfSDavid du Colombier extern int	verbose, s_trail, analyze, no_wrapup;
177dd7cddfSDavid du Colombier extern char	*claimproc, *eventmap, Buf[];
187dd7cddfSDavid du Colombier extern Ordered	*all_names;
19219b2ee8SDavid du Colombier extern Symbol	*Fname, *context;
207dd7cddfSDavid du Colombier extern int	lineno, nr_errs, dumptab, xspin, jumpsteps, columns;
21312a1df1SDavid du Colombier extern int	u_sync, Elcnt, interactive, TstOnly, cutoff;
22312a1df1SDavid du Colombier extern short	has_enabled;
23*00d97012SDavid du Colombier extern int	limited_vis, old_scope_rules, product, nclaims;
24219b2ee8SDavid du Colombier 
25219b2ee8SDavid du Colombier RunList		*X   = (RunList  *) 0;
26219b2ee8SDavid du Colombier RunList		*run = (RunList  *) 0;
27219b2ee8SDavid du Colombier RunList		*LastX  = (RunList  *) 0; /* previous executing proc */
28219b2ee8SDavid du Colombier ProcList	*rdy = (ProcList *) 0;
29219b2ee8SDavid du Colombier Element		*LastStep = ZE;
307dd7cddfSDavid du Colombier int		nproc=0, nstop=0, Tval=0;
317dd7cddfSDavid du Colombier int		Rvous=0, depth=0, nrRdy=0, MadeChoice;
327dd7cddfSDavid du Colombier short		Have_claim=0, Skip_claim=0;
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier static int	Priority_Sum = 0;
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 
39219b2ee8SDavid du Colombier void
runnable(ProcList * p,int weight,int noparams)407dd7cddfSDavid du Colombier runnable(ProcList *p, int weight, int noparams)
41219b2ee8SDavid du Colombier {	RunList *r = (RunList *) emalloc(sizeof(RunList));
42219b2ee8SDavid du Colombier 
43219b2ee8SDavid du Colombier 	r->n  = p->n;
44219b2ee8SDavid du Colombier 	r->tn = p->tn;
45*00d97012SDavid du Colombier 	r->b  = p->b;
46312a1df1SDavid du Colombier 	r->pid = nproc++ - nstop + Skip_claim;
47312a1df1SDavid du Colombier 
48*00d97012SDavid du Colombier 	if (!noparams && ((verbose&4) || (verbose&32)))
49*00d97012SDavid du Colombier 		printf("Starting %s with pid %d\n",
50*00d97012SDavid du Colombier 			p->n?p->n->name:"--", r->pid);
51312a1df1SDavid du Colombier 
52312a1df1SDavid du Colombier 	if (!p->s)
53*00d97012SDavid du Colombier 		fatal("parsing error, no sequence %s",
54*00d97012SDavid du Colombier 			p->n?p->n->name:"--");
55312a1df1SDavid du Colombier 
56312a1df1SDavid du Colombier 	r->pc = huntele(p->s->frst, p->s->frst->status, -1);
577dd7cddfSDavid du Colombier 	r->ps = p->s;
58312a1df1SDavid du Colombier 
59312a1df1SDavid du Colombier 	if (p->s->last)
607dd7cddfSDavid du Colombier 		p->s->last->status |= ENDSTATE; /* normal end state */
61312a1df1SDavid du Colombier 
62219b2ee8SDavid du Colombier 	r->nxt = run;
637dd7cddfSDavid du Colombier 	r->prov = p->prov;
647dd7cddfSDavid du Colombier 	r->priority = weight;
65*00d97012SDavid du Colombier 
667dd7cddfSDavid du Colombier 	if (noparams) setlocals(r);
677dd7cddfSDavid du Colombier 	Priority_Sum += weight;
68*00d97012SDavid du Colombier 
69219b2ee8SDavid du Colombier 	run = r;
70219b2ee8SDavid du Colombier }
71219b2ee8SDavid du Colombier 
72219b2ee8SDavid du Colombier ProcList *
ready(Symbol * n,Lextok * p,Sequence * s,int det,Lextok * prov,enum btypes b)73*00d97012SDavid du Colombier ready(Symbol *n, Lextok *p, Sequence *s, int det, Lextok *prov, enum btypes b)
747dd7cddfSDavid du Colombier 	/* n=name, p=formals, s=body det=deterministic prov=provided */
75219b2ee8SDavid du Colombier {	ProcList *r = (ProcList *) emalloc(sizeof(ProcList));
76219b2ee8SDavid du Colombier 	Lextok *fp, *fpt; int j; extern int Npars;
77219b2ee8SDavid du Colombier 
78219b2ee8SDavid du Colombier 	r->n = n;
79219b2ee8SDavid du Colombier 	r->p = p;
80219b2ee8SDavid du Colombier 	r->s = s;
81*00d97012SDavid du Colombier 	r->b = b;
827dd7cddfSDavid du Colombier 	r->prov = prov;
83219b2ee8SDavid du Colombier 	r->tn = nrRdy++;
84*00d97012SDavid du Colombier 	if (det != 0 && det != 1)
85*00d97012SDavid du Colombier 	{	fprintf(stderr, "spin: bad value for det (cannot happen)\n");
86*00d97012SDavid du Colombier 	}
877dd7cddfSDavid du Colombier 	r->det = (short) det;
88219b2ee8SDavid du Colombier 	r->nxt = rdy;
89219b2ee8SDavid du Colombier 	rdy = r;
90219b2ee8SDavid du Colombier 
91219b2ee8SDavid du Colombier 	for (fp  = p, j = 0;  fp;  fp = fp->rgt)
92219b2ee8SDavid du Colombier 	for (fpt = fp->lft;  fpt; fpt = fpt->rgt)
93219b2ee8SDavid du Colombier 		j++;	/* count # of parameters */
94219b2ee8SDavid du Colombier 	Npars = max(Npars, j);
95219b2ee8SDavid du Colombier 
96219b2ee8SDavid du Colombier 	return rdy;
97219b2ee8SDavid du Colombier }
98219b2ee8SDavid du Colombier 
99219b2ee8SDavid du Colombier int
find_maxel(Symbol * s)100219b2ee8SDavid du Colombier find_maxel(Symbol *s)
101219b2ee8SDavid du Colombier {	ProcList *p;
102219b2ee8SDavid du Colombier 
103219b2ee8SDavid du Colombier 	for (p = rdy; p; p = p->nxt)
104219b2ee8SDavid du Colombier 		if (p->n == s)
105219b2ee8SDavid du Colombier 			return p->s->maxel++;
106219b2ee8SDavid du Colombier 	return Elcnt++;
107219b2ee8SDavid du Colombier }
108219b2ee8SDavid du Colombier 
1097dd7cddfSDavid du Colombier static void
formdump(void)110219b2ee8SDavid du Colombier formdump(void)
111219b2ee8SDavid du Colombier {	ProcList *p;
112219b2ee8SDavid du Colombier 	Lextok *f, *t;
113219b2ee8SDavid du Colombier 	int cnt;
114219b2ee8SDavid du Colombier 
115219b2ee8SDavid du Colombier 	for (p = rdy; p; p = p->nxt)
116219b2ee8SDavid du Colombier 	{	if (!p->p) continue;
117219b2ee8SDavid du Colombier 		cnt = -1;
118219b2ee8SDavid du Colombier 		for (f = p->p; f; f = f->rgt)	/* types */
119219b2ee8SDavid du Colombier 		for (t = f->lft; t; t = t->rgt)	/* formals */
120219b2ee8SDavid du Colombier 		{	if (t->ntyp != ',')
121219b2ee8SDavid du Colombier 				t->sym->Nid = cnt--;	/* overload Nid */
122219b2ee8SDavid du Colombier 			else
123219b2ee8SDavid du Colombier 				t->lft->sym->Nid = cnt--;
124219b2ee8SDavid du Colombier 		}
125219b2ee8SDavid du Colombier 	}
126219b2ee8SDavid du Colombier }
127219b2ee8SDavid du Colombier 
1287dd7cddfSDavid du Colombier void
announce(char * w)1297dd7cddfSDavid du Colombier announce(char *w)
1307dd7cddfSDavid du Colombier {
1317dd7cddfSDavid du Colombier 	if (columns)
1327dd7cddfSDavid du Colombier 	{	extern char Buf[];
1337dd7cddfSDavid du Colombier 		extern int firstrow;
1347dd7cddfSDavid du Colombier 		firstrow = 1;
1357dd7cddfSDavid du Colombier 		if (columns == 2)
1367dd7cddfSDavid du Colombier 		{	sprintf(Buf, "%d:%s",
137312a1df1SDavid du Colombier 			run->pid - Have_claim, run->n->name);
138312a1df1SDavid du Colombier 			pstext(run->pid - Have_claim, Buf);
1397dd7cddfSDavid du Colombier 		} else
1407dd7cddfSDavid du Colombier 			printf("proc %d = %s\n",
1417dd7cddfSDavid du Colombier 			run->pid - Have_claim, run->n->name);
1427dd7cddfSDavid du Colombier 		return;
1437dd7cddfSDavid du Colombier 	}
144312a1df1SDavid du Colombier 
1457dd7cddfSDavid du Colombier 	if (dumptab
1467dd7cddfSDavid du Colombier 	||  analyze
147*00d97012SDavid du Colombier 	||  product
1487dd7cddfSDavid du Colombier 	||  s_trail
1497dd7cddfSDavid du Colombier 	|| !(verbose&4))
1507dd7cddfSDavid du Colombier 		return;
151312a1df1SDavid du Colombier 
1527dd7cddfSDavid du Colombier 	if (w)
1537dd7cddfSDavid du Colombier 		printf("  0:	proc  - (%s) ", w);
1547dd7cddfSDavid du Colombier 	else
1557dd7cddfSDavid du Colombier 		whoruns(1);
1567dd7cddfSDavid du Colombier 	printf("creates proc %2d (%s)",
1577dd7cddfSDavid du Colombier 		run->pid - Have_claim,
1587dd7cddfSDavid du Colombier 		run->n->name);
1597dd7cddfSDavid du Colombier 	if (run->priority > 1)
1607dd7cddfSDavid du Colombier 		printf(" priority %d", run->priority);
1617dd7cddfSDavid du Colombier 	printf("\n");
1627dd7cddfSDavid du Colombier }
163219b2ee8SDavid du Colombier 
164312a1df1SDavid du Colombier #ifndef MAXP
165312a1df1SDavid du Colombier #define MAXP	255	/* matches max nr of processes in verifier */
166312a1df1SDavid du Colombier #endif
167312a1df1SDavid du Colombier 
1687dd7cddfSDavid du Colombier int
enable(Lextok * m)1697dd7cddfSDavid du Colombier enable(Lextok *m)
1707dd7cddfSDavid du Colombier {	ProcList *p;
1717dd7cddfSDavid du Colombier 	Symbol *s = m->sym;	/* proctype name */
1727dd7cddfSDavid du Colombier 	Lextok *n = m->lft;	/* actual parameters */
1737dd7cddfSDavid du Colombier 
1747dd7cddfSDavid du Colombier 	if (m->val < 1) m->val = 1;	/* minimum priority */
175219b2ee8SDavid du Colombier 	for (p = rdy; p; p = p->nxt)
176219b2ee8SDavid du Colombier 		if (strcmp(s->name, p->n->name) == 0)
177312a1df1SDavid du Colombier 		{	if (nproc-nstop >= MAXP)
178312a1df1SDavid du Colombier 			{	printf("spin: too many processes (%d max)\n", MAXP);
179312a1df1SDavid du Colombier 				break;
180312a1df1SDavid du Colombier 			}
181312a1df1SDavid du Colombier 			runnable(p, m->val, 0);
1827dd7cddfSDavid du Colombier 			announce((char *) 0);
183219b2ee8SDavid du Colombier 			setparams(run, p, n);
1847dd7cddfSDavid du Colombier 			setlocals(run); /* after setparams */
185312a1df1SDavid du Colombier 			return run->pid - Have_claim + Skip_claim; /* effective simu pid */
186219b2ee8SDavid du Colombier 		}
187219b2ee8SDavid du Colombier 	return 0; /* process not found */
188219b2ee8SDavid du Colombier }
189219b2ee8SDavid du Colombier 
190219b2ee8SDavid du Colombier void
check_param_count(int i,Lextok * m)191f3793cddSDavid du Colombier check_param_count(int i, Lextok *m)
192f3793cddSDavid du Colombier {	ProcList *p;
193f3793cddSDavid du Colombier 	Symbol *s = m->sym;	/* proctype name */
194f3793cddSDavid du Colombier 	Lextok *f, *t;		/* formal pars */
195f3793cddSDavid du Colombier 	int cnt = 0;
196f3793cddSDavid du Colombier 
197f3793cddSDavid du Colombier 	for (p = rdy; p; p = p->nxt)
198f3793cddSDavid du Colombier 	{	if (strcmp(s->name, p->n->name) == 0)
199f3793cddSDavid du Colombier 		{	if (m->lft)	/* actual param list */
200f3793cddSDavid du Colombier 			{	lineno = m->lft->ln;
201f3793cddSDavid du Colombier 				Fname  = m->lft->fn;
202f3793cddSDavid du Colombier 			}
203f3793cddSDavid du Colombier 			for (f = p->p;   f; f = f->rgt) /* one type at a time */
204f3793cddSDavid du Colombier 			for (t = f->lft; t; t = t->rgt)	/* count formal params */
205f3793cddSDavid du Colombier 			{	cnt++;
206f3793cddSDavid du Colombier 			}
207f3793cddSDavid du Colombier 			if (i != cnt)
208f3793cddSDavid du Colombier 			{	printf("spin: saw %d parameters, expected %d\n", i, cnt);
209f3793cddSDavid du Colombier 				non_fatal("wrong number of parameters", "");
210f3793cddSDavid du Colombier 			}
211f3793cddSDavid du Colombier 			break;
212f3793cddSDavid du Colombier 	}	}
213f3793cddSDavid du Colombier }
214f3793cddSDavid du Colombier 
215f3793cddSDavid du Colombier void
start_claim(int n)216219b2ee8SDavid du Colombier start_claim(int n)
217219b2ee8SDavid du Colombier {	ProcList *p;
2187dd7cddfSDavid du Colombier 	RunList  *r, *q = (RunList *) 0;
219219b2ee8SDavid du Colombier 
220219b2ee8SDavid du Colombier 	for (p = rdy; p; p = p->nxt)
221*00d97012SDavid du Colombier 		if (p->tn == n && p->b == N_CLAIM)
2227dd7cddfSDavid du Colombier 		{	runnable(p, 1, 1);
2237dd7cddfSDavid du Colombier 			goto found;
224219b2ee8SDavid du Colombier 		}
225*00d97012SDavid du Colombier 	printf("spin: couldn't find claim %d (ignored)\n", n);
226*00d97012SDavid du Colombier 	if (verbose&32)
227*00d97012SDavid du Colombier 	for (p = rdy; p; p = p->nxt)
228*00d97012SDavid du Colombier 		printf("\t%d = %s\n", p->tn, p->n->name);
229*00d97012SDavid du Colombier 
2307dd7cddfSDavid du Colombier 	Skip_claim = 1;
2317dd7cddfSDavid du Colombier 	goto done;
2327dd7cddfSDavid du Colombier found:
233312a1df1SDavid du Colombier 	/* move claim to far end of runlist, and reassign it pid 0 */
2347dd7cddfSDavid du Colombier 	if (columns == 2)
235*00d97012SDavid du Colombier 	{	extern char Buf[];
236*00d97012SDavid du Colombier 		depth = 0;
237*00d97012SDavid du Colombier 		sprintf(Buf, "%d:%s", 0, p->n->name);
238*00d97012SDavid du Colombier 		pstext(0, Buf);
2397dd7cddfSDavid du Colombier 		for (r = run; r; r = r->nxt)
240*00d97012SDavid du Colombier 		{	if (r->b != N_CLAIM)
241*00d97012SDavid du Colombier 			{	sprintf(Buf, "%d:%s", r->pid+1, r->n->name);
2427dd7cddfSDavid du Colombier 				pstext(r->pid+1, Buf);
243*00d97012SDavid du Colombier 	}	}	}
244312a1df1SDavid du Colombier 
245312a1df1SDavid du Colombier 	if (run->pid == 0) return; /* it is the first process started */
2467dd7cddfSDavid du Colombier 
2477dd7cddfSDavid du Colombier 	q = run; run = run->nxt;
248312a1df1SDavid du Colombier 	q->pid = 0; q->nxt = (RunList *) 0;	/* remove */
2497dd7cddfSDavid du Colombier done:
250312a1df1SDavid du Colombier 	Have_claim = 1;
2517dd7cddfSDavid du Colombier 	for (r = run; r; r = r->nxt)
252312a1df1SDavid du Colombier 	{	r->pid = r->pid+Have_claim;	/* adjust */
2537dd7cddfSDavid du Colombier 		if (!r->nxt)
2547dd7cddfSDavid du Colombier 		{	r->nxt = q;
2557dd7cddfSDavid du Colombier 			break;
2567dd7cddfSDavid du Colombier 	}	}
257312a1df1SDavid du Colombier }
258312a1df1SDavid du Colombier 
259312a1df1SDavid du Colombier int
f_pid(char * n)260312a1df1SDavid du Colombier f_pid(char *n)
261312a1df1SDavid du Colombier {	RunList *r;
262312a1df1SDavid du Colombier 	int rval = -1;
263312a1df1SDavid du Colombier 
264312a1df1SDavid du Colombier 	for (r = run; r; r = r->nxt)
265312a1df1SDavid du Colombier 		if (strcmp(n, r->n->name) == 0)
266312a1df1SDavid du Colombier 		{	if (rval >= 0)
267312a1df1SDavid du Colombier 			{	printf("spin: remote ref to proctype %s, ", n);
268312a1df1SDavid du Colombier 				printf("has more than one match: %d and %d\n",
269312a1df1SDavid du Colombier 					rval, r->pid);
270312a1df1SDavid du Colombier 			} else
271312a1df1SDavid du Colombier 				rval = r->pid;
272312a1df1SDavid du Colombier 		}
273312a1df1SDavid du Colombier 	return rval;
274219b2ee8SDavid du Colombier }
275219b2ee8SDavid du Colombier 
276219b2ee8SDavid du Colombier void
wrapup(int fini)277219b2ee8SDavid du Colombier wrapup(int fini)
278219b2ee8SDavid du Colombier {
279312a1df1SDavid du Colombier 	limited_vis = 0;
2807dd7cddfSDavid du Colombier 	if (columns)
2817dd7cddfSDavid du Colombier 	{	extern void putpostlude(void);
2827dd7cddfSDavid du Colombier 		if (columns == 2) putpostlude();
2837dd7cddfSDavid du Colombier 		if (!no_wrapup)
2847dd7cddfSDavid du Colombier 		printf("-------------\nfinal state:\n-------------\n");
2857dd7cddfSDavid du Colombier 	}
2867dd7cddfSDavid du Colombier 	if (no_wrapup)
2877dd7cddfSDavid du Colombier 		goto short_cut;
288219b2ee8SDavid du Colombier 	if (nproc != nstop)
2897dd7cddfSDavid du Colombier 	{	int ov = verbose;
290312a1df1SDavid du Colombier 		printf("#processes: %d\n", nproc-nstop - Have_claim + Skip_claim);
2917dd7cddfSDavid du Colombier 		verbose &= ~4;
292219b2ee8SDavid du Colombier 		dumpglobals();
2937dd7cddfSDavid du Colombier 		verbose = ov;
294219b2ee8SDavid du Colombier 		verbose &= ~1;	/* no more globals */
295219b2ee8SDavid du Colombier 		verbose |= 32;	/* add process states */
296219b2ee8SDavid du Colombier 		for (X = run; X; X = X->nxt)
297219b2ee8SDavid du Colombier 			talk(X);
2987dd7cddfSDavid du Colombier 		verbose = ov;	/* restore */
299219b2ee8SDavid du Colombier 	}
300312a1df1SDavid du Colombier 	printf("%d process%s created\n",
301312a1df1SDavid du Colombier 		nproc - Have_claim + Skip_claim,
302312a1df1SDavid du Colombier 		(xspin || nproc!=1)?"es":"");
3037dd7cddfSDavid du Colombier short_cut:
3047dd7cddfSDavid du Colombier 	if (xspin) alldone(0);	/* avoid an abort from xspin */
3057dd7cddfSDavid du Colombier 	if (fini)  alldone(1);
306219b2ee8SDavid du Colombier }
307219b2ee8SDavid du Colombier 
308219b2ee8SDavid du Colombier static char is_blocked[256];
309219b2ee8SDavid du Colombier 
3107dd7cddfSDavid du Colombier static int
p_blocked(int p)311219b2ee8SDavid du Colombier p_blocked(int p)
312312a1df1SDavid du Colombier {	int i, j;
313219b2ee8SDavid du Colombier 
314219b2ee8SDavid du Colombier 	is_blocked[p%256] = 1;
315219b2ee8SDavid du Colombier 	for (i = j = 0; i < nproc - nstop; i++)
316219b2ee8SDavid du Colombier 		j += is_blocked[i];
317219b2ee8SDavid du Colombier 	if (j >= nproc - nstop)
318219b2ee8SDavid du Colombier 	{	memset(is_blocked, 0, 256);
319219b2ee8SDavid du Colombier 		return 1;
320219b2ee8SDavid du Colombier 	}
321219b2ee8SDavid du Colombier 	return 0;
322219b2ee8SDavid du Colombier }
323219b2ee8SDavid du Colombier 
3247dd7cddfSDavid du Colombier static Element *
silent_moves(Element * e)325219b2ee8SDavid du Colombier silent_moves(Element *e)
326219b2ee8SDavid du Colombier {	Element *f;
327219b2ee8SDavid du Colombier 
328f3793cddSDavid du Colombier 	if (e->n)
329219b2ee8SDavid du Colombier 	switch (e->n->ntyp) {
330219b2ee8SDavid du Colombier 	case GOTO:
331219b2ee8SDavid du Colombier 		if (Rvous) break;
332219b2ee8SDavid du Colombier 		f = get_lab(e->n, 1);
333219b2ee8SDavid du Colombier 		cross_dsteps(e->n, f->n);
334219b2ee8SDavid du Colombier 		return f; /* guard against goto cycles */
335219b2ee8SDavid du Colombier 	case UNLESS:
336219b2ee8SDavid du Colombier 		return silent_moves(e->sub->this->frst);
337219b2ee8SDavid du Colombier 	case NON_ATOMIC:
338219b2ee8SDavid du Colombier 	case ATOMIC:
339219b2ee8SDavid du Colombier 	case D_STEP:
340219b2ee8SDavid du Colombier 		e->n->sl->this->last->nxt = e->nxt;
341219b2ee8SDavid du Colombier 		return silent_moves(e->n->sl->this->frst);
342219b2ee8SDavid du Colombier 	case '.':
3437dd7cddfSDavid du Colombier 		return silent_moves(e->nxt);
344219b2ee8SDavid du Colombier 	}
345219b2ee8SDavid du Colombier 	return e;
346219b2ee8SDavid du Colombier }
347219b2ee8SDavid du Colombier 
348f3793cddSDavid du Colombier static RunList *
pickproc(RunList * Y)349f3793cddSDavid du Colombier pickproc(RunList *Y)
3507dd7cddfSDavid du Colombier {	SeqList *z; Element *has_else;
3517dd7cddfSDavid du Colombier 	short Choices[256];
352312a1df1SDavid du Colombier 	int j, k, nr_else = 0;
3537dd7cddfSDavid du Colombier 
3547dd7cddfSDavid du Colombier 	if (nproc <= nstop+1)
3557dd7cddfSDavid du Colombier 	{	X = run;
356f3793cddSDavid du Colombier 		return NULL;
3577dd7cddfSDavid du Colombier 	}
3587dd7cddfSDavid du Colombier 	if (!interactive || depth < jumpsteps)
3597dd7cddfSDavid du Colombier 	{	/* was: j = (int) Rand()%(nproc-nstop); */
3607dd7cddfSDavid du Colombier 		if (Priority_Sum < nproc-nstop)
3617dd7cddfSDavid du Colombier 			fatal("cannot happen - weights", (char *)0);
3627dd7cddfSDavid du Colombier 		j = (int) Rand()%Priority_Sum;
363f3793cddSDavid du Colombier 
3647dd7cddfSDavid du Colombier 		while (j - X->priority >= 0)
3657dd7cddfSDavid du Colombier 		{	j -= X->priority;
366f3793cddSDavid du Colombier 			Y = X;
3677dd7cddfSDavid du Colombier 			X = X->nxt;
368f3793cddSDavid du Colombier 			if (!X) { Y = NULL; X = run; }
3697dd7cddfSDavid du Colombier 		}
3707dd7cddfSDavid du Colombier 	} else
3717dd7cddfSDavid du Colombier 	{	int only_choice = -1;
3727dd7cddfSDavid du Colombier 		int no_choice = 0, proc_no_ch, proc_k;
373f3793cddSDavid du Colombier 
374f3793cddSDavid du Colombier 		Tval = 0;	/* new 4.2.6 */
3757dd7cddfSDavid du Colombier try_again:	printf("Select a statement\n");
3767dd7cddfSDavid du Colombier try_more:	for (X = run, k = 1; X; X = X->nxt)
3777dd7cddfSDavid du Colombier 		{	if (X->pid > 255) break;
3787dd7cddfSDavid du Colombier 
3797dd7cddfSDavid du Colombier 			Choices[X->pid] = (short) k;
3807dd7cddfSDavid du Colombier 
3817dd7cddfSDavid du Colombier 			if (!X->pc
3827dd7cddfSDavid du Colombier 			||  (X->prov && !eval(X->prov)))
3837dd7cddfSDavid du Colombier 			{	if (X == run)
3847dd7cddfSDavid du Colombier 					Choices[X->pid] = 0;
3857dd7cddfSDavid du Colombier 				continue;
3867dd7cddfSDavid du Colombier 			}
3877dd7cddfSDavid du Colombier 			X->pc = silent_moves(X->pc);
3887dd7cddfSDavid du Colombier 			if (!X->pc->sub && X->pc->n)
3897dd7cddfSDavid du Colombier 			{	int unex;
3907dd7cddfSDavid du Colombier 				unex = !Enabled0(X->pc);
3917dd7cddfSDavid du Colombier 				if (unex)
3927dd7cddfSDavid du Colombier 					no_choice++;
3937dd7cddfSDavid du Colombier 				else
3947dd7cddfSDavid du Colombier 					only_choice = k;
3957dd7cddfSDavid du Colombier 				if (!xspin && unex && !(verbose&32))
3967dd7cddfSDavid du Colombier 				{	k++;
3977dd7cddfSDavid du Colombier 					continue;
3987dd7cddfSDavid du Colombier 				}
3997dd7cddfSDavid du Colombier 				printf("\tchoice %d: ", k++);
4007dd7cddfSDavid du Colombier 				p_talk(X->pc, 0);
4017dd7cddfSDavid du Colombier 				if (unex)
4027dd7cddfSDavid du Colombier 					printf(" unexecutable,");
4037dd7cddfSDavid du Colombier 				printf(" [");
4047dd7cddfSDavid du Colombier 				comment(stdout, X->pc->n, 0);
4057dd7cddfSDavid du Colombier 				if (X->pc->esc) printf(" + Escape");
4067dd7cddfSDavid du Colombier 				printf("]\n");
4077dd7cddfSDavid du Colombier 			} else {
4087dd7cddfSDavid du Colombier 			has_else = ZE;
4097dd7cddfSDavid du Colombier 			proc_no_ch = no_choice;
4107dd7cddfSDavid du Colombier 			proc_k = k;
4117dd7cddfSDavid du Colombier 			for (z = X->pc->sub, j=0; z; z = z->nxt)
4127dd7cddfSDavid du Colombier 			{	Element *y = silent_moves(z->this->frst);
4137dd7cddfSDavid du Colombier 				int unex;
4147dd7cddfSDavid du Colombier 				if (!y) continue;
4157dd7cddfSDavid du Colombier 
4167dd7cddfSDavid du Colombier 				if (y->n->ntyp == ELSE)
4177dd7cddfSDavid du Colombier 				{	has_else = (Rvous)?ZE:y;
4187dd7cddfSDavid du Colombier 					nr_else = k++;
4197dd7cddfSDavid du Colombier 					continue;
4207dd7cddfSDavid du Colombier 				}
4217dd7cddfSDavid du Colombier 
4227dd7cddfSDavid du Colombier 				unex = !Enabled0(y);
4237dd7cddfSDavid du Colombier 				if (unex)
4247dd7cddfSDavid du Colombier 					no_choice++;
4257dd7cddfSDavid du Colombier 				else
4267dd7cddfSDavid du Colombier 					only_choice = k;
4277dd7cddfSDavid du Colombier 				if (!xspin && unex && !(verbose&32))
4287dd7cddfSDavid du Colombier 				{	k++;
4297dd7cddfSDavid du Colombier 					continue;
4307dd7cddfSDavid du Colombier 				}
4317dd7cddfSDavid du Colombier 				printf("\tchoice %d: ", k++);
4327dd7cddfSDavid du Colombier 				p_talk(X->pc, 0);
4337dd7cddfSDavid du Colombier 				if (unex)
4347dd7cddfSDavid du Colombier 					printf(" unexecutable,");
4357dd7cddfSDavid du Colombier 				printf(" [");
4367dd7cddfSDavid du Colombier 				comment(stdout, y->n, 0);
4377dd7cddfSDavid du Colombier 				printf("]\n");
4387dd7cddfSDavid du Colombier 			}
4397dd7cddfSDavid du Colombier 			if (has_else)
4407dd7cddfSDavid du Colombier 			{	if (no_choice-proc_no_ch >= (k-proc_k)-1)
4417dd7cddfSDavid du Colombier 				{	only_choice = nr_else;
4427dd7cddfSDavid du Colombier 					printf("\tchoice %d: ", nr_else);
4437dd7cddfSDavid du Colombier 					p_talk(X->pc, 0);
4447dd7cddfSDavid du Colombier 					printf(" [else]\n");
4457dd7cddfSDavid du Colombier 				} else
4467dd7cddfSDavid du Colombier 				{	no_choice++;
4477dd7cddfSDavid du Colombier 					printf("\tchoice %d: ", nr_else);
4487dd7cddfSDavid du Colombier 					p_talk(X->pc, 0);
4497dd7cddfSDavid du Colombier 					printf(" unexecutable, [else]\n");
4507dd7cddfSDavid du Colombier 			}	}
4517dd7cddfSDavid du Colombier 		}	}
4527dd7cddfSDavid du Colombier 		X = run;
4537dd7cddfSDavid du Colombier 		if (k - no_choice < 2 && Tval == 0)
4547dd7cddfSDavid du Colombier 		{	Tval = 1;
4557dd7cddfSDavid du Colombier 			no_choice = 0; only_choice = -1;
4567dd7cddfSDavid du Colombier 			goto try_more;
4577dd7cddfSDavid du Colombier 		}
4587dd7cddfSDavid du Colombier 		if (xspin)
4597dd7cddfSDavid du Colombier 			printf("Make Selection %d\n\n", k-1);
4607dd7cddfSDavid du Colombier 		else
4617dd7cddfSDavid du Colombier 		{	if (k - no_choice < 2)
4627dd7cddfSDavid du Colombier 			{	printf("no executable choices\n");
4637dd7cddfSDavid du Colombier 				alldone(0);
4647dd7cddfSDavid du Colombier 			}
4657dd7cddfSDavid du Colombier 			printf("Select [1-%d]: ", k-1);
4667dd7cddfSDavid du Colombier 		}
4677dd7cddfSDavid du Colombier 		if (!xspin && k - no_choice == 2)
4687dd7cddfSDavid du Colombier 		{	printf("%d\n", only_choice);
4697dd7cddfSDavid du Colombier 			j = only_choice;
4707dd7cddfSDavid du Colombier 		} else
4717dd7cddfSDavid du Colombier 		{	char buf[256];
4727dd7cddfSDavid du Colombier 			fflush(stdout);
473*00d97012SDavid du Colombier 			if (scanf("%64s", buf) == 0)
474*00d97012SDavid du Colombier 			{	printf("\tno input\n");
475*00d97012SDavid du Colombier 				goto try_again;
476*00d97012SDavid du Colombier 			}
4777dd7cddfSDavid du Colombier 			j = -1;
478*00d97012SDavid du Colombier 			if (isdigit((int) buf[0]))
4797dd7cddfSDavid du Colombier 				j = atoi(buf);
4807dd7cddfSDavid du Colombier 			else
4817dd7cddfSDavid du Colombier 			{	if (buf[0] == 'q')
4827dd7cddfSDavid du Colombier 					alldone(0);
4837dd7cddfSDavid du Colombier 			}
4847dd7cddfSDavid du Colombier 			if (j < 1 || j >= k)
4857dd7cddfSDavid du Colombier 			{	printf("\tchoice is outside range\n");
4867dd7cddfSDavid du Colombier 				goto try_again;
4877dd7cddfSDavid du Colombier 		}	}
4887dd7cddfSDavid du Colombier 		MadeChoice = 0;
489f3793cddSDavid du Colombier 		Y = NULL;
490f3793cddSDavid du Colombier 		for (X = run; X; Y = X, X = X->nxt)
4917dd7cddfSDavid du Colombier 		{	if (!X->nxt
4927dd7cddfSDavid du Colombier 			||   X->nxt->pid > 255
4937dd7cddfSDavid du Colombier 			||   j < Choices[X->nxt->pid])
4947dd7cddfSDavid du Colombier 			{
4957dd7cddfSDavid du Colombier 				MadeChoice = 1+j-Choices[X->pid];
4967dd7cddfSDavid du Colombier 				break;
4977dd7cddfSDavid du Colombier 		}	}
4987dd7cddfSDavid du Colombier 	}
499f3793cddSDavid du Colombier 	return Y;
5007dd7cddfSDavid du Colombier }
5017dd7cddfSDavid du Colombier 
502219b2ee8SDavid du Colombier void
multi_claims(void)503*00d97012SDavid du Colombier multi_claims(void)
504*00d97012SDavid du Colombier {	ProcList *p, *q = NULL;
505*00d97012SDavid du Colombier 
506*00d97012SDavid du Colombier 	if (nclaims > 1)
507*00d97012SDavid du Colombier 	{	printf("  the model contains %d never claims:", nclaims);
508*00d97012SDavid du Colombier 		for (p = rdy; p; p = p->nxt)
509*00d97012SDavid du Colombier 		{	if (p->b == N_CLAIM)
510*00d97012SDavid du Colombier 			{	printf("%s%s", q?", ":" ", p->n->name);
511*00d97012SDavid du Colombier 				q = p;
512*00d97012SDavid du Colombier 		}	}
513*00d97012SDavid du Colombier 		printf("\n");
514*00d97012SDavid du Colombier 		printf("  only one claim is used in a verification run\n");
515*00d97012SDavid du Colombier 		printf("  choose which one with ./pan -N name (defaults to -N %s)\n",
516*00d97012SDavid du Colombier 			q?q->n->name:"--");
517*00d97012SDavid du Colombier 	}
518*00d97012SDavid du Colombier }
519*00d97012SDavid du Colombier 
520*00d97012SDavid du Colombier void
sched(void)521219b2ee8SDavid du Colombier sched(void)
522219b2ee8SDavid du Colombier {	Element *e;
523f3793cddSDavid du Colombier 	RunList *Y = NULL;	/* previous process in run queue */
524219b2ee8SDavid du Colombier 	RunList *oX;
525312a1df1SDavid du Colombier 	int go, notbeyond = 0;
5267dd7cddfSDavid du Colombier #ifdef PC
5277dd7cddfSDavid du Colombier 	int bufmax = 100;
5287dd7cddfSDavid du Colombier #endif
529219b2ee8SDavid du Colombier 	if (dumptab)
530219b2ee8SDavid du Colombier 	{	formdump();
531219b2ee8SDavid du Colombier 		symdump();
532219b2ee8SDavid du Colombier 		dumplabels();
533219b2ee8SDavid du Colombier 		return;
534219b2ee8SDavid du Colombier 	}
535219b2ee8SDavid du Colombier 
536219b2ee8SDavid du Colombier 	if (has_enabled && u_sync > 0)
5377dd7cddfSDavid du Colombier 	{	printf("spin: error, cannot use 'enabled()' in ");
5387dd7cddfSDavid du Colombier 		printf("models with synchronous channels.\n");
539219b2ee8SDavid du Colombier 		nr_errs++;
540219b2ee8SDavid du Colombier 	}
541*00d97012SDavid du Colombier 	if (product)
542*00d97012SDavid du Colombier 	{	sync_product();
543*00d97012SDavid du Colombier 		alldone(0);
544*00d97012SDavid du Colombier 	}
545219b2ee8SDavid du Colombier 	if (analyze)
546219b2ee8SDavid du Colombier 	{	gensrc();
547*00d97012SDavid du Colombier 		multi_claims();
548219b2ee8SDavid du Colombier 		return;
549*00d97012SDavid du Colombier 	}
550*00d97012SDavid du Colombier 	if (s_trail)
551219b2ee8SDavid du Colombier 	{	match_trail();
552219b2ee8SDavid du Colombier 		return;
553219b2ee8SDavid du Colombier 	}
554219b2ee8SDavid du Colombier 	if (claimproc)
5557dd7cddfSDavid du Colombier 	printf("warning: never claim not used in random simulation\n");
5567dd7cddfSDavid du Colombier 	if (eventmap)
5577dd7cddfSDavid du Colombier 	printf("warning: trace assertion not used in random simulation\n");
558219b2ee8SDavid du Colombier 
559219b2ee8SDavid du Colombier 	X = run;
560f3793cddSDavid du Colombier 	Y = pickproc(Y);
5617dd7cddfSDavid du Colombier 
562219b2ee8SDavid du Colombier 	while (X)
563219b2ee8SDavid du Colombier 	{	context = X->n;
564219b2ee8SDavid du Colombier 		if (X->pc && X->pc->n)
565219b2ee8SDavid du Colombier 		{	lineno = X->pc->n->ln;
566219b2ee8SDavid du Colombier 			Fname  = X->pc->n->fn;
567219b2ee8SDavid du Colombier 		}
568312a1df1SDavid du Colombier 		if (cutoff > 0 && depth >= cutoff)
569312a1df1SDavid du Colombier 		{	printf("-------------\n");
570312a1df1SDavid du Colombier 			printf("depth-limit (-u%d steps) reached\n", cutoff);
571312a1df1SDavid du Colombier 			break;
572312a1df1SDavid du Colombier 		}
5737dd7cddfSDavid du Colombier #ifdef PC
5747dd7cddfSDavid du Colombier 		if (xspin && !interactive && --bufmax <= 0)
575312a1df1SDavid du Colombier 		{	int c; /* avoid buffer overflow on pc's */
5767dd7cddfSDavid du Colombier 			printf("spin: type return to proceed\n");
5777dd7cddfSDavid du Colombier 			fflush(stdout);
578312a1df1SDavid du Colombier 			c = getc(stdin);
579312a1df1SDavid du Colombier 			if (c == 'q') wrapup(0);
5807dd7cddfSDavid du Colombier 			bufmax = 100;
5817dd7cddfSDavid du Colombier 		}
5827dd7cddfSDavid du Colombier #endif
583219b2ee8SDavid du Colombier 		depth++; LastStep = ZE;
584219b2ee8SDavid du Colombier 		oX = X;	/* a rendezvous could change it */
5857dd7cddfSDavid du Colombier 		go = 1;
586*00d97012SDavid du Colombier 		if (X->prov && X->pc
5877dd7cddfSDavid du Colombier 		&& !(X->pc->status & D_ATOM)
5887dd7cddfSDavid du Colombier 		&& !eval(X->prov))
5897dd7cddfSDavid du Colombier 		{	if (!xspin && ((verbose&32) || (verbose&4)))
5907dd7cddfSDavid du Colombier 			{	p_talk(X->pc, 1);
5917dd7cddfSDavid du Colombier 				printf("\t<<Not Enabled>>\n");
5927dd7cddfSDavid du Colombier 			}
5937dd7cddfSDavid du Colombier 			go = 0;
5947dd7cddfSDavid du Colombier 		}
5957dd7cddfSDavid du Colombier 		if (go && (e = eval_sub(X->pc)))
5967dd7cddfSDavid du Colombier 		{	if (depth >= jumpsteps
5977dd7cddfSDavid du Colombier 			&& ((verbose&32) || (verbose&4)))
598219b2ee8SDavid du Colombier 			{	if (X == oX)
599312a1df1SDavid du Colombier 				if (!(e->status & D_ATOM) || (verbose&32)) /* no talking in d_steps */
600219b2ee8SDavid du Colombier 				{	p_talk(X->pc, 1);
601219b2ee8SDavid du Colombier 					printf("	[");
602219b2ee8SDavid du Colombier 					if (!LastStep) LastStep = X->pc;
603219b2ee8SDavid du Colombier 					comment(stdout, LastStep->n, 0);
604219b2ee8SDavid du Colombier 					printf("]\n");
605219b2ee8SDavid du Colombier 				}
606219b2ee8SDavid du Colombier 				if (verbose&1) dumpglobals();
607219b2ee8SDavid du Colombier 				if (verbose&2) dumplocal(X);
608312a1df1SDavid du Colombier 
609312a1df1SDavid du Colombier 				if (!(e->status & D_ATOM))
610312a1df1SDavid du Colombier 				if (xspin)
611312a1df1SDavid du Colombier 					printf("\n");
612219b2ee8SDavid du Colombier 			}
613*00d97012SDavid du Colombier 			if (oX != X
614*00d97012SDavid du Colombier 			||  (X->pc->status & (ATOM|D_ATOM)))		/* new 5.0 */
615312a1df1SDavid du Colombier 			{	e = silent_moves(e);
616312a1df1SDavid du Colombier 				notbeyond = 0;
617312a1df1SDavid du Colombier 			}
618219b2ee8SDavid du Colombier 			oX->pc = e; LastX = X;
6197dd7cddfSDavid du Colombier 
6207dd7cddfSDavid du Colombier 			if (!interactive) Tval = 0;
621219b2ee8SDavid du Colombier 			memset(is_blocked, 0, 256);
622219b2ee8SDavid du Colombier 
623312a1df1SDavid du Colombier 			if (X->pc && (X->pc->status & (ATOM|L_ATOM))
624312a1df1SDavid du Colombier 			&&  (notbeyond == 0 || oX != X))
625312a1df1SDavid du Colombier 			{	if ((X->pc->status & L_ATOM))
6267dd7cddfSDavid du Colombier 					notbeyond = 1;
6277dd7cddfSDavid du Colombier 				continue; /* no process switch */
6287dd7cddfSDavid du Colombier 			}
629219b2ee8SDavid du Colombier 		} else
630219b2ee8SDavid du Colombier 		{	depth--;
631*00d97012SDavid du Colombier 			if (oX->pc && (oX->pc->status & D_ATOM))
632*00d97012SDavid du Colombier 			{	non_fatal("stmnt in d_step blocks", (char *)0);
633*00d97012SDavid du Colombier 			}
634*00d97012SDavid du Colombier 			if (X->pc
635*00d97012SDavid du Colombier 			&&  X->pc->n
636*00d97012SDavid du Colombier 			&&  X->pc->n->ntyp == '@'
637219b2ee8SDavid du Colombier 			&&  X->pid == (nproc-nstop-1))
638f3793cddSDavid du Colombier 			{	if (X != run && Y != NULL)
639219b2ee8SDavid du Colombier 					Y->nxt = X->nxt;
640219b2ee8SDavid du Colombier 				else
641219b2ee8SDavid du Colombier 					run = X->nxt;
642219b2ee8SDavid du Colombier 				nstop++;
6437dd7cddfSDavid du Colombier 				Priority_Sum -= X->priority;
644219b2ee8SDavid du Colombier 				if (verbose&4)
645219b2ee8SDavid du Colombier 				{	whoruns(1);
6467dd7cddfSDavid du Colombier 					dotag(stdout, "terminates\n");
647219b2ee8SDavid du Colombier 				}
648219b2ee8SDavid du Colombier 				LastX = X;
6497dd7cddfSDavid du Colombier 				if (!interactive) Tval = 0;
650219b2ee8SDavid du Colombier 				if (nproc == nstop) break;
651219b2ee8SDavid du Colombier 				memset(is_blocked, 0, 256);
652f3793cddSDavid du Colombier 				/* proc X is no longer in runlist */
653f3793cddSDavid du Colombier 				X = (X->nxt) ? X->nxt : run;
654219b2ee8SDavid du Colombier 			} else
6557dd7cddfSDavid du Colombier 			{	if (p_blocked(X->pid))
656219b2ee8SDavid du Colombier 				{	if (Tval) break;
657219b2ee8SDavid du Colombier 					Tval = 1;
6587dd7cddfSDavid du Colombier 					if (depth >= jumpsteps)
659312a1df1SDavid du Colombier 					{	oX = X;
660312a1df1SDavid du Colombier 						X = (RunList *) 0; /* to suppress indent */
6617dd7cddfSDavid du Colombier 						dotag(stdout, "timeout\n");
662312a1df1SDavid du Colombier 						X = oX;
663312a1df1SDavid du Colombier 		}	}	}	}
664*00d97012SDavid du Colombier 
665*00d97012SDavid du Colombier 		if (!run || !X) break;	/* new 5.0 */
666*00d97012SDavid du Colombier 
667f3793cddSDavid du Colombier 		Y = pickproc(X);
6687dd7cddfSDavid du Colombier 		notbeyond = 0;
669219b2ee8SDavid du Colombier 	}
670219b2ee8SDavid du Colombier 	context = ZS;
671219b2ee8SDavid du Colombier 	wrapup(0);
672219b2ee8SDavid du Colombier }
673219b2ee8SDavid du Colombier 
674219b2ee8SDavid du Colombier int
complete_rendez(void)675219b2ee8SDavid du Colombier complete_rendez(void)
676219b2ee8SDavid du Colombier {	RunList *orun = X, *tmp;
677219b2ee8SDavid du Colombier 	Element  *s_was = LastStep;
678219b2ee8SDavid du Colombier 	Element *e;
6797dd7cddfSDavid du Colombier 	int j, ointer = interactive;
680219b2ee8SDavid du Colombier 
681219b2ee8SDavid du Colombier 	if (s_trail)
682219b2ee8SDavid du Colombier 		return 1;
6837dd7cddfSDavid du Colombier 	if (orun->pc->status & D_ATOM)
6847dd7cddfSDavid du Colombier 		fatal("rv-attempt in d_step sequence", (char *)0);
685219b2ee8SDavid du Colombier 	Rvous = 1;
6867dd7cddfSDavid du Colombier 	interactive = 0;
6877dd7cddfSDavid du Colombier 
6887dd7cddfSDavid du Colombier 	j = (int) Rand()%Priority_Sum;	/* randomize start point */
6897dd7cddfSDavid du Colombier 	X = run;
6907dd7cddfSDavid du Colombier 	while (j - X->priority >= 0)
6917dd7cddfSDavid du Colombier 	{	j -= X->priority;
6927dd7cddfSDavid du Colombier 		X = X->nxt;
6937dd7cddfSDavid du Colombier 		if (!X) X = run;
6947dd7cddfSDavid du Colombier 	}
6957dd7cddfSDavid du Colombier 	for (j = nproc - nstop; j > 0; j--)
6967dd7cddfSDavid du Colombier 	{	if (X != orun
6977dd7cddfSDavid du Colombier 		&& (!X->prov || eval(X->prov))
6987dd7cddfSDavid du Colombier 		&& (e = eval_sub(X->pc)))
6997dd7cddfSDavid du Colombier 		{	if (TstOnly)
7007dd7cddfSDavid du Colombier 			{	X = orun;
7017dd7cddfSDavid du Colombier 				Rvous = 0;
7027dd7cddfSDavid du Colombier 				goto out;
7037dd7cddfSDavid du Colombier 			}
7047dd7cddfSDavid du Colombier 			if ((verbose&32) || (verbose&4))
705219b2ee8SDavid du Colombier 			{	tmp = orun; orun = X; X = tmp;
706219b2ee8SDavid du Colombier 				if (!s_was) s_was = X->pc;
707219b2ee8SDavid du Colombier 				p_talk(s_was, 1);
708219b2ee8SDavid du Colombier 				printf("	[");
709219b2ee8SDavid du Colombier 				comment(stdout, s_was->n, 0);
710219b2ee8SDavid du Colombier 				printf("]\n");
711219b2ee8SDavid du Colombier 				tmp = orun; orun = X; X = tmp;
712219b2ee8SDavid du Colombier 				if (!LastStep) LastStep = X->pc;
713219b2ee8SDavid du Colombier 				p_talk(LastStep, 1);
714219b2ee8SDavid du Colombier 				printf("	[");
715219b2ee8SDavid du Colombier 				comment(stdout, LastStep->n, 0);
716219b2ee8SDavid du Colombier 				printf("]\n");
717219b2ee8SDavid du Colombier 			}
7187dd7cddfSDavid du Colombier 			Rvous = 0; /* before silent_moves */
7197dd7cddfSDavid du Colombier 			X->pc = silent_moves(e);
7207dd7cddfSDavid du Colombier out:				interactive = ointer;
721219b2ee8SDavid du Colombier 			return 1;
722219b2ee8SDavid du Colombier 		}
7237dd7cddfSDavid du Colombier 
7247dd7cddfSDavid du Colombier 		X = X->nxt;
7257dd7cddfSDavid du Colombier 		if (!X) X = run;
7267dd7cddfSDavid du Colombier 	}
727219b2ee8SDavid du Colombier 	Rvous = 0;
728219b2ee8SDavid du Colombier 	X = orun;
7297dd7cddfSDavid du Colombier 	interactive = ointer;
730219b2ee8SDavid du Colombier 	return 0;
731219b2ee8SDavid du Colombier }
732219b2ee8SDavid du Colombier 
733219b2ee8SDavid du Colombier /***** Runtime - Local Variables *****/
734219b2ee8SDavid du Colombier 
7357dd7cddfSDavid du Colombier static void
addsymbol(RunList * r,Symbol * s)736219b2ee8SDavid du Colombier addsymbol(RunList *r, Symbol  *s)
737219b2ee8SDavid du Colombier {	Symbol *t;
738219b2ee8SDavid du Colombier 	int i;
739219b2ee8SDavid du Colombier 
740219b2ee8SDavid du Colombier 	for (t = r->symtab; t; t = t->next)
741*00d97012SDavid du Colombier 		if (strcmp(t->name, s->name) == 0
742*00d97012SDavid du Colombier 		&& (old_scope_rules
743*00d97012SDavid du Colombier 		 || strcmp((const char *)t->bscp, (const char *)s->bscp) == 0))
744219b2ee8SDavid du Colombier 			return;		/* it's already there */
745219b2ee8SDavid du Colombier 
746219b2ee8SDavid du Colombier 	t = (Symbol *) emalloc(sizeof(Symbol));
747219b2ee8SDavid du Colombier 	t->name = s->name;
748219b2ee8SDavid du Colombier 	t->type = s->type;
7497dd7cddfSDavid du Colombier 	t->hidden = s->hidden;
7507dd7cddfSDavid du Colombier 	t->nbits  = s->nbits;
751219b2ee8SDavid du Colombier 	t->nel  = s->nel;
752219b2ee8SDavid du Colombier 	t->ini  = s->ini;
753219b2ee8SDavid du Colombier 	t->setat = depth;
7547dd7cddfSDavid du Colombier 	t->context = r->n;
755*00d97012SDavid du Colombier 
756*00d97012SDavid du Colombier 	t->bscp  = (unsigned char *) emalloc(strlen((const char *)s->bscp)+1);
757*00d97012SDavid du Colombier 	strcpy((char *)t->bscp, (const char *)s->bscp);
758*00d97012SDavid du Colombier 
759219b2ee8SDavid du Colombier 	if (s->type != STRUCT)
760219b2ee8SDavid du Colombier 	{	if (s->val)	/* if already initialized, copy info */
761219b2ee8SDavid du Colombier 		{	t->val = (int *) emalloc(s->nel*sizeof(int));
762219b2ee8SDavid du Colombier 			for (i = 0; i < s->nel; i++)
763219b2ee8SDavid du Colombier 				t->val[i] = s->val[i];
764219b2ee8SDavid du Colombier 		} else
765*00d97012SDavid du Colombier 		{	(void) checkvar(t, 0);	/* initialize it */
766*00d97012SDavid du Colombier 		}
767219b2ee8SDavid du Colombier 	} else
768219b2ee8SDavid du Colombier 	{	if (s->Sval)
769219b2ee8SDavid du Colombier 			fatal("saw preinitialized struct %s", s->name);
770219b2ee8SDavid du Colombier 		t->Slst = s->Slst;
771219b2ee8SDavid du Colombier 		t->Snm  = s->Snm;
772219b2ee8SDavid du Colombier 		t->owner = s->owner;
7737dd7cddfSDavid du Colombier 	/*	t->context = r->n; */
774219b2ee8SDavid du Colombier 	}
775219b2ee8SDavid du Colombier 	t->next = r->symtab;	/* add it */
776219b2ee8SDavid du Colombier 	r->symtab = t;
777219b2ee8SDavid du Colombier }
778219b2ee8SDavid du Colombier 
7797dd7cddfSDavid du Colombier static void
setlocals(RunList * r)7807dd7cddfSDavid du Colombier setlocals(RunList *r)
7817dd7cddfSDavid du Colombier {	Ordered	*walk;
7827dd7cddfSDavid du Colombier 	Symbol	*sp;
7837dd7cddfSDavid du Colombier 	RunList	*oX = X;
7847dd7cddfSDavid du Colombier 
7857dd7cddfSDavid du Colombier 	X = r;
7867dd7cddfSDavid du Colombier 	for (walk = all_names; walk; walk = walk->next)
7877dd7cddfSDavid du Colombier 	{	sp = walk->entry;
7887dd7cddfSDavid du Colombier 		if (sp
7897dd7cddfSDavid du Colombier 		&&  sp->context
7907dd7cddfSDavid du Colombier 		&&  strcmp(sp->context->name, r->n->name) == 0
7917dd7cddfSDavid du Colombier 		&&  sp->Nid >= 0
7927dd7cddfSDavid du Colombier 		&& (sp->type == UNSIGNED
7937dd7cddfSDavid du Colombier 		||  sp->type == BIT
7947dd7cddfSDavid du Colombier 		||  sp->type == MTYPE
7957dd7cddfSDavid du Colombier 		||  sp->type == BYTE
7967dd7cddfSDavid du Colombier 		||  sp->type == CHAN
7977dd7cddfSDavid du Colombier 		||  sp->type == SHORT
7987dd7cddfSDavid du Colombier 		||  sp->type == INT
7997dd7cddfSDavid du Colombier 		||  sp->type == STRUCT))
8007dd7cddfSDavid du Colombier 		{	if (!findloc(sp))
8017dd7cddfSDavid du Colombier 			non_fatal("setlocals: cannot happen '%s'",
8027dd7cddfSDavid du Colombier 				sp->name);
8037dd7cddfSDavid du Colombier 		}
8047dd7cddfSDavid du Colombier 	}
8057dd7cddfSDavid du Colombier 	X = oX;
8067dd7cddfSDavid du Colombier }
8077dd7cddfSDavid du Colombier 
8087dd7cddfSDavid du Colombier static void
oneparam(RunList * r,Lextok * t,Lextok * a,ProcList * p)809219b2ee8SDavid du Colombier oneparam(RunList *r, Lextok *t, Lextok *a, ProcList *p)
810219b2ee8SDavid du Colombier {	int k; int at, ft;
811219b2ee8SDavid du Colombier 	RunList *oX = X;
812219b2ee8SDavid du Colombier 
813219b2ee8SDavid du Colombier 	if (!a)
814219b2ee8SDavid du Colombier 		fatal("missing actual parameters: '%s'", p->n->name);
815*00d97012SDavid du Colombier 	if (t->sym->nel > 1 || t->sym->isarray)
816219b2ee8SDavid du Colombier 		fatal("array in parameter list, %s", t->sym->name);
817219b2ee8SDavid du Colombier 	k = eval(a->lft);
818219b2ee8SDavid du Colombier 
819219b2ee8SDavid du Colombier 	at = Sym_typ(a->lft);
820219b2ee8SDavid du Colombier 	X = r;	/* switch context */
821219b2ee8SDavid du Colombier 	ft = Sym_typ(t);
822219b2ee8SDavid du Colombier 
823219b2ee8SDavid du Colombier 	if (at != ft && (at == CHAN || ft == CHAN))
824*00d97012SDavid du Colombier 	{	char buf[256], tag1[64], tag2[64];
825219b2ee8SDavid du Colombier 		(void) sputtype(tag1, ft);
826219b2ee8SDavid du Colombier 		(void) sputtype(tag2, at);
8277dd7cddfSDavid du Colombier 		sprintf(buf, "type-clash in params of %s(..), (%s<-> %s)",
828219b2ee8SDavid du Colombier 			p->n->name, tag1, tag2);
829219b2ee8SDavid du Colombier 		non_fatal("%s", buf);
830219b2ee8SDavid du Colombier 	}
831219b2ee8SDavid du Colombier 	t->ntyp = NAME;
832219b2ee8SDavid du Colombier 	addsymbol(r, t->sym);
833219b2ee8SDavid du Colombier 	(void) setval(t, k);
834219b2ee8SDavid du Colombier 
835219b2ee8SDavid du Colombier 	X = oX;
836219b2ee8SDavid du Colombier }
837219b2ee8SDavid du Colombier 
8387dd7cddfSDavid du Colombier static void
setparams(RunList * r,ProcList * p,Lextok * q)839219b2ee8SDavid du Colombier setparams(RunList *r, ProcList *p, Lextok *q)
840219b2ee8SDavid du Colombier {	Lextok *f, *a;	/* formal and actual pars */
841219b2ee8SDavid du Colombier 	Lextok *t;	/* list of pars of 1 type */
842219b2ee8SDavid du Colombier 
843219b2ee8SDavid du Colombier 	if (q)
844219b2ee8SDavid du Colombier 	{	lineno = q->ln;
845219b2ee8SDavid du Colombier 		Fname  = q->fn;
846219b2ee8SDavid du Colombier 	}
847219b2ee8SDavid du Colombier 	for (f = p->p, a = q; f; f = f->rgt) /* one type at a time */
848219b2ee8SDavid du Colombier 	for (t = f->lft; t; t = t->rgt, a = (a)?a->rgt:a)
849219b2ee8SDavid du Colombier 	{	if (t->ntyp != ',')
850219b2ee8SDavid du Colombier 			oneparam(r, t, a, p);	/* plain var */
851219b2ee8SDavid du Colombier 		else
8527dd7cddfSDavid du Colombier 			oneparam(r, t->lft, a, p); /* expanded struct */
853219b2ee8SDavid du Colombier 	}
854219b2ee8SDavid du Colombier }
855219b2ee8SDavid du Colombier 
856219b2ee8SDavid du Colombier Symbol *
findloc(Symbol * s)857219b2ee8SDavid du Colombier findloc(Symbol *s)
858219b2ee8SDavid du Colombier {	Symbol *r;
859219b2ee8SDavid du Colombier 
860219b2ee8SDavid du Colombier 	if (!X)
861219b2ee8SDavid du Colombier 	{	/* fatal("error, cannot eval '%s' (no proc)", s->name); */
862219b2ee8SDavid du Colombier 		return ZS;
863219b2ee8SDavid du Colombier 	}
864219b2ee8SDavid du Colombier 	for (r = X->symtab; r; r = r->next)
865*00d97012SDavid du Colombier 		if (strcmp(r->name, s->name) == 0
866*00d97012SDavid du Colombier 		&& (old_scope_rules || strcmp((const char *)r->bscp, (const char *)s->bscp) == 0))
867219b2ee8SDavid du Colombier 			break;
868219b2ee8SDavid du Colombier 	if (!r)
869219b2ee8SDavid du Colombier 	{	addsymbol(X, s);
870219b2ee8SDavid du Colombier 		r = X->symtab;
871219b2ee8SDavid du Colombier 	}
872219b2ee8SDavid du Colombier 	return r;
873219b2ee8SDavid du Colombier }
874219b2ee8SDavid du Colombier 
875219b2ee8SDavid du Colombier int
in_bound(Symbol * r,int n)876312a1df1SDavid du Colombier in_bound(Symbol *r, int n)
877312a1df1SDavid du Colombier {
878312a1df1SDavid du Colombier 	if (!r)	return 0;
879312a1df1SDavid du Colombier 
880312a1df1SDavid du Colombier 	if (n >= r->nel || n < 0)
881312a1df1SDavid du Colombier 	{	printf("spin: indexing %s[%d] - size is %d\n",
882312a1df1SDavid du Colombier 			r->name, n, r->nel);
883312a1df1SDavid du Colombier 		non_fatal("indexing array \'%s\'", r->name);
884312a1df1SDavid du Colombier 		return 0;
885312a1df1SDavid du Colombier 	}
886312a1df1SDavid du Colombier 	return 1;
887312a1df1SDavid du Colombier }
888312a1df1SDavid du Colombier 
889312a1df1SDavid du Colombier int
getlocal(Lextok * sn)890219b2ee8SDavid du Colombier getlocal(Lextok *sn)
891219b2ee8SDavid du Colombier {	Symbol *r, *s = sn->sym;
892219b2ee8SDavid du Colombier 	int n = eval(sn->lft);
893219b2ee8SDavid du Colombier 
894219b2ee8SDavid du Colombier 	r = findloc(s);
895219b2ee8SDavid du Colombier 	if (r && r->type == STRUCT)
896219b2ee8SDavid du Colombier 		return Rval_struct(sn, r, 1); /* 1 = check init */
897312a1df1SDavid du Colombier 	if (in_bound(r, n))
898312a1df1SDavid du Colombier 		return cast_val(r->type, r->val[n], r->nbits);
899219b2ee8SDavid du Colombier 	return 0;
900219b2ee8SDavid du Colombier }
901219b2ee8SDavid du Colombier 
902219b2ee8SDavid du Colombier int
setlocal(Lextok * p,int m)903219b2ee8SDavid du Colombier setlocal(Lextok *p, int m)
904219b2ee8SDavid du Colombier {	Symbol *r = findloc(p->sym);
905219b2ee8SDavid du Colombier 	int n = eval(p->lft);
906219b2ee8SDavid du Colombier 
907312a1df1SDavid du Colombier 	if (in_bound(r, n))
908219b2ee8SDavid du Colombier 	{	if (r->type == STRUCT)
909219b2ee8SDavid du Colombier 			(void) Lval_struct(p, r, 1, m); /* 1 = check init */
910219b2ee8SDavid du Colombier 		else
911312a1df1SDavid du Colombier 		{
912312a1df1SDavid du Colombier #if 0
913312a1df1SDavid du Colombier 			if (r->nbits > 0)
9147dd7cddfSDavid du Colombier 				m = (m & ((1<<r->nbits)-1));
9157dd7cddfSDavid du Colombier 			r->val[n] = m;
916312a1df1SDavid du Colombier #else
917312a1df1SDavid du Colombier 			r->val[n] = cast_val(r->type, m, r->nbits);
918312a1df1SDavid du Colombier #endif
919219b2ee8SDavid du Colombier 			r->setat = depth;
920219b2ee8SDavid du Colombier 	}	}
921219b2ee8SDavid du Colombier 
922219b2ee8SDavid du Colombier 	return 1;
923219b2ee8SDavid du Colombier }
924219b2ee8SDavid du Colombier 
925219b2ee8SDavid du Colombier void
whoruns(int lnr)926219b2ee8SDavid du Colombier whoruns(int lnr)
927219b2ee8SDavid du Colombier {	if (!X) return;
928219b2ee8SDavid du Colombier 
929219b2ee8SDavid du Colombier 	if (lnr) printf("%3d:	", depth);
930219b2ee8SDavid du Colombier 	printf("proc ");
9317dd7cddfSDavid du Colombier 	if (Have_claim && X->pid == 0)
932219b2ee8SDavid du Colombier 		printf(" -");
933219b2ee8SDavid du Colombier 	else
9347dd7cddfSDavid du Colombier 		printf("%2d", X->pid - Have_claim);
935219b2ee8SDavid du Colombier 	printf(" (%s) ", X->n->name);
936219b2ee8SDavid du Colombier }
937219b2ee8SDavid du Colombier 
9387dd7cddfSDavid du Colombier static void
talk(RunList * r)939219b2ee8SDavid du Colombier talk(RunList *r)
940219b2ee8SDavid du Colombier {
9417dd7cddfSDavid du Colombier 	if ((verbose&32) || (verbose&4))
942219b2ee8SDavid du Colombier 	{	p_talk(r->pc, 1);
943219b2ee8SDavid du Colombier 		printf("\n");
944219b2ee8SDavid du Colombier 		if (verbose&1) dumpglobals();
945219b2ee8SDavid du Colombier 		if (verbose&2) dumplocal(r);
946219b2ee8SDavid du Colombier 	}
947219b2ee8SDavid du Colombier }
948219b2ee8SDavid du Colombier 
949219b2ee8SDavid du Colombier void
p_talk(Element * e,int lnr)950219b2ee8SDavid du Colombier p_talk(Element *e, int lnr)
9517dd7cddfSDavid du Colombier {	static int lastnever = -1;
952*00d97012SDavid du Colombier 	static char nbuf[128];
9537dd7cddfSDavid du Colombier 	int newnever = -1;
9547dd7cddfSDavid du Colombier 
9557dd7cddfSDavid du Colombier 	if (e && e->n)
9567dd7cddfSDavid du Colombier 		newnever = e->n->ln;
9577dd7cddfSDavid du Colombier 
9587dd7cddfSDavid du Colombier 	if (Have_claim && X && X->pid == 0
9597dd7cddfSDavid du Colombier 	&&  lastnever != newnever && e)
9607dd7cddfSDavid du Colombier 	{	if (xspin)
9617dd7cddfSDavid du Colombier 		{	printf("MSC: ~G line %d\n", newnever);
962312a1df1SDavid du Colombier #if 0
963312a1df1SDavid du Colombier 			printf("%3d:	proc  - (NEVER) line   %d \"never\" ",
9647dd7cddfSDavid du Colombier 				depth, newnever);
9657dd7cddfSDavid du Colombier 			printf("(state 0)\t[printf('MSC: never\\\\n')]\n");
9667dd7cddfSDavid du Colombier 		} else
967312a1df1SDavid du Colombier 		{	printf("%3d:	proc  - (NEVER) line   %d \"never\"\n",
9687dd7cddfSDavid du Colombier 				depth, newnever);
969312a1df1SDavid du Colombier #endif
9707dd7cddfSDavid du Colombier 		}
9717dd7cddfSDavid du Colombier 		lastnever = newnever;
9727dd7cddfSDavid du Colombier 	}
9737dd7cddfSDavid du Colombier 
974219b2ee8SDavid du Colombier 	whoruns(lnr);
975219b2ee8SDavid du Colombier 	if (e)
976*00d97012SDavid du Colombier 	{	if (e->n)
977*00d97012SDavid du Colombier 		{	char *ptr = e->n->fn->name;
978*00d97012SDavid du Colombier 			char *qtr = nbuf;
979*00d97012SDavid du Colombier 			while (*ptr != '\0')
980*00d97012SDavid du Colombier 			{	if (*ptr != '"')
981*00d97012SDavid du Colombier 				{	*qtr++ = *ptr;
982*00d97012SDavid du Colombier 				}
983*00d97012SDavid du Colombier 				ptr++;
984*00d97012SDavid du Colombier 			}
985*00d97012SDavid du Colombier 			*qtr = '\0';
986*00d97012SDavid du Colombier 		} else
987*00d97012SDavid du Colombier 		{	strcpy(nbuf, "-");
988*00d97012SDavid du Colombier 		}
989*00d97012SDavid du Colombier 		printf("%s:%d (state %d)",
990*00d97012SDavid du Colombier 			nbuf,
991219b2ee8SDavid du Colombier 			e->n?e->n->ln:-1,
992219b2ee8SDavid du Colombier 			e->seqno);
9937dd7cddfSDavid du Colombier 		if (!xspin
9947dd7cddfSDavid du Colombier 		&&  ((e->status&ENDSTATE) || has_lab(e, 2)))	/* 2=end */
9957dd7cddfSDavid du Colombier 		{	printf(" <valid end state>");
9967dd7cddfSDavid du Colombier 		}
9977dd7cddfSDavid du Colombier 	}
998219b2ee8SDavid du Colombier }
999219b2ee8SDavid du Colombier 
1000219b2ee8SDavid du Colombier int
remotelab(Lextok * n)1001219b2ee8SDavid du Colombier remotelab(Lextok *n)
1002219b2ee8SDavid du Colombier {	int i;
1003219b2ee8SDavid du Colombier 
1004219b2ee8SDavid du Colombier 	lineno = n->ln;
1005219b2ee8SDavid du Colombier 	Fname  = n->fn;
1006312a1df1SDavid du Colombier 	if (n->sym->type != 0 && n->sym->type != LABEL)
1007312a1df1SDavid du Colombier 	{	printf("spin: error, type: %d\n", n->sym->type);
1008219b2ee8SDavid du Colombier 		fatal("not a labelname: '%s'", n->sym->name);
1009312a1df1SDavid du Colombier 	}
10107dd7cddfSDavid du Colombier 	if (n->indstep >= 0)
10117dd7cddfSDavid du Colombier 	{	fatal("remote ref to label '%s' inside d_step",
10127dd7cddfSDavid du Colombier 			n->sym->name);
10137dd7cddfSDavid du Colombier 	}
10147dd7cddfSDavid du Colombier 	if ((i = find_lab(n->sym, n->lft->sym, 1)) == 0)
1015219b2ee8SDavid du Colombier 		fatal("unknown labelname: %s", n->sym->name);
1016219b2ee8SDavid du Colombier 	return i;
1017219b2ee8SDavid du Colombier }
1018219b2ee8SDavid du Colombier 
1019219b2ee8SDavid du Colombier int
remotevar(Lextok * n)1020219b2ee8SDavid du Colombier remotevar(Lextok *n)
1021312a1df1SDavid du Colombier {	int prno, i, added=0;
1022312a1df1SDavid du Colombier 	RunList *Y, *oX;
1023312a1df1SDavid du Colombier 	Lextok *onl;
1024312a1df1SDavid du Colombier 	Symbol *os;
1025219b2ee8SDavid du Colombier 
1026219b2ee8SDavid du Colombier 	lineno = n->ln;
1027219b2ee8SDavid du Colombier 	Fname  = n->fn;
1028219b2ee8SDavid du Colombier 
1029312a1df1SDavid du Colombier 	if (!n->lft->lft)
1030312a1df1SDavid du Colombier 		prno = f_pid(n->lft->sym->name);
1031312a1df1SDavid du Colombier 	else
1032312a1df1SDavid du Colombier 	{	prno = eval(n->lft->lft); /* pid - can cause recursive call */
1033312a1df1SDavid du Colombier #if 0
1034312a1df1SDavid du Colombier 		if (n->lft->lft->ntyp == CONST)	/* user-guessed pid */
1035312a1df1SDavid du Colombier #endif
1036312a1df1SDavid du Colombier 		{	prno += Have_claim;
1037312a1df1SDavid du Colombier 			added = Have_claim;
1038312a1df1SDavid du Colombier 	}	}
1039312a1df1SDavid du Colombier 
1040312a1df1SDavid du Colombier 	if (prno < 0)
1041312a1df1SDavid du Colombier 		return 0;	/* non-existing process */
1042312a1df1SDavid du Colombier #if 0
1043312a1df1SDavid du Colombier 	i = nproc - nstop;
1044312a1df1SDavid du Colombier 	for (Y = run; Y; Y = Y->nxt)
1045312a1df1SDavid du Colombier 	{	--i;
1046312a1df1SDavid du Colombier 		printf("	%s: i=%d, prno=%d, ->pid=%d\n", Y->n->name, i, prno, Y->pid);
1047312a1df1SDavid du Colombier 	}
1048312a1df1SDavid du Colombier #endif
1049*00d97012SDavid du Colombier 	i = nproc - nstop + Skip_claim;	/* 6.0: added Skip_claim */
1050219b2ee8SDavid du Colombier 	for (Y = run; Y; Y = Y->nxt)
10517dd7cddfSDavid du Colombier 	if (--i == prno)
1052219b2ee8SDavid du Colombier 	{	if (strcmp(Y->n->name, n->lft->sym->name) != 0)
1053312a1df1SDavid du Colombier 		{	printf("spin: remote reference error on '%s[%d]'\n",
1054312a1df1SDavid du Colombier 				n->lft->sym->name, prno-added);
10557dd7cddfSDavid du Colombier 			non_fatal("refers to wrong proctype '%s'", Y->n->name);
1056219b2ee8SDavid du Colombier 		}
1057219b2ee8SDavid du Colombier 		if (strcmp(n->sym->name, "_p") == 0)
10587dd7cddfSDavid du Colombier 		{	if (Y->pc)
1059219b2ee8SDavid du Colombier 				return Y->pc->seqno;
10607dd7cddfSDavid du Colombier 			/* harmless, can only happen with -t */
10617dd7cddfSDavid du Colombier 			return 0;
10627dd7cddfSDavid du Colombier 		}
1063312a1df1SDavid du Colombier #if 1
1064312a1df1SDavid du Colombier 		/* new 4.0 allow remote variables */
1065312a1df1SDavid du Colombier 		oX = X;
1066312a1df1SDavid du Colombier 		X = Y;
1067312a1df1SDavid du Colombier 
1068312a1df1SDavid du Colombier 		onl = n->lft;
1069312a1df1SDavid du Colombier 		n->lft = n->rgt;
1070312a1df1SDavid du Colombier 
1071312a1df1SDavid du Colombier 		os = n->sym;
1072312a1df1SDavid du Colombier 		n->sym = findloc(n->sym);
1073312a1df1SDavid du Colombier 
1074312a1df1SDavid du Colombier 		i = getval(n);
1075312a1df1SDavid du Colombier 
1076312a1df1SDavid du Colombier 		n->sym = os;
1077312a1df1SDavid du Colombier 		n->lft = onl;
1078312a1df1SDavid du Colombier 		X = oX;
1079312a1df1SDavid du Colombier 		return i;
1080312a1df1SDavid du Colombier #else
1081219b2ee8SDavid du Colombier 		break;
1082312a1df1SDavid du Colombier #endif
1083219b2ee8SDavid du Colombier 	}
1084312a1df1SDavid du Colombier 	printf("remote ref: %s[%d] ", n->lft->sym->name, prno-added);
1085219b2ee8SDavid du Colombier 	non_fatal("%s not found", n->sym->name);
10867dd7cddfSDavid du Colombier 	printf("have only:\n");
10877dd7cddfSDavid du Colombier 	i = nproc - nstop - 1;
10887dd7cddfSDavid du Colombier 	for (Y = run; Y; Y = Y->nxt, i--)
10897dd7cddfSDavid du Colombier 		if (!strcmp(Y->n->name, n->lft->sym->name))
10907dd7cddfSDavid du Colombier 		printf("\t%d\t%s\n", i, Y->n->name);
1091219b2ee8SDavid du Colombier 
1092219b2ee8SDavid du Colombier 	return 0;
1093219b2ee8SDavid du Colombier }
1094