summaryrefslogtreecommitdiff
path: root/sys/src/cmd/spin/pangen1.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2017-11-22 21:09:31 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2017-11-22 21:09:31 +0100
commit28e9566dc539244b3b429c21c556d656733839c2 (patch)
tree1564ecdf009d240cb9247a10a0fcb6491e0424c4 /sys/src/cmd/spin/pangen1.c
parent077e719dfbf9bf2582bed80026251cc0d108c16e (diff)
spin: Update to most recent version. (thanks Ori_B)
from Ori_B: There were a small number of changes needed from the tarball on spinroot.org: - The mkfile needed to be updated - Memory.h needed to not be included - It needed to invoke /bin/cpp instead of gcc -E - It depended on `yychar`, which our yacc doesn't provide. I'm still figuring out how to use spin, but it seems to do the right thing when testing a few of the examples: % cd $home/src/Spin/Examples/ % spin -a peterson.pml % pcc pan.c -D_POSIX_SOURCE % ./6.out (Spin Version 6.4.7 -- 19 August 2017) + Partial Order Reduction Full statespace search for: never claim - (none specified) assertion violations + acceptance cycles - (not selected) invalid end states + State-vector 32 byte, depth reached 24, errors: 0 40 states, stored 27 states, matched 67 transitions (= stored+matched) 0 atomic steps hash conflicts: 0 (resolved) Stats on memory usage (in Megabytes): 0.002 equivalent memory usage for states (stored*(State-vector + overhead)) 0.292 actual memory usage for states 128.000 memory used for hash table (-w24) 0.534 memory used for DFS stack (-m10000) 128.730 total actual memory usage unreached in proctype user /tmp/Spin/Examples/peterson.pml:20, state 10, "-end-" (1 of 10 states) pan: elapsed time 1.25 seconds pan: rate 32 states/second
Diffstat (limited to 'sys/src/cmd/spin/pangen1.c')
-rw-r--r--sys/src/cmd/spin/pangen1.c655
1 files changed, 482 insertions, 173 deletions
diff --git a/sys/src/cmd/spin/pangen1.c b/sys/src/cmd/spin/pangen1.c
index cbef9dba5..3a537626d 100644
--- a/sys/src/cmd/spin/pangen1.c
+++ b/sys/src/cmd/spin/pangen1.c
@@ -1,18 +1,22 @@
/***** spin: pangen1.c *****/
-/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */
-/* All Rights Reserved. This software is for educational purposes only. */
-/* No guarantee whatsoever is expressed or implied by the distribution of */
-/* this code. Permission is given to distribute this code provided that */
-/* this introductory message is not removed and no monies are exchanged. */
-/* Software written by Gerard J. Holzmann. For tool documentation see: */
-/* http://spinroot.com/ */
-/* Send all bug-reports and/or questions to: bugs@spinroot.com */
+/*
+ * This file is part of the public release of Spin. It is subject to the
+ * terms in the LICENSE file that is included in this source directory.
+ * Tool documentation is available at http://spinroot.com
+ */
#include "spin.h"
#include "y.tab.h"
#include "pangen1.h"
#include "pangen3.h"
+#include "pangen6.h"
+#include <assert.h>
+#ifdef SOLARIS
+#include <sys/int_limits.h>
+#else
+#include <stdint.h>
+#endif
extern FILE *tc, *th, *tt;
extern Label *labtab;
@@ -20,9 +24,10 @@ extern Ordered *all_names;
extern ProcList *rdy;
extern Queue *qtab;
extern Symbol *Fname;
-extern int lineno, verbose, Pid, separate;
+extern int lineno, verbose, Pid, separate, old_scope_rules, nclaims;
extern int nrRdy, nqs, mst, Mpars, claimnr, eventmapnr;
-extern short has_sorted, has_random, has_provided;
+extern short has_sorted, has_random, has_provided, has_priority;
+extern Queue *ltab[];
int Npars=0, u_sync=0, u_async=0, hastrack = 1;
short has_io = 0;
@@ -36,9 +41,10 @@ static int doglobal(char *, int);
static void dohidden(void);
static void do_init(FILE *, Symbol *);
static void end_labs(Symbol *, int);
-static void put_ptype(char *, int, int, int);
+static void put_ptype(char *, int, int, int, enum btypes);
static void tc_predef_np(void);
static void put_pinit(ProcList *);
+static void multi_init(void);
void walk_struct(FILE *, int, char *, Symbol *, char *, char *, char *);
static void
@@ -46,7 +52,22 @@ reverse_names(ProcList *p)
{
if (!p) return;
reverse_names(p->nxt);
- fprintf(th, " \"%s\",\n", p->n->name);
+ fprintf(tc, " \"%s\",\n", p->n->name);
+}
+static void
+reverse_types(ProcList *p)
+{
+ if (!p) return;
+ reverse_types(p->nxt);
+ fprintf(tc, " %d, /* %s */\n", p->b, p->n->name);
+}
+
+static int
+blog(int n) /* for small log2 without rounding problems */
+{ int m=1, r=2;
+
+ while (r < n) { m++; r *= 2; }
+ return 1+m;
}
void
@@ -57,37 +78,129 @@ genheader(void)
{ putunames(th);
goto here;
}
-
+ /* 5.2.3: gcc 3 no longer seems to compute sizeof at compile time */
+ fprintf(th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *));
fprintf(th, "#define SYNC %d\n", u_sync);
fprintf(th, "#define ASYNC %d\n\n", u_async);
+ fprintf(th, "#ifndef NCORE\n");
+ fprintf(th, " #ifdef DUAL_CORE\n");
+ fprintf(th, " #define NCORE 2\n");
+ fprintf(th, " #elif QUAD_CORE\n");
+ fprintf(th, " #define NCORE 4\n");
+ fprintf(th, " #else\n");
+ fprintf(th, " #define NCORE 1\n");
+ fprintf(th, " #endif\n");
+ fprintf(th, "#endif\n\n");
putunames(th);
- fprintf(tc, "short Air[] = { ");
+ fprintf(tc, "\nshort Air[] = { ");
for (p = rdy, i=0; p; p = p->nxt, i++)
fprintf(tc, "%s (short) Air%d", (p!=rdy)?",":"", i);
fprintf(tc, ", (short) Air%d", i); /* np_ */
+ if (nclaims > 1)
+ { fprintf(tc, "\n#ifndef NOCLAIM\n");
+ fprintf(tc, " , (short) Air%d", i+1); /* Multi */
+ fprintf(tc, "\n#endif\n\t");
+ }
fprintf(tc, " };\n");
- fprintf(th, "char *procname[] = {\n");
+ fprintf(tc, "char *procname[] = {\n");
reverse_names(rdy);
- fprintf(th, " \":np_:\",\n");
- fprintf(th, "};\n\n");
+ fprintf(tc, " \":np_:\",\n");
+ fprintf(tc, " 0\n");
+ fprintf(tc, "};\n\n");
+
+ fprintf(tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM);
+ fprintf(tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC);
+ fprintf(tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n",
+ P_PROC, E_TRACE, N_TRACE);
+
+ fprintf(tc, "int Btypes[] = {\n");
+ reverse_types(rdy);
+ fprintf(tc, " 0 /* :np_: */\n");
+ fprintf(tc, "};\n\n");
here:
for (p = rdy; p; p = p->nxt)
- put_ptype(p->n->name, p->tn, mst, nrRdy+1);
+ put_ptype(p->n->name, p->tn, mst, nrRdy+1, p->b);
/* +1 for np_ */
- put_ptype("np_", nrRdy, mst, nrRdy+1);
+ put_ptype("np_", nrRdy, mst, nrRdy+1, 0);
+
+ if (nclaims > 1)
+ { /* this is the structure that goes into the state-vector
+ * instead of the actual never claims
+ * this assumes that the claims do not have any local variables
+ * this claim records the types and states of all subclaims in an array
+ * NB: not sure if we need the first 3 fields in this structure
+ * it's here for now to avoid breaking some possible dependence
+ * in the calculations above, we were already taking into account
+ * that there is one never-claim, which will now be this one
+ */
+
+ i = blog(mst);
+ fprintf(th, "\n");
+
+ fprintf(th, "#ifndef NOCLAIM\n");
+ fprintf(th, " #undef VERI\n");
+ fprintf(th, " #define VERI %d\n", nrRdy+1);
+ fprintf(th, " #define Pclaim P%d\n\n", nrRdy+1);
+ fprintf(th, "typedef struct P%d {\n", nrRdy+1);
+ fprintf(th, " unsigned _pid : 8; /* always zero */\n");
+ fprintf(th, " unsigned _t : %d; /* active-claim type */\n",
+ blog(nrRdy+1));
+ fprintf(th, " unsigned _p : %d; /* active-claim state */\n",
+ i);
+ fprintf(th, " unsigned _n : %d; /* active-claim index */\n",
+ blog(nclaims));
+ if (i <= UINT8_MAX) /* in stdint.h = UCHAR_MAX from limits.h */
+ { fprintf(th, " uchar c_cur[NCLAIMS]; /* claim-states */\n");
+ } else if (i <= UINT16_MAX) /* really USHRT_MAX from limits.h */
+ { fprintf(th, " ushort c_cur[NCLAIMS]; /* claim-states */\n");
+ } else /* the most unlikely case */
+ { fprintf(th, " uint c_cur[NCLAIMS]; /* claim-states */\n");
+ }
+ fprintf(th, "} P%d;\n", nrRdy+1);
+
+ fprintf(tc, "#ifndef NOCLAIM\n");
+ fprintf(tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n");
+ fprintf(tc, "#endif\n");
+
+ fprintf(th, " #define Air%d (0)\n\n", nrRdy+1);
+ fprintf(th, "#endif\n");
+ /*
+ * find special states as:
+ * stopstate [ claimnr ][ curstate ] == 1
+ * accpstate [ claimnr ][ curstate ]
+ * progstate [ claimnr ][ curstate ]
+ * reached [ claimnr ][ curstate ]
+ * visstate [ claimnr ][ curstate ]
+ * loopstate [ claimnr ][ curstate ]
+ * mapstate [ claimnr ][ curstate ]
+ */
+ } else
+ { fprintf(th, "#define Pclaim P0\n");
+ fprintf(th, "#ifndef NCLAIMS\n");
+ fprintf(th, " #define NCLAIMS 1\n");
+ fprintf(th, "#endif\n");
+ fprintf(tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n");
+ }
ntimes(th, 0, 1, Head0);
if (separate != 2)
{ extern void c_add_stack(FILE *);
+ extern void c_stack_size(FILE *);
ntimes(th, 0, 1, Header);
+ fprintf(th, "#define StackSize (");
+ c_stack_size(th);
+ fprintf(th, ")\n");
+
c_add_stack(th);
ntimes(th, 0, 1, Header0);
+ } else
+ { fprintf(th, "extern char *emalloc(unsigned long);\n");
}
ntimes(th, 0, 1, Head1);
@@ -96,7 +209,13 @@ here:
hastrack = c_add_sv(th);
+ fprintf(th, "#ifdef TRIX\n");
+ fprintf(th, " /* room for 512 proc+chan ptrs, + safety margin */\n");
+ fprintf(th, " char *_ids_[MAXPROC+MAXQ+4];\n");
+ fprintf(th, "#else\n");
fprintf(th, " uchar sv[VECTORSZ];\n");
+ fprintf(th, "#endif\n");
+
fprintf(th, "} State");
#ifdef SOLARIS
fprintf(th,"\n#ifdef GCC\n");
@@ -105,8 +224,24 @@ here:
#endif
fprintf(th, ";\n\n");
- fprintf(th, "#define HAS_TRACK %d\n", hastrack);
+ fprintf(th, "#ifdef TRIX\n");
+ fprintf(th, "typedef struct TRIX_v6 {\n");
+ fprintf(th, " uchar *body; /* aligned */\n");
+ fprintf(th, "#ifndef BFS\n");
+ fprintf(th, " short modified;\n");
+ fprintf(th, "#endif\n");
+ fprintf(th, " short psize;\n");
+ fprintf(th, " short parent_pid;\n");
+ fprintf(th, " struct TRIX_v6 *nxt;\n");
+ fprintf(th, "} TRIX_v6;\n");
+ fprintf(th, "#endif\n\n");
+ fprintf(th, "#define HAS_TRACK %d\n", hastrack);
+ if (0 && hastrack) /* not really a problem */
+ { fprintf(th, "#ifdef BFS_PAR\n");
+ fprintf(th, " #error cannot use BFS_PAR on models with c_track stmnts\n");
+ fprintf(th, "#endif\n");
+ }
if (separate != 2)
dohidden();
}
@@ -116,14 +251,36 @@ genaddproc(void)
{ ProcList *p;
int i = 0;
- if (separate ==2) goto shortcut;
+ if (separate == 2) goto shortcut;
+
+ ntimes(tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */
- fprintf(tc, "int\naddproc(int n");
- for (i = 0; i < Npars; i++)
+ fprintf(tc, "#ifdef TRIX\n");
+ fprintf(tc, "int what_p_size(int);\n");
+ fprintf(tc, "int what_q_size(int);\n\n");
+
+ /* the number of processes just changed by 1 (up or down) */
+ /* this means that the channel indices move up or down by one slot */
+ /* not all new channels may have a valid index yet, but we move */
+ /* all of them anyway, as if they existed */
+ ntimes(tc, 0, 1, R7a);
+ fprintf(tc, "#endif\n\n");
+
+ ntimes(tc, 0, 1, R7b);
+
+ fprintf(tc, "int\naddproc(int calling_pid, int priority, int n");
+ for (/* i = 0 */; i < Npars; i++)
fprintf(tc, ", int par%d", i);
ntimes(tc, 0, 1, Addp0);
ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */
+
+ if (nclaims > 1)
+ { fprintf(tc, "#ifndef NOCLAIM\n");
+ ntimes(tc, nrRdy+1, nrRdy+2, R5);
+ fprintf(tc, "#endif\n");
+ }
+
ntimes(tc, 0, 1, Addp1);
if (has_provided)
@@ -132,6 +289,9 @@ genaddproc(void)
fprintf(tt, "{\n\tswitch(ot) {\n");
}
shortcut:
+ if (nclaims > 1)
+ { multi_init();
+ }
tc_predef_np();
for (p = rdy; p; p = p->nxt)
{ Pid = p->tn;
@@ -157,8 +317,17 @@ void
do_locinits(FILE *fd)
{ ProcList *p;
+ /* the locinit functions may refer to pptr or qptr */
+ fprintf(fd, "#if VECTORSZ>32000\n");
+ fprintf(fd, " extern int \n");
+ fprintf(fd, "#else\n");
+ fprintf(fd, " extern short \n");
+ fprintf(fd, "#endif\n");
+ fprintf(fd, " *proc_offset, *q_offset;\n");
+
for (p = rdy; p; p = p->nxt)
- c_add_locinit(fd, p->tn, p->n->name);
+ { c_add_locinit(fd, p->tn, p->n->name);
+ }
}
void
@@ -167,63 +336,89 @@ genother(void)
switch (separate) {
case 2:
- if (claimnr >= 0)
- ntimes(tc, claimnr, claimnr+1, R0); /* claim only */
+ if (nclaims > 0)
+ { for (p = rdy; p; p = p->nxt)
+ { if (p->b == N_CLAIM)
+ { ntimes(tc, p->tn, p->tn+1, R0); /* claims only */
+ fprintf(tc, "#ifdef HAS_CODE\n");
+ ntimes(tc, p->tn, p->tn+1, R00);
+ fprintf(tc, "#endif\n");
+ } } }
break;
case 1:
ntimes(tc, 0, 1, Code0);
- ntimes(tc, 0, claimnr, R0); /* all except claim */
- ntimes(tc, claimnr+1, nrRdy, R0);
+ for (p = rdy; p; p = p->nxt)
+ { if (p->b != N_CLAIM)
+ { ntimes(tc, p->tn, p->tn+1, R0); /* all except claims */
+ fprintf(tc, "#ifdef HAS_CODE\n");
+ ntimes(tc, p->tn, p->tn+1, R00);
+ fprintf(tc, "#endif\n");
+ } }
break;
case 0:
ntimes(tc, 0, 1, Code0);
ntimes(tc, 0, nrRdy+1, R0); /* +1 for np_ */
+ fprintf(tc, "#ifdef HAS_CODE\n");
+ ntimes(tc, 0, nrRdy+1, R00); /* +1 for np_ */
+ fprintf(tc, "#endif\n");
break;
}
+ /* new place, make sure Maxbody is set to its final value here */
+ fprintf(tc, "\n");
+
+ if (separate != 2)
+ { ntimes(tc, 1, u_sync+u_async+1, R3); /* nqs is still 0 */
+ fprintf(tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n");
+ fprintf(tc, "\tif ((Maxbody %% WS) != 0)\n");
+ fprintf(tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n");
+ }
for (p = rdy; p; p = p->nxt)
end_labs(p->n, p->tn);
switch (separate) {
case 2:
- if (claimnr >= 0)
- ntimes(tc, claimnr, claimnr+1, R0a); /* claim only */
+ if (nclaims > 0)
+ { for (p = rdy; p; p = p->nxt)
+ { if (p->b == N_CLAIM)
+ { ntimes(tc, p->tn, p->tn+1, R0a); /* claims only */
+ } } }
return;
case 1:
- ntimes(tc, 0, claimnr, R0a); /* all except claim */
- ntimes(tc, claimnr+1, nrRdy, R0a);
+ for (p = rdy; p; p = p->nxt)
+ { if (p->b != N_CLAIM)
+ { ntimes(tc, p->tn, p->tn+1, R0a); /* all except claims */
+ } }
fprintf(tc, " if (state_tables)\n");
- fprintf(tc, " ini_claim(%d, 0);\n", claimnr);
+ fprintf(tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */
+ if (acceptors == 0)
+ { acceptors = 1; /* assume at least 1 acceptstate */
+ }
break;
case 0:
ntimes(tc, 0, nrRdy, R0a); /* all */
break;
}
- ntimes(tc, 0, 1, R0b);
- if (separate == 1 && acceptors == 0)
- acceptors = 1; /* assume at least 1 acceptstate */
ntimes(th, acceptors, acceptors+1, Code1);
ntimes(th, progressors, progressors+1, Code3);
- ntimes(th, nrRdy+1, nrRdy+2, R2); /* +1 for np_ */
- fprintf(tc, " iniglobals();\n");
- ntimes(tc, 0, 1, Code2a);
- ntimes(tc, 0, 1, Code2b); /* bfs option */
- ntimes(tc, 0, 1, Code2c);
+ ntimes(tc, 0, 1, Code2a); /* dfs, bfs */
+ ntimes(tc, 0, 1, Code2e); /* multicore */
+ ntimes(tc, 0, 1, Code2c); /* multicore */
+ ntimes(tc, 0, 1, Code2d);
+
+ fprintf(tc, "void\ndo_reach(void)\n{\n");
ntimes(tc, 0, nrRdy, R4);
fprintf(tc, "}\n\n");
- fprintf(tc, "void\n");
- fprintf(tc, "iniglobals(void)\n{\n");
+ fprintf(tc, "void\niniglobals(int calling_pid)\n{\n");
if (doglobal("", INIV) > 0)
{ fprintf(tc, "#ifdef VAR_RANGES\n");
(void) doglobal("logval(\"", LOGV);
fprintf(tc, "#endif\n");
}
- ntimes(tc, 1, nqs+1, R3);
- fprintf(tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);");
- fprintf(tc, "\n}\n\n");
+ fprintf(tc, "}\n\n");
}
void
@@ -248,17 +443,17 @@ end_labs(Symbol *s, int i)
Label *l;
int j; char foo[128];
- if ((i == claimnr && separate == 1)
- || (i != claimnr && separate == 2))
+ if ((pid_is_claim(i) && separate == 1)
+ || (!pid_is_claim(i) && separate == 2))
return;
for (l = labtab; l; l = l->nxt)
for (j = 0; ln[j].n; j++)
- if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0
+ { if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0
&& strcmp(l->c->name, s->name) == 0)
{ fprintf(tc, "\t%s[%d][%d] = 1;\n",
ln[j].t, i, l->e->seqno);
- acceptors += ln[j].m;
+ acceptors += ln[j].m;
progressors += ln[j].p;
if (l->e->status & D_ATOM)
{ sprintf(foo, "%s label inside d_step",
@@ -272,8 +467,7 @@ end_labs(Symbol *s, int i)
Fname = l->e->n->fn;
printf("spin: %3d:%s, warning, %s - is invisible\n",
lineno, Fname?Fname->name:"-", foo);
- }
- }
+ } } }
/* visible states -- through remote refs: */
for (l = labtab; l; l = l->nxt)
if (l->visible
@@ -286,7 +480,7 @@ end_labs(Symbol *s, int i)
}
void
-ntimes(FILE *fd, int n, int m, char *c[])
+ntimes(FILE *fd, int n, int m, const char *c[])
{
int i, j;
for (j = 0; c[j]; j++)
@@ -305,7 +499,7 @@ prehint(Symbol *s)
n = (s->context != ZS)?s->context->ini:s->ini;
if (n)
- printf("line %3d %s, ", n->ln, n->fn->name);
+ printf("line %s:%d, ", n->fn->name, n->ln);
}
void
@@ -338,7 +532,7 @@ checktype(Symbol *sp, char *s)
{ if (!(verbose&32)) return;
sputtype(buf, sp->type);
i = (int) strlen(buf);
- while (buf[--i] == ' ') buf[i] = '\0';
+ while (i > 0 && buf[--i] == ' ') buf[i] = '\0';
prehint(sp);
if (sp->context)
printf("proctype %s:", s);
@@ -361,12 +555,12 @@ checktype(Symbol *sp, char *s)
}
}
-int
-dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s)
+static int
+dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s, enum btypes b)
{ int h, j, k=0; extern int nr_errs;
Ordered *walk;
Symbol *sp;
- char buf[64], buf2[128], buf3[128];
+ char buf[128], buf2[128], buf3[128];
if (dowhat == INIV)
{ /* initialize in order of declaration */
@@ -390,7 +584,8 @@ dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s)
if (sp->context
&& !sp->owner
&& sp->type == Types[j]
- && ((h == 0 && sp->nel == 1) || (h == 1 && sp->nel > 1))
+ && ((h == 0 && (sp->nel == 1 && sp->isarray == 0))
+ || (h == 1 && (sp->nel > 1 || sp->isarray == 1)))
&& strcmp(s, sp->context->name) == 0)
{ switch (dowhat) {
case LOGV:
@@ -409,7 +604,7 @@ dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s)
k++;
break;
}
- if (strcmp(s, ":never:") == 0)
+ if (b == N_CLAIM)
{ printf("error: %s defines local %s\n",
s, sp->name);
nr_errs++;
@@ -425,8 +620,8 @@ c_chandump(FILE *fd)
int i;
if (!qtab)
- { fprintf(fd, "void\nc_chandump(int unused) ");
- fprintf(fd, "{ unused = unused++; /* avoid complaints */ }\n");
+ { fprintf(fd, "void\nc_chandump(int unused)\n");
+ fprintf(fd, "{\tunused++; /* avoid complaints */\n}\n");
return;
}
@@ -465,9 +660,19 @@ c_chandump(FILE *fd)
void
c_var(FILE *fd, char *pref, Symbol *sp)
-{ char buf[256];
+{ char *ptr, buf[256];
int i;
+ if (!sp)
+ { fatal("cannot happen - c_var", 0);
+ }
+
+ ptr = sp->name;
+ if (!old_scope_rules)
+ { while (*ptr == '_' || isdigit((int)*ptr))
+ { ptr++;
+ } }
+
switch (sp->type) {
case STRUCT:
/* c_struct(fd, pref, sp); */
@@ -476,34 +681,40 @@ c_var(FILE *fd, char *pref, Symbol *sp)
sprintf(buf, "%s%s.", pref, sp->name);
c_struct(fd, buf, sp);
break;
+ case MTYPE:
case BIT: case BYTE:
case SHORT: case INT:
case UNSIGNED:
sputtype(buf, sp->type);
- if (sp->nel == 1)
- { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n",
- buf, sp->name, pref, sp->name);
+ if (sp->nel == 1 && sp->isarray == 0)
+ {
+ if (sp->type == MTYPE && ismtype(sp->name))
+ { fprintf(fd, "\tprintf(\"\t%s %s:\t%d\\n\");\n",
+ buf, ptr, ismtype(sp->name));
+ } else
+ { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n",
+ buf, ptr, pref, sp->name);
+ }
} else
{ fprintf(fd, "\t{\tint l_in;\n");
fprintf(fd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel);
fprintf(fd, "\t\t{\n");
fprintf(fd, "\t\t\tprintf(\"\t%s %s[%%d]:\t%%d\\n\", l_in, %s%s[l_in]);\n",
- buf, sp->name, pref, sp->name);
+ buf, ptr, pref, sp->name);
fprintf(fd, "\t\t}\n");
fprintf(fd, "\t}\n");
}
break;
case CHAN:
- if (sp->nel == 1)
- { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ",
- sp->name);
+ if (sp->nel == 1 && sp->isarray == 0)
+ { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ", ptr);
fprintf(fd, "%s%s, q_len(%s%s));\n",
pref, sp->name, pref, sp->name);
fprintf(fd, "\tc_chandump(%s%s);\n", pref, sp->name);
} else
for (i = 0; i < sp->nel; i++)
{ fprintf(fd, "\tprintf(\"\tchan %s[%d] (=%%d):\tlen %%d:\\t\", ",
- sp->name, i);
+ ptr, i);
fprintf(fd, "%s%s[%d], q_len(%s%s[%d]));\n",
pref, sp->name, i, pref, sp->name, i);
fprintf(fd, "\tc_chandump(%s%s[%d]);\n",
@@ -518,9 +729,7 @@ c_splurge_any(ProcList *p)
{ Ordered *walk;
Symbol *sp;
- if (strcmp(p->n->name, ":never:") != 0
- && strcmp(p->n->name, ":trace:") != 0
- && strcmp(p->n->name, ":notrace:") != 0)
+ if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE)
for (walk = all_names; walk; walk = walk->next)
{ sp = walk->entry;
if (!sp->context
@@ -541,9 +750,7 @@ c_splurge(FILE *fd, ProcList *p)
Symbol *sp;
char pref[64];
- if (strcmp(p->n->name, ":never:") != 0
- && strcmp(p->n->name, ":trace:") != 0
- && strcmp(p->n->name, ":notrace:") != 0)
+ if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE)
for (walk = all_names; walk; walk = walk->next)
{ sp = walk->entry;
if (!sp->context
@@ -571,10 +778,8 @@ c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */
fprintf(fd, " printf(\"global vars:\\n\");\n");
for (walk = all_names; walk; walk = walk->next)
{ sp = walk->entry;
- if (sp->context || sp->owner || (sp->hidden&1)
- || (sp->type == MTYPE && ismtype(sp->name)))
+ if (sp->context || sp->owner || (sp->hidden&1))
continue;
-
c_var(fd, "now.", sp);
}
fprintf(fd, "}\n");
@@ -583,8 +788,6 @@ c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */
fprintf(fd, " switch(tp) {\n");
for (p = rdy; p; p = p->nxt)
{ fprintf(fd, " case %d:\n", p->tn);
- fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n",
- p->n->name);
if (c_splurge_any(p))
{ fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n",
p->n->name);
@@ -633,8 +836,9 @@ doglobal(char *pre, int dowhat)
checktype(sp, (char *) 0);
cnt++; /* fall through */
case PUTV:
- do_var(tc, dowhat, (sp->hidden&1)?"":"now.", sp,
- "", " = ", ";\n");
+ do_var(tc, dowhat,
+ (sp->hidden&1)?"":"now.", sp,
+ "", " = ", ";\n");
break;
} } }
return cnt;
@@ -652,28 +856,37 @@ dohidden(void)
if ((sp->hidden&1)
&& sp->type == Types[j])
{ if (sp->context || sp->owner)
- fatal("cannot hide non-globals (%s)", sp->name);
+ fatal("cannot hide non-globals (%s)", sp->name);
if (sp->type == CHAN)
- fatal("cannot hide channels (%s)", sp->name);
+ fatal("cannot hide channels (%s)", sp->name);
fprintf(th, "/* hidden variable: */");
typ2c(sp);
} }
- fprintf(th, "int _; /* a predefined write-only variable */\n\n");
}
void
do_var(FILE *ofd, int dowhat, char *s, Symbol *sp,
char *pre, char *sep, char *ter)
{ int i;
+ char *ptr = sp?sp->name:"";
+
+ if (!sp)
+ { fatal("cannot happen - do_var", 0);
+ }
switch(dowhat) {
case PUTV:
-
if (sp->hidden&1) break;
typ2c(sp);
break;
+
case LOGV:
+ if (!old_scope_rules)
+ { while (*ptr == '_' || isdigit((int)*ptr))
+ { ptr++;
+ } }
+ /* fall thru */
case INIV:
if (sp->type == STRUCT)
{ /* struct may contain a chan */
@@ -682,13 +895,16 @@ do_var(FILE *ofd, int dowhat, char *s, Symbol *sp,
}
if (!sp->ini && dowhat != LOGV) /* it defaults to 0 */
break;
- if (sp->nel == 1)
- { fprintf(ofd, "\t\t%s%s%s%s",
- pre, s, sp->name, sep);
- if (dowhat == LOGV)
+ if (sp->nel == 1 && sp->isarray == 0)
+ { if (dowhat == LOGV)
+ { fprintf(ofd, "\t\t%s%s%s%s",
+ pre, s, ptr, sep);
fprintf(ofd, "%s%s", s, sp->name);
- else
+ } else
+ { fprintf(ofd, "\t\t%s%s%s%s",
+ pre, s, sp->name, sep);
do_init(ofd, sp);
+ }
fprintf(ofd, "%s", ter);
} else
{ if (sp->ini && sp->ini->ntyp == CHAN)
@@ -702,77 +918,86 @@ do_var(FILE *ofd, int dowhat, char *s, Symbol *sp,
do_init(ofd, sp);
fprintf(ofd, "%s", ter);
}
- } else
- { fprintf(ofd, "\t{\tint l_in;\n");
- fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel);
- fprintf(ofd, "\t\t{\n");
- fprintf(ofd, "\t\t\t%s%s%s[l_in]%s",
+ } else if (sp->ini)
+ { if (dowhat != LOGV && sp->isarray && sp->ini->ntyp == ',')
+ { Lextok *z, *y;
+ z = sp->ini;
+ for (i = 0; i < sp->nel; i++)
+ { if (z && z->ntyp == ',')
+ { y = z->lft;
+ z = z->rgt;
+ } else
+ { y = z;
+ }
+ fprintf(ofd, "\t\t%s%s%s[%d]%s",
+ pre, s, sp->name, i, sep);
+ putstmnt(ofd, y, 0);
+ fprintf(ofd, "%s", ter);
+ }
+ } else
+ { fprintf(ofd, "\t{\tint l_in;\n");
+ fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n",
+ sp->nel);
+ fprintf(ofd, "\t\t{\n");
+ fprintf(ofd, "\t\t\t%s%s%s[l_in]%s",
pre, s, sp->name, sep);
- if (dowhat == LOGV)
- fprintf(ofd, "%s%s[l_in]", s, sp->name);
- else
- putstmnt(ofd, sp->ini, 0);
- fprintf(ofd, "%s", ter);
- fprintf(ofd, "\t\t}\n");
- fprintf(ofd, "\t}\n");
- } }
+ if (dowhat == LOGV)
+ { fprintf(ofd, "%s%s[l_in]", s, sp->name);
+ } else
+ { putstmnt(ofd, sp->ini, 0);
+ }
+ fprintf(ofd, "%s", ter);
+ fprintf(ofd, "\t\t}\n");
+ fprintf(ofd, "\t}\n");
+ } } }
break;
}
}
static void
do_init(FILE *ofd, Symbol *sp)
-{ int i; extern Queue *ltab[];
+{ int i;
if (sp->ini
&& sp->type == CHAN
&& ((i = qmake(sp)) > 0))
{ if (sp->ini->ntyp == CHAN)
- fprintf(ofd, "addqueue(%d, %d)",
- i, ltab[i-1]->nslots == 0);
- else
- fprintf(ofd, "%d", i);
+ { fprintf(ofd, "addqueue(calling_pid, %d, %d)",
+ i, ltab[i-1]->nslots == 0);
+ } else
+ { fprintf(ofd, "%d", i);
+ }
} else
- putstmnt(ofd, sp->ini, 0);
-}
-
-static int
-blog(int n) /* for small log2 without rounding problems */
-{ int m=1, r=2;
-
- while (r < n) { m++; r *= 2; }
- return 1+m;
+ { putstmnt(ofd, sp->ini, 0);
+ }
}
static void
-put_ptype(char *s, int i, int m0, int m1)
+put_ptype(char *s, int i, int m0, int m1, enum btypes b)
{ int k;
- if (strcmp(s, ":init:") == 0)
- fprintf(th, "#define Pinit ((P%d *)this)\n", i);
-
- if (strcmp(s, ":never:") != 0
- && strcmp(s, ":trace:") != 0
- && strcmp(s, ":notrace:") != 0
- && strcmp(s, ":init:") != 0
- && strcmp(s, "_:never_template:_") != 0
- && strcmp(s, "np_") != 0)
- fprintf(th, "#define P%s ((P%d *)this)\n", s, i);
+ if (b == I_PROC)
+ { fprintf(th, "#define Pinit ((P%d *)this)\n", i);
+ } else if (b == P_PROC || b == A_PROC)
+ { fprintf(th, "#define P%s ((P%d *)this)\n", s, i);
+ }
fprintf(th, "typedef struct P%d { /* %s */\n", i, s);
fprintf(th, " unsigned _pid : 8; /* 0..255 */\n");
fprintf(th, " unsigned _t : %d; /* proctype */\n", blog(m1));
fprintf(th, " unsigned _p : %d; /* state */\n", blog(m0));
+ fprintf(th, "#ifdef HAS_PRIORITY\n");
+ fprintf(th, " unsigned _priority : 8; /* 0..255 */\n");
+ fprintf(th, "#endif\n");
LstSet = ZS;
nBits = 8 + blog(m1) + blog(m0);
- k = dolocal(tc, "", PUTV, i, s); /* includes pars */
-
+ k = dolocal(tc, "", PUTV, i, s, b); /* includes pars */
c_add_loc(th, s);
fprintf(th, "} P%d;\n", i);
if ((!LstSet && k > 0) || has_state)
- fprintf(th, "#define Air%d 0\n", i);
- else
+ fprintf(th, "#define Air%d 0\n\n", i);
+ else if (LstSet || k == 0) /* 5.0, added condition */
{ fprintf(th, "#define Air%d (sizeof(P%d) - ", i, i);
if (k == 0)
{ fprintf(th, "%d", (nBits+7)/8);
@@ -802,35 +1027,79 @@ put_ptype(char *s, int i, int m0, int m1)
fatal("cannot happen Air %s",
LstSet->name);
}
-done: fprintf(th, ")\n");
+done: fprintf(th, ")\n\n");
}
}
static void
tc_predef_np(void)
-{ int i = nrRdy; /* 1+ highest proctype nr */
-
- fprintf(th, "#define _NP_ %d\n", i);
-/* if (separate == 2) fprintf(th, "extern "); */
- fprintf(th, "uchar reached%d[3]; /* np_ */\n", i);
+{
+ fprintf(th, "#define _NP_ %d\n", nrRdy); /* 1+ highest proctype nr */
- fprintf(th, "#define nstates%d 3 /* np_ */\n", i);
- fprintf(th, "#define endstate%d 2 /* np_ */\n\n", i);
- fprintf(th, "#define start%d 0 /* np_ */\n", i);
+ fprintf(th, "#define _nstates%d 3 /* np_ */\n", nrRdy);
+ fprintf(th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy);
+ fprintf(th, "#define _start%d 0 /* np_ */\n", nrRdy);
- fprintf(tc, "\tcase %d: /* np_ */\n", i);
+ fprintf(tc, "\tcase %d: /* np_ */\n", nrRdy);
if (separate == 1)
- { fprintf(tc, "\t\tini_claim(%d, h);\n", i);
+ { fprintf(tc, "\t\tini_claim(%d, h);\n", nrRdy);
} else
- { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i);
- fprintf(tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", i);
- fprintf(tc, "\t\treached%d[0] = 1;\n", i);
- fprintf(tc, "\t\taccpstate[%d][1] = 1;\n", i);
+ { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy);
+ fprintf(tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy);
+
+ fprintf(tc, "#ifdef HAS_PRIORITY\n");
+ fprintf(tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy);
+ fprintf(tc, "#endif\n");
+
+ fprintf(tc, "\t\treached%d[0] = 1;\n", nrRdy);
+ fprintf(tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy);
}
fprintf(tc, "\t\tbreak;\n");
}
static void
+multi_init(void)
+{ ProcList *p;
+ Element *e;
+ int i = nrRdy+1;
+ int ini, j;
+ int nrc = nclaims;
+
+ fprintf(tc, "#ifndef NOCLAIM\n");
+ fprintf(tc, "\tcase %d: /* claim select */\n", i);
+ for (p = rdy, j = 0; p; p = p->nxt, j++)
+ { if (p->b == N_CLAIM)
+ { e = p->s->frst;
+ ini = huntele(e, e->status, -1)->seqno;
+
+ fprintf(tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n",
+ j, p->tn, p->n->name);
+ fprintf(tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n",
+ i, j, ini);
+ fprintf(tc, "\t\treached%d[%d]=1;\n", p->tn, ini);
+
+ /* the default initial claim is first one in model */
+ if (--nrc == 0)
+ { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn);
+ fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini);
+ fprintf(tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n",
+ i, j, p->n->name);
+ fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", p->tn);
+ fprintf(tc, "#ifndef BFS\n");
+ fprintf(tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n");
+ fprintf(tc, "\t\t\tprintf(\"0: Claim %s (%d), from state %d\\n\");\n",
+ p->n->name, p->tn, ini);
+ fprintf(tc, "#endif\n");
+ }
+ } }
+ fprintf(tc, "\t\tif (whichclaim != -1)\n");
+ fprintf(tc, "\t\t{ select_claim(whichclaim);\n");
+ fprintf(tc, "\t\t}\n");
+ fprintf(tc, "\t\tbreak;\n\n");
+ fprintf(tc, "#endif\n");
+}
+
+static void
put_pinit(ProcList *P)
{ Lextok *fp, *fpt, *t;
Element *e = P->s->frst;
@@ -839,29 +1108,36 @@ put_pinit(ProcList *P)
int i = P->tn;
int ini, j, k;
- if (i == claimnr
+ if (pid_is_claim(i)
&& separate == 1)
{ fprintf(tc, "\tcase %d: /* %s */\n", i, s->name);
fprintf(tc, "\t\tini_claim(%d, h);\n", i);
fprintf(tc, "\t\tbreak;\n");
return;
}
- if (i != claimnr
+ if (!pid_is_claim(i)
&& separate == 2)
return;
ini = huntele(e, e->status, -1)->seqno;
- fprintf(th, "#define start%d %d\n", i, ini);
- if (i == claimnr)
- fprintf(th, "#define start_claim %d\n", ini);
+ fprintf(th, "#define _start%d %d\n", i, ini);
if (i == eventmapnr)
fprintf(th, "#define start_event %d\n", ini);
fprintf(tc, "\tcase %d: /* %s */\n", i, s->name);
fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i);
- fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;", i, ini);
- fprintf(tc, " reached%d[%d]=1;\n", i, ini);
+ fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini);
+ fprintf(tc, "#ifdef HAS_PRIORITY\n");
+
+ fprintf(tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n",
+ i, (P->priority<1)? 1 : P->priority);
+
+ fprintf(tc, "#endif\n");
+ fprintf(tc, "\t\treached%d[%d]=1;\n", i, ini);
+ if (P->b == N_CLAIM)
+ { fprintf(tc, "\t\tsrc_claim = src_ln%d;\n", i);
+ }
if (has_provided)
{ fprintf(tt, "\tcase %d: /* %s */\n\t\t", i, s->name);
@@ -879,7 +1155,7 @@ put_pinit(ProcList *P)
for (fp = p, j=0; fp; fp = fp->rgt)
for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++)
{ t = (fpt->ntyp == ',') ? fpt->lft : fpt;
- if (t->sym->nel != 1)
+ if (t->sym->nel > 1 || t->sym->isarray)
{ lineno = t->ln;
Fname = t->fn;
fatal("array in parameter list, %s",
@@ -898,10 +1174,10 @@ put_pinit(ProcList *P)
fprintf(tc, " = par%d;\n", j);
}
fprintf(tc, "\t\t/* locals: */\n");
- k = dolocal(tc, "", INIV, i, s->name);
+ k = dolocal(tc, "", INIV, i, s->name, P->b);
if (k > 0)
{ fprintf(tc, "#ifdef VAR_RANGES\n");
- (void) dolocal(tc, "logval(\"", LOGV, i, s->name);
+ (void) dolocal(tc, "logval(\"", LOGV, i, s->name, P->b);
fprintf(tc, "#endif\n");
}
@@ -929,17 +1205,19 @@ huntstart(Element *f)
} }
if (cnt >= 200 || !e)
- fatal("confusing control structure", (char *) 0);
+ { lineno = (f && f->n)?f->n->ln:lineno;
+ fatal("confusing control. structure", (char *) 0);
+ }
return e;
}
Element *
-huntele(Element *f, int o, int stopat)
+huntele(Element *f, unsigned int o, int stopat)
{ Element *g, *e = f;
int cnt=0; /* a precaution against loops */
if (e)
- for (cnt = 0; cnt < 200 && e->n; cnt++)
+ for ( ; cnt < 500 && e->n; cnt++)
{
if (e->seqno == stopat)
break;
@@ -947,6 +1225,10 @@ huntele(Element *f, int o, int stopat)
switch (e->n->ntyp) {
case GOTO:
g = get_lab(e->n,1);
+ if (e == g)
+ { lineno = (f && f->n)?f->n->ln:lineno;
+ fatal("infinite goto loop", (char *) 0);
+ }
cross_dsteps(e->n, g->n);
break;
case '.':
@@ -957,6 +1239,9 @@ huntele(Element *f, int o, int stopat)
break;
case UNLESS:
g = huntele(e->sub->this->frst, o, stopat);
+ if (!g)
+ { fatal("unexpected error 1", (char *) 0);
+ }
break;
case D_STEP:
case ATOMIC:
@@ -968,8 +1253,10 @@ huntele(Element *f, int o, int stopat)
return e;
e = g;
}
- if (cnt >= 200 || !e)
+ if (cnt >= 500 || !e)
+ { lineno = (f && f->n)?f->n->ln:lineno;
fatal("confusing control structure", (char *) 0);
+ }
return e;
}
@@ -992,7 +1279,7 @@ typ2c(Symbol *sp)
nBits += sp->nbits;
break;
case BIT:
- if (sp->nel == 1 && !(sp->hidden&1))
+ if (sp->nel == 1 && sp->isarray == 0 && !(sp->hidden&1))
{ fprintf(th, "\tunsigned %s : 1", sp->name);
LstSet = sp;
nBits++;
@@ -1031,13 +1318,13 @@ typ2c(Symbol *sp)
fatal("variable %s undeclared", sp->name);
}
- if (sp->nel != 1)
+ if (sp->nel > 1 || sp->isarray)
fprintf(th, "[%d]", sp->nel);
fprintf(th, ";\n");
}
static void
-ncases(FILE *fd, int p, int n, int m, char *c[])
+ncases(FILE *fd, int p, int n, int m, const char *c[])
{ int i, j;
for (j = 0; c[j]; j++)
@@ -1067,12 +1354,11 @@ genaddqueue(void)
Queue *q;
ntimes(tc, 0, 1, Addq0);
+
if (has_io && !nqs)
fprintf(th, "#define NQS 1 /* nqs=%d, but has_io */\n", nqs);
else
fprintf(th, "#define NQS %d\n", nqs);
- fprintf(th, "short q_flds[%d];\n", nqs+1);
- fprintf(th, "short q_max[%d];\n", nqs+1);
for (q = qtab; q; q = q->nxt)
if (q->nslots > qmax)
@@ -1124,6 +1410,22 @@ genaddqueue(void)
ntimes(tc, 0, 1, Addq1);
+ fprintf(tc, "#ifdef TRIX\n");
+ fprintf(tc, "int\nwhat_p_size(int t)\n{\tint j;\n");
+ fprintf(tc, " switch (t) {\n");
+ ntimes(tc, 0, nrRdy+1, R5); /* +1 for np_ */
+ fprintf(tc, " default: Uerror(\"bad proctype\");\n");
+ fprintf(tc, " }\n return j;\n}\n\n");
+
+ fprintf(tc, "int\nwhat_q_size(int t)\n{\tint j;\n");
+ fprintf(tc, " switch (t) {\n");
+ for (j = 0; j < nqs+1; j++)
+ { fprintf(tc, " case %d: j = sizeof(Q%d); break;\n", j, j);
+ }
+ fprintf(tc, " default: Uerror(\"bad qtype\");\n");
+ fprintf(tc, " }\n return j;\n}\n");
+ fprintf(tc, "#endif\n\n");
+
if (has_random)
{ fprintf(th, "int Q_has(int");
for (j = 0; j < Mpars; j++)
@@ -1159,7 +1461,7 @@ genaddqueue(void)
fprintf(tc, "void\nqsend(int into, int sorted");
for (j = 0; j < Mpars; j++)
fprintf(tc, ", int fld%d", j);
- fprintf(tc, ")\n");
+ fprintf(tc, ", int args_given)\n");
ntimes(tc, 0, 1, Addq11);
for (q = qtab; q; q = q->nxt)
@@ -1202,6 +1504,12 @@ genaddqueue(void)
sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
for (j = 0; j < q->nflds; j++)
fprintf(tc, "\t\t%s%d = fld%d;\n", buf0, j, j);
+ fprintf(tc, "\t\tif (args_given != %d)\n", q->nflds);
+ fprintf(tc, "\t\t{ if (args_given > %d)\n", q->nflds);
+ fprintf(tc, "\t\t uerror(\"too many parameters in send stmnt\");\n");
+ fprintf(tc, "\t\t else\n");
+ fprintf(tc, "\t\t uerror(\"too few parameters in send stmnt\");\n");
+ fprintf(tc, "\t\t}\n");
fprintf(tc, "\t\tbreak;\n");
}
ntimes(tc, 0, 1, Addq2);
@@ -1261,14 +1569,15 @@ genaddqueue(void)
fprintf(tc, " case %d: j = sizeof(Q%d); break;\n",
q->qid, q->qid);
ntimes(tc, 0, 1, R8b);
+ ntimes(th, 0, 1, Proto); /* function prototypes */
- ntimes(th, 0, 1, Proto); /* tag on function prototypes */
fprintf(th, "void qsend(int, int");
for (j = 0; j < Mpars; j++)
fprintf(th, ", int");
- fprintf(th, ");\n");
+ fprintf(th, ", int);\n\n");
- fprintf(th, "#define Addproc(x) addproc(x");
+ fprintf(th, "#define Addproc(x,y) addproc(256, y, x");
+ /* 256 is param outside the range of valid pids */
for (j = 0; j < Npars; j++)
fprintf(th, ", 0");
fprintf(th, ")\n");