void Proc::exec() { Word opcode = W_OM_DOPC((*prg_)[pc_]); switch (opcode) { case dStype: execStype(); break; case dAdd: execAdd(); break; case dSub: execSub(); break; case dMult: execMult(); break; case dDiv: execDiv(); break; case dOutput: execOutput(); break; case dPhi: execPhi(); break; default: assert(false); } }
static long process(acalcoutRecord *pcalc) { rpvtStruct *prpvt = (rpvtStruct *)pcalc->rpvt; long i; double *pnew, *pprev; if (aCalcoutRecordDebug) printf("acalcoutRecord(%s):process: pact=%d, cact=%d, dlya=%d\n", pcalc->name, pcalc->pact, pcalc->cact, pcalc->dlya); /* Make sure. Autosave is capable of setting NUSE to an illegal value. */ if ((pcalc->nuse < 0) || (pcalc->nuse > pcalc->nelm)) { pcalc->nuse = pcalc->nelm; db_post_events(pcalc,&pcalc->nuse, DBE_VALUE|DBE_LOG); } /* If we're getting processed, we can no longer put off allocating memory */ if (pcalc->aval == NULL) pcalc->aval = (double *)calloc(pcalc->nelm, sizeof(double)); if (pcalc->oav == NULL) pcalc->oav = (double *)calloc(pcalc->nelm, sizeof(double)); if (!pcalc->pact) { pcalc->pact = TRUE; /* record scalar-field values so we can tell which ones aCalcPerform wrote to. */ for (i=0, pnew=&pcalc->a, pprev=&pcalc->pa; i<MAX_FIELDS; i++, pnew++, pprev++) { *pprev = *pnew; } /* if some links are CA, check connections */ if (prpvt->caLinkStat != NO_CA_LINKS) checkLinks(pcalc); if (fetch_values(pcalc)==0) { long stat; if (aCalcoutRecordDebug >= 5) printf("acalcoutRecord(%s):process: queueing aCalcPerform\n", pcalc->name); pcalc->cact = 0; stat = doCalc(pcalc); if (stat) printf("%s:process: doCalc failed.\n", pcalc->name); if (stat == 0 && pcalc->cact == 1) { pcalc->pact = 1; /* we'll get processed again when the calculation is done */ return(0); } else { if (afterCalc(pcalc) == ASYNC) return(0); } } } else { /* pact == TRUE */ /* Who invoked us ? */ if (pcalc->cact) { pcalc->cact = 0; if (afterCalc(pcalc) == ASYNC) return(0); } else if (pcalc->dlya) { /* callbackRequestProcessCallbackDelayed() called us */ pcalc->dlya = 0; db_post_events(pcalc,&pcalc->dlya,DBE_VALUE); /* Must set pact 0 so that asynchronous device support works */ pcalc->pact = 0; execOutput(pcalc); if (pcalc->pact) return(0); pcalc->pact = TRUE; } else { /* We must have been called by asynchronous device support */ writeValue(pcalc); } } /*checkAlarms(pcalc); This is too late; IVOA might have vetoed output */ recGblGetTimeStamp(pcalc); if (aCalcoutRecordDebug >= 5) { printf("acalcoutRecord(%s):process:calling monitor \n", pcalc->name); } monitor(pcalc); recGblFwdLink(pcalc); pcalc->pact = FALSE; if (aCalcoutRecordDebug >= 5) { printf("acalcoutRecord(%s):process-done\n", pcalc->name); } if (aCalcoutRecordDebug) printf("acalcoutRecord(%s):process: exit, pact==0\n", pcalc->name); return(0); }
static long afterCalc(acalcoutRecord *pcalc) { rpvtStruct *prpvt = (rpvtStruct *)pcalc->rpvt; short doOutput = 0; long i, j; double **panew; i = acalcGetNumElements( pcalc ); #if MIND_UNUSED_ELEMENTS if (i < pcalc->nelm) { for (; i<pcalc->nelm; i++) pcalc->aval[i] = 0; } #endif /* post array fields that aCalcPerform wrote to. */ for (j=0, panew=&pcalc->aa; j<ARRAY_MAX_FIELDS; j++, panew++) { if (*panew && (pcalc->amask & (1<<j))) { db_post_events(pcalc, *panew, DBE_VALUE|DBE_LOG); } } if (aCalcoutRecordDebug >= 5) { printf("acalcoutRecord(%s):aCalcPerform returns val=%f, aval=[%f %f...]\n", pcalc->name, pcalc->val, pcalc->aval[0], pcalc->aval[1]); } if (pcalc->cstat) recGblSetSevr(pcalc,CALC_ALARM,INVALID_ALARM); else pcalc->udf = FALSE; /* Check VAL against limits */ checkAlarms(pcalc); /* check for output link execution */ switch (pcalc->oopt) { case acalcoutOOPT_Every_Time: doOutput = 1; break; case acalcoutOOPT_On_Change: if (fabs(pcalc->pval - pcalc->val) > pcalc->mdel) doOutput = 1; break; case acalcoutOOPT_Transition_To_Zero: if ((pcalc->pval != 0) && (pcalc->val == 0)) doOutput = 1; break; case acalcoutOOPT_Transition_To_Non_zero: if ((pcalc->pval == 0) && (pcalc->val != 0)) doOutput = 1; break; case acalcoutOOPT_When_Zero: if (!pcalc->val) doOutput = 1; break; case acalcoutOOPT_When_Non_zero: if (pcalc->val) doOutput = 1; break; case acalcoutOOPT_Never: doOutput = 0; break; } pcalc->pval = pcalc->val; if (doOutput) { if (pcalc->odly > 0.0) { pcalc->dlya = 1; db_post_events(pcalc,&pcalc->dlya,DBE_VALUE); callbackRequestProcessCallbackDelayed(&prpvt->doOutCb, pcalc->prio, pcalc, (double)pcalc->odly); if (aCalcoutRecordDebug >= 5) printf("acalcoutRecord(%s):process: exit, wait for delay\n", pcalc->name); return(ASYNC); } else { if (aCalcoutRecordDebug >= 5) printf("acalcoutRecord(%s):calling execOutput\n", pcalc->name); pcalc->pact = FALSE; execOutput(pcalc); if (pcalc->pact) { if (aCalcoutRecordDebug >= 5) printf("acalcoutRecord(%s):process: exit, pact==1\n", pcalc->name); return(ASYNC); } pcalc->pact = TRUE; } } return(SYNC); }
static long process(calcoutRecord *prec) { rpvtStruct *prpvt = prec->rpvt; int doOutput; if (!prec->pact) { prec->pact = TRUE; /* if some links are CA, check connections */ if (prpvt->caLinkStat != NO_CA_LINKS) { checkLinks(prec); } if (fetch_values(prec) == 0) { if (calcPerform(&prec->a, &prec->val, prec->rpcl)) { recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM); } else { prec->udf = isnan(prec->val); } } checkAlarms(prec); /* check for output link execution */ switch (prec->oopt) { case calcoutOOPT_Every_Time: doOutput = 1; break; case calcoutOOPT_On_Change: doOutput = ! (fabs(prec->pval - prec->val) <= prec->mdel); break; case calcoutOOPT_Transition_To_Zero: doOutput = ((prec->pval != 0.0) && (prec->val == 0.0)); break; case calcoutOOPT_Transition_To_Non_zero: doOutput = ((prec->pval == 0.0) && (prec->val != 0.0)); break; case calcoutOOPT_When_Zero: doOutput = (prec->val == 0.0); break; case calcoutOOPT_When_Non_zero: doOutput = (prec->val != 0.0); break; default: doOutput = 0; break; } prec->pval = prec->val; if (doOutput) { if (prec->odly > 0.0) { prec->dlya = 1; recGblGetTimeStamp(prec); db_post_events(prec, &prec->dlya, DBE_VALUE); callbackRequestProcessCallbackDelayed(&prpvt->doOutCb, prec->prio, prec, (double)prec->odly); return 0; } else { prec->pact = FALSE; execOutput(prec); if (prec->pact) return 0; prec->pact = TRUE; } } recGblGetTimeStamp(prec); } else { /* pact == TRUE */ if (prec->dlya) { prec->dlya = 0; recGblGetTimeStamp(prec); db_post_events(prec, &prec->dlya, DBE_VALUE); /* Make pact FALSE for asynchronous device support*/ prec->pact = FALSE; execOutput(prec); if (prec->pact) return 0; prec->pact = TRUE; } else {/*Device Support is asynchronous*/ writeValue(prec); recGblGetTimeStamp(prec); } } monitor(prec); recGblFwdLink(prec); prec->pact = FALSE; return 0; }