xref: /plan9-contrib/sys/src/cmd/spin/sched.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
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