1219b2ee8SDavid du Colombier /***** spin: mesg.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
9*de2caf28SDavid du Colombier #include <stdlib.h>
10*de2caf28SDavid du Colombier #include <assert.h>
11219b2ee8SDavid du Colombier #include "spin.h"
12219b2ee8SDavid du Colombier #include "y.tab.h"
13219b2ee8SDavid du Colombier
14312a1df1SDavid du Colombier #ifndef MAXQ
15219b2ee8SDavid du Colombier #define MAXQ 2500 /* default max # queues */
16312a1df1SDavid du Colombier #endif
17219b2ee8SDavid du Colombier
18*de2caf28SDavid du Colombier extern RunList *X_lst;
19219b2ee8SDavid du Colombier extern Symbol *Fname;
207dd7cddfSDavid du Colombier extern int verbose, TstOnly, s_trail, analyze, columns;
217dd7cddfSDavid du Colombier extern int lineno, depth, xspin, m_loss, jumpsteps;
227dd7cddfSDavid du Colombier extern int nproc, nstop;
237dd7cddfSDavid du Colombier extern short Have_claim;
24219b2ee8SDavid du Colombier
25*de2caf28SDavid du Colombier QH *qh_lst;
26219b2ee8SDavid du Colombier Queue *qtab = (Queue *) 0; /* linked list of queues */
27219b2ee8SDavid du Colombier Queue *ltab[MAXQ]; /* linear list of queues */
28*de2caf28SDavid du Colombier int nrqs = 0, firstrow = 1, has_stdin = 0;
29*de2caf28SDavid du Colombier char GBuf[4096];
307dd7cddfSDavid du Colombier
317dd7cddfSDavid du Colombier static Lextok *n_rem = (Lextok *) 0;
327dd7cddfSDavid du Colombier static Queue *q_rem = (Queue *) 0;
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier static int a_rcv(Queue *, Lextok *, int);
357dd7cddfSDavid du Colombier static int a_snd(Queue *, Lextok *);
367dd7cddfSDavid du Colombier static int sa_snd(Queue *, Lextok *);
377dd7cddfSDavid du Colombier static int s_snd(Queue *, Lextok *);
38*de2caf28SDavid du Colombier extern Lextok **find_mtype_list(const char *);
39*de2caf28SDavid du Colombier extern char *which_mtype(const char *);
40*de2caf28SDavid du Colombier extern void sr_buf(int, int, const char *);
41*de2caf28SDavid du Colombier extern void sr_mesg(FILE *, int, int, const char *);
427dd7cddfSDavid du Colombier extern void putarrow(int, int);
437dd7cddfSDavid du Colombier static void sr_talk(Lextok *, int, char *, char *, int, Queue *);
44219b2ee8SDavid du Colombier
45219b2ee8SDavid du Colombier int
cnt_mpars(Lextok * n)46219b2ee8SDavid du Colombier cnt_mpars(Lextok *n)
47219b2ee8SDavid du Colombier { Lextok *m;
48219b2ee8SDavid du Colombier int i=0;
49219b2ee8SDavid du Colombier
50219b2ee8SDavid du Colombier for (m = n; m; m = m->rgt)
51219b2ee8SDavid du Colombier i += Cnt_flds(m);
52219b2ee8SDavid du Colombier return i;
53219b2ee8SDavid du Colombier }
54219b2ee8SDavid du Colombier
55219b2ee8SDavid du Colombier int
qmake(Symbol * s)56219b2ee8SDavid du Colombier qmake(Symbol *s)
57219b2ee8SDavid du Colombier { Lextok *m;
58219b2ee8SDavid du Colombier Queue *q;
59*de2caf28SDavid du Colombier int i, j;
60219b2ee8SDavid du Colombier
61219b2ee8SDavid du Colombier if (!s->ini)
62219b2ee8SDavid du Colombier return 0;
63219b2ee8SDavid du Colombier
64*de2caf28SDavid du Colombier if (nrqs >= MAXQ)
65219b2ee8SDavid du Colombier { lineno = s->ini->ln;
66219b2ee8SDavid du Colombier Fname = s->ini->fn;
67219b2ee8SDavid du Colombier fatal("too many queues (%s)", s->name);
68219b2ee8SDavid du Colombier }
69*de2caf28SDavid du Colombier if (analyze && nrqs >= 255)
707dd7cddfSDavid du Colombier { fatal("too many channel types", (char *)0);
717dd7cddfSDavid du Colombier }
72219b2ee8SDavid du Colombier
73219b2ee8SDavid du Colombier if (s->ini->ntyp != CHAN)
74219b2ee8SDavid du Colombier return eval(s->ini);
75219b2ee8SDavid du Colombier
76219b2ee8SDavid du Colombier q = (Queue *) emalloc(sizeof(Queue));
77*de2caf28SDavid du Colombier q->qid = (short) ++nrqs;
78219b2ee8SDavid du Colombier q->nslots = s->ini->val;
79219b2ee8SDavid du Colombier q->nflds = cnt_mpars(s->ini->rgt);
80219b2ee8SDavid du Colombier q->setat = depth;
81219b2ee8SDavid du Colombier
82219b2ee8SDavid du Colombier i = max(1, q->nslots); /* 0-slot qs get 1 slot minimum */
83*de2caf28SDavid du Colombier j = q->nflds * i;
84219b2ee8SDavid du Colombier
85*de2caf28SDavid du Colombier q->contents = (int *) emalloc(j*sizeof(int));
86219b2ee8SDavid du Colombier q->fld_width = (int *) emalloc(q->nflds*sizeof(int));
87*de2caf28SDavid du Colombier q->mtp = (char **) emalloc(q->nflds*sizeof(char *));
887dd7cddfSDavid du Colombier q->stepnr = (int *) emalloc(i*sizeof(int));
89219b2ee8SDavid du Colombier
90219b2ee8SDavid du Colombier for (m = s->ini->rgt, i = 0; m; m = m->rgt)
91219b2ee8SDavid du Colombier { if (m->sym && m->ntyp == STRUCT)
92*de2caf28SDavid du Colombier { i = Width_set(q->fld_width, i, getuname(m->sym));
93*de2caf28SDavid du Colombier } else
94*de2caf28SDavid du Colombier { if (m->sym)
95*de2caf28SDavid du Colombier { q->mtp[i] = m->sym->name;
96219b2ee8SDavid du Colombier }
97*de2caf28SDavid du Colombier q->fld_width[i++] = m->ntyp;
98*de2caf28SDavid du Colombier } }
99219b2ee8SDavid du Colombier q->nxt = qtab;
100219b2ee8SDavid du Colombier qtab = q;
101219b2ee8SDavid du Colombier ltab[q->qid-1] = q;
102219b2ee8SDavid du Colombier
103219b2ee8SDavid du Colombier return q->qid;
104219b2ee8SDavid du Colombier }
105219b2ee8SDavid du Colombier
106219b2ee8SDavid du Colombier int
qfull(Lextok * n)107219b2ee8SDavid du Colombier qfull(Lextok *n)
108219b2ee8SDavid du Colombier { int whichq = eval(n->lft)-1;
109219b2ee8SDavid du Colombier
110219b2ee8SDavid du Colombier if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
111219b2ee8SDavid du Colombier return (ltab[whichq]->qlen >= ltab[whichq]->nslots);
112219b2ee8SDavid du Colombier return 0;
113219b2ee8SDavid du Colombier }
114219b2ee8SDavid du Colombier
115219b2ee8SDavid du Colombier int
qlen(Lextok * n)116219b2ee8SDavid du Colombier qlen(Lextok *n)
117219b2ee8SDavid du Colombier { int whichq = eval(n->lft)-1;
118219b2ee8SDavid du Colombier
119219b2ee8SDavid du Colombier if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
120219b2ee8SDavid du Colombier return ltab[whichq]->qlen;
121219b2ee8SDavid du Colombier return 0;
122219b2ee8SDavid du Colombier }
123219b2ee8SDavid du Colombier
124219b2ee8SDavid du Colombier int
q_is_sync(Lextok * n)125219b2ee8SDavid du Colombier q_is_sync(Lextok *n)
126219b2ee8SDavid du Colombier { int whichq = eval(n->lft)-1;
127219b2ee8SDavid du Colombier
128219b2ee8SDavid du Colombier if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
129219b2ee8SDavid du Colombier return (ltab[whichq]->nslots == 0);
130219b2ee8SDavid du Colombier return 0;
131219b2ee8SDavid du Colombier }
132219b2ee8SDavid du Colombier
133219b2ee8SDavid du Colombier int
qsend(Lextok * n)134219b2ee8SDavid du Colombier qsend(Lextok *n)
135219b2ee8SDavid du Colombier { int whichq = eval(n->lft)-1;
136219b2ee8SDavid du Colombier
137219b2ee8SDavid du Colombier if (whichq == -1)
138219b2ee8SDavid du Colombier { printf("Error: sending to an uninitialized chan\n");
139*de2caf28SDavid du Colombier /* whichq = 0; */
140219b2ee8SDavid du Colombier return 0;
141219b2ee8SDavid du Colombier }
142219b2ee8SDavid du Colombier if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
143219b2ee8SDavid du Colombier { ltab[whichq]->setat = depth;
144219b2ee8SDavid du Colombier if (ltab[whichq]->nslots > 0)
145*de2caf28SDavid du Colombier { return a_snd(ltab[whichq], n);;
146*de2caf28SDavid du Colombier } else
147*de2caf28SDavid du Colombier { return s_snd(ltab[whichq], n);
148*de2caf28SDavid du Colombier } }
149219b2ee8SDavid du Colombier return 0;
150219b2ee8SDavid du Colombier }
151219b2ee8SDavid du Colombier
152*de2caf28SDavid du Colombier #ifndef PC
153*de2caf28SDavid du Colombier #include <termios.h>
154*de2caf28SDavid du Colombier static struct termios initial_settings, new_settings;
155*de2caf28SDavid du Colombier
156*de2caf28SDavid du Colombier void
peek_ch_init(void)157*de2caf28SDavid du Colombier peek_ch_init(void)
158*de2caf28SDavid du Colombier {
159*de2caf28SDavid du Colombier tcgetattr(0,&initial_settings);
160*de2caf28SDavid du Colombier
161*de2caf28SDavid du Colombier new_settings = initial_settings;
162*de2caf28SDavid du Colombier new_settings.c_lflag &= ~ICANON;
163*de2caf28SDavid du Colombier new_settings.c_lflag &= ~ECHO;
164*de2caf28SDavid du Colombier new_settings.c_lflag &= ~ISIG;
165*de2caf28SDavid du Colombier new_settings.c_cc[VMIN] = 0;
166*de2caf28SDavid du Colombier new_settings.c_cc[VTIME] = 0;
167*de2caf28SDavid du Colombier }
168*de2caf28SDavid du Colombier
169*de2caf28SDavid du Colombier int
peek_ch(void)170*de2caf28SDavid du Colombier peek_ch(void)
171*de2caf28SDavid du Colombier { int n;
172*de2caf28SDavid du Colombier
173*de2caf28SDavid du Colombier has_stdin = 1;
174*de2caf28SDavid du Colombier
175*de2caf28SDavid du Colombier tcsetattr(0, TCSANOW, &new_settings);
176*de2caf28SDavid du Colombier n = getchar();
177*de2caf28SDavid du Colombier tcsetattr(0, TCSANOW, &initial_settings);
178*de2caf28SDavid du Colombier
179*de2caf28SDavid du Colombier return n;
180*de2caf28SDavid du Colombier }
181*de2caf28SDavid du Colombier #endif
182*de2caf28SDavid du Colombier
183219b2ee8SDavid du Colombier int
qrecv(Lextok * n,int full)184219b2ee8SDavid du Colombier qrecv(Lextok *n, int full)
185219b2ee8SDavid du Colombier { int whichq = eval(n->lft)-1;
186219b2ee8SDavid du Colombier
187219b2ee8SDavid du Colombier if (whichq == -1)
1887dd7cddfSDavid du Colombier { if (n->sym && !strcmp(n->sym->name, "STDIN"))
1897dd7cddfSDavid du Colombier { Lextok *m;
190*de2caf28SDavid du Colombier #ifndef PC
191*de2caf28SDavid du Colombier static int did_once = 0;
192*de2caf28SDavid du Colombier if (!did_once) /* 6.2.4 */
193*de2caf28SDavid du Colombier { peek_ch_init();
194*de2caf28SDavid du Colombier did_once = 1;
195*de2caf28SDavid du Colombier }
196*de2caf28SDavid du Colombier #endif
1977dd7cddfSDavid du Colombier if (TstOnly) return 1;
1987dd7cddfSDavid du Colombier
1997dd7cddfSDavid du Colombier for (m = n->rgt; m; m = m->rgt)
2007dd7cddfSDavid du Colombier if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL)
201*de2caf28SDavid du Colombier {
202*de2caf28SDavid du Colombier #ifdef PC
203*de2caf28SDavid du Colombier int c = getchar();
204*de2caf28SDavid du Colombier #else
205*de2caf28SDavid du Colombier int c = peek_ch(); /* 6.2.4, was getchar(); */
206*de2caf28SDavid du Colombier #endif
207*de2caf28SDavid du Colombier if (c == 27 || c == 3) /* escape or control-c */
208*de2caf28SDavid du Colombier { printf("quit\n");
209*de2caf28SDavid du Colombier exit(0);
210*de2caf28SDavid du Colombier } /* else: non-blocking */
211*de2caf28SDavid du Colombier if (c == EOF) return 0; /* no char available */
2127dd7cddfSDavid du Colombier (void) setval(m->lft, c);
2137dd7cddfSDavid du Colombier } else
214*de2caf28SDavid du Colombier { fatal("invalid use of STDIN", (char *)0);
215*de2caf28SDavid du Colombier }
2167dd7cddfSDavid du Colombier return 1;
2177dd7cddfSDavid du Colombier }
2187dd7cddfSDavid du Colombier printf("Error: receiving from an uninitialized chan %s\n",
2197dd7cddfSDavid du Colombier n->sym?n->sym->name:"");
220*de2caf28SDavid du Colombier /* whichq = 0; */
221219b2ee8SDavid du Colombier return 0;
222219b2ee8SDavid du Colombier }
223219b2ee8SDavid du Colombier if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
224219b2ee8SDavid du Colombier { ltab[whichq]->setat = depth;
225219b2ee8SDavid du Colombier return a_rcv(ltab[whichq], n, full);
226219b2ee8SDavid du Colombier }
227219b2ee8SDavid du Colombier return 0;
228219b2ee8SDavid du Colombier }
229219b2ee8SDavid du Colombier
2307dd7cddfSDavid du Colombier static int
sa_snd(Queue * q,Lextok * n)231219b2ee8SDavid du Colombier sa_snd(Queue *q, Lextok *n) /* sorted asynchronous */
232219b2ee8SDavid du Colombier { Lextok *m;
233219b2ee8SDavid du Colombier int i, j, k;
234219b2ee8SDavid du Colombier int New, Old;
235219b2ee8SDavid du Colombier
236219b2ee8SDavid du Colombier for (i = 0; i < q->qlen; i++)
237219b2ee8SDavid du Colombier for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
2387dd7cddfSDavid du Colombier { New = cast_val(q->fld_width[j], eval(m->lft), 0);
239219b2ee8SDavid du Colombier Old = q->contents[i*q->nflds+j];
24000d97012SDavid du Colombier if (New == Old)
24100d97012SDavid du Colombier continue;
24200d97012SDavid du Colombier if (New > Old)
24300d97012SDavid du Colombier break; /* inner loop */
24400d97012SDavid du Colombier goto found; /* New < Old */
245219b2ee8SDavid du Colombier }
246219b2ee8SDavid du Colombier found:
247219b2ee8SDavid du Colombier for (j = q->qlen-1; j >= i; j--)
248219b2ee8SDavid du Colombier for (k = 0; k < q->nflds; k++)
249219b2ee8SDavid du Colombier { q->contents[(j+1)*q->nflds+k] =
250219b2ee8SDavid du Colombier q->contents[j*q->nflds+k]; /* shift up */
2517dd7cddfSDavid du Colombier if (k == 0)
2527dd7cddfSDavid du Colombier q->stepnr[j+1] = q->stepnr[j];
253219b2ee8SDavid du Colombier }
254219b2ee8SDavid du Colombier return i*q->nflds; /* new q offset */
255219b2ee8SDavid du Colombier }
256219b2ee8SDavid du Colombier
257219b2ee8SDavid du Colombier void
typ_ck(int ft,int at,char * s)258219b2ee8SDavid du Colombier typ_ck(int ft, int at, char *s)
259219b2ee8SDavid du Colombier {
2607dd7cddfSDavid du Colombier if ((verbose&32) && ft != at
261*de2caf28SDavid du Colombier && (ft == CHAN || at == CHAN)
262*de2caf28SDavid du Colombier && (at != PREDEF || strcmp(s, "recv") != 0))
263*de2caf28SDavid du Colombier { char buf[256], tag1[64], tag2[64];
264219b2ee8SDavid du Colombier (void) sputtype(tag1, ft);
265219b2ee8SDavid du Colombier (void) sputtype(tag2, at);
266219b2ee8SDavid du Colombier sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2);
267219b2ee8SDavid du Colombier non_fatal("%s", buf);
268219b2ee8SDavid du Colombier }
269219b2ee8SDavid du Colombier }
270219b2ee8SDavid du Colombier
271*de2caf28SDavid du Colombier static void
mtype_ck(char * p,Lextok * arg)272*de2caf28SDavid du Colombier mtype_ck(char *p, Lextok *arg)
273*de2caf28SDavid du Colombier { char *t, *s = p?p:"_unnamed_";
274*de2caf28SDavid du Colombier
275*de2caf28SDavid du Colombier if (!arg
276*de2caf28SDavid du Colombier || !arg->sym)
277*de2caf28SDavid du Colombier { return;
278*de2caf28SDavid du Colombier }
279*de2caf28SDavid du Colombier
280*de2caf28SDavid du Colombier switch (arg->ntyp) {
281*de2caf28SDavid du Colombier case NAME:
282*de2caf28SDavid du Colombier if (arg->sym->mtype_name)
283*de2caf28SDavid du Colombier { t = arg->sym->mtype_name->name;
284*de2caf28SDavid du Colombier } else
285*de2caf28SDavid du Colombier { t = "_unnamed_";
286*de2caf28SDavid du Colombier }
287*de2caf28SDavid du Colombier break;
288*de2caf28SDavid du Colombier case CONST:
289*de2caf28SDavid du Colombier t = which_mtype(arg->sym->name);
290*de2caf28SDavid du Colombier break;
291*de2caf28SDavid du Colombier default:
292*de2caf28SDavid du Colombier t = "expression";
293*de2caf28SDavid du Colombier break;
294*de2caf28SDavid du Colombier }
295*de2caf28SDavid du Colombier
296*de2caf28SDavid du Colombier if (strcmp(s, t) != 0)
297*de2caf28SDavid du Colombier { printf("spin: %s:%d, Error: '%s' is type '%s', but ",
298*de2caf28SDavid du Colombier arg->fn?arg->fn->name:"", arg->ln,
299*de2caf28SDavid du Colombier arg->sym->name, t);
300*de2caf28SDavid du Colombier printf("should be type '%s'\n", s);
301*de2caf28SDavid du Colombier non_fatal("incorrect type of '%s'", arg->sym->name);
302*de2caf28SDavid du Colombier }
303*de2caf28SDavid du Colombier }
304*de2caf28SDavid du Colombier
3057dd7cddfSDavid du Colombier static int
a_snd(Queue * q,Lextok * n)306219b2ee8SDavid du Colombier a_snd(Queue *q, Lextok *n)
307219b2ee8SDavid du Colombier { Lextok *m;
308219b2ee8SDavid du Colombier int i = q->qlen*q->nflds; /* q offset */
309219b2ee8SDavid du Colombier int j = 0; /* q field# */
310219b2ee8SDavid du Colombier
311219b2ee8SDavid du Colombier if (q->nslots > 0 && q->qlen >= q->nslots)
312*de2caf28SDavid du Colombier { return m_loss; /* q is full */
313*de2caf28SDavid du Colombier }
314219b2ee8SDavid du Colombier
315*de2caf28SDavid du Colombier if (TstOnly)
316*de2caf28SDavid du Colombier { return 1;
317*de2caf28SDavid du Colombier }
318219b2ee8SDavid du Colombier if (n->val) i = sa_snd(q, n); /* sorted insert */
319219b2ee8SDavid du Colombier
3207dd7cddfSDavid du Colombier q->stepnr[i/q->nflds] = depth;
3217dd7cddfSDavid du Colombier
322219b2ee8SDavid du Colombier for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
323219b2ee8SDavid du Colombier { int New = eval(m->lft);
3247dd7cddfSDavid du Colombier q->contents[i+j] = cast_val(q->fld_width[j], New, 0);
325*de2caf28SDavid du Colombier
326*de2caf28SDavid du Colombier if (q->fld_width[i+j] == MTYPE)
327*de2caf28SDavid du Colombier { mtype_ck(q->mtp[i+j], m->lft); /* 6.4.8 */
328219b2ee8SDavid du Colombier }
3297dd7cddfSDavid du Colombier if ((verbose&16) && depth >= jumpsteps)
330*de2caf28SDavid du Colombier { sr_talk(n, New, "Send ", "->", j, q); /* XXX j was i+j in 6.4.8 */
331*de2caf28SDavid du Colombier }
332*de2caf28SDavid du Colombier typ_ck(q->fld_width[i+j], Sym_typ(m->lft), "send");
333*de2caf28SDavid du Colombier }
334*de2caf28SDavid du Colombier
335*de2caf28SDavid du Colombier if ((verbose&16) && depth >= jumpsteps)
336219b2ee8SDavid du Colombier { for (i = j; i < q->nflds; i++)
337*de2caf28SDavid du Colombier { sr_talk(n, 0, "Send ", "->", i, q);
338*de2caf28SDavid du Colombier }
339219b2ee8SDavid du Colombier if (j < q->nflds)
340*de2caf28SDavid du Colombier { printf("%3d: warning: missing params in send\n",
3417dd7cddfSDavid du Colombier depth);
342219b2ee8SDavid du Colombier }
343*de2caf28SDavid du Colombier if (m)
344*de2caf28SDavid du Colombier { printf("%3d: warning: too many params in send\n",
345*de2caf28SDavid du Colombier depth);
346*de2caf28SDavid du Colombier } }
347219b2ee8SDavid du Colombier q->qlen++;
348219b2ee8SDavid du Colombier return 1;
349219b2ee8SDavid du Colombier }
350219b2ee8SDavid du Colombier
3517dd7cddfSDavid du Colombier static int
a_rcv(Queue * q,Lextok * n,int full)352219b2ee8SDavid du Colombier a_rcv(Queue *q, Lextok *n, int full)
353219b2ee8SDavid du Colombier { Lextok *m;
3547dd7cddfSDavid du Colombier int i=0, oi, j, k;
355219b2ee8SDavid du Colombier extern int Rvous;
356219b2ee8SDavid du Colombier
3577dd7cddfSDavid du Colombier if (q->qlen == 0)
358*de2caf28SDavid du Colombier { return 0; /* q is empty */
359*de2caf28SDavid du Colombier }
360219b2ee8SDavid du Colombier try_slot:
361219b2ee8SDavid du Colombier /* test executability */
362219b2ee8SDavid du Colombier for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++)
363*de2caf28SDavid du Colombier {
364*de2caf28SDavid du Colombier if (q->fld_width[i*q->nflds+j] == MTYPE)
365*de2caf28SDavid du Colombier { mtype_ck(q->mtp[i*q->nflds+j], m->lft); /* 6.4.8 */
366*de2caf28SDavid du Colombier }
367*de2caf28SDavid du Colombier
368*de2caf28SDavid du Colombier if (m->lft->ntyp == CONST
369219b2ee8SDavid du Colombier && q->contents[i*q->nflds+j] != m->lft->val)
370*de2caf28SDavid du Colombier {
371*de2caf28SDavid du Colombier if (n->val == 0 /* fifo recv */
372*de2caf28SDavid du Colombier || n->val == 2 /* fifo poll */
373*de2caf28SDavid du Colombier || ++i >= q->qlen) /* last slot */
374*de2caf28SDavid du Colombier { return 0; /* no match */
375*de2caf28SDavid du Colombier }
376*de2caf28SDavid du Colombier goto try_slot; /* random recv */
377*de2caf28SDavid du Colombier }
378*de2caf28SDavid du Colombier
379*de2caf28SDavid du Colombier if (m->lft->ntyp == EVAL)
380*de2caf28SDavid du Colombier { Lextok *fix = m->lft->lft;
381*de2caf28SDavid du Colombier
382*de2caf28SDavid du Colombier if (fix->ntyp == ',') /* new, usertype7 */
383*de2caf28SDavid du Colombier { do {
384*de2caf28SDavid du Colombier assert(j < q->nflds);
385*de2caf28SDavid du Colombier if (q->contents[i*q->nflds+j] != eval(fix->lft))
386*de2caf28SDavid du Colombier { if (n->val == 0
387*de2caf28SDavid du Colombier || n->val == 2
388*de2caf28SDavid du Colombier || ++i >= q->qlen)
389*de2caf28SDavid du Colombier { return 0;
390*de2caf28SDavid du Colombier }
391*de2caf28SDavid du Colombier goto try_slot; /* random recv */
392*de2caf28SDavid du Colombier }
393*de2caf28SDavid du Colombier j++;
394*de2caf28SDavid du Colombier fix = fix->rgt;
395*de2caf28SDavid du Colombier } while (fix && fix->ntyp == ',');
396*de2caf28SDavid du Colombier j--;
397*de2caf28SDavid du Colombier } else
398*de2caf28SDavid du Colombier { if (q->contents[i*q->nflds+j] != eval(fix))
399219b2ee8SDavid du Colombier { if (n->val == 0 /* fifo recv */
4007dd7cddfSDavid du Colombier || n->val == 2 /* fifo poll */
401219b2ee8SDavid du Colombier || ++i >= q->qlen) /* last slot */
402*de2caf28SDavid du Colombier { return 0; /* no match */
403219b2ee8SDavid du Colombier }
404*de2caf28SDavid du Colombier goto try_slot; /* random recv */
405*de2caf28SDavid du Colombier } } }
406*de2caf28SDavid du Colombier }
407*de2caf28SDavid du Colombier
408219b2ee8SDavid du Colombier if (TstOnly) return 1;
409219b2ee8SDavid du Colombier
410219b2ee8SDavid du Colombier if (verbose&8)
411219b2ee8SDavid du Colombier { if (j < q->nflds)
412*de2caf28SDavid du Colombier { printf("%3d: warning: missing params in next recv\n",
4137dd7cddfSDavid du Colombier depth);
414*de2caf28SDavid du Colombier } else if (m)
415*de2caf28SDavid du Colombier { printf("%3d: warning: too many params in next recv\n",
4167dd7cddfSDavid du Colombier depth);
417*de2caf28SDavid du Colombier } }
418219b2ee8SDavid du Colombier
419219b2ee8SDavid du Colombier /* set the fields */
4207dd7cddfSDavid du Colombier if (Rvous)
4217dd7cddfSDavid du Colombier { n_rem = n;
4227dd7cddfSDavid du Colombier q_rem = q;
4237dd7cddfSDavid du Colombier }
424219b2ee8SDavid du Colombier
4257dd7cddfSDavid du Colombier oi = q->stepnr[i];
4267dd7cddfSDavid du Colombier for (m = n->rgt, j = 0; m && j < q->nflds; m = m->rgt, j++)
4277dd7cddfSDavid du Colombier { if (columns && !full) /* was columns == 1 */
4287dd7cddfSDavid du Colombier continue;
4297dd7cddfSDavid du Colombier if ((verbose&8) && !Rvous && depth >= jumpsteps)
4307dd7cddfSDavid du Colombier { sr_talk(n, q->contents[i*q->nflds+j],
4317dd7cddfSDavid du Colombier (full && n->val < 2)?"Recv ":"[Recv] ", "<-", j, q);
4327dd7cddfSDavid du Colombier }
4337dd7cddfSDavid du Colombier if (!full)
4347dd7cddfSDavid du Colombier continue; /* test */
4357dd7cddfSDavid du Colombier if (m && m->lft->ntyp != CONST && m->lft->ntyp != EVAL)
436219b2ee8SDavid du Colombier { (void) setval(m->lft, q->contents[i*q->nflds+j]);
437219b2ee8SDavid du Colombier typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv");
438219b2ee8SDavid du Colombier }
4397dd7cddfSDavid du Colombier if (n->val < 2) /* not a poll */
4407dd7cddfSDavid du Colombier for (k = i; k < q->qlen-1; k++)
4417dd7cddfSDavid du Colombier { q->contents[k*q->nflds+j] =
442219b2ee8SDavid du Colombier q->contents[(k+1)*q->nflds+j];
4437dd7cddfSDavid du Colombier if (j == 0)
4447dd7cddfSDavid du Colombier q->stepnr[k] = q->stepnr[k+1];
445219b2ee8SDavid du Colombier }
4467dd7cddfSDavid du Colombier }
4477dd7cddfSDavid du Colombier
4487dd7cddfSDavid du Colombier if ((!columns || full)
4497dd7cddfSDavid du Colombier && (verbose&8) && !Rvous && depth >= jumpsteps)
4507dd7cddfSDavid du Colombier for (i = j; i < q->nflds; i++)
4517dd7cddfSDavid du Colombier { sr_talk(n, 0,
4527dd7cddfSDavid du Colombier (full && n->val < 2)?"Recv ":"[Recv] ", "<-", i, q);
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier if (columns == 2 && full && !Rvous && depth >= jumpsteps)
4557dd7cddfSDavid du Colombier putarrow(oi, depth);
4567dd7cddfSDavid du Colombier
4577dd7cddfSDavid du Colombier if (full && n->val < 2)
4587dd7cddfSDavid du Colombier q->qlen--;
459219b2ee8SDavid du Colombier return 1;
460219b2ee8SDavid du Colombier }
461219b2ee8SDavid du Colombier
4627dd7cddfSDavid du Colombier static int
s_snd(Queue * q,Lextok * n)463219b2ee8SDavid du Colombier s_snd(Queue *q, Lextok *n)
464219b2ee8SDavid du Colombier { Lextok *m;
465*de2caf28SDavid du Colombier RunList *rX, *sX = X_lst; /* rX=recvr, sX=sendr */
466219b2ee8SDavid du Colombier int i, j = 0; /* q field# */
467219b2ee8SDavid du Colombier
468219b2ee8SDavid du Colombier for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
4697dd7cddfSDavid du Colombier { q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0);
470219b2ee8SDavid du Colombier typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send");
471*de2caf28SDavid du Colombier
472*de2caf28SDavid du Colombier if (q->fld_width[j] == MTYPE)
473*de2caf28SDavid du Colombier { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */
474*de2caf28SDavid du Colombier } }
475*de2caf28SDavid du Colombier
476219b2ee8SDavid du Colombier q->qlen = 1;
477219b2ee8SDavid du Colombier if (!complete_rendez())
478219b2ee8SDavid du Colombier { q->qlen = 0;
479219b2ee8SDavid du Colombier return 0;
480219b2ee8SDavid du Colombier }
4817dd7cddfSDavid du Colombier if (TstOnly)
4827dd7cddfSDavid du Colombier { q->qlen = 0;
4837dd7cddfSDavid du Colombier return 1;
4847dd7cddfSDavid du Colombier }
4857dd7cddfSDavid du Colombier q->stepnr[0] = depth;
4867dd7cddfSDavid du Colombier if ((verbose&16) && depth >= jumpsteps)
487219b2ee8SDavid du Colombier { m = n->rgt;
488*de2caf28SDavid du Colombier rX = X_lst; X_lst = sX;
489*de2caf28SDavid du Colombier
490219b2ee8SDavid du Colombier for (j = 0; m && j < q->nflds; m = m->rgt, j++)
491*de2caf28SDavid du Colombier { sr_talk(n, eval(m->lft), "Sent ", "->", j, q);
492*de2caf28SDavid du Colombier }
493*de2caf28SDavid du Colombier
494219b2ee8SDavid du Colombier for (i = j; i < q->nflds; i++)
495*de2caf28SDavid du Colombier { sr_talk(n, 0, "Sent ", "->", i, q);
496*de2caf28SDavid du Colombier }
497*de2caf28SDavid du Colombier
498219b2ee8SDavid du Colombier if (j < q->nflds)
499*de2caf28SDavid du Colombier { printf("%3d: warning: missing params in rv-send\n",
5007dd7cddfSDavid du Colombier depth);
501*de2caf28SDavid du Colombier } else if (m)
502*de2caf28SDavid du Colombier { printf("%3d: warning: too many params in rv-send\n",
5037dd7cddfSDavid du Colombier depth);
504*de2caf28SDavid du Colombier }
505*de2caf28SDavid du Colombier
506*de2caf28SDavid du Colombier X_lst = rX; /* restore receiver's context */
507219b2ee8SDavid du Colombier if (!s_trail)
5087dd7cddfSDavid du Colombier { if (!n_rem || !q_rem)
5097dd7cddfSDavid du Colombier fatal("cannot happen, s_snd", (char *) 0);
5107dd7cddfSDavid du Colombier m = n_rem->rgt;
511219b2ee8SDavid du Colombier for (j = 0; m && j < q->nflds; m = m->rgt, j++)
512*de2caf28SDavid du Colombier {
513*de2caf28SDavid du Colombier if (q->fld_width[j] == MTYPE)
514*de2caf28SDavid du Colombier { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */
515*de2caf28SDavid du Colombier }
516312a1df1SDavid du Colombier
517*de2caf28SDavid du Colombier if (m->lft->ntyp != NAME
518*de2caf28SDavid du Colombier || strcmp(m->lft->sym->name, "_") != 0)
519*de2caf28SDavid du Colombier { i = eval(m->lft);
520*de2caf28SDavid du Colombier } else
521*de2caf28SDavid du Colombier { i = 0;
522*de2caf28SDavid du Colombier }
523312a1df1SDavid du Colombier if (verbose&8)
5247dd7cddfSDavid du Colombier sr_talk(n_rem,i,"Recv ","<-",j,q_rem);
5257dd7cddfSDavid du Colombier }
526312a1df1SDavid du Colombier if (verbose&8)
5277dd7cddfSDavid du Colombier for (i = j; i < q->nflds; i++)
5287dd7cddfSDavid du Colombier sr_talk(n_rem, 0, "Recv ", "<-", j, q_rem);
5297dd7cddfSDavid du Colombier if (columns == 2)
5307dd7cddfSDavid du Colombier putarrow(depth, depth);
5317dd7cddfSDavid du Colombier }
5327dd7cddfSDavid du Colombier n_rem = (Lextok *) 0;
5337dd7cddfSDavid du Colombier q_rem = (Queue *) 0;
534219b2ee8SDavid du Colombier }
535219b2ee8SDavid du Colombier return 1;
536219b2ee8SDavid du Colombier }
537219b2ee8SDavid du Colombier
53800d97012SDavid du Colombier static void
channm(Lextok * n)5397dd7cddfSDavid du Colombier channm(Lextok *n)
540312a1df1SDavid du Colombier { char lbuf[512];
5417dd7cddfSDavid du Colombier
5427dd7cddfSDavid du Colombier if (n->sym->type == CHAN)
543*de2caf28SDavid du Colombier strcat(GBuf, n->sym->name);
5447dd7cddfSDavid du Colombier else if (n->sym->type == NAME)
545*de2caf28SDavid du Colombier strcat(GBuf, lookup(n->sym->name)->name);
5467dd7cddfSDavid du Colombier else if (n->sym->type == STRUCT)
5477dd7cddfSDavid du Colombier { Symbol *r = n->sym;
5487dd7cddfSDavid du Colombier if (r->context)
54900d97012SDavid du Colombier { r = findloc(r);
55000d97012SDavid du Colombier if (!r)
551*de2caf28SDavid du Colombier { strcat(GBuf, "*?*");
55200d97012SDavid du Colombier return;
55300d97012SDavid du Colombier } }
5547dd7cddfSDavid du Colombier ini_struct(r);
5557dd7cddfSDavid du Colombier printf("%s", r->name);
556312a1df1SDavid du Colombier strcpy(lbuf, "");
5577dd7cddfSDavid du Colombier struct_name(n->lft, r, 1, lbuf);
558*de2caf28SDavid du Colombier strcat(GBuf, lbuf);
5597dd7cddfSDavid du Colombier } else
560*de2caf28SDavid du Colombier strcat(GBuf, "-");
5617dd7cddfSDavid du Colombier if (n->lft->lft)
5627dd7cddfSDavid du Colombier { sprintf(lbuf, "[%d]", eval(n->lft->lft));
563*de2caf28SDavid du Colombier strcat(GBuf, lbuf);
5647dd7cddfSDavid du Colombier }
5657dd7cddfSDavid du Colombier }
5667dd7cddfSDavid du Colombier
5677dd7cddfSDavid du Colombier static void
difcolumns(Lextok * n,char * tr,int v,int j,Queue * q)5687dd7cddfSDavid du Colombier difcolumns(Lextok *n, char *tr, int v, int j, Queue *q)
569*de2caf28SDavid du Colombier { extern int prno;
5707dd7cddfSDavid du Colombier
5717dd7cddfSDavid du Colombier if (j == 0)
572*de2caf28SDavid du Colombier { GBuf[0] = '\0';
5737dd7cddfSDavid du Colombier channm(n);
574*de2caf28SDavid du Colombier strcat(GBuf, (strncmp(tr, "Sen", 3))?"?":"!");
5757dd7cddfSDavid du Colombier } else
576*de2caf28SDavid du Colombier strcat(GBuf, ",");
577*de2caf28SDavid du Colombier if (tr[0] == '[') strcat(GBuf, "[");
578*de2caf28SDavid du Colombier sr_buf(v, q->fld_width[j] == MTYPE, q->mtp[j]);
5797dd7cddfSDavid du Colombier if (j == q->nflds - 1)
5807dd7cddfSDavid du Colombier { int cnr;
581*de2caf28SDavid du Colombier if (s_trail)
582*de2caf28SDavid du Colombier { cnr = prno - Have_claim;
583*de2caf28SDavid du Colombier } else
584*de2caf28SDavid du Colombier { cnr = X_lst?X_lst->pid - Have_claim:0;
585*de2caf28SDavid du Colombier }
586*de2caf28SDavid du Colombier if (tr[0] == '[') strcat(GBuf, "]");
587*de2caf28SDavid du Colombier pstext(cnr, GBuf);
5887dd7cddfSDavid du Colombier }
5897dd7cddfSDavid du Colombier }
5907dd7cddfSDavid du Colombier
5917dd7cddfSDavid du Colombier static void
docolumns(Lextok * n,char * tr,int v,int j,Queue * q)5927dd7cddfSDavid du Colombier docolumns(Lextok *n, char *tr, int v, int j, Queue *q)
5937dd7cddfSDavid du Colombier { int i;
5947dd7cddfSDavid du Colombier
5957dd7cddfSDavid du Colombier if (firstrow)
5967dd7cddfSDavid du Colombier { printf("q\\p");
5977dd7cddfSDavid du Colombier for (i = 0; i < nproc-nstop - Have_claim; i++)
5987dd7cddfSDavid du Colombier printf(" %3d", i);
5997dd7cddfSDavid du Colombier printf("\n");
6007dd7cddfSDavid du Colombier firstrow = 0;
6017dd7cddfSDavid du Colombier }
6027dd7cddfSDavid du Colombier if (j == 0)
6037dd7cddfSDavid du Colombier { printf("%3d", q->qid);
604*de2caf28SDavid du Colombier if (X_lst)
605*de2caf28SDavid du Colombier for (i = 0; i < X_lst->pid - Have_claim; i++)
6067dd7cddfSDavid du Colombier printf(" .");
6077dd7cddfSDavid du Colombier printf(" ");
608*de2caf28SDavid du Colombier GBuf[0] = '\0';
6097dd7cddfSDavid du Colombier channm(n);
610*de2caf28SDavid du Colombier printf("%s%c", GBuf, (strncmp(tr, "Sen", 3))?'?':'!');
6117dd7cddfSDavid du Colombier } else
6127dd7cddfSDavid du Colombier printf(",");
6137dd7cddfSDavid du Colombier if (tr[0] == '[') printf("[");
614*de2caf28SDavid du Colombier sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]);
6157dd7cddfSDavid du Colombier if (j == q->nflds - 1)
6167dd7cddfSDavid du Colombier { if (tr[0] == '[') printf("]");
6177dd7cddfSDavid du Colombier printf("\n");
6187dd7cddfSDavid du Colombier }
6197dd7cddfSDavid du Colombier }
6207dd7cddfSDavid du Colombier
6217dd7cddfSDavid du Colombier void
qhide(int q)6227dd7cddfSDavid du Colombier qhide(int q)
6237dd7cddfSDavid du Colombier { QH *p = (QH *) emalloc(sizeof(QH));
6247dd7cddfSDavid du Colombier p->n = q;
625*de2caf28SDavid du Colombier p->nxt = qh_lst;
626*de2caf28SDavid du Colombier qh_lst = p;
6277dd7cddfSDavid du Colombier }
6287dd7cddfSDavid du Colombier
6297dd7cddfSDavid du Colombier int
qishidden(int q)6307dd7cddfSDavid du Colombier qishidden(int q)
6317dd7cddfSDavid du Colombier { QH *p;
632*de2caf28SDavid du Colombier for (p = qh_lst; p; p = p->nxt)
6337dd7cddfSDavid du Colombier if (p->n == q)
6347dd7cddfSDavid du Colombier return 1;
6357dd7cddfSDavid du Colombier return 0;
6367dd7cddfSDavid du Colombier }
6377dd7cddfSDavid du Colombier
6387dd7cddfSDavid du Colombier static void
sr_talk(Lextok * n,int v,char * tr,char * a,int j,Queue * q)639219b2ee8SDavid du Colombier sr_talk(Lextok *n, int v, char *tr, char *a, int j, Queue *q)
64000d97012SDavid du Colombier { char s[128];
6417dd7cddfSDavid du Colombier
6427dd7cddfSDavid du Colombier if (qishidden(eval(n->lft)))
6437dd7cddfSDavid du Colombier return;
6447dd7cddfSDavid du Colombier
6457dd7cddfSDavid du Colombier if (columns)
6467dd7cddfSDavid du Colombier { if (columns == 2)
6477dd7cddfSDavid du Colombier difcolumns(n, tr, v, j, q);
6487dd7cddfSDavid du Colombier else
6497dd7cddfSDavid du Colombier docolumns(n, tr, v, j, q);
6507dd7cddfSDavid du Colombier return;
6517dd7cddfSDavid du Colombier }
652219b2ee8SDavid du Colombier if (xspin)
6537dd7cddfSDavid du Colombier { if ((verbose&4) && tr[0] != '[')
654219b2ee8SDavid du Colombier sprintf(s, "(state -)\t[values: %d",
655219b2ee8SDavid du Colombier eval(n->lft));
656219b2ee8SDavid du Colombier else
657219b2ee8SDavid du Colombier sprintf(s, "(state -)\t[%d", eval(n->lft));
658219b2ee8SDavid du Colombier if (strncmp(tr, "Sen", 3) == 0)
659219b2ee8SDavid du Colombier strcat(s, "!");
660219b2ee8SDavid du Colombier else
661219b2ee8SDavid du Colombier strcat(s, "?");
662219b2ee8SDavid du Colombier } else
663219b2ee8SDavid du Colombier { strcpy(s, tr);
664219b2ee8SDavid du Colombier }
6657dd7cddfSDavid du Colombier
666219b2ee8SDavid du Colombier if (j == 0)
66700d97012SDavid du Colombier { char snm[128];
66800d97012SDavid du Colombier whoruns(1);
66900d97012SDavid du Colombier { char *ptr = n->fn->name;
67000d97012SDavid du Colombier char *qtr = snm;
67100d97012SDavid du Colombier while (*ptr != '\0')
67200d97012SDavid du Colombier { if (*ptr != '\"')
67300d97012SDavid du Colombier { *qtr++ = *ptr;
67400d97012SDavid du Colombier }
67500d97012SDavid du Colombier ptr++;
67600d97012SDavid du Colombier }
67700d97012SDavid du Colombier *qtr = '\0';
67800d97012SDavid du Colombier printf("%s:%d %s",
67900d97012SDavid du Colombier snm, n->ln, s);
68000d97012SDavid du Colombier }
681219b2ee8SDavid du Colombier } else
682*de2caf28SDavid du Colombier { printf(",");
683*de2caf28SDavid du Colombier }
684*de2caf28SDavid du Colombier sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]);
685219b2ee8SDavid du Colombier
686219b2ee8SDavid du Colombier if (j == q->nflds - 1)
687219b2ee8SDavid du Colombier { if (xspin)
688219b2ee8SDavid du Colombier { printf("]\n");
689219b2ee8SDavid du Colombier if (!(verbose&4)) printf("\n");
690219b2ee8SDavid du Colombier return;
691219b2ee8SDavid du Colombier }
692219b2ee8SDavid du Colombier printf("\t%s queue %d (", a, eval(n->lft));
693*de2caf28SDavid du Colombier GBuf[0] = '\0';
6947dd7cddfSDavid du Colombier channm(n);
695*de2caf28SDavid du Colombier printf("%s)\n", GBuf);
696219b2ee8SDavid du Colombier }
697219b2ee8SDavid du Colombier fflush(stdout);
698219b2ee8SDavid du Colombier }
699219b2ee8SDavid du Colombier
700219b2ee8SDavid du Colombier void
sr_buf(int v,int j,const char * s)701*de2caf28SDavid du Colombier sr_buf(int v, int j, const char *s)
7027dd7cddfSDavid du Colombier { int cnt = 1; Lextok *n;
703f3793cddSDavid du Colombier char lbuf[512];
704*de2caf28SDavid du Colombier Lextok *Mtype = ZN;
705219b2ee8SDavid du Colombier
706*de2caf28SDavid du Colombier if (j)
707*de2caf28SDavid du Colombier { Mtype = *find_mtype_list(s?s:"_unnamed_");
708*de2caf28SDavid du Colombier }
709219b2ee8SDavid du Colombier for (n = Mtype; n && j; n = n->rgt, cnt++)
710*de2caf28SDavid du Colombier { if (cnt == v)
711f3793cddSDavid du Colombier { if(strlen(n->lft->sym->name) >= sizeof(lbuf))
712f3793cddSDavid du Colombier { non_fatal("mtype name %s too long", n->lft->sym->name);
713f3793cddSDavid du Colombier break;
714f3793cddSDavid du Colombier }
715f3793cddSDavid du Colombier sprintf(lbuf, "%s", n->lft->sym->name);
716*de2caf28SDavid du Colombier strcat(GBuf, lbuf);
717219b2ee8SDavid du Colombier return;
718*de2caf28SDavid du Colombier } }
7197dd7cddfSDavid du Colombier sprintf(lbuf, "%d", v);
720*de2caf28SDavid du Colombier strcat(GBuf, lbuf);
7217dd7cddfSDavid du Colombier }
7227dd7cddfSDavid du Colombier
7237dd7cddfSDavid du Colombier void
sr_mesg(FILE * fd,int v,int j,const char * s)724*de2caf28SDavid du Colombier sr_mesg(FILE *fd, int v, int j, const char *s)
725*de2caf28SDavid du Colombier { GBuf[0] ='\0';
726*de2caf28SDavid du Colombier
727*de2caf28SDavid du Colombier sr_buf(v, j, s);
728*de2caf28SDavid du Colombier fprintf(fd, GBuf, (char *) 0); /* prevent compiler warning */
729219b2ee8SDavid du Colombier }
730219b2ee8SDavid du Colombier
731219b2ee8SDavid du Colombier void
doq(Symbol * s,int n,RunList * r)732219b2ee8SDavid du Colombier doq(Symbol *s, int n, RunList *r)
733219b2ee8SDavid du Colombier { Queue *q;
734219b2ee8SDavid du Colombier int j, k;
735219b2ee8SDavid du Colombier
736219b2ee8SDavid du Colombier if (!s->val) /* uninitialized queue */
737219b2ee8SDavid du Colombier return;
738219b2ee8SDavid du Colombier for (q = qtab; q; q = q->nxt)
739219b2ee8SDavid du Colombier if (q->qid == s->val[n])
740219b2ee8SDavid du Colombier { if (xspin > 0
741219b2ee8SDavid du Colombier && (verbose&4)
742219b2ee8SDavid du Colombier && q->setat < depth)
74300d97012SDavid du Colombier { continue;
74400d97012SDavid du Colombier }
745*de2caf28SDavid du Colombier if (q->nslots == 0)
746*de2caf28SDavid du Colombier { continue; /* rv q always empty */
747*de2caf28SDavid du Colombier }
748*de2caf28SDavid du Colombier
749219b2ee8SDavid du Colombier printf("\t\tqueue %d (", q->qid);
750219b2ee8SDavid du Colombier if (r)
751*de2caf28SDavid du Colombier { printf("%s(%d):", r->n->name, r->pid - Have_claim);
752*de2caf28SDavid du Colombier }
753*de2caf28SDavid du Colombier
75400d97012SDavid du Colombier if (s->nel > 1 || s->isarray)
755*de2caf28SDavid du Colombier { printf("%s[%d]): ", s->name, n);
756*de2caf28SDavid du Colombier } else
757*de2caf28SDavid du Colombier { printf("%s): ", s->name);
758*de2caf28SDavid du Colombier }
759*de2caf28SDavid du Colombier
760219b2ee8SDavid du Colombier for (k = 0; k < q->qlen; k++)
761219b2ee8SDavid du Colombier { printf("[");
762219b2ee8SDavid du Colombier for (j = 0; j < q->nflds; j++)
763219b2ee8SDavid du Colombier { if (j > 0) printf(",");
764*de2caf28SDavid du Colombier sr_mesg(stdout,
765*de2caf28SDavid du Colombier q->contents[k*q->nflds+j],
766*de2caf28SDavid du Colombier q->fld_width[j] == MTYPE,
767*de2caf28SDavid du Colombier q->mtp[j]);
768219b2ee8SDavid du Colombier }
769219b2ee8SDavid du Colombier printf("]");
770219b2ee8SDavid du Colombier }
771219b2ee8SDavid du Colombier printf("\n");
772219b2ee8SDavid du Colombier break;
773219b2ee8SDavid du Colombier }
774219b2ee8SDavid du Colombier }
7757dd7cddfSDavid du Colombier
7767dd7cddfSDavid du Colombier void
nochan_manip(Lextok * p,Lextok * n,int d)777*de2caf28SDavid du Colombier nochan_manip(Lextok *p, Lextok *n, int d) /* p=lhs n=rhs */
7787dd7cddfSDavid du Colombier { int e = 1;
7797dd7cddfSDavid du Colombier
780*de2caf28SDavid du Colombier if (!n
781*de2caf28SDavid du Colombier || !p
782*de2caf28SDavid du Colombier || !p->sym
783*de2caf28SDavid du Colombier || p->sym->type == STRUCT)
784*de2caf28SDavid du Colombier { /* if a struct, assignments to structure fields arent checked yet */
785*de2caf28SDavid du Colombier return;
786*de2caf28SDavid du Colombier }
787*de2caf28SDavid du Colombier
7887dd7cddfSDavid du Colombier if (d == 0 && p->sym && p->sym->type == CHAN)
789312a1df1SDavid du Colombier { setaccess(p->sym, ZS, 0, 'L');
790312a1df1SDavid du Colombier
791312a1df1SDavid du Colombier if (n && n->ntyp == CONST)
792312a1df1SDavid du Colombier fatal("invalid asgn to chan", (char *) 0);
793312a1df1SDavid du Colombier
794312a1df1SDavid du Colombier if (n && n->sym && n->sym->type == CHAN)
795312a1df1SDavid du Colombier { setaccess(n->sym, ZS, 0, 'V');
796312a1df1SDavid du Colombier return;
797312a1df1SDavid du Colombier }
798312a1df1SDavid du Colombier }
7997dd7cddfSDavid du Colombier
800*de2caf28SDavid du Colombier if (!d && n && n->ismtyp) /* rhs is an mtype value (a constant) */
801*de2caf28SDavid du Colombier { char *lhs = "_unnamed_", *rhs = "_unnamed_";
802*de2caf28SDavid du Colombier
803*de2caf28SDavid du Colombier if (p->sym)
804*de2caf28SDavid du Colombier { lhs = p->sym->mtype_name?p->sym->mtype_name->name:"_unnamed_";
805*de2caf28SDavid du Colombier }
806*de2caf28SDavid du Colombier if (n->sym)
807*de2caf28SDavid du Colombier { rhs = which_mtype(n->sym->name); /* only for constants */
808*de2caf28SDavid du Colombier }
809*de2caf28SDavid du Colombier
810*de2caf28SDavid du Colombier if (p->sym && !p->sym->mtype_name && n->sym)
811*de2caf28SDavid du Colombier { p->sym->mtype_name = (Symbol *) emalloc(sizeof(Symbol));
812*de2caf28SDavid du Colombier p->sym->mtype_name->name = rhs;
813*de2caf28SDavid du Colombier } else if (strcmp(lhs, rhs) != 0)
814*de2caf28SDavid du Colombier { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but '%s' is type '%s'\n",
815*de2caf28SDavid du Colombier p->fn->name, p->ln,
816*de2caf28SDavid du Colombier p->sym?p->sym->name:"?", lhs,
817*de2caf28SDavid du Colombier n->sym?n->sym->name:"?", rhs);
818*de2caf28SDavid du Colombier non_fatal("type error", (char *) 0);
819*de2caf28SDavid du Colombier } }
820*de2caf28SDavid du Colombier
82100d97012SDavid du Colombier /* ok on the rhs of an assignment: */
822*de2caf28SDavid du Colombier if (!n
823*de2caf28SDavid du Colombier || n->ntyp == LEN || n->ntyp == RUN
82400d97012SDavid du Colombier || n->ntyp == FULL || n->ntyp == NFULL
825*de2caf28SDavid du Colombier || n->ntyp == EMPTY || n->ntyp == NEMPTY
826*de2caf28SDavid du Colombier || n->ntyp == 'R')
8277dd7cddfSDavid du Colombier return;
8287dd7cddfSDavid du Colombier
8297dd7cddfSDavid du Colombier if (n->sym && n->sym->type == CHAN)
8307dd7cddfSDavid du Colombier { if (d == 1)
8317dd7cddfSDavid du Colombier fatal("invalid use of chan name", (char *) 0);
8327dd7cddfSDavid du Colombier else
8337dd7cddfSDavid du Colombier setaccess(n->sym, ZS, 0, 'V');
8347dd7cddfSDavid du Colombier }
8357dd7cddfSDavid du Colombier
8367dd7cddfSDavid du Colombier if (n->ntyp == NAME
8377dd7cddfSDavid du Colombier || n->ntyp == '.')
838*de2caf28SDavid du Colombier { e = 0; /* array index or struct element */
839*de2caf28SDavid du Colombier }
8407dd7cddfSDavid du Colombier
8417dd7cddfSDavid du Colombier nochan_manip(p, n->lft, e);
8427dd7cddfSDavid du Colombier nochan_manip(p, n->rgt, 1);
8437dd7cddfSDavid du Colombier }
844f3793cddSDavid du Colombier
84500d97012SDavid du Colombier typedef struct BaseName {
84600d97012SDavid du Colombier char *str;
84700d97012SDavid du Colombier int cnt;
84800d97012SDavid du Colombier struct BaseName *nxt;
84900d97012SDavid du Colombier } BaseName;
850*de2caf28SDavid du Colombier
851*de2caf28SDavid du Colombier static BaseName *bsn;
85200d97012SDavid du Colombier
85300d97012SDavid du Colombier void
newbasename(char * s)85400d97012SDavid du Colombier newbasename(char *s)
85500d97012SDavid du Colombier { BaseName *b;
85600d97012SDavid du Colombier
85700d97012SDavid du Colombier /* printf("+++++++++%s\n", s); */
85800d97012SDavid du Colombier for (b = bsn; b; b = b->nxt)
85900d97012SDavid du Colombier if (strcmp(b->str, s) == 0)
86000d97012SDavid du Colombier { b->cnt++;
86100d97012SDavid du Colombier return;
86200d97012SDavid du Colombier }
86300d97012SDavid du Colombier b = (BaseName *) emalloc(sizeof(BaseName));
86400d97012SDavid du Colombier b->str = emalloc(strlen(s)+1);
86500d97012SDavid du Colombier b->cnt = 1;
86600d97012SDavid du Colombier strcpy(b->str, s);
86700d97012SDavid du Colombier b->nxt = bsn;
86800d97012SDavid du Colombier bsn = b;
86900d97012SDavid du Colombier }
87000d97012SDavid du Colombier
87100d97012SDavid du Colombier void
delbasename(char * s)87200d97012SDavid du Colombier delbasename(char *s)
87300d97012SDavid du Colombier { BaseName *b, *prv = (BaseName *) 0;
87400d97012SDavid du Colombier
87500d97012SDavid du Colombier for (b = bsn; b; prv = b, b = b->nxt)
87600d97012SDavid du Colombier { if (strcmp(b->str, s) == 0)
87700d97012SDavid du Colombier { b->cnt--;
87800d97012SDavid du Colombier if (b->cnt == 0)
87900d97012SDavid du Colombier { if (prv)
88000d97012SDavid du Colombier { prv->nxt = b->nxt;
88100d97012SDavid du Colombier } else
88200d97012SDavid du Colombier { bsn = b->nxt;
88300d97012SDavid du Colombier } }
88400d97012SDavid du Colombier /* printf("---------%s\n", s); */
88500d97012SDavid du Colombier break;
88600d97012SDavid du Colombier } }
88700d97012SDavid du Colombier }
88800d97012SDavid du Colombier
88900d97012SDavid du Colombier void
checkindex(char * s,char * t)89000d97012SDavid du Colombier checkindex(char *s, char *t)
89100d97012SDavid du Colombier { BaseName *b;
89200d97012SDavid du Colombier
89300d97012SDavid du Colombier /* printf("xxx Check %s (%s)\n", s, t); */
89400d97012SDavid du Colombier for (b = bsn; b; b = b->nxt)
89500d97012SDavid du Colombier {
89600d97012SDavid du Colombier /* printf(" %s\n", b->str); */
89700d97012SDavid du Colombier if (strcmp(b->str, s) == 0)
89800d97012SDavid du Colombier { non_fatal("do not index an array with itself (%s)", t);
89900d97012SDavid du Colombier break;
90000d97012SDavid du Colombier } }
90100d97012SDavid du Colombier }
90200d97012SDavid du Colombier
90300d97012SDavid du Colombier void
scan_tree(Lextok * t,char * mn,char * mx)90400d97012SDavid du Colombier scan_tree(Lextok *t, char *mn, char *mx)
90500d97012SDavid du Colombier { char sv[512];
90600d97012SDavid du Colombier char tmp[32];
90700d97012SDavid du Colombier int oln = lineno;
90800d97012SDavid du Colombier
90900d97012SDavid du Colombier if (!t) return;
91000d97012SDavid du Colombier
91100d97012SDavid du Colombier lineno = t->ln;
91200d97012SDavid du Colombier
91300d97012SDavid du Colombier if (t->ntyp == NAME)
914*de2caf28SDavid du Colombier { if (strlen(t->sym->name) + strlen(mn) > 256) // conservative
915*de2caf28SDavid du Colombier { fatal("name too long", t->sym->name);
916*de2caf28SDavid du Colombier }
917*de2caf28SDavid du Colombier
918*de2caf28SDavid du Colombier strcat(mn, t->sym->name);
91900d97012SDavid du Colombier strcat(mx, t->sym->name);
92000d97012SDavid du Colombier if (t->lft) /* array index */
92100d97012SDavid du Colombier { strcat(mn, "[]");
92200d97012SDavid du Colombier newbasename(mn);
92300d97012SDavid du Colombier strcpy(sv, mn); /* save */
92400d97012SDavid du Colombier strcpy(mn, ""); /* clear */
92500d97012SDavid du Colombier strcat(mx, "[");
92600d97012SDavid du Colombier scan_tree(t->lft, mn, mx); /* index */
92700d97012SDavid du Colombier strcat(mx, "]");
92800d97012SDavid du Colombier checkindex(mn, mx); /* match against basenames */
92900d97012SDavid du Colombier strcpy(mn, sv); /* restore */
93000d97012SDavid du Colombier delbasename(mn);
93100d97012SDavid du Colombier }
93200d97012SDavid du Colombier if (t->rgt) /* structure element */
93300d97012SDavid du Colombier { scan_tree(t->rgt, mn, mx);
93400d97012SDavid du Colombier }
93500d97012SDavid du Colombier } else if (t->ntyp == CONST)
93600d97012SDavid du Colombier { strcat(mn, "1"); /* really: t->val */
93700d97012SDavid du Colombier sprintf(tmp, "%d", t->val);
93800d97012SDavid du Colombier strcat(mx, tmp);
93900d97012SDavid du Colombier } else if (t->ntyp == '.')
94000d97012SDavid du Colombier { strcat(mn, ".");
94100d97012SDavid du Colombier strcat(mx, ".");
94200d97012SDavid du Colombier scan_tree(t->lft, mn, mx);
94300d97012SDavid du Colombier } else
94400d97012SDavid du Colombier { strcat(mn, "??");
94500d97012SDavid du Colombier strcat(mx, "??");
94600d97012SDavid du Colombier }
94700d97012SDavid du Colombier lineno = oln;
94800d97012SDavid du Colombier }
94900d97012SDavid du Colombier
95000d97012SDavid du Colombier void
no_nested_array_refs(Lextok * n)95100d97012SDavid du Colombier no_nested_array_refs(Lextok *n) /* a [ a[1] ] with a[1] = 1, causes trouble in pan.b */
95200d97012SDavid du Colombier { char mn[512];
95300d97012SDavid du Colombier char mx[512];
95400d97012SDavid du Colombier
95500d97012SDavid du Colombier /* printf("==================================ZAP\n"); */
95600d97012SDavid du Colombier bsn = (BaseName *) 0; /* start new list */
95700d97012SDavid du Colombier strcpy(mn, "");
95800d97012SDavid du Colombier strcpy(mx, "");
95900d97012SDavid du Colombier
96000d97012SDavid du Colombier scan_tree(n, mn, mx);
96100d97012SDavid du Colombier /* printf("==> %s\n", mn); */
96200d97012SDavid du Colombier }
96300d97012SDavid du Colombier
964f3793cddSDavid du Colombier void
no_internals(Lextok * n)965f3793cddSDavid du Colombier no_internals(Lextok *n)
966f3793cddSDavid du Colombier { char *sp;
967f3793cddSDavid du Colombier
968f3793cddSDavid du Colombier if (!n->sym
969f3793cddSDavid du Colombier || !n->sym->name)
970f3793cddSDavid du Colombier return;
971f3793cddSDavid du Colombier
972f3793cddSDavid du Colombier sp = n->sym->name;
973f3793cddSDavid du Colombier
974f3793cddSDavid du Colombier if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0)
975*de2caf28SDavid du Colombier || (strlen(sp) == strlen("_pid") && strcmp(sp, "_pid") == 0)
976f3793cddSDavid du Colombier || (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0))
977*de2caf28SDavid du Colombier { fatal("invalid assignment to %s", sp);
978f3793cddSDavid du Colombier }
97900d97012SDavid du Colombier
98000d97012SDavid du Colombier no_nested_array_refs(n);
981f3793cddSDavid du Colombier }
982