1 /***** spin: pangen1.c *****/
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
16 #include <sys/int_limits.h>
21 extern FILE *tc, *th, *tt;
23 extern Ordered *all_names;
27 extern int lineno, verbose, Pid, separate, old_scope_rules, nclaims;
28 extern int nrRdy, nqs, mst, Mpars, claimnr, eventmapnr;
29 extern short has_sorted, has_random, has_provided, has_priority;
32 int Npars=0, u_sync=0, u_async=0, hastrack = 1;
34 short has_state=0; /* code contains c_state */
36 static Symbol *LstSet=ZS;
37 static int acceptors=0, progressors=0, nBits=0;
38 static int Types[] = { UNSIGNED, BIT, BYTE, CHAN, MTYPE, SHORT, INT, STRUCT };
40 static int doglobal(char *, int);
41 static void dohidden(void);
42 static void do_init(FILE *, Symbol *);
43 static void end_labs(Symbol *, int);
44 static void put_ptype(char *, int, int, int, enum btypes);
45 static void tc_predef_np(void);
46 static void put_pinit(ProcList *);
47 static void multi_init(void);
48 void walk_struct(FILE *, int, char *, Symbol *, char *, char *, char *);
51 reverse_names(ProcList *p)
54 reverse_names(p->nxt);
55 fprintf(tc, " \"%s\",\n", p->n->name);
58 reverse_types(ProcList *p)
61 reverse_types(p->nxt);
62 fprintf(tc, " %d, /* %s */\n", p->b, p->n->name);
66 blog(int n) /* for small log2 without rounding problems */
69 while (r < n) { m++; r *= 2; }
81 /* 5.2.3: gcc 3 no longer seems to compute sizeof at compile time */
82 fprintf(th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *));
83 fprintf(th, "#define SYNC %d\n", u_sync);
84 fprintf(th, "#define ASYNC %d\n\n", u_async);
85 fprintf(th, "#ifndef NCORE\n");
86 fprintf(th, " #ifdef DUAL_CORE\n");
87 fprintf(th, " #define NCORE 2\n");
88 fprintf(th, " #elif QUAD_CORE\n");
89 fprintf(th, " #define NCORE 4\n");
90 fprintf(th, " #else\n");
91 fprintf(th, " #define NCORE 1\n");
92 fprintf(th, " #endif\n");
93 fprintf(th, "#endif\n\n");
97 fprintf(tc, "\nshort Air[] = { ");
98 for (p = rdy, i=0; p; p = p->nxt, i++)
99 fprintf(tc, "%s (short) Air%d", (p!=rdy)?",":"", i);
100 fprintf(tc, ", (short) Air%d", i); /* np_ */
102 { fprintf(tc, "\n#ifndef NOCLAIM\n");
103 fprintf(tc, " , (short) Air%d", i+1); /* Multi */
104 fprintf(tc, "\n#endif\n\t");
106 fprintf(tc, " };\n");
108 fprintf(tc, "char *procname[] = {\n");
110 fprintf(tc, " \":np_:\",\n");
112 fprintf(tc, "};\n\n");
114 fprintf(tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM);
115 fprintf(tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC);
116 fprintf(tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n",
117 P_PROC, E_TRACE, N_TRACE);
119 fprintf(tc, "int Btypes[] = {\n");
121 fprintf(tc, " 0 /* :np_: */\n");
122 fprintf(tc, "};\n\n");
125 for (p = rdy; p; p = p->nxt)
126 put_ptype(p->n->name, p->tn, mst, nrRdy+1, p->b);
128 put_ptype("np_", nrRdy, mst, nrRdy+1, 0);
131 { /* this is the structure that goes into the state-vector
132 * instead of the actual never claims
133 * this assumes that the claims do not have any local variables
134 * this claim records the types and states of all subclaims in an array
135 * NB: not sure if we need the first 3 fields in this structure
136 * it's here for now to avoid breaking some possible dependence
137 * in the calculations above, we were already taking into account
138 * that there is one never-claim, which will now be this one
144 fprintf(th, "#ifndef NOCLAIM\n");
145 fprintf(th, " #undef VERI\n");
146 fprintf(th, " #define VERI %d\n", nrRdy+1);
147 fprintf(th, " #define Pclaim P%d\n\n", nrRdy+1);
148 fprintf(th, "typedef struct P%d {\n", nrRdy+1);
149 fprintf(th, " unsigned _pid : 8; /* always zero */\n");
150 fprintf(th, " unsigned _t : %d; /* active-claim type */\n",
152 fprintf(th, " unsigned _p : %d; /* active-claim state */\n",
154 fprintf(th, " unsigned _n : %d; /* active-claim index */\n",
156 if (i <= UINT8_MAX) /* in stdint.h = UCHAR_MAX from limits.h */
157 { fprintf(th, " uchar c_cur[NCLAIMS]; /* claim-states */\n");
158 } else if (i <= UINT16_MAX) /* really USHRT_MAX from limits.h */
159 { fprintf(th, " ushort c_cur[NCLAIMS]; /* claim-states */\n");
160 } else /* the most unlikely case */
161 { fprintf(th, " uint c_cur[NCLAIMS]; /* claim-states */\n");
163 fprintf(th, "} P%d;\n", nrRdy+1);
165 fprintf(tc, "#ifndef NOCLAIM\n");
166 fprintf(tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n");
167 fprintf(tc, "#endif\n");
169 fprintf(th, " #define Air%d (0)\n\n", nrRdy+1);
170 fprintf(th, "#endif\n");
172 * find special states as:
173 * stopstate [ claimnr ][ curstate ] == 1
174 * accpstate [ claimnr ][ curstate ]
175 * progstate [ claimnr ][ curstate ]
176 * reached [ claimnr ][ curstate ]
177 * visstate [ claimnr ][ curstate ]
178 * loopstate [ claimnr ][ curstate ]
179 * mapstate [ claimnr ][ curstate ]
182 { fprintf(th, "#define Pclaim P0\n");
183 fprintf(th, "#ifndef NCLAIMS\n");
184 fprintf(th, " #define NCLAIMS 1\n");
185 fprintf(th, "#endif\n");
186 fprintf(tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n");
189 ntimes(th, 0, 1, Head0);
192 { extern void c_add_stack(FILE *);
193 extern void c_stack_size(FILE *);
195 ntimes(th, 0, 1, Header);
196 fprintf(th, "#define StackSize (");
201 ntimes(th, 0, 1, Header0);
203 { fprintf(th, "extern char *emalloc(unsigned long);\n");
205 ntimes(th, 0, 1, Head1);
208 (void) doglobal("", PUTV);
210 hastrack = c_add_sv(th);
212 fprintf(th, "#ifdef TRIX\n");
213 fprintf(th, " /* room for 512 proc+chan ptrs, + safety margin */\n");
214 fprintf(th, " char *_ids_[MAXPROC+MAXQ+4];\n");
215 fprintf(th, "#else\n");
216 fprintf(th, " uchar sv[VECTORSZ];\n");
217 fprintf(th, "#endif\n");
219 fprintf(th, "} State");
221 fprintf(th,"\n#ifdef GCC\n");
222 fprintf(th, "\t__attribute__ ((aligned(8)))");
223 fprintf(th, "\n#endif\n\t");
225 fprintf(th, ";\n\n");
227 fprintf(th, "#ifdef TRIX\n");
228 fprintf(th, "typedef struct TRIX_v6 {\n");
229 fprintf(th, " uchar *body; /* aligned */\n");
230 fprintf(th, "#ifndef BFS\n");
231 fprintf(th, " short modified;\n");
232 fprintf(th, "#endif\n");
233 fprintf(th, " short psize;\n");
234 fprintf(th, " short parent_pid;\n");
235 fprintf(th, " struct TRIX_v6 *nxt;\n");
236 fprintf(th, "} TRIX_v6;\n");
237 fprintf(th, "#endif\n\n");
239 fprintf(th, "#define HAS_TRACK %d\n", hastrack);
240 if (0 && hastrack) /* not really a problem */
241 { fprintf(th, "#ifdef BFS_PAR\n");
242 fprintf(th, " #error cannot use BFS_PAR on models with c_track stmnts\n");
243 fprintf(th, "#endif\n");
254 if (separate == 2) goto shortcut;
256 ntimes(tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */
258 fprintf(tc, "#ifdef TRIX\n");
259 fprintf(tc, "int what_p_size(int);\n");
260 fprintf(tc, "int what_q_size(int);\n\n");
262 /* the number of processes just changed by 1 (up or down) */
263 /* this means that the channel indices move up or down by one slot */
264 /* not all new channels may have a valid index yet, but we move */
265 /* all of them anyway, as if they existed */
266 ntimes(tc, 0, 1, R7a);
267 fprintf(tc, "#endif\n\n");
269 ntimes(tc, 0, 1, R7b);
271 fprintf(tc, "int\naddproc(int calling_pid, int priority, int n");
272 for (/* i = 0 */; i < Npars; i++)
273 fprintf(tc, ", int par%d", i);
275 ntimes(tc, 0, 1, Addp0);
276 ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */
279 { fprintf(tc, "#ifndef NOCLAIM\n");
280 ntimes(tc, nrRdy+1, nrRdy+2, R5);
281 fprintf(tc, "#endif\n");
284 ntimes(tc, 0, 1, Addp1);
287 { fprintf(tt, "\nint\nprovided(int II, unsigned char ot, ");
288 fprintf(tt, "int tt, Trans *t)\n");
289 fprintf(tt, "{\n\tswitch(ot) {\n");
296 for (p = rdy; p; p = p->nxt)
300 if (separate == 2) return;
304 { fprintf(tt, "\tdefault: return 1; /* e.g., a claim */\n");
305 fprintf(tt, "\t}\n\treturn 0;\n}\n");
308 ntimes(tc, i, i+1, R6);
310 ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */
312 ntimes(tc, 1, nrRdy, R5);
313 ntimes(tc, 0, 1, R8a);
317 do_locinits(FILE *fd)
320 /* the locinit functions may refer to pptr or qptr */
321 fprintf(fd, "#if VECTORSZ>32000\n");
322 fprintf(fd, " extern int \n");
323 fprintf(fd, "#else\n");
324 fprintf(fd, " extern short \n");
325 fprintf(fd, "#endif\n");
326 fprintf(fd, " *proc_offset, *q_offset;\n");
328 for (p = rdy; p; p = p->nxt)
329 { c_add_locinit(fd, p->tn, p->n->name);
340 { for (p = rdy; p; p = p->nxt)
341 { if (p->b == N_CLAIM)
342 { ntimes(tc, p->tn, p->tn+1, R0); /* claims only */
343 fprintf(tc, "#ifdef HAS_CODE\n");
344 ntimes(tc, p->tn, p->tn+1, R00);
345 fprintf(tc, "#endif\n");
349 ntimes(tc, 0, 1, Code0);
350 for (p = rdy; p; p = p->nxt)
351 { if (p->b != N_CLAIM)
352 { ntimes(tc, p->tn, p->tn+1, R0); /* all except claims */
353 fprintf(tc, "#ifdef HAS_CODE\n");
354 ntimes(tc, p->tn, p->tn+1, R00);
355 fprintf(tc, "#endif\n");
359 ntimes(tc, 0, 1, Code0);
360 ntimes(tc, 0, nrRdy+1, R0); /* +1 for np_ */
361 fprintf(tc, "#ifdef HAS_CODE\n");
362 ntimes(tc, 0, nrRdy+1, R00); /* +1 for np_ */
363 fprintf(tc, "#endif\n");
366 /* new place, make sure Maxbody is set to its final value here */
370 { ntimes(tc, 1, u_sync+u_async+1, R3); /* nqs is still 0 */
371 fprintf(tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n");
372 fprintf(tc, "\tif ((Maxbody %% WS) != 0)\n");
373 fprintf(tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n");
376 for (p = rdy; p; p = p->nxt)
377 end_labs(p->n, p->tn);
382 { for (p = rdy; p; p = p->nxt)
383 { if (p->b == N_CLAIM)
384 { ntimes(tc, p->tn, p->tn+1, R0a); /* claims only */
388 for (p = rdy; p; p = p->nxt)
389 { if (p->b != N_CLAIM)
390 { ntimes(tc, p->tn, p->tn+1, R0a); /* all except claims */
392 fprintf(tc, " if (state_tables)\n");
393 fprintf(tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */
395 { acceptors = 1; /* assume at least 1 acceptstate */
399 ntimes(tc, 0, nrRdy, R0a); /* all */
403 ntimes(th, acceptors, acceptors+1, Code1);
404 ntimes(th, progressors, progressors+1, Code3);
406 ntimes(tc, 0, 1, Code2a); /* dfs, bfs */
407 ntimes(tc, 0, 1, Code2e); /* multicore */
408 ntimes(tc, 0, 1, Code2c); /* multicore */
409 ntimes(tc, 0, 1, Code2d);
411 fprintf(tc, "void\ndo_reach(void)\n{\n");
412 ntimes(tc, 0, nrRdy, R4);
413 fprintf(tc, "}\n\n");
415 fprintf(tc, "void\niniglobals(int calling_pid)\n{\n");
416 if (doglobal("", INIV) > 0)
417 { fprintf(tc, "#ifdef VAR_RANGES\n");
418 (void) doglobal("logval(\"", LOGV);
419 fprintf(tc, "#endif\n");
421 fprintf(tc, "}\n\n");
427 ntimes(tc, 0, 1, SvMap);
431 char *s, *t; int n, m, p;
433 {"end", "stopstate", 3, 0, 0},
434 {"progress", "progstate", 8, 0, 1},
435 {"accept", "accpstate", 6, 1, 0},
440 end_labs(Symbol *s, int i)
444 int j; char foo[128];
446 if ((pid_is_claim(i) && separate == 1)
447 || (!pid_is_claim(i) && separate == 2))
450 for (l = labtab; l; l = l->nxt)
451 for (j = 0; ln[j].n; j++)
452 { if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0
453 && strcmp(l->c->name, s->name) == 0)
454 { fprintf(tc, "\t%s[%d][%d] = 1;\n",
455 ln[j].t, i, l->e->seqno);
456 acceptors += ln[j].m;
457 progressors += ln[j].p;
458 if (l->e->status & D_ATOM)
459 { sprintf(foo, "%s label inside d_step",
463 if (j > 0 && (l->e->status & ATOM))
464 { sprintf(foo, "%s label inside atomic",
466 complain: lineno = l->e->n->ln;
468 printf("spin: %3d:%s, warning, %s - is invisible\n",
469 lineno, Fname?Fname->name:"-", foo);
471 /* visible states -- through remote refs: */
472 for (l = labtab; l; l = l->nxt)
474 && strcmp(l->s->context->name, s->name) == 0)
475 fprintf(tc, "\tvisstate[%d][%d] = 1;\n",
483 ntimes(FILE *fd, int n, int m, const char *c[])
486 for (j = 0; c[j]; j++)
487 for (i = n; i < m; i++)
488 { fprintf(fd, c[j], i, i, i, i, i, i);
497 printf("spin: warning, ");
500 n = (s->context != ZS)?s->context->ini:s->ini;
502 printf("line %s:%d, ", n->fn->name, n->ln);
506 checktype(Symbol *sp, char *s)
507 { char buf[128]; int i;
515 if (sp->hidden&16) /* formal parameter */
516 { ProcList *p; Lextok *f, *t;
518 for (p = rdy; p; p = p->nxt)
520 && strcmp(s, p->n->name) == 0)
523 for (f = p->p; f; f = f->rgt) /* list of types */
524 for (t = f->lft; t; t = t->rgt, posnr++)
526 && strcmp(t->sym->name, sp->name) == 0)
527 { checkrun(sp, posnr);
531 } else if (!(sp->hidden&4))
532 { if (!(verbose&32)) return;
533 sputtype(buf, sp->type);
534 i = (int) strlen(buf);
535 while (i > 0 && buf[--i] == ' ') buf[i] = '\0';
538 printf("proctype %s:", s);
541 printf(" '%s %s' could be declared 'bit %s'\n",
542 buf, sp->name, sp->name);
543 } else if (sp->type != BYTE && !(sp->hidden&8))
544 { if (!(verbose&32)) return;
545 sputtype(buf, sp->type);
546 i = (int) strlen(buf);
547 while (buf[--i] == ' ') buf[i] = '\0';
550 printf("proctype %s:", s);
553 printf(" '%s %s' could be declared 'byte %s'\n",
554 buf, sp->name, sp->name);
559 dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s, enum btypes b)
560 { int h, j, k=0; extern int nr_errs;
563 char buf[128], buf2[128], buf3[128];
566 { /* initialize in order of declaration */
567 for (walk = all_names; walk; walk = walk->next)
571 && strcmp(s, sp->context->name) == 0)
572 { checktype(sp, s); /* fall through */
573 if (!(sp->hidden&16))
574 { sprintf(buf, "((P%d *)pptr(h))->", p);
575 do_var(ofd, dowhat, buf, sp, "", " = ", ";\n");
580 { for (j = 0; j < 8; j++)
581 for (h = 0; h <= 1; h++)
582 for (walk = all_names; walk; walk = walk->next)
586 && sp->type == Types[j]
587 && ((h == 0 && (sp->nel == 1 && sp->isarray == 0))
588 || (h == 1 && (sp->nel > 1 || sp->isarray == 1)))
589 && strcmp(s, sp->context->name) == 0)
595 sprintf(buf, "%s%s:", pre, s);
596 { sprintf(buf2, "\", ((P%d *)pptr(h))->", p);
597 sprintf(buf3, ");\n");
599 do_var(ofd, dowhat, "", sp, buf, buf2, buf3);
602 sprintf(buf, "((P%d *)pptr(h))->", p);
603 do_var(ofd, dowhat, buf, sp, "", " = ", ";\n");
608 { printf("error: %s defines local %s\n",
623 { fprintf(fd, "void\nc_chandump(int unused)\n");
624 fprintf(fd, "{\tunused++; /* avoid complaints */\n}\n");
628 fprintf(fd, "void\nc_chandump(int from)\n");
629 fprintf(fd, "{ uchar *z; int slot;\n");
631 fprintf(fd, " from--;\n");
632 fprintf(fd, " if (from >= (int) now._nr_qs || from < 0)\n");
633 fprintf(fd, " { printf(\"pan: bad qid %%d\\n\", from+1);\n");
634 fprintf(fd, " return;\n");
636 fprintf(fd, " z = qptr(from);\n");
637 fprintf(fd, " switch (((Q0 *)z)->_t) {\n");
639 for (q = qtab; q; q = q->nxt)
640 { fprintf(fd, " case %d:\n\t\t", q->qid);
641 sprintf(buf, "((Q%d *)z)->", q->qid);
643 fprintf(fd, "for (slot = 0; slot < %sQlen; slot++)\n\t\t", buf);
644 fprintf(fd, "{ printf(\" [\");\n\t\t");
645 for (i = 0; i < q->nflds; i++)
646 { if (q->fld_width[i] == MTYPE)
647 { fprintf(fd, "\tprintm(%scontents[slot].fld%d);\n\t\t",
650 fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d);\n\t\t",
653 fprintf(fd, " printf(\"],\");\n\t\t");
654 fprintf(fd, "}\n\t\t");
655 fprintf(fd, "break;\n");
658 fprintf(fd, " printf(\"\\n\");\n}\n");
662 c_var(FILE *fd, char *pref, Symbol *sp)
663 { char *ptr, buf[256];
667 { fatal("cannot happen - c_var", 0);
671 if (!old_scope_rules)
672 { while (*ptr == '_' || isdigit((int)*ptr))
678 /* c_struct(fd, pref, sp); */
679 fprintf(fd, "\t\tprintf(\"\t(struct %s)\\n\");\n",
681 sprintf(buf, "%s%s.", pref, sp->name);
682 c_struct(fd, buf, sp);
686 case SHORT: case INT:
688 sputtype(buf, sp->type);
689 if (sp->nel == 1 && sp->isarray == 0)
691 if (sp->type == MTYPE && ismtype(sp->name))
692 { fprintf(fd, "\tprintf(\"\t%s %s:\t%d\\n\");\n",
693 buf, ptr, ismtype(sp->name));
695 { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n",
696 buf, ptr, pref, sp->name);
699 { fprintf(fd, "\t{\tint l_in;\n");
700 fprintf(fd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel);
701 fprintf(fd, "\t\t{\n");
702 fprintf(fd, "\t\t\tprintf(\"\t%s %s[%%d]:\t%%d\\n\", l_in, %s%s[l_in]);\n",
703 buf, ptr, pref, sp->name);
704 fprintf(fd, "\t\t}\n");
705 fprintf(fd, "\t}\n");
709 if (sp->nel == 1 && sp->isarray == 0)
710 { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ", ptr);
711 fprintf(fd, "%s%s, q_len(%s%s));\n",
712 pref, sp->name, pref, sp->name);
713 fprintf(fd, "\tc_chandump(%s%s);\n", pref, sp->name);
715 for (i = 0; i < sp->nel; i++)
716 { fprintf(fd, "\tprintf(\"\tchan %s[%d] (=%%d):\tlen %%d:\\t\", ",
718 fprintf(fd, "%s%s[%d], q_len(%s%s[%d]));\n",
719 pref, sp->name, i, pref, sp->name, i);
720 fprintf(fd, "\tc_chandump(%s%s[%d]);\n",
728 c_splurge_any(ProcList *p)
732 if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE)
733 for (walk = all_names; walk; walk = walk->next)
737 || strcmp(sp->context->name, p->n->name) != 0
738 || sp->owner || (sp->hidden&1)
739 || (sp->type == MTYPE && ismtype(sp->name)))
748 c_splurge(FILE *fd, ProcList *p)
753 if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE)
754 for (walk = all_names; walk; walk = walk->next)
758 || strcmp(sp->context->name, p->n->name) != 0
759 || sp->owner || (sp->hidden&1)
760 || (sp->type == MTYPE && ismtype(sp->name)))
763 sprintf(pref, "((P%d *)pptr(pid))->", p->tn);
769 c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */
774 extern Lextok *Mtype;
777 fprintf(fd, "void\nc_globals(void)\n{\t/* int i; */\n");
778 fprintf(fd, " printf(\"global vars:\\n\");\n");
779 for (walk = all_names; walk; walk = walk->next)
781 if (sp->context || sp->owner || (sp->hidden&1))
783 c_var(fd, "now.", sp);
787 fprintf(fd, "void\nc_locals(int pid, int tp)\n{\t/* int i; */\n");
788 fprintf(fd, " switch(tp) {\n");
789 for (p = rdy; p; p = p->nxt)
790 { fprintf(fd, " case %d:\n", p->tn);
791 if (c_splurge_any(p))
792 { fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n",
796 { fprintf(fd, " \t/* none */\n");
798 fprintf(fd, " \tbreak;\n");
800 fprintf(fd, " }\n}\n");
802 fprintf(fd, "void\nprintm(int x)\n{\n");
803 fprintf(fd, " switch (x) {\n");
804 for (n = Mtype, j = 1; n && j; n = n->rgt, j++)
805 fprintf(fd, "\tcase %d: Printf(\"%s\"); break;\n",
806 j, n->lft->sym->name);
807 fprintf(fd, " default: Printf(\"%%d\", x);\n");
813 doglobal(char *pre, int dowhat)
818 for (j = 0; j < 8; j++)
819 for (walk = all_names; walk; walk = walk->next)
823 && sp->type == Types[j])
824 { if (Types[j] != MTYPE || !ismtype(sp->name))
832 do_var(tc, dowhat, "", sp,
833 pre, "\", now.", ");\n");
836 checktype(sp, (char *) 0);
837 cnt++; /* fall through */
840 (sp->hidden&1)?"":"now.", sp,
853 for (j = 0; j < 8; j++)
854 for (walk = all_names; walk; walk = walk->next)
857 && sp->type == Types[j])
858 { if (sp->context || sp->owner)
859 fatal("cannot hide non-globals (%s)", sp->name);
860 if (sp->type == CHAN)
861 fatal("cannot hide channels (%s)", sp->name);
862 fprintf(th, "/* hidden variable: */");
868 do_var(FILE *ofd, int dowhat, char *s, Symbol *sp,
869 char *pre, char *sep, char *ter)
871 char *ptr = sp?sp->name:"";
874 { fatal("cannot happen - do_var", 0);
879 if (sp->hidden&1) break;
885 if (!old_scope_rules)
886 { while (*ptr == '_' || isdigit((int)*ptr))
891 if (sp->type == STRUCT)
892 { /* struct may contain a chan */
893 walk_struct(ofd, dowhat, s, sp, pre, sep, ter);
896 if (!sp->ini && dowhat != LOGV) /* it defaults to 0 */
898 if (sp->nel == 1 && sp->isarray == 0)
899 { if (dowhat == LOGV)
900 { fprintf(ofd, "\t\t%s%s%s%s",
902 fprintf(ofd, "%s%s", s, sp->name);
904 { fprintf(ofd, "\t\t%s%s%s%s",
905 pre, s, sp->name, sep);
908 fprintf(ofd, "%s", ter);
910 { if (sp->ini && sp->ini->ntyp == CHAN)
911 { for (i = 0; i < sp->nel; i++)
912 { fprintf(ofd, "\t\t%s%s%s[%d]%s",
913 pre, s, sp->name, i, sep);
915 fprintf(ofd, "%s%s[%d]",
919 fprintf(ofd, "%s", ter);
922 { if (dowhat != LOGV && sp->isarray && sp->ini->ntyp == ',')
925 for (i = 0; i < sp->nel; i++)
926 { if (z && z->ntyp == ',')
932 fprintf(ofd, "\t\t%s%s%s[%d]%s",
933 pre, s, sp->name, i, sep);
935 fprintf(ofd, "%s", ter);
938 { fprintf(ofd, "\t{\tint l_in;\n");
939 fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n",
941 fprintf(ofd, "\t\t{\n");
942 fprintf(ofd, "\t\t\t%s%s%s[l_in]%s",
943 pre, s, sp->name, sep);
945 { fprintf(ofd, "%s%s[l_in]", s, sp->name);
947 { putstmnt(ofd, sp->ini, 0);
949 fprintf(ofd, "%s", ter);
950 fprintf(ofd, "\t\t}\n");
951 fprintf(ofd, "\t}\n");
958 do_init(FILE *ofd, Symbol *sp)
963 && ((i = qmake(sp)) > 0))
964 { if (sp->ini->ntyp == CHAN)
965 { fprintf(ofd, "addqueue(calling_pid, %d, %d)",
966 i, ltab[i-1]->nslots == 0);
968 { fprintf(ofd, "%d", i);
971 { putstmnt(ofd, sp->ini, 0);
976 put_ptype(char *s, int i, int m0, int m1, enum btypes b)
980 { fprintf(th, "#define Pinit ((P%d *)this)\n", i);
981 } else if (b == P_PROC || b == A_PROC)
982 { fprintf(th, "#define P%s ((P%d *)this)\n", s, i);
985 fprintf(th, "typedef struct P%d { /* %s */\n", i, s);
986 fprintf(th, " unsigned _pid : 8; /* 0..255 */\n");
987 fprintf(th, " unsigned _t : %d; /* proctype */\n", blog(m1));
988 fprintf(th, " unsigned _p : %d; /* state */\n", blog(m0));
989 fprintf(th, "#ifdef HAS_PRIORITY\n");
990 fprintf(th, " unsigned _priority : 8; /* 0..255 */\n");
991 fprintf(th, "#endif\n");
993 nBits = 8 + blog(m1) + blog(m0);
994 k = dolocal(tc, "", PUTV, i, s, b); /* includes pars */
997 fprintf(th, "} P%d;\n", i);
998 if ((!LstSet && k > 0) || has_state)
999 fprintf(th, "#define Air%d 0\n\n", i);
1000 else if (LstSet || k == 0) /* 5.0, added condition */
1001 { fprintf(th, "#define Air%d (sizeof(P%d) - ", i, i);
1003 { fprintf(th, "%d", (nBits+7)/8);
1006 if ((LstSet->type != BIT && LstSet->type != UNSIGNED)
1007 || LstSet->nel != 1)
1008 { fprintf(th, "Offsetof(P%d, %s) - %d*sizeof(",
1009 i, LstSet->name, LstSet->nel);
1011 switch(LstSet->type) {
1013 fprintf(th, "%d", (nBits+7)/8);
1016 if (LstSet->nel == 1)
1017 { fprintf(th, "%d", (nBits+7)/8);
1019 } /* else fall through */
1020 case MTYPE: case BYTE: case CHAN:
1021 fprintf(th, "uchar)"); break;
1023 fprintf(th, "short)"); break;
1025 fprintf(th, "int)"); break;
1027 fatal("cannot happen Air %s",
1030 done: fprintf(th, ")\n\n");
1037 fprintf(th, "#define _NP_ %d\n", nrRdy); /* 1+ highest proctype nr */
1039 fprintf(th, "#define _nstates%d 3 /* np_ */\n", nrRdy);
1040 fprintf(th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy);
1041 fprintf(th, "#define _start%d 0 /* np_ */\n", nrRdy);
1043 fprintf(tc, "\tcase %d: /* np_ */\n", nrRdy);
1045 { fprintf(tc, "\t\tini_claim(%d, h);\n", nrRdy);
1047 { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy);
1048 fprintf(tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy);
1050 fprintf(tc, "#ifdef HAS_PRIORITY\n");
1051 fprintf(tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy);
1052 fprintf(tc, "#endif\n");
1054 fprintf(tc, "\t\treached%d[0] = 1;\n", nrRdy);
1055 fprintf(tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy);
1057 fprintf(tc, "\t\tbreak;\n");
1068 fprintf(tc, "#ifndef NOCLAIM\n");
1069 fprintf(tc, "\tcase %d: /* claim select */\n", i);
1070 for (p = rdy, j = 0; p; p = p->nxt, j++)
1071 { if (p->b == N_CLAIM)
1073 ini = huntele(e, e->status, -1)->seqno;
1075 fprintf(tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n",
1076 j, p->tn, p->n->name);
1077 fprintf(tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n",
1079 fprintf(tc, "\t\treached%d[%d]=1;\n", p->tn, ini);
1081 /* the default initial claim is first one in model */
1083 { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn);
1084 fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini);
1085 fprintf(tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n",
1087 fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", p->tn);
1088 fprintf(tc, "#ifndef BFS\n");
1089 fprintf(tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n");
1090 fprintf(tc, "\t\t\tprintf(\"0: Claim %s (%d), from state %d\\n\");\n",
1091 p->n->name, p->tn, ini);
1092 fprintf(tc, "#endif\n");
1095 fprintf(tc, "\t\tif (whichclaim != -1)\n");
1096 fprintf(tc, "\t\t{ select_claim(whichclaim);\n");
1097 fprintf(tc, "\t\t}\n");
1098 fprintf(tc, "\t\tbreak;\n\n");
1099 fprintf(tc, "#endif\n");
1103 put_pinit(ProcList *P)
1104 { Lextok *fp, *fpt, *t;
1105 Element *e = P->s->frst;
1113 { fprintf(tc, "\tcase %d: /* %s */\n", i, s->name);
1114 fprintf(tc, "\t\tini_claim(%d, h);\n", i);
1115 fprintf(tc, "\t\tbreak;\n");
1118 if (!pid_is_claim(i)
1122 ini = huntele(e, e->status, -1)->seqno;
1123 fprintf(th, "#define _start%d %d\n", i, ini);
1124 if (i == eventmapnr)
1125 fprintf(th, "#define start_event %d\n", ini);
1127 fprintf(tc, "\tcase %d: /* %s */\n", i, s->name);
1129 fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i);
1130 fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini);
1131 fprintf(tc, "#ifdef HAS_PRIORITY\n");
1133 fprintf(tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n",
1134 i, (P->priority<1)? 1 : P->priority);
1136 fprintf(tc, "#endif\n");
1137 fprintf(tc, "\t\treached%d[%d]=1;\n", i, ini);
1138 if (P->b == N_CLAIM)
1139 { fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", i);
1143 { fprintf(tt, "\tcase %d: /* %s */\n\t\t", i, s->name);
1145 { fprintf(tt, "if (");
1146 putstmnt(tt, P->prov, 0);
1147 fprintf(tt, ")\n\t\t\t");
1149 fprintf(tt, "return 1;\n");
1151 fprintf(tt, "\t\tbreak;\n");
1154 fprintf(tc, "\t\t/* params: */\n");
1155 for (fp = p, j=0; fp; fp = fp->rgt)
1156 for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++)
1157 { t = (fpt->ntyp == ',') ? fpt->lft : fpt;
1158 if (t->sym->nel > 1 || t->sym->isarray)
1161 fatal("array in parameter list, %s",
1164 fprintf(tc, "\t\t((P%d *)pptr(h))->", i);
1165 if (t->sym->type == STRUCT)
1166 { if (full_name(tc, t, t->sym, 1))
1169 fatal("hidden array in parameter %s",
1173 fprintf(tc, "%s", t->sym->name);
1174 fprintf(tc, " = par%d;\n", j);
1176 fprintf(tc, "\t\t/* locals: */\n");
1177 k = dolocal(tc, "", INIV, i, s->name, P->b);
1179 { fprintf(tc, "#ifdef VAR_RANGES\n");
1180 (void) dolocal(tc, "logval(\"", LOGV, i, s->name, P->b);
1181 fprintf(tc, "#endif\n");
1184 fprintf(tc, "#ifdef HAS_CODE\n");
1185 fprintf(tc, "\t\tlocinit%d(h);\n", i);
1186 fprintf(tc, "#endif\n");
1188 dumpclaims(tc, i, s->name);
1189 fprintf(tc, "\t break;\n");
1193 huntstart(Element *f)
1195 Element *elast = (Element *) 0;
1198 while (elast != e && cnt++ < 200) /* new 4.0.8 */
1201 { if (e->n->ntyp == '.' && e->nxt)
1203 else if (e->n->ntyp == UNLESS)
1204 e = e->sub->this->frst;
1207 if (cnt >= 200 || !e)
1208 { lineno = (f && f->n)?f->n->ln:lineno;
1209 fatal("confusing control. structure", (char *) 0);
1215 huntele(Element *f, unsigned int o, int stopat)
1216 { Element *g, *e = f;
1217 int cnt=0; /* a precaution against loops */
1220 for ( ; cnt < 500 && e->n; cnt++)
1222 if (e->seqno == stopat)
1225 switch (e->n->ntyp) {
1227 g = get_lab(e->n,1);
1229 { lineno = (f && f->n)?f->n->ln:lineno;
1230 fatal("infinite goto loop", (char *) 0);
1232 cross_dsteps(e->n, g->n);
1241 g = huntele(e->sub->this->frst, o, stopat);
1243 { fatal("unexpected error 1", (char *) 0);
1252 if ((o & ATOM) && !(g->status & ATOM))
1256 if (cnt >= 500 || !e)
1257 { lineno = (f && f->n)?f->n->ln:lineno;
1258 fatal("confusing control structure", (char *) 0);
1265 { int wsbits = sizeof(long)*8; /* wordsize in bits */
1269 fprintf(th, "\tuchar %s;", sp->name);
1271 fprintf(th, "\tunsigned %s : %d",
1272 sp->name, sp->nbits);
1274 if (nBits%wsbits > 0
1275 && wsbits - nBits%wsbits < sp->nbits)
1276 { /* must padd to a word-boundary */
1277 nBits += wsbits - nBits%wsbits;
1282 if (sp->nel == 1 && sp->isarray == 0 && !(sp->hidden&1))
1283 { fprintf(th, "\tunsigned %s : 1", sp->name);
1287 } /* else fall through */
1288 if (!(sp->hidden&1) && (verbose&32))
1289 printf("spin: warning: bit-array %s[%d] mapped to byte-array\n",
1291 nBits += 8*sp->nel; /* mapped onto array of uchars */
1294 case CHAN: /* good for up to 255 channels */
1295 fprintf(th, "\tuchar %s", sp->name);
1299 fprintf(th, "\tshort %s", sp->name);
1303 fprintf(th, "\tint %s", sp->name);
1308 fatal("undeclared structure element %s", sp->name);
1309 fprintf(th, "\tstruct %s %s",
1318 fatal("variable %s undeclared", sp->name);
1321 if (sp->nel > 1 || sp->isarray)
1322 fprintf(th, "[%d]", sp->nel);
1327 ncases(FILE *fd, int p, int n, int m, const char *c[])
1330 for (j = 0; c[j]; j++)
1331 for (i = n; i < m; i++)
1332 { fprintf(fd, c[j], i, p, i);
1342 fprintf(th, "uchar");
1343 else if (qmax < 65535)
1344 fprintf(th, "ushort");
1346 fprintf(th, "uint");
1347 fprintf(th, " Qlen; /* q_size */\n");
1356 ntimes(tc, 0, 1, Addq0);
1359 fprintf(th, "#define NQS 1 /* nqs=%d, but has_io */\n", nqs);
1361 fprintf(th, "#define NQS %d\n", nqs);
1363 for (q = qtab; q; q = q->nxt)
1364 if (q->nslots > qmax)
1367 for (q = qtab; q; q = q->nxt)
1369 fprintf(tc, "\tcase %d: j = sizeof(Q%d);", j, j);
1370 fprintf(tc, " q_flds[%d] = %d;", j, q->nflds);
1371 fprintf(tc, " q_max[%d] = %d;", j, max(1,q->nslots));
1372 fprintf(tc, " break;\n");
1374 fprintf(th, "typedef struct Q%d {\n", j);
1375 qlen_type(qmax); /* 4.2.2 */
1376 fprintf(th, " uchar _t; /* q_type */\n");
1377 fprintf(th, " struct {\n");
1379 for (j = 0; j < q->nflds; j++)
1380 { switch (q->fld_width[j]) {
1383 { fprintf(th, "\t\tunsigned");
1384 fprintf(th, " fld%d : 1;\n", j);
1386 } /* else fall through: smaller struct */
1390 fprintf(th, "\t\tuchar fld%d;\n", j);
1393 fprintf(th, "\t\tshort fld%d;\n", j);
1396 fprintf(th, "\t\tint fld%d;\n", j);
1399 fatal("bad channel spec", "");
1402 fprintf(th, " } contents[%d];\n", max(1, q->nslots));
1403 fprintf(th, "} Q%d;\n", q->qid);
1406 fprintf(th, "typedef struct Q0 {\t/* generic q */\n");
1407 qlen_type(qmax); /* 4.2.2 */
1408 fprintf(th, " uchar _t;\n");
1409 fprintf(th, "} Q0;\n");
1411 ntimes(tc, 0, 1, Addq1);
1413 fprintf(tc, "#ifdef TRIX\n");
1414 fprintf(tc, "int\nwhat_p_size(int t)\n{\tint j;\n");
1415 fprintf(tc, " switch (t) {\n");
1416 ntimes(tc, 0, nrRdy+1, R5); /* +1 for np_ */
1417 fprintf(tc, " default: Uerror(\"bad proctype\");\n");
1418 fprintf(tc, " }\n return j;\n}\n\n");
1420 fprintf(tc, "int\nwhat_q_size(int t)\n{\tint j;\n");
1421 fprintf(tc, " switch (t) {\n");
1422 for (j = 0; j < nqs+1; j++)
1423 { fprintf(tc, " case %d: j = sizeof(Q%d); break;\n", j, j);
1425 fprintf(tc, " default: Uerror(\"bad qtype\");\n");
1426 fprintf(tc, " }\n return j;\n}\n");
1427 fprintf(tc, "#endif\n\n");
1430 { fprintf(th, "int Q_has(int");
1431 for (j = 0; j < Mpars; j++)
1432 fprintf(th, ", int, int");
1433 fprintf(th, ");\n");
1435 fprintf(tc, "int\nQ_has(int into");
1436 for (j = 0; j < Mpars; j++)
1437 fprintf(tc, ", int want%d, int fld%d", j, j);
1439 fprintf(tc, "{ int i;\n\n");
1440 fprintf(tc, " if (!into--)\n");
1441 fprintf(tc, " uerror(\"ref to unknown chan ");
1442 fprintf(tc, "(recv-poll)\");\n\n");
1443 fprintf(tc, " if (into >= now._nr_qs || into < 0)\n");
1444 fprintf(tc, " Uerror(\"qrecv bad queue#\");\n\n");
1445 fprintf(tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;");
1446 fprintf(tc, " i++)\n");
1447 fprintf(tc, " {\n");
1448 for (j = 0; j < Mpars; j++)
1449 { fprintf(tc, " if (want%d && ", j);
1450 fprintf(tc, "qrecv(into+1, i, %d, 0) != fld%d)\n",
1452 fprintf(tc, " continue;\n");
1454 fprintf(tc, " return i+1;\n");
1455 fprintf(tc, " }\n");
1456 fprintf(tc, " return 0;\n");
1460 fprintf(tc, "#if NQS>0\n");
1461 fprintf(tc, "void\nqsend(int into, int sorted");
1462 for (j = 0; j < Mpars; j++)
1463 fprintf(tc, ", int fld%d", j);
1464 fprintf(tc, ", int args_given)\n");
1465 ntimes(tc, 0, 1, Addq11);
1467 for (q = qtab; q; q = q->nxt)
1468 { sprintf(buf0, "((Q%d *)z)->", q->qid);
1469 fprintf(tc, "\tcase %d:%s\n", q->qid,
1470 (q->nslots)?"":" /* =rv= */");
1471 if (q->nslots == 0) /* reset handshake point */
1472 fprintf(tc, "\t\t(trpt+2)->o_m = 0;\n");
1475 { fprintf(tc, "\t\tif (!sorted) goto append%d;\n", q->qid);
1476 fprintf(tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0);
1477 fprintf(tc, "\t\t{\t/* find insertion point */\n");
1478 sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
1479 for (j = 0; j < q->nflds; j++)
1480 { fprintf(tc, "\t\t\tif (fld%d > %s%d) continue;\n",
1482 fprintf(tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j);
1483 fprintf(tc, "goto found%d;\n\n", q->qid);
1485 fprintf(tc, "\t\t}\n");
1486 fprintf(tc, "\tfound%d:\n", q->qid);
1487 sprintf(buf0, "((Q%d *)z)->", q->qid);
1488 fprintf(tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0);
1489 fprintf(tc, "\t\t{\t/* shift up */\n");
1490 for (j = 0; j < q->nflds; j++)
1491 { fprintf(tc, "\t\t\t%scontents[k+1].fld%d = ",
1493 fprintf(tc, "%scontents[k].fld%d;\n",
1496 fprintf(tc, "\t\t}\n");
1497 fprintf(tc, "\tappend%d:\t/* insert in slot j */\n", q->qid);
1500 fprintf(tc, "#ifdef HAS_SORTED\n");
1501 fprintf(tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */
1502 fprintf(tc, "#endif\n");
1503 fprintf(tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0);
1504 sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
1505 for (j = 0; j < q->nflds; j++)
1506 fprintf(tc, "\t\t%s%d = fld%d;\n", buf0, j, j);
1507 fprintf(tc, "\t\tif (args_given != %d)\n", q->nflds);
1508 fprintf(tc, "\t\t{ if (args_given > %d)\n", q->nflds);
1509 fprintf(tc, "\t\t uerror(\"too many parameters in send stmnt\");\n");
1510 fprintf(tc, "\t\t else\n");
1511 fprintf(tc, "\t\t uerror(\"too few parameters in send stmnt\");\n");
1512 fprintf(tc, "\t\t}\n");
1513 fprintf(tc, "\t\tbreak;\n");
1515 ntimes(tc, 0, 1, Addq2);
1517 for (q = qtab; q; q = q->nxt)
1518 fprintf(tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots));
1520 ntimes(tc, 0, 1, Addq3);
1522 for (q = qtab; q; q = q->nxt)
1523 fprintf(tc, "\tcase %d: return (q_sz(from) == %d);\n",
1524 q->qid, max(1, q->nslots));
1526 ntimes(tc, 0, 1, Addq4);
1527 for (q = qtab; q; q = q->nxt)
1528 { sprintf(buf0, "((Q%d *)z)->", q->qid);
1529 fprintf(tc, " case %d:%s\n\t\t",
1530 q->qid, (q->nslots)?"":" /* =rv= */");
1532 { fprintf(tc, "if (fld == 0) r = %s", buf0);
1533 fprintf(tc, "contents[slot].fld0;\n");
1535 { fprintf(tc, "switch (fld) {\n");
1536 ncases(tc, q->qid, 0, q->nflds, R12);
1537 fprintf(tc, "\t\tdefault: Uerror");
1538 fprintf(tc, "(\"too many fields in recv\");\n");
1539 fprintf(tc, "\t\t}\n");
1541 fprintf(tc, "\t\tif (done)\n");
1543 { fprintf(tc, "\t\t{ j = %sQlen - 1;\n", buf0);
1544 fprintf(tc, "\t\t %sQlen = 0;\n", buf0);
1545 sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid);
1547 { fprintf(tc, "\t\t{ j = %sQlen;\n", buf0);
1548 fprintf(tc, "\t\t %sQlen = --j;\n", buf0);
1549 fprintf(tc, "\t\t for (k=slot; k<j; k++)\n");
1550 fprintf(tc, "\t\t {\n");
1551 sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid);
1552 for (j = 0; j < q->nflds; j++)
1553 { fprintf(tc, "\t%s[k].fld%d = \n", buf0, j);
1554 fprintf(tc, "\t\t%s[k+1].fld%d;\n", buf0, j);
1556 fprintf(tc, "\t\t }\n");
1559 for (j = 0; j < q->nflds; j++)
1560 fprintf(tc, "%s[j].fld%d = 0;\n", buf0, j);
1561 fprintf(tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds);
1562 fprintf(tc, "\tuerror(\"missing pars in receive\");\n");
1563 /* incompletely received msgs cannot be unrecv'ed */
1564 fprintf(tc, "\t\t}\n");
1565 fprintf(tc, "\t\tbreak;\n");
1567 ntimes(tc, 0, 1, Addq5);
1568 for (q = qtab; q; q = q->nxt)
1569 fprintf(tc, " case %d: j = sizeof(Q%d); break;\n",
1571 ntimes(tc, 0, 1, R8b);
1572 ntimes(th, 0, 1, Proto); /* function prototypes */
1574 fprintf(th, "void qsend(int, int");
1575 for (j = 0; j < Mpars; j++)
1576 fprintf(th, ", int");
1577 fprintf(th, ", int);\n\n");
1579 fprintf(th, "#define Addproc(x,y) addproc(256, y, x");
1580 /* 256 is param outside the range of valid pids */
1581 for (j = 0; j < Npars; j++)