/* * dereference macro ... return one of the DEREF_* values * for DEREF_ERROR, error is reported here */ static int varDeref(char *name) { Symbol s; Expr *x; LexIn *t; /* lookup macro name */ if ((s = symLookup(&vars, name)) == NULL) { fprintf(stderr, "undefined macro name $%s\n", name); return DEREF_ERROR; } x = symValue(s); /* string macro */ if (x->sem == SEM_CHAR) { t = (LexIn *) zalloc(sizeof(LexIn)); t->prev = lin; lin = t; lin->name = (char *) alloc(strlen(name) + 1); strcpy(lin->name, name); lin->macro = (char *) x->ring; lin->lno = 1; lin->cno = 0; return DEREF_STRING; } /* boolean valued macro */ if (x->sem == SEM_BOOLEAN) { yylval.x = x; return DEREF_BOOL; } /* constant numeric valued macro */ if (x->sem == SEM_NUMCONST) { /* * need to copy the Expr as the one returned here may be freed * later after constant folding, and we need the real macro's * value to be available for use in later rules */ yylval.x = newExpr(NOP, NULL, NULL, -1, -1, -1, 1, SEM_NUMCONST); yylval.x->smpls[0].ptr = x->smpls[0].ptr; yylval.x->valid = 1; return DEREF_NUMBER; } /* variable numeric valued macro */ if (x->sem == SEM_NUMVAR) { yylval.x = x; return DEREF_NUMBER; } fprintf(stderr, "varDeref(%s): internal botch sem=%d?\n", name, x->sem); dumpExpr(x); exit(1); }
/* send pmDescriptors for all expressions in given task */ void sendDescs(Task *task) { Symbol *s; int i; s = task->rules; for (i = 0; i < task->nrules; i++) { sendDesc(symValue(*s), task->rslt->vset[i]); s++; } }
/* statement */ Symbol statement(char *name, Expr *x) { Symbol s; /* error guard */ if (x == NULL) return NULL; /* if name not given, make one up */ if (name == NULL) name = nameGen(); /* the parsed object is a rule (expression to evaluate) */ if (x->op != NOP) { if (symLookup(&rules, name)) { synerr(); fprintf(stderr, "rule \"%s\" multiply defined\n", name); freeExpr(x); return NULL; } else { if (errs == 0) { postExpr(x); s = symIntern(&rules, name); } else return NULL; } } /* the parsed object is a non-rule */ else { if ( (s = symLookup(&vars, name)) ) freeExpr(symValue(s)); else s = symIntern(&vars, name); } symValue(s) = x; return s; }
void dstructInit(void) { Expr *x; double zero = 0.0; /* not-a-number initialization */ mynan = zero / zero; /* set up symbol tables */ symSetTable(&hosts); symSetTable(&metrics); symSetTable(&rules); symSetTable(&vars); /* set yp inter-sample interval (delta) symbol */ symDelta = symIntern(&vars, "delta"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = δ x->valid = 1; symValue(symDelta) = x; /* set up time symbols */ symMinute = symIntern(&vars, "minute"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = &minute; x->valid = 1; symValue(symMinute) = x; symHour = symIntern(&vars, "hour"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = &hour; x->valid = 1; symValue(symHour) = x; symDay = symIntern(&vars, "day"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = &day; x->valid = 1; symValue(symDay) = x; symMonth = symIntern(&vars, "month"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = &month; x->valid = 1; symValue(symMonth) = x; symYear = symIntern(&vars, "year"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = &year; x->valid = 1; symValue(symYear) = x; symWeekday = symIntern(&vars, "day_of_week"); x = newExpr(OP_VAR, NULL,NULL, -1, -1, -1, 1, SEM_NUMVAR); x->smpls[0].ptr = &weekday; x->valid = 1; symValue(symWeekday) = x; }
void dumpRules(void) { Task *t; Symbol *s; int i; for (t = taskq; t != NULL; t = t->next) { s = t->rules; for (i = 0; i < t->nrules; i++, s++) { fprintf(stderr, "\nRule: %s\n", symName(*s)); dumpTree((Expr *)symValue(*s)); } } }
/* pragmatics analysis */ void pragmatics(Symbol rule, RealTime delta) { Expr *x = symValue(rule); Task *t; if (x->op != NOP) { t = findTask(delta); bundle(t, x); t->nrules++; t->rules = (Symbol *) ralloc(t->rules, t->nrules * sizeof(Symbol)); t->rules[t->nrules-1] = symCopy(rule); perf->eval_expected += (float)1/delta; } }
/* invalidate all expressions being evaluated i.e. mark values as unknown */ void invalidate(void) { Task *t; Expr *x; Symbol *s; int i; t = taskq; while (t) { s = t->rules; for (i = 0; i < t->nrules; i++) { x = symValue(*s); clobber(x); s++; } t = t->next; } }
/* * find all expressions for a host that has just been marked "down" * and invalidate them */ static void mark_all(Host *hdown) { Task *t; Symbol *s; Metric *m; Expr *x; int i; for (t = taskq; t != NULL; t = t->next) { s = t->rules; for (i = 0; i < t->nrules; i++, s++) { x = (Expr *)symValue(*s); for (m = x->metrics; m != NULL; m = m->next) { if (m->host == hdown) clobber(x); } } } }
/* evaluate Task */ static void eval(Task *task) { Symbol *s; pmValueSet *vset; int i; /* fetch metrics */ taskFetch(task); /* evaluate rule expressions */ s = task->rules; for (i = 0; i < task->nrules; i++) { curr = symValue(*s); if (curr->op < NOP) { (curr->eval)(curr); perf->eval_actual++; } s++; } if (verbose) { /* send binary values */ if (agent) { int sts; s = task->rules; for (i = 0; i < task->nrules; i++) { vset = task->rslt->vset[i]; fillVSet(symValue(*s), vset); s++; } __pmOverrideLastFd(PDU_OVERRIDE2); sts = __pmSendResult(STDOUT_FILENO, pmWhichContext(), task->rslt); if (sts < 0) { fprintf(stderr, "Error: __pmSendResult to summary agent failed: %s\n", pmErrStr(sts)); exit(0); } } /* send values to applet */ else if (applet) { s = task->rules; for (i = 0; i < task->nrules; i++) { showValue(stdout, symValue(*s)); putchar(' '); s++; } putchar('\n'); } /* print values in ASCII */ else { s = task->rules; for (i = 0; i < task->nrules; i++) { printf("%s", symName(*s)); if (archives || showTimeFlag) { printf(" ("); showTime(stdout, now); putchar(')'); } printf(": "); switch (verbose) { case 1: showValue(stdout, symValue(*s)); break; case 2: showAnnotatedValue(stdout, symValue(*s)); break; case 3: showSatisfyingValue(stdout, symValue(*s)); break; } putchar('\n'); s++; } putchar('\n'); } } }