xref: /plan9-contrib/sys/src/cmd/spin/run.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
1219b2ee8SDavid du Colombier /***** spin: run.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 
13*de2caf28SDavid du Colombier extern RunList	*X_lst, *run_lst;
14219b2ee8SDavid du Colombier extern Symbol	*Fname;
15219b2ee8SDavid du Colombier extern Element	*LastStep;
16*de2caf28SDavid du Colombier extern int	Rvous, lineno, Tval, interactive, MadeChoice, Priority_Sum;
177dd7cddfSDavid du Colombier extern int	TstOnly, verbose, s_trail, xspin, jumpsteps, depth;
18*de2caf28SDavid du Colombier extern int	analyze, nproc, nstop, no_print, like_java, old_priority_rules;
19*de2caf28SDavid du Colombier extern short	Have_claim;
20219b2ee8SDavid du Colombier 
21219b2ee8SDavid du Colombier static long	Seed = 1;
227dd7cddfSDavid du Colombier static int	E_Check = 0, Escape_Check = 0;
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier static int	eval_sync(Element *);
257dd7cddfSDavid du Colombier static int	pc_enabled(Lextok *n);
26*de2caf28SDavid du Colombier static int	get_priority(Lextok *n);
27*de2caf28SDavid du Colombier static void	set_priority(Lextok *n, Lextok *m);
28*de2caf28SDavid du Colombier extern void	sr_buf(int, int, const char *);
29219b2ee8SDavid du Colombier 
30219b2ee8SDavid du Colombier void
Srand(unsigned int s)31219b2ee8SDavid du Colombier Srand(unsigned int s)
32219b2ee8SDavid du Colombier {	Seed = s;
33219b2ee8SDavid du Colombier }
34219b2ee8SDavid du Colombier 
35219b2ee8SDavid du Colombier long
Rand(void)36219b2ee8SDavid du Colombier Rand(void)
37219b2ee8SDavid du Colombier {	/* CACM 31(10), Oct 1988 */
38219b2ee8SDavid du Colombier 	Seed = 16807*(Seed%127773) - 2836*(Seed/127773);
39219b2ee8SDavid du Colombier 	if (Seed <= 0) Seed += 2147483647;
40219b2ee8SDavid du Colombier 	return Seed;
41219b2ee8SDavid du Colombier }
42219b2ee8SDavid du Colombier 
43219b2ee8SDavid du Colombier Element *
rev_escape(SeqList * e)447dd7cddfSDavid du Colombier rev_escape(SeqList *e)
45*de2caf28SDavid du Colombier {	Element *r = (Element *) 0;
467dd7cddfSDavid du Colombier 
47*de2caf28SDavid du Colombier 	if (e)
48*de2caf28SDavid du Colombier 	{	if ((r = rev_escape(e->nxt)) == ZE) /* reversed order */
49*de2caf28SDavid du Colombier 		{	r = eval_sub(e->this->frst);
50*de2caf28SDavid du Colombier 	}	}
517dd7cddfSDavid du Colombier 
527dd7cddfSDavid du Colombier 	return r;
537dd7cddfSDavid du Colombier }
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier Element *
eval_sub(Element * e)56219b2ee8SDavid du Colombier eval_sub(Element *e)
57219b2ee8SDavid du Colombier {	Element *f, *g;
58219b2ee8SDavid du Colombier 	SeqList *z;
5900d97012SDavid du Colombier 	int i, j, k, only_pos;
60219b2ee8SDavid du Colombier 
6100d97012SDavid du Colombier 	if (!e || !e->n)
62219b2ee8SDavid du Colombier 		return ZE;
63219b2ee8SDavid du Colombier #ifdef DEBUG
647dd7cddfSDavid du Colombier 	printf("\n\teval_sub(%d %s: line %d) ",
657dd7cddfSDavid du Colombier 		e->Seqno, e->esc?"+esc":"", e->n?e->n->ln:0);
66219b2ee8SDavid du Colombier 	comment(stdout, e->n, 0);
67219b2ee8SDavid du Colombier 	printf("\n");
68219b2ee8SDavid du Colombier #endif
69219b2ee8SDavid du Colombier 	if (e->n->ntyp == GOTO)
70219b2ee8SDavid du Colombier 	{	if (Rvous) return ZE;
7100d97012SDavid du Colombier 		LastStep = e;
7200d97012SDavid du Colombier 		f = get_lab(e->n, 1);
7300d97012SDavid du Colombier 		f = huntele(f, e->status, -1); /* 5.2.3: was missing */
74219b2ee8SDavid du Colombier 		cross_dsteps(e->n, f->n);
7500d97012SDavid du Colombier #ifdef DEBUG
7600d97012SDavid du Colombier 		printf("GOTO leads to %d\n", f->seqno);
7700d97012SDavid du Colombier #endif
78219b2ee8SDavid du Colombier 		return f;
79219b2ee8SDavid du Colombier 	}
80219b2ee8SDavid du Colombier 	if (e->n->ntyp == UNLESS)
81219b2ee8SDavid du Colombier 	{	/* escapes were distributed into sequence */
82219b2ee8SDavid du Colombier 		return eval_sub(e->sub->this->frst);
83219b2ee8SDavid du Colombier 	} else if (e->sub)	/* true for IF, DO, and UNLESS */
84219b2ee8SDavid du Colombier 	{	Element *has_else = ZE;
857dd7cddfSDavid du Colombier 		Element *bas_else = ZE;
86312a1df1SDavid du Colombier 		int nr_else = 0, nr_choices = 0;
8700d97012SDavid du Colombier 		only_pos = -1;
88219b2ee8SDavid du Colombier 
897dd7cddfSDavid du Colombier 		if (interactive
907dd7cddfSDavid du Colombier 		&& !MadeChoice && !E_Check
917dd7cddfSDavid du Colombier 		&& !Escape_Check
927dd7cddfSDavid du Colombier 		&& !(e->status&(D_ATOM))
937dd7cddfSDavid du Colombier 		&& depth >= jumpsteps)
94219b2ee8SDavid du Colombier 		{	printf("Select stmnt (");
95219b2ee8SDavid du Colombier 			whoruns(0); printf(")\n");
967dd7cddfSDavid du Colombier 			if (nproc-nstop > 1)
9700d97012SDavid du Colombier 			{	printf("\tchoice 0: other process\n");
9800d97012SDavid du Colombier 				nr_choices++;
9900d97012SDavid du Colombier 				only_pos = 0;
10000d97012SDavid du Colombier 		}	}
101219b2ee8SDavid du Colombier 		for (z = e->sub, j=0; z; z = z->nxt)
102219b2ee8SDavid du Colombier 		{	j++;
1037dd7cddfSDavid du Colombier 			if (interactive
1047dd7cddfSDavid du Colombier 			&& !MadeChoice && !E_Check
1057dd7cddfSDavid du Colombier 			&& !Escape_Check
1067dd7cddfSDavid du Colombier 			&& !(e->status&(D_ATOM))
1077dd7cddfSDavid du Colombier 			&& depth >= jumpsteps
108219b2ee8SDavid du Colombier 			&& z->this->frst
1097dd7cddfSDavid du Colombier 			&& (xspin || (verbose&32) || Enabled0(z->this->frst)))
1107dd7cddfSDavid du Colombier 			{	if (z->this->frst->n->ntyp == ELSE)
1117dd7cddfSDavid du Colombier 				{	has_else = (Rvous)?ZE:z->this->frst->nxt;
1127dd7cddfSDavid du Colombier 					nr_else = j;
1137dd7cddfSDavid du Colombier 					continue;
1147dd7cddfSDavid du Colombier 				}
1157dd7cddfSDavid du Colombier 				printf("\tchoice %d: ", j);
1167dd7cddfSDavid du Colombier #if 0
1177dd7cddfSDavid du Colombier 				if (z->this->frst->n)
1187dd7cddfSDavid du Colombier 					printf("line %d, ", z->this->frst->n->ln);
1197dd7cddfSDavid du Colombier #endif
120219b2ee8SDavid du Colombier 				if (!Enabled0(z->this->frst))
121219b2ee8SDavid du Colombier 					printf("unexecutable, ");
1227dd7cddfSDavid du Colombier 				else
12300d97012SDavid du Colombier 				{	nr_choices++;
12400d97012SDavid du Colombier 					only_pos = j;
12500d97012SDavid du Colombier 				}
126219b2ee8SDavid du Colombier 				comment(stdout, z->this->frst->n, 0);
127219b2ee8SDavid du Colombier 				printf("\n");
128219b2ee8SDavid du Colombier 		}	}
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier 		if (nr_choices == 0 && has_else)
13100d97012SDavid du Colombier 		{	printf("\tchoice %d: (else)\n", nr_else);
13200d97012SDavid du Colombier 			only_pos = nr_else;
13300d97012SDavid du Colombier 		}
13400d97012SDavid du Colombier 
13500d97012SDavid du Colombier 		if (nr_choices <= 1 && only_pos != -1 && !MadeChoice)
13600d97012SDavid du Colombier 		{	MadeChoice = only_pos;
13700d97012SDavid du Colombier 		}
1387dd7cddfSDavid du Colombier 
1397dd7cddfSDavid du Colombier 		if (interactive && depth >= jumpsteps
1407dd7cddfSDavid du Colombier 		&& !Escape_Check
1417dd7cddfSDavid du Colombier 		&& !(e->status&(D_ATOM))
1427dd7cddfSDavid du Colombier 		&& !E_Check)
1437dd7cddfSDavid du Colombier 		{	if (!MadeChoice)
1447dd7cddfSDavid du Colombier 			{	char buf[256];
1457dd7cddfSDavid du Colombier 				if (xspin)
146219b2ee8SDavid du Colombier 					printf("Make Selection %d\n\n", j);
147219b2ee8SDavid du Colombier 				else
148219b2ee8SDavid du Colombier 					printf("Select [0-%d]: ", j);
149219b2ee8SDavid du Colombier 				fflush(stdout);
15000d97012SDavid du Colombier 				if (scanf("%64s", buf) <= 0)
15100d97012SDavid du Colombier 				{	printf("no input\n");
15200d97012SDavid du Colombier 					return ZE;
15300d97012SDavid du Colombier 				}
15400d97012SDavid du Colombier 				if (isdigit((int)buf[0]))
1557dd7cddfSDavid du Colombier 					k = atoi(buf);
1567dd7cddfSDavid du Colombier 				else
1577dd7cddfSDavid du Colombier 				{	if (buf[0] == 'q')
1587dd7cddfSDavid du Colombier 						alldone(0);
1597dd7cddfSDavid du Colombier 					k = -1;
1607dd7cddfSDavid du Colombier 				}
161219b2ee8SDavid du Colombier 			} else
1627dd7cddfSDavid du Colombier 			{	k = MadeChoice;
1637dd7cddfSDavid du Colombier 				MadeChoice = 0;
164219b2ee8SDavid du Colombier 			}
165219b2ee8SDavid du Colombier 			if (k < 1 || k > j)
1667dd7cddfSDavid du Colombier 			{	if (k != 0) printf("\tchoice outside range\n");
167219b2ee8SDavid du Colombier 				return ZE;
168219b2ee8SDavid du Colombier 			}
169219b2ee8SDavid du Colombier 			k--;
170219b2ee8SDavid du Colombier 		} else
1717dd7cddfSDavid du Colombier 		{	if (e->n && e->n->indstep >= 0)
1727dd7cddfSDavid du Colombier 				k = 0;	/* select 1st executable guard */
1737dd7cddfSDavid du Colombier 			else
174219b2ee8SDavid du Colombier 				k = Rand()%j;	/* nondeterminism */
1757dd7cddfSDavid du Colombier 		}
17600d97012SDavid du Colombier 
1777dd7cddfSDavid du Colombier 		has_else = ZE;
1787dd7cddfSDavid du Colombier 		bas_else = ZE;
179219b2ee8SDavid du Colombier 		for (i = 0, z = e->sub; i < j+k; i++)
180219b2ee8SDavid du Colombier 		{	if (z->this->frst
181219b2ee8SDavid du Colombier 			&&  z->this->frst->n->ntyp == ELSE)
1827dd7cddfSDavid du Colombier 			{	bas_else = z->this->frst;
1837dd7cddfSDavid du Colombier 				has_else = (Rvous)?ZE:bas_else->nxt;
1847dd7cddfSDavid du Colombier 				if (!interactive || depth < jumpsteps
1857dd7cddfSDavid du Colombier 				|| Escape_Check
1867dd7cddfSDavid du Colombier 				|| (e->status&(D_ATOM)))
187219b2ee8SDavid du Colombier 				{	z = (z->nxt)?z->nxt:e->sub;
188219b2ee8SDavid du Colombier 					continue;
1897dd7cddfSDavid du Colombier 				}
1907dd7cddfSDavid du Colombier 			}
191312a1df1SDavid du Colombier 			if (z->this->frst
192312a1df1SDavid du Colombier 			&&  ((z->this->frst->n->ntyp == ATOMIC
193312a1df1SDavid du Colombier 			  ||  z->this->frst->n->ntyp == D_STEP)
194312a1df1SDavid du Colombier 			  &&  z->this->frst->n->sl->this->frst->n->ntyp == ELSE))
195312a1df1SDavid du Colombier 			{	bas_else = z->this->frst->n->sl->this->frst;
196312a1df1SDavid du Colombier 				has_else = (Rvous)?ZE:bas_else->nxt;
197312a1df1SDavid du Colombier 				if (!interactive || depth < jumpsteps
198312a1df1SDavid du Colombier 				|| Escape_Check
199312a1df1SDavid du Colombier 				|| (e->status&(D_ATOM)))
200312a1df1SDavid du Colombier 				{	z = (z->nxt)?z->nxt:e->sub;
201312a1df1SDavid du Colombier 					continue;
202312a1df1SDavid du Colombier 				}
203312a1df1SDavid du Colombier 			}
204219b2ee8SDavid du Colombier 			if (i >= k)
205312a1df1SDavid du Colombier 			{	if ((f = eval_sub(z->this->frst)) != ZE)
206219b2ee8SDavid du Colombier 					return f;
2077dd7cddfSDavid du Colombier 				else if (interactive && depth >= jumpsteps
2087dd7cddfSDavid du Colombier 				&& !(e->status&(D_ATOM)))
2097dd7cddfSDavid du Colombier 				{	if (!E_Check && !Escape_Check)
2107dd7cddfSDavid du Colombier 						printf("\tunexecutable\n");
211219b2ee8SDavid du Colombier 					return ZE;
212219b2ee8SDavid du Colombier 			}	}
213219b2ee8SDavid du Colombier 			z = (z->nxt)?z->nxt:e->sub;
214219b2ee8SDavid du Colombier 		}
2157dd7cddfSDavid du Colombier 		LastStep = bas_else;
216219b2ee8SDavid du Colombier 		return has_else;
217219b2ee8SDavid du Colombier 	} else
218219b2ee8SDavid du Colombier 	{	if (e->n->ntyp == ATOMIC
219219b2ee8SDavid du Colombier 		||  e->n->ntyp == D_STEP)
220219b2ee8SDavid du Colombier 		{	f = e->n->sl->this->frst;
221219b2ee8SDavid du Colombier 			g = e->n->sl->this->last;
222219b2ee8SDavid du Colombier 			g->nxt = e->nxt;
223219b2ee8SDavid du Colombier 			if (!(g = eval_sub(f)))	/* atomic guard */
224219b2ee8SDavid du Colombier 				return ZE;
225219b2ee8SDavid du Colombier 			return g;
226219b2ee8SDavid du Colombier 		} else if (e->n->ntyp == NON_ATOMIC)
227219b2ee8SDavid du Colombier 		{	f = e->n->sl->this->frst;
228219b2ee8SDavid du Colombier 			g = e->n->sl->this->last;
229219b2ee8SDavid du Colombier 			g->nxt = e->nxt;		/* close it */
230219b2ee8SDavid du Colombier 			return eval_sub(f);
231219b2ee8SDavid du Colombier 		} else if (e->n->ntyp == '.')
2327dd7cddfSDavid du Colombier 		{	if (!Rvous) return e->nxt;
2337dd7cddfSDavid du Colombier 			return eval_sub(e->nxt);
234219b2ee8SDavid du Colombier 		} else
235219b2ee8SDavid du Colombier 		{	SeqList *x;
2367dd7cddfSDavid du Colombier 			if (!(e->status & (D_ATOM))
237*de2caf28SDavid du Colombier 			&&  e->esc && (verbose&32))
2387dd7cddfSDavid du Colombier 			{	printf("Stmnt [");
239219b2ee8SDavid du Colombier 				comment(stdout, e->n, 0);
2407dd7cddfSDavid du Colombier 				printf("] has escape(s): ");
241219b2ee8SDavid du Colombier 				for (x = e->esc; x; x = x->nxt)
2427dd7cddfSDavid du Colombier 				{	printf("[");
2437dd7cddfSDavid du Colombier 					g = x->this->frst;
2447dd7cddfSDavid du Colombier 					if (g->n->ntyp == ATOMIC
2457dd7cddfSDavid du Colombier 					||  g->n->ntyp == NON_ATOMIC)
2467dd7cddfSDavid du Colombier 						g = g->n->sl->this->frst;
2477dd7cddfSDavid du Colombier 					comment(stdout, g->n, 0);
2487dd7cddfSDavid du Colombier 					printf("] ");
2497dd7cddfSDavid du Colombier 				}
2507dd7cddfSDavid du Colombier 				printf("\n");
2517dd7cddfSDavid du Colombier 			}
252312a1df1SDavid du Colombier #if 0
2537dd7cddfSDavid du Colombier 			if (!(e->status & D_ATOM))	/* escapes don't reach inside d_steps */
254312a1df1SDavid du Colombier 			/* 4.2.4: only the guard of a d_step can have an escape */
255312a1df1SDavid du Colombier #endif
25600d97012SDavid du Colombier #if 1
25700d97012SDavid du Colombier 			if (!s_trail)	/* trail determines selections, new 5.2.5 */
25800d97012SDavid du Colombier #endif
2597dd7cddfSDavid du Colombier 			{	Escape_Check++;
2607dd7cddfSDavid du Colombier 				if (like_java)
261312a1df1SDavid du Colombier 				{	if ((g = rev_escape(e->esc)) != ZE)
2627dd7cddfSDavid du Colombier 					{	if (verbose&4)
263*de2caf28SDavid du Colombier 						{	printf("\tEscape taken (-J) ");
264*de2caf28SDavid du Colombier 							if (g->n && g->n->fn)
265*de2caf28SDavid du Colombier 								printf("%s:%d", g->n->fn->name, g->n->ln);
266*de2caf28SDavid du Colombier 							printf("\n");
267*de2caf28SDavid du Colombier 						}
2687dd7cddfSDavid du Colombier 						Escape_Check--;
2697dd7cddfSDavid du Colombier 						return g;
2707dd7cddfSDavid du Colombier 					}
2717dd7cddfSDavid du Colombier 				} else
2727dd7cddfSDavid du Colombier 				{	for (x = e->esc; x; x = x->nxt)
273312a1df1SDavid du Colombier 					{	if ((g = eval_sub(x->this->frst)) != ZE)
274219b2ee8SDavid du Colombier 						{	if (verbose&4)
27500d97012SDavid du Colombier 							{	printf("\tEscape taken ");
27600d97012SDavid du Colombier 								if (g->n && g->n->fn)
27700d97012SDavid du Colombier 									printf("%s:%d", g->n->fn->name, g->n->ln);
27800d97012SDavid du Colombier 								printf("\n");
27900d97012SDavid du Colombier 							}
2807dd7cddfSDavid du Colombier 							Escape_Check--;
281219b2ee8SDavid du Colombier 							return g;
2827dd7cddfSDavid du Colombier 				}	}	}
2837dd7cddfSDavid du Colombier 				Escape_Check--;
2847dd7cddfSDavid du Colombier 			}
285219b2ee8SDavid du Colombier 			switch (e->n->ntyp) {
286*de2caf28SDavid du Colombier 			case ASGN:
287*de2caf28SDavid du Colombier 				if (check_track(e->n) == STRUCT) { break; }
288*de2caf28SDavid du Colombier 				/* else fall thru */
289219b2ee8SDavid du Colombier 			case TIMEOUT: case RUN:
290312a1df1SDavid du Colombier 			case PRINT: case PRINTM:
291312a1df1SDavid du Colombier 			case C_CODE: case C_EXPR:
292*de2caf28SDavid du Colombier 			case ASSERT:
293219b2ee8SDavid du Colombier 			case 's': case 'r': case 'c':
294219b2ee8SDavid du Colombier 				/* toplevel statements only */
295219b2ee8SDavid du Colombier 				LastStep = e;
296219b2ee8SDavid du Colombier 			default:
297219b2ee8SDavid du Colombier 				break;
298219b2ee8SDavid du Colombier 			}
2997dd7cddfSDavid du Colombier 			if (Rvous)
3007dd7cddfSDavid du Colombier 			{
3017dd7cddfSDavid du Colombier 				return (eval_sync(e))?e->nxt:ZE;
3027dd7cddfSDavid du Colombier 			}
303219b2ee8SDavid du Colombier 			return (eval(e->n))?e->nxt:ZE;
304219b2ee8SDavid du Colombier 		}
305219b2ee8SDavid du Colombier 	}
3067dd7cddfSDavid du Colombier 	return ZE; /* not reached */
307219b2ee8SDavid du Colombier }
308219b2ee8SDavid du Colombier 
3097dd7cddfSDavid du Colombier static int
eval_sync(Element * e)310219b2ee8SDavid du Colombier eval_sync(Element *e)
311219b2ee8SDavid du Colombier {	/* allow only synchronous receives
3127dd7cddfSDavid du Colombier 	   and related node types    */
313219b2ee8SDavid du Colombier 	Lextok *now = (e)?e->n:ZN;
314219b2ee8SDavid du Colombier 
315219b2ee8SDavid du Colombier 	if (!now
316219b2ee8SDavid du Colombier 	||  now->ntyp != 'r'
3177dd7cddfSDavid du Colombier 	||  now->val >= 2	/* no rv with a poll */
318219b2ee8SDavid du Colombier 	||  !q_is_sync(now))
3197dd7cddfSDavid du Colombier 	{
320219b2ee8SDavid du Colombier 		return 0;
3217dd7cddfSDavid du Colombier 	}
322219b2ee8SDavid du Colombier 
323219b2ee8SDavid du Colombier 	LastStep = e;
324219b2ee8SDavid du Colombier 	return eval(now);
325219b2ee8SDavid du Colombier }
326219b2ee8SDavid du Colombier 
3277dd7cddfSDavid du Colombier static int
assign(Lextok * now)328219b2ee8SDavid du Colombier assign(Lextok *now)
329219b2ee8SDavid du Colombier {	int t;
330219b2ee8SDavid du Colombier 
331219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
332219b2ee8SDavid du Colombier 
333219b2ee8SDavid du Colombier 	switch (now->rgt->ntyp) {
334219b2ee8SDavid du Colombier 	case FULL:	case NFULL:
335219b2ee8SDavid du Colombier 	case EMPTY:	case NEMPTY:
336219b2ee8SDavid du Colombier 	case RUN:	case LEN:
337219b2ee8SDavid du Colombier 		t = BYTE;
338219b2ee8SDavid du Colombier 		break;
339219b2ee8SDavid du Colombier 	default:
340219b2ee8SDavid du Colombier 		t = Sym_typ(now->rgt);
341219b2ee8SDavid du Colombier 		break;
342219b2ee8SDavid du Colombier 	}
343219b2ee8SDavid du Colombier 	typ_ck(Sym_typ(now->lft), t, "assignment");
344*de2caf28SDavid du Colombier 
345219b2ee8SDavid du Colombier 	return setval(now->lft, eval(now->rgt));
346219b2ee8SDavid du Colombier }
347219b2ee8SDavid du Colombier 
3487dd7cddfSDavid du Colombier static int
nonprogress(void)3497dd7cddfSDavid du Colombier nonprogress(void)	/* np_ */
3507dd7cddfSDavid du Colombier {	RunList	*r;
3517dd7cddfSDavid du Colombier 
352*de2caf28SDavid du Colombier 	for (r = run_lst; r; r = r->nxt)
3537dd7cddfSDavid du Colombier 	{	if (has_lab(r->pc, 4))	/* 4=progress */
3547dd7cddfSDavid du Colombier 			return 0;
3557dd7cddfSDavid du Colombier 	}
3567dd7cddfSDavid du Colombier 	return 1;
3577dd7cddfSDavid du Colombier }
3587dd7cddfSDavid du Colombier 
359219b2ee8SDavid du Colombier int
eval(Lextok * now)360219b2ee8SDavid du Colombier eval(Lextok *now)
361*de2caf28SDavid du Colombier {	int temp;
362*de2caf28SDavid du Colombier 
363219b2ee8SDavid du Colombier 	if (now) {
364219b2ee8SDavid du Colombier 	lineno = now->ln;
365219b2ee8SDavid du Colombier 	Fname  = now->fn;
366219b2ee8SDavid du Colombier #ifdef DEBUG
367219b2ee8SDavid du Colombier 	printf("eval ");
368219b2ee8SDavid du Colombier 	comment(stdout, now, 0);
369219b2ee8SDavid du Colombier 	printf("\n");
370219b2ee8SDavid du Colombier #endif
371219b2ee8SDavid du Colombier 	switch (now->ntyp) {
372219b2ee8SDavid du Colombier 	case CONST: return now->val;
373219b2ee8SDavid du Colombier 	case   '!': return !eval(now->lft);
374219b2ee8SDavid du Colombier 	case  UMIN: return -eval(now->lft);
375219b2ee8SDavid du Colombier 	case   '~': return ~eval(now->lft);
376219b2ee8SDavid du Colombier 
377*de2caf28SDavid du Colombier 	case   '/': temp = eval(now->rgt);
378*de2caf28SDavid du Colombier 		    if (temp == 0)
379*de2caf28SDavid du Colombier 		    {	fatal("division by zero", (char *) 0);
380*de2caf28SDavid du Colombier 		    }
381*de2caf28SDavid du Colombier 		    return (eval(now->lft) / temp);
382219b2ee8SDavid du Colombier 	case   '*': return (eval(now->lft) * eval(now->rgt));
383219b2ee8SDavid du Colombier 	case   '-': return (eval(now->lft) - eval(now->rgt));
384219b2ee8SDavid du Colombier 	case   '+': return (eval(now->lft) + eval(now->rgt));
385*de2caf28SDavid du Colombier 	case   '%': temp = eval(now->rgt);
386*de2caf28SDavid du Colombier 		    if (temp == 0)
387*de2caf28SDavid du Colombier 		    {	fatal("taking modulo of zero", (char *) 0);
388*de2caf28SDavid du Colombier 		    }
389*de2caf28SDavid du Colombier 		    return (eval(now->lft) % temp);
390219b2ee8SDavid du Colombier 	case    LT: return (eval(now->lft) <  eval(now->rgt));
391219b2ee8SDavid du Colombier 	case    GT: return (eval(now->lft) >  eval(now->rgt));
392219b2ee8SDavid du Colombier 	case   '&': return (eval(now->lft) &  eval(now->rgt));
3937dd7cddfSDavid du Colombier 	case   '^': return (eval(now->lft) ^  eval(now->rgt));
394219b2ee8SDavid du Colombier 	case   '|': return (eval(now->lft) |  eval(now->rgt));
395219b2ee8SDavid du Colombier 	case    LE: return (eval(now->lft) <= eval(now->rgt));
396219b2ee8SDavid du Colombier 	case    GE: return (eval(now->lft) >= eval(now->rgt));
397219b2ee8SDavid du Colombier 	case    NE: return (eval(now->lft) != eval(now->rgt));
398219b2ee8SDavid du Colombier 	case    EQ: return (eval(now->lft) == eval(now->rgt));
399219b2ee8SDavid du Colombier 	case    OR: return (eval(now->lft) || eval(now->rgt));
400219b2ee8SDavid du Colombier 	case   AND: return (eval(now->lft) && eval(now->rgt));
401219b2ee8SDavid du Colombier 	case LSHIFT: return (eval(now->lft) << eval(now->rgt));
402219b2ee8SDavid du Colombier 	case RSHIFT: return (eval(now->lft) >> eval(now->rgt));
403219b2ee8SDavid du Colombier 	case   '?': return (eval(now->lft) ? eval(now->rgt->lft)
404219b2ee8SDavid du Colombier 					   : eval(now->rgt->rgt));
405219b2ee8SDavid du Colombier 
406312a1df1SDavid du Colombier 	case     'p': return remotevar(now);	/* _p for remote reference */
407219b2ee8SDavid du Colombier 	case     'q': return remotelab(now);
408219b2ee8SDavid du Colombier 	case     'R': return qrecv(now, 0);	/* test only    */
409219b2ee8SDavid du Colombier 	case     LEN: return qlen(now);
410219b2ee8SDavid du Colombier 	case    FULL: return (qfull(now));
411219b2ee8SDavid du Colombier 	case   EMPTY: return (qlen(now)==0);
412219b2ee8SDavid du Colombier 	case   NFULL: return (!qfull(now));
413219b2ee8SDavid du Colombier 	case  NEMPTY: return (qlen(now)>0);
4147dd7cddfSDavid du Colombier 	case ENABLED: if (s_trail) return 1;
4157dd7cddfSDavid du Colombier 		      return pc_enabled(now->lft);
416*de2caf28SDavid du Colombier 
417*de2caf28SDavid du Colombier 	case GET_P: return get_priority(now->lft);
418*de2caf28SDavid du Colombier 	case SET_P: set_priority(now->lft->lft, now->lft->rgt); return 1;
419*de2caf28SDavid du Colombier 
420*de2caf28SDavid du Colombier 	case    EVAL:	if (now->lft->ntyp == ',')
421*de2caf28SDavid du Colombier 			{	Lextok *fix = now->lft;
422*de2caf28SDavid du Colombier 				do {					/* new */
423*de2caf28SDavid du Colombier 					if (eval(fix->lft) == 0)	/* usertype6 */
424*de2caf28SDavid du Colombier 					{	return 0;
425*de2caf28SDavid du Colombier 					}
426*de2caf28SDavid du Colombier 					fix = fix->rgt;
427*de2caf28SDavid du Colombier 				} while (fix && fix->ntyp == ',');
428*de2caf28SDavid du Colombier 				return 1;
429*de2caf28SDavid du Colombier 			}
430*de2caf28SDavid du Colombier 			return eval(now->lft);
431*de2caf28SDavid du Colombier 
432219b2ee8SDavid du Colombier 	case  PC_VAL: return pc_value(now->lft);
4337dd7cddfSDavid du Colombier 	case NONPROGRESS: return nonprogress();
434219b2ee8SDavid du Colombier 	case    NAME: return getval(now);
435219b2ee8SDavid du Colombier 
436219b2ee8SDavid du Colombier 	case TIMEOUT: return Tval;
4377dd7cddfSDavid du Colombier 	case     RUN: return TstOnly?1:enable(now);
438219b2ee8SDavid du Colombier 
439219b2ee8SDavid du Colombier 	case   's': return qsend(now);		/* send         */
4407dd7cddfSDavid du Colombier 	case   'r': return qrecv(now, 1);	/* receive or poll */
441219b2ee8SDavid du Colombier 	case   'c': return eval(now->lft);	/* condition    */
4427dd7cddfSDavid du Colombier 	case PRINT: return TstOnly?1:interprint(stdout, now);
443312a1df1SDavid du Colombier 	case PRINTM: return TstOnly?1:printm(stdout, now);
444*de2caf28SDavid du Colombier 	case  ASGN:
445*de2caf28SDavid du Colombier 		if (check_track(now) == STRUCT) { return 1; }
446*de2caf28SDavid du Colombier 		return assign(now);
447312a1df1SDavid du Colombier 
44800d97012SDavid du Colombier 	case C_CODE: if (!analyze)
44900d97012SDavid du Colombier 		     {	printf("%s:\t", now->sym->name);
45000d97012SDavid du Colombier 		     	plunk_inline(stdout, now->sym->name, 0, 1);
45100d97012SDavid du Colombier 		     }
452312a1df1SDavid du Colombier 		     return 1; /* uninterpreted */
453312a1df1SDavid du Colombier 
45400d97012SDavid du Colombier 	case C_EXPR: if (!analyze)
45500d97012SDavid du Colombier 		     {	printf("%s:\t", now->sym->name);
456312a1df1SDavid du Colombier 		     	plunk_expr(stdout, now->sym->name);
457312a1df1SDavid du Colombier 		     	printf("\n");
45800d97012SDavid du Colombier 		     }
459312a1df1SDavid du Colombier 		     return 1; /* uninterpreted */
460312a1df1SDavid du Colombier 
461219b2ee8SDavid du Colombier 	case ASSERT: if (TstOnly || eval(now->lft)) return 1;
462219b2ee8SDavid du Colombier 		     non_fatal("assertion violated", (char *) 0);
4637dd7cddfSDavid du Colombier 			printf("spin: text of failed assertion: assert(");
4647dd7cddfSDavid du Colombier 			comment(stdout, now->lft, 0);
4657dd7cddfSDavid du Colombier 			printf(")\n");
4667dd7cddfSDavid du Colombier 		     if (s_trail && !xspin) return 1;
467219b2ee8SDavid du Colombier 		     wrapup(1); /* doesn't return */
468219b2ee8SDavid du Colombier 
4697dd7cddfSDavid du Colombier 	case  IF: case DO: case BREAK: case UNLESS:	/* compound */
470219b2ee8SDavid du Colombier 	case   '.': return 1;	/* return label for compound */
471219b2ee8SDavid du Colombier 	case   '@': return 0;	/* stop state */
472219b2ee8SDavid du Colombier 	case  ELSE: return 1;	/* only hit here in guided trails */
473*de2caf28SDavid du Colombier 
474*de2caf28SDavid du Colombier 	case ',':	/* reached through option -A with array initializer */
475*de2caf28SDavid du Colombier 	case 0:
476*de2caf28SDavid du Colombier 		    return 0;	/* not great, but safe */
477*de2caf28SDavid du Colombier 
478219b2ee8SDavid du Colombier 	default   : printf("spin: bad node type %d (run)\n", now->ntyp);
4797dd7cddfSDavid du Colombier 		    if (s_trail) printf("spin: trail file doesn't match spec?\n");
480219b2ee8SDavid du Colombier 		    fatal("aborting", 0);
481219b2ee8SDavid du Colombier 	}}
482219b2ee8SDavid du Colombier 	return 0;
483219b2ee8SDavid du Colombier }
484219b2ee8SDavid du Colombier 
485219b2ee8SDavid du Colombier int
printm(FILE * fd,Lextok * n)486312a1df1SDavid du Colombier printm(FILE *fd, Lextok *n)
487*de2caf28SDavid du Colombier {	extern char GBuf[];
488*de2caf28SDavid du Colombier 	char *s = 0;
489312a1df1SDavid du Colombier 	int j;
490312a1df1SDavid du Colombier 
491*de2caf28SDavid du Colombier 	GBuf[0] = '\0';
492312a1df1SDavid du Colombier 	if (!no_print)
493*de2caf28SDavid du Colombier 	if (!s_trail || depth >= jumpsteps)
494*de2caf28SDavid du Colombier 	{
495*de2caf28SDavid du Colombier 		if (n->lft->sym
496*de2caf28SDavid du Colombier 		&&  n->lft->sym->mtype_name)
497*de2caf28SDavid du Colombier 		{	s = n->lft->sym->mtype_name->name;
498*de2caf28SDavid du Colombier 		}
499*de2caf28SDavid du Colombier 
500312a1df1SDavid du Colombier 		if (n->lft->ismtyp)
501*de2caf28SDavid du Colombier 		{	j = n->lft->val;
502*de2caf28SDavid du Colombier 		} else	/* constant */
503*de2caf28SDavid du Colombier 		{	j = eval(n->lft);
504*de2caf28SDavid du Colombier 		}
505*de2caf28SDavid du Colombier 		sr_buf(j, 1, s);
506*de2caf28SDavid du Colombier 		dotag(fd, GBuf);
507312a1df1SDavid du Colombier 	}
508312a1df1SDavid du Colombier 	return 1;
509312a1df1SDavid du Colombier }
510312a1df1SDavid du Colombier 
511312a1df1SDavid du Colombier int
interprint(FILE * fd,Lextok * n)5127dd7cddfSDavid du Colombier interprint(FILE *fd, Lextok *n)
513219b2ee8SDavid du Colombier {	Lextok *tmp = n->lft;
514*de2caf28SDavid du Colombier 	char c, *s = n->sym->name, *t = 0;
51500d97012SDavid du Colombier 	int i, j; char lbuf[512]; /* matches value in sr_buf() */
516*de2caf28SDavid du Colombier 	extern char GBuf[];	/* global, size 4096 */
517*de2caf28SDavid du Colombier 	char tBuf[4096];	/* match size of global GBuf[] */
518219b2ee8SDavid du Colombier 
519*de2caf28SDavid du Colombier 	GBuf[0] = '\0';
5207dd7cddfSDavid du Colombier 	if (!no_print)
5217dd7cddfSDavid du Colombier 	if (!s_trail || depth >= jumpsteps) {
5227dd7cddfSDavid du Colombier 	for (i = 0; i < (int) strlen(s); i++)
523219b2ee8SDavid du Colombier 		switch (s[i]) {
524219b2ee8SDavid du Colombier 		case '\"': break; /* ignore */
525219b2ee8SDavid du Colombier 		case '\\':
526219b2ee8SDavid du Colombier 			 switch(s[++i]) {
527*de2caf28SDavid du Colombier 			 case 't': strcat(GBuf, "\t"); break;
528*de2caf28SDavid du Colombier 			 case 'n': strcat(GBuf, "\n"); break;
5297dd7cddfSDavid du Colombier 			 default:  goto onechar;
530219b2ee8SDavid du Colombier 			 }
531219b2ee8SDavid du Colombier 			 break;
532219b2ee8SDavid du Colombier 		case  '%':
533219b2ee8SDavid du Colombier 			 if ((c = s[++i]) == '%')
534*de2caf28SDavid du Colombier 			 {	strcat(GBuf, "%"); /* literal */
535219b2ee8SDavid du Colombier 				break;
536219b2ee8SDavid du Colombier 			 }
537219b2ee8SDavid du Colombier 			 if (!tmp)
538219b2ee8SDavid du Colombier 			 {	non_fatal("too few print args %s", s);
539219b2ee8SDavid du Colombier 				break;
540219b2ee8SDavid du Colombier 			 }
541219b2ee8SDavid du Colombier 			 j = eval(tmp->lft);
542*de2caf28SDavid du Colombier 
543*de2caf28SDavid du Colombier 			 if (c == 'e'
544*de2caf28SDavid du Colombier 			 &&  tmp->lft
545*de2caf28SDavid du Colombier 			 &&  tmp->lft->sym
546*de2caf28SDavid du Colombier 			 &&  tmp->lft->sym->mtype_name)
547*de2caf28SDavid du Colombier 			 {	t = tmp->lft->sym->mtype_name->name;
548*de2caf28SDavid du Colombier 			 }
549*de2caf28SDavid du Colombier 
550219b2ee8SDavid du Colombier 			 tmp = tmp->rgt;
551219b2ee8SDavid du Colombier 			 switch(c) {
5527dd7cddfSDavid du Colombier 			 case 'c': sprintf(lbuf, "%c", j); break;
5537dd7cddfSDavid du Colombier 			 case 'd': sprintf(lbuf, "%d", j); break;
5547dd7cddfSDavid du Colombier 
555*de2caf28SDavid du Colombier 			 case 'e': strcpy(tBuf, GBuf);	/* event name */
556*de2caf28SDavid du Colombier 				   GBuf[0] = '\0';
557*de2caf28SDavid du Colombier 
558*de2caf28SDavid du Colombier 				   sr_buf(j, 1, t);
559*de2caf28SDavid du Colombier 
560*de2caf28SDavid du Colombier 				   strcpy(lbuf, GBuf);
561*de2caf28SDavid du Colombier 				   strcpy(GBuf, tBuf);
5627dd7cddfSDavid du Colombier 				   break;
5637dd7cddfSDavid du Colombier 
5647dd7cddfSDavid du Colombier 			 case 'o': sprintf(lbuf, "%o", j); break;
5657dd7cddfSDavid du Colombier 			 case 'u': sprintf(lbuf, "%u", (unsigned) j); break;
5667dd7cddfSDavid du Colombier 			 case 'x': sprintf(lbuf, "%x", j); break;
5677dd7cddfSDavid du Colombier 			 default:  non_fatal("bad print cmd: '%s'", &s[i-1]);
5687dd7cddfSDavid du Colombier 				   lbuf[0] = '\0'; break;
5697dd7cddfSDavid du Colombier 			 }
5707dd7cddfSDavid du Colombier 			 goto append;
5717dd7cddfSDavid du Colombier 		default:
5727dd7cddfSDavid du Colombier onechar:		 lbuf[0] = s[i]; lbuf[1] = '\0';
573*de2caf28SDavid du Colombier append:			 strcat(GBuf, lbuf);
574219b2ee8SDavid du Colombier 			 break;
575219b2ee8SDavid du Colombier 		}
576*de2caf28SDavid du Colombier 		dotag(fd, GBuf);
577219b2ee8SDavid du Colombier 	}
578*de2caf28SDavid du Colombier 	if (strlen(GBuf) >= 4096) fatal("printf string too long", 0);
579219b2ee8SDavid du Colombier 	return 1;
580219b2ee8SDavid du Colombier }
581219b2ee8SDavid du Colombier 
5827dd7cddfSDavid du Colombier static int
Enabled1(Lextok * n)583219b2ee8SDavid du Colombier Enabled1(Lextok *n)
584219b2ee8SDavid du Colombier {	int i; int v = verbose;
585219b2ee8SDavid du Colombier 
586219b2ee8SDavid du Colombier 	if (n)
587219b2ee8SDavid du Colombier 	switch (n->ntyp) {
5887dd7cddfSDavid du Colombier 	case 'c':
5897dd7cddfSDavid du Colombier 		if (has_typ(n->lft, RUN))
5907dd7cddfSDavid du Colombier 			return 1;	/* conservative */
5917dd7cddfSDavid du Colombier 		/* else fall through */
592219b2ee8SDavid du Colombier 	default:	/* side-effect free */
593219b2ee8SDavid du Colombier 		verbose = 0;
5947dd7cddfSDavid du Colombier 		E_Check++;
595219b2ee8SDavid du Colombier 		i = eval(n);
5967dd7cddfSDavid du Colombier 		E_Check--;
597219b2ee8SDavid du Colombier 		verbose = v;
598219b2ee8SDavid du Colombier 		return i;
599219b2ee8SDavid du Colombier 
600*de2caf28SDavid du Colombier 	case SET_P:
601312a1df1SDavid du Colombier 	case C_CODE: case C_EXPR:
602312a1df1SDavid du Colombier 	case PRINT: case PRINTM:
603312a1df1SDavid du Colombier 	case   ASGN: case ASSERT:
604219b2ee8SDavid du Colombier 		return 1;
605219b2ee8SDavid du Colombier 
6067dd7cddfSDavid du Colombier 	case 's':
6077dd7cddfSDavid du Colombier 		if (q_is_sync(n))
6087dd7cddfSDavid du Colombier 		{	if (Rvous) return 0;
6097dd7cddfSDavid du Colombier 			TstOnly = 1; verbose = 0;
6107dd7cddfSDavid du Colombier 			E_Check++;
611219b2ee8SDavid du Colombier 			i = eval(n);
6127dd7cddfSDavid du Colombier 			E_Check--;
6137dd7cddfSDavid du Colombier 			TstOnly = 0; verbose = v;
6147dd7cddfSDavid du Colombier 			return i;
6157dd7cddfSDavid du Colombier 		}
6167dd7cddfSDavid du Colombier 		return (!qfull(n));
6177dd7cddfSDavid du Colombier 	case 'r':
6187dd7cddfSDavid du Colombier 		if (q_is_sync(n))
6197dd7cddfSDavid du Colombier 			return 0;	/* it's never a user-choice */
6207dd7cddfSDavid du Colombier 		n->ntyp = 'R'; verbose = 0;
6217dd7cddfSDavid du Colombier 		E_Check++;
6227dd7cddfSDavid du Colombier 		i = eval(n);
6237dd7cddfSDavid du Colombier 		E_Check--;
624219b2ee8SDavid du Colombier 		n->ntyp = 'r'; verbose = v;
625219b2ee8SDavid du Colombier 		return i;
626219b2ee8SDavid du Colombier 	}
627219b2ee8SDavid du Colombier 	return 0;
628219b2ee8SDavid du Colombier }
629219b2ee8SDavid du Colombier 
630219b2ee8SDavid du Colombier int
Enabled0(Element * e)631219b2ee8SDavid du Colombier Enabled0(Element *e)
632219b2ee8SDavid du Colombier {	SeqList *z;
633219b2ee8SDavid du Colombier 
634219b2ee8SDavid du Colombier 	if (!e || !e->n)
635219b2ee8SDavid du Colombier 		return 0;
636219b2ee8SDavid du Colombier 
637219b2ee8SDavid du Colombier 	switch (e->n->ntyp) {
6387dd7cddfSDavid du Colombier 	case '@':
639*de2caf28SDavid du Colombier 		return X_lst->pid == (nproc-nstop-1);
640219b2ee8SDavid du Colombier 	case '.':
641*de2caf28SDavid du Colombier 	case SET_P:
642219b2ee8SDavid du Colombier 		return 1;
643219b2ee8SDavid du Colombier 	case GOTO:
644219b2ee8SDavid du Colombier 		if (Rvous) return 0;
645219b2ee8SDavid du Colombier 		return 1;
646219b2ee8SDavid du Colombier 	case UNLESS:
647219b2ee8SDavid du Colombier 		return Enabled0(e->sub->this->frst);
648219b2ee8SDavid du Colombier 	case ATOMIC:
649219b2ee8SDavid du Colombier 	case D_STEP:
650219b2ee8SDavid du Colombier 	case NON_ATOMIC:
651219b2ee8SDavid du Colombier 		return Enabled0(e->n->sl->this->frst);
652219b2ee8SDavid du Colombier 	}
653219b2ee8SDavid du Colombier 	if (e->sub)	/* true for IF, DO, and UNLESS */
654219b2ee8SDavid du Colombier 	{	for (z = e->sub; z; z = z->nxt)
655219b2ee8SDavid du Colombier 			if (Enabled0(z->this->frst))
656219b2ee8SDavid du Colombier 				return 1;
657219b2ee8SDavid du Colombier 		return 0;
658219b2ee8SDavid du Colombier 	}
659219b2ee8SDavid du Colombier 	for (z = e->esc; z; z = z->nxt)
660219b2ee8SDavid du Colombier 	{	if (Enabled0(z->this->frst))
661219b2ee8SDavid du Colombier 			return 1;
662219b2ee8SDavid du Colombier 	}
6637dd7cddfSDavid du Colombier #if 0
6647dd7cddfSDavid du Colombier 	printf("enabled1 ");
6657dd7cddfSDavid du Colombier 	comment(stdout, e->n, 0);
6667dd7cddfSDavid du Colombier 	printf(" ==> %s\n", Enabled1(e->n)?"yes":"nope");
6677dd7cddfSDavid du Colombier #endif
668219b2ee8SDavid du Colombier 	return Enabled1(e->n);
669219b2ee8SDavid du Colombier }
6707dd7cddfSDavid du Colombier 
6717dd7cddfSDavid du Colombier int
pc_enabled(Lextok * n)6727dd7cddfSDavid du Colombier pc_enabled(Lextok *n)
6737dd7cddfSDavid du Colombier {	int i = nproc - nstop;
6747dd7cddfSDavid du Colombier 	int pid = eval(n);
6757dd7cddfSDavid du Colombier 	int result = 0;
6767dd7cddfSDavid du Colombier 	RunList *Y, *oX;
6777dd7cddfSDavid du Colombier 
678*de2caf28SDavid du Colombier 	if (pid == X_lst->pid)
679*de2caf28SDavid du Colombier 		fatal("used: enabled(pid=thisproc) [%s]", X_lst->n->name);
680312a1df1SDavid du Colombier 
681*de2caf28SDavid du Colombier 	for (Y = run_lst; Y; Y = Y->nxt)
6827dd7cddfSDavid du Colombier 		if (--i == pid)
683*de2caf28SDavid du Colombier 		{	oX = X_lst; X_lst = Y;
684*de2caf28SDavid du Colombier 			result = Enabled0(X_lst->pc);
685*de2caf28SDavid du Colombier 			X_lst = oX;
6867dd7cddfSDavid du Colombier 			break;
6877dd7cddfSDavid du Colombier 		}
6887dd7cddfSDavid du Colombier 	return result;
6897dd7cddfSDavid du Colombier }
69000d97012SDavid du Colombier 
691*de2caf28SDavid du Colombier int
pc_highest(Lextok * n)692*de2caf28SDavid du Colombier pc_highest(Lextok *n)
693*de2caf28SDavid du Colombier {	int i = nproc - nstop;
694*de2caf28SDavid du Colombier 	int pid = eval(n);
695*de2caf28SDavid du Colombier 	int target = 0, result = 1;
696*de2caf28SDavid du Colombier 	RunList *Y, *oX;
697*de2caf28SDavid du Colombier 
698*de2caf28SDavid du Colombier 	if (X_lst->prov && !eval(X_lst->prov))
699*de2caf28SDavid du Colombier 	{	return 0; /* can't be highest unless fully enabled */
700*de2caf28SDavid du Colombier 	}
701*de2caf28SDavid du Colombier 
702*de2caf28SDavid du Colombier 	for (Y = run_lst; Y; Y = Y->nxt)
703*de2caf28SDavid du Colombier 	{	if (--i == pid)
704*de2caf28SDavid du Colombier 		{	target = Y->priority;
705*de2caf28SDavid du Colombier 			break;
706*de2caf28SDavid du Colombier 	}	}
707*de2caf28SDavid du Colombier if (0) printf("highest for pid %d @ priority = %d\n", pid, target);
708*de2caf28SDavid du Colombier 
709*de2caf28SDavid du Colombier 	oX = X_lst;
710*de2caf28SDavid du Colombier 	i = nproc - nstop;
711*de2caf28SDavid du Colombier 	for (Y = run_lst; Y; Y = Y->nxt)
712*de2caf28SDavid du Colombier 	{	i--;
713*de2caf28SDavid du Colombier if (0) printf("	pid %d @ priority %d\t", Y->pid, Y->priority);
714*de2caf28SDavid du Colombier 		if (Y->priority > target)
715*de2caf28SDavid du Colombier 		{	X_lst = Y;
716*de2caf28SDavid du Colombier if (0) printf("enabled: %s\n", Enabled0(X_lst->pc)?"yes":"nope");
717*de2caf28SDavid du Colombier if (0) printf("provided: %s\n", eval(X_lst->prov)?"yes":"nope");
718*de2caf28SDavid du Colombier 			if (Enabled0(X_lst->pc) && (!X_lst->prov || eval(X_lst->prov)))
719*de2caf28SDavid du Colombier 			{	result = 0;
720*de2caf28SDavid du Colombier 				break;
721*de2caf28SDavid du Colombier 		}	}
722*de2caf28SDavid du Colombier else
723*de2caf28SDavid du Colombier if (0) printf("\n");
724*de2caf28SDavid du Colombier 	}
725*de2caf28SDavid du Colombier 	X_lst = oX;
726*de2caf28SDavid du Colombier 
727*de2caf28SDavid du Colombier 	return result;
728*de2caf28SDavid du Colombier }
729*de2caf28SDavid du Colombier 
730*de2caf28SDavid du Colombier int
get_priority(Lextok * n)731*de2caf28SDavid du Colombier get_priority(Lextok *n)
732*de2caf28SDavid du Colombier {	int i = nproc - nstop;
733*de2caf28SDavid du Colombier 	int pid = eval(n);
734*de2caf28SDavid du Colombier 	RunList *Y;
735*de2caf28SDavid du Colombier 
736*de2caf28SDavid du Colombier 	if (old_priority_rules)
737*de2caf28SDavid du Colombier 	{	return 1;
738*de2caf28SDavid du Colombier 	}
739*de2caf28SDavid du Colombier 
740*de2caf28SDavid du Colombier 	for (Y = run_lst; Y; Y = Y->nxt)
741*de2caf28SDavid du Colombier 	{	if (--i == pid)
742*de2caf28SDavid du Colombier 		{	return Y->priority;
743*de2caf28SDavid du Colombier 	}	}
744*de2caf28SDavid du Colombier 	return 0;
745*de2caf28SDavid du Colombier }
746*de2caf28SDavid du Colombier 
747*de2caf28SDavid du Colombier void
set_priority(Lextok * n,Lextok * p)748*de2caf28SDavid du Colombier set_priority(Lextok *n, Lextok *p)
749*de2caf28SDavid du Colombier {	int i = nproc - nstop - Have_claim;
750*de2caf28SDavid du Colombier 	int pid = eval(n);
751*de2caf28SDavid du Colombier 	RunList *Y;
752*de2caf28SDavid du Colombier 
753*de2caf28SDavid du Colombier 	if (old_priority_rules)
754*de2caf28SDavid du Colombier 	{	return;
755*de2caf28SDavid du Colombier 	}
756*de2caf28SDavid du Colombier 	for (Y = run_lst; Y; Y = Y->nxt)
757*de2caf28SDavid du Colombier 	{	if (--i == pid)
758*de2caf28SDavid du Colombier 		{	Priority_Sum -= Y->priority;
759*de2caf28SDavid du Colombier 			Y->priority = eval(p);
760*de2caf28SDavid du Colombier 			Priority_Sum += Y->priority;
761*de2caf28SDavid du Colombier 			if (1)
762*de2caf28SDavid du Colombier 			{	printf("%3d: setting priority of proc %d (%s) to %d\n",
763*de2caf28SDavid du Colombier 					depth, pid, Y->n->name, Y->priority);
764*de2caf28SDavid du Colombier 	}	}	}
765*de2caf28SDavid du Colombier 	if (verbose&32)
766*de2caf28SDavid du Colombier 	{	printf("\tPid\tName\tPriority\n");
767*de2caf28SDavid du Colombier 		for (Y = run_lst; Y; Y = Y->nxt)
768*de2caf28SDavid du Colombier 		{	printf("\t%d\t%s\t%d\n",
769*de2caf28SDavid du Colombier 				Y->pid,
770*de2caf28SDavid du Colombier 				Y->n->name,
771*de2caf28SDavid du Colombier 				Y->priority);
772*de2caf28SDavid du Colombier 	}	}
773*de2caf28SDavid du Colombier }
774