/* $NetBSD: procs.c,v 1.12 2007/01/18 12:43:38 cbiere Exp $ */ /* * This code is such a kludge that I don't want to put my name on it. * It was a ridiculously fast hack and needs rewriting. * However it does work... */ #include <sys/cdefs.h> __KERNEL_RCSID(0, "$NetBSD: procs.c,v 1.12 2007/01/18 12:43:38 cbiere Exp $"); #include <stdio.h> #include <strings.h> #include <unistd.h> #include "malloc.h" #include "main.h" #include "debug.h" #include "sets.h" #include "procs.h" struct Predicate { int p_index; int p_transno; char *p_str; struct Predicate *p_next; }; struct Stateent { int s_index; int s_newstate; int s_action; struct Stateent *s_next; }; struct Object *SameState = (struct Object *)-1; int Index = 0; int Nstates = 0; int Nevents = 0; struct Predicate **Predlist; struct Stateent **Statelist; extern FILE *astringfile; int predtable(); void end_events() { int size, part; char *addr; IFDEBUG(X) /* finish estring[], start astring[] */ if(debug['X'] < 2 ) fprintf(astringfile, "};\n\nchar *%s_astring[] = {\n\"NULLACTION\",\n", protocol); ENDDEBUG /* NOSTRICT */ Statelist = (struct Stateent **) Malloc((Nstates+1) * sizeof(struct Statent *)); /* NOSTRICT */ Predlist = (struct Predicate **) Malloc ( (((Nevents)<<Eventshift)+Nstates)*sizeof(struct Predicate *) ); size = (((Nevents)<<Eventshift)+Nstates)*sizeof(struct Predicate *) ; addr = (char *)Predlist; IFDEBUG(N) fprintf(OUT, "Predlist at %p, sbrk %p bzero size %d at addr %p\n", Predlist, sbrk(0), size, addr); ENDDEBUG #define BZSIZE 8192 while(size) { part = size>BZSIZE?BZSIZE:size; IFDEBUG(N) fprintf(OUT, "bzero addr %p part %d size %d\n",addr, part, size); ENDDEBUG bzero(addr, part); IFDEBUG(N) fprintf(OUT, "after bzero addr %p part %d size %d\n",addr, part, size); ENDDEBUG addr += part; size -= part; } IFDEBUG(N) fprintf(OUT, "endevents..done \n"); ENDDEBUG } int acttable(f,actstring) char *actstring; FILE *f; { static int Actindex = 0; extern FILE *astringfile; extern int pgoption; IFDEBUG(a) fprintf(OUT,"acttable()\n"); ENDDEBUG fprintf(f, "case 0x%x: \n", ++Actindex); if(pgoption) { fprintf(f, "asm(\" # dummy statement\");\n"); fprintf(f, "asm(\"_Xebec_action_%x: \");\n", Actindex ); fprintf(f, "asm(\".data\");\n"); fprintf(f, "asm(\".globl _Xebec_action_%x# X profiling\");\n", Actindex ); fprintf(f, "asm(\".long 0 # X profiling\");\n"); fprintf(f, "asm(\".text # X profiling\");\n"); fprintf(f, "asm(\"cas r0,r15,r0 # X profiling\");\n"); fprintf(f, "asm(\"bali r15,mcount # X profiling\");\n"); } fprintf(f, "\t\t%s\n\t\t break;\n", actstring); IFDEBUG(X) if(debug['X']<2) { register int len = 0; fputc('"',astringfile); while(*actstring) { if( *actstring == '\n' ) { fputc('\\', astringfile); len++; fputc('n', astringfile); } else if (*actstring == '\\') { fputc('\\', astringfile); len++; fputc('\\', astringfile); } else if (*actstring == '\"') { fputc('\\', astringfile); len++; fputc('\"', astringfile); } else fputc(*actstring, astringfile); actstring++; len++; } fprintf(astringfile,"\",\n"); if (len > LINELEN) { fprintf(stderr, "Action too long: %d\n",len); Exit(-1); } } ENDDEBUG return(Actindex); } static int Npred=0, Ndefpred=0, Ntrans=0, Ndefevent=0, Nnulla=0; void statetable(string, oldstate, newstate, action, event) char *string; int action; struct Object *oldstate, *newstate, *event; { register int different; IFDEBUG(a) fprintf(OUT,"statetable(%p, %p,%p, 0x%x)\n", string, oldstate, newstate, action); fprintf(OUT,"statetable(%s, %s,%s, 0x%x)\n", string, oldstate->obj_name, newstate->obj_name, action); ENDDEBUG if( !action) Nnulla++; if( newstate->obj_kind == OBJ_SET) { fprintf(stderr, "Newstate cannot be a set\n"); Exit(-1); } different = (newstate != SameState); (void) predtable( oldstate, event, string, action, (newstate->obj_number) * different ); IFDEBUG(a) fprintf(OUT,"EXIT statetable\n"); ENDDEBUG } void stateentry(idx, oldstate, newstate, action) int idx, action; int oldstate, newstate; { extern FILE *statevalfile; IFDEBUG(a) fprintf(OUT,"stateentry(0x%x,0x%x,0x%x,0x%x) Statelist@%p, val %p\n", idx, oldstate, newstate,action, &Statelist, Statelist); ENDDEBUG fprintf(statevalfile, "{0x%x,0x%x},\n", newstate, action); } int predtable(os, oe, str, action, newstate) struct Object *os, *oe; char *str; int action, newstate; { register struct Predicate *p, **q; register int event, state; register struct Object *e, *s; struct Object *firste; extern FILE *statevalfile; if (oe == (struct Object *)0 ) { Ndefevent++; fprintf(stderr, "DEFAULT EVENTS aren't implemented; trans ignored\n"); return (-1); } Ntrans++; IFDEBUG(g) fprintf(stdout, "PREDTAB: s %5s; e %5s\n", os->obj_kind==OBJ_SET?"SET":"item", oe->obj_kind==OBJ_SET?"SET":"item"); ENDDEBUG if (os->obj_kind == OBJ_SET) s = os->obj_members; else s = os; if (oe->obj_kind == OBJ_SET) firste = oe->obj_members; else firste = oe; if(newstate) { fprintf(statevalfile, "{0x%x,0x%x},\n",newstate, action); Index++; } while (s) { if( !newstate ) { /* !newstate --> SAME */ /* i.e., use old obj_number */ fprintf(statevalfile, "{0x%x,0x%x},\n",s->obj_number, action); Index++; } e = firste; while (e) { event = e->obj_number; state = s->obj_number; IFDEBUG(g) fprintf(stdout,"pred table event=0x%x, state 0x%x\n", event, state); fflush(stdout); ENDDEBUG if( !str /* DEFAULT PREDICATE */) { Ndefpred++; IFDEBUG(g) fprintf(stdout, "DEFAULT pred state 0x%x, event 0x%x, Index 0x%x\n", state, event, Index); fflush(stdout); ENDDEBUG } else Npred++; /* put at END of list */ #ifndef LINT IFDEBUG(g) fprintf(stdout, "predicate for event 0x%x, state 0x%x is 0x%x, %s\n", event, state, Index, str); fflush(stdout); ENDDEBUG #endif /* LINT */ for( ((q = &Predlist[(event<<Eventshift)+state]), (p = Predlist[(event<<Eventshift)+state])); p ; p = p->p_next ) { q = &p->p_next; } p = (struct Predicate *)Malloc(sizeof(struct Predicate)); p->p_next = (struct Predicate *)0; p->p_str = str; p->p_index = Index; p->p_transno = transno; *q = p; IFDEBUG(g) fprintf(stdout, "predtable index 0x%x, transno %d, E %p, S %p\n", Index, transno, e, s); ENDDEBUG e = e->obj_members; } s = s->obj_members; } return Index ; } void printprotoerrs() { register int e,s; fprintf(stderr, "[ Event, State ] without any transitions :\n"); for(e = 0; e < Nevents; e++) { fprintf(stderr, "Event 0x%x: states ", e); for(s = 0; s < Nstates; s++) { if( Predlist[(e<<Eventshift)+s] == 0 ) fprintf(stderr, "0x%x ", s); } fprintf(stderr, "\n"); } } #ifndef LINT void dump_predtable(f) FILE *f; { struct Predicate *p; register int e,s, hadapred; int defaultindex; int defaultItrans; #ifdef notdef extern int bytesmalloced; extern int byteswasted; fprintf(stdout, " Xebec used %8d bytes of storage, wasted %8d bytes\n", bytesmalloced, byteswasted); #endif /* notdef */ fprintf(stdout, " %8d states\n %8d events\n %8d transitions\n", Nstates, Nevents, Ntrans); fprintf(stdout, " %8d predicates\n %8d default predicates used\n", Npred, Ndefpred); fprintf(stdout, " %8d null actions\n", Nnulla); putdriver(f, 5); for(e = 0; e < Nevents; e++) { for(s = 0; s < Nstates; s++) { p = Predlist[(e<<Eventshift)+s]; hadapred=0; defaultindex=0; defaultItrans=0; if(p) { IFDEBUG(d) fflush(f); ENDDEBUG while(p) { if(p->p_str) { if(!hadapred) fprintf(f, "case 0x%x:\n\t", (e<<Eventshift) + s); hadapred = 1; fprintf(f, "if %s return 0x%x;\n\t else ", p->p_str, p->p_index); } else { if(defaultindex) { fprintf(stderr, "\nConflict between transitions %d and %d: duplicate default \n", p->p_transno, defaultItrans); Exit(-1); } defaultindex = p->p_index; defaultItrans = p->p_transno; } p = p->p_next; } if( hadapred) { fprintf(f, "return 0x%x;\n", defaultindex); } IFDEBUG(d) fflush(f); ENDDEBUG } IFDEBUG(g) fprintf(stdout, "loop: e 0x%x s 0x%x hadapred 0x%x dindex 0x%x for trans 0x%x\n", e, s, hadapred, defaultindex, defaultItrans); ENDDEBUG if ( hadapred ) { /* put a -1 in the array - Predlist is temporary storage */ Predlist[(e<<Eventshift)+s] = (struct Predicate *)(-1); } else { /* put defaultindex in the array */ /* if defaultindex is zero, then the driver will * cause an erroraction (same as if no default * were given and none of the predicates were true; * also same as if no preds or defaults were given * for this combo) */ Predlist[(e<<Eventshift)+s] = (struct Predicate *)(defaultindex); } } } fprintf(f, "default: return 0;\n} /* end switch */\n"); #ifdef notdef fprintf(f, "/*NOTREACHED*/return 0;\n} /* _Xebec_index() */\n"); #else /* !notdef */ fprintf(f, "} /* _Xebec_index() */\n"); #endif /* notdef */ fprintf(f, "static int inx[%d][%d] = { {", Nevents+1,Nstates); for(s = 0; s< Nstates; s++) fprintf(f, "0,"); /* event 0 */ fprintf(f, "},\n"); for(e = 0; e < Nevents; e++) { fprintf(f, " {"); for(s = 0; s < Nstates; s++) { register struct Predicate *xyz = Predlist[(e<<Eventshift)+s]; /* this kludge is to avoid a lint msg. concerning * loss of bits */ if (xyz == (struct Predicate *)(-1)) fprintf(f, "-1,"); else fprintf(f, "%p,", Predlist[(e<<Eventshift)+s]); } fprintf(f, " },\n"); } fprintf(f, "};"); } #endif /* LINT */ char * stash(buf) char *buf; { register int len; register char *c; /* grot */ len = strlen(buf); c = Malloc(len+1); #ifdef LINT c = #endif /* LINT */ strcpy(c, buf); IFDEBUG(z) fprintf(stdout,"stash %s at %p\n", c,c); ENDDEBUG return(c); } #ifdef notdef dump_pentry(event,state) int event,state; { register struct Predicate *p, **q; for( ((q = &Predlist[(event<<Eventshift) +state]), (p = Predlist[(event<<Eventshift) + state])); p!= (struct Predicate *)0 ; p = p->p_next ) { #ifndef LINT IFDEBUG(a) fprintf(OUT, "dump_pentry for event 0x%x, state 0x%x is 0x%x\n", event, state, p); ENDDEBUG #endif /* LINT */ q = &p->p_next; } } #endif /* notdef */