static void create_thread ( plc_sThread *tp, plc_sProctbl *ptp, plc_sProcess *pp ) { pwr_tStatus sts; long int phase; tp->aref.Objid = ptp->thread; tp->init = ptp->init; tp->exec = ptp->exec; tp->first_scan = 1; tp->PlcThread = pwrb_PlcThread_Init(&sts, tp); tp->csup_lh = csup_Init(&sts, ptp->thread, tp->f_scan_time); tp->i_scan_time = tp->f_scan_time * 1000.0 + 0.5; time_FloatToD(&tp->scan_time, tp->f_scan_time); tp->pp = pp; plc_inittimer(tp); tp->exit = FALSE; link_io_copy_areas(tp); que_Create(&sts, &tp->q_in); que_Create(&sts, &tp->q_out); sts = gdh_ObjidToName(ptp->thread, tp->name, sizeof(tp->name), cdh_mNName); if (EVEN(sts)) { errh_Error("Get name of thread object %s, %m", cdh_ObjidToString(NULL, ptp->thread, 1), sts); return; } sts = gdh_ObjidToPointer(ptp->thread, (void *)&tp->PlcThread); if (EVEN(sts)) { errh_Error("Direct link to thread object \"%s\", %m", tp->name, sts); return; } #if defined OS_LYNX && USE_RT_TIMER sem_init(&tp->ScanSem, 0, 0); tp->ScanMultiple = tp->i_scan_time / (CLK_TCK/1000); tp->IntervalCount = tp->ScanMultiple; #endif sts = thread_Create(&tp->tid, tp->name, (void *(*)())&plc_thread, tp); if (EVEN(sts)) { errh_Error("Creating thread \"%s\", %m", tp->name, sts); return; } /* Wait for thread to initialize. */ phase = (long int)que_Get(&sts, &tp->q_out, NULL, NULL); pwr_Assert(phase == 1); }
void RunTimeCounterFo_exec( plc_sThread *tp, pwr_sClass_RunTimeCounterFo *o) { pwr_tDeltaTime TimeSince; pwr_sClass_RunTimeCounter *co = (pwr_sClass_RunTimeCounter *) o->PlcConnectP; if ( !co) return; if ( *o->ResetP && !o->OldReset) co->TripReset = 1; time_FloatToD( &TimeSince, *o->ScanTime); /* Test if New Trip */ if (co->TripReset) { co->OldTripNOfStarts = co->TripNOfStarts; co->OldTripUsage = co->TripUsage; co->OldTripTime = co->TripTime; co->OldTripRunTime = co->TripRunTime; co->TripNOfStarts = 0; co->TripRunTime.tv_sec = co->TripRunTime.tv_nsec = 0; co->TripTime.tv_sec = co->TripTime.tv_nsec = 0; time_GetTime( &co->ResetTime); co->TripReset = 0; } /* Update Calendar time */ time_Dadd( &co->TotalTime, &co->TotalTime, &TimeSince); time_Dadd( &co->TripTime, &co->TripTime, &TimeSince); /* Test if running */ o->Start = 0; if (*o->RunningP) { /* New start ? */ if ( !o->Running) { o->Start = 1; co->TotalNOfStarts++; co->TripNOfStarts++; time_GetTime( &co->StartTime); } /* End if new start */ /* Update Running Time */ time_Dadd( &co->TripRunTime, &co->TripRunTime, &TimeSince); time_Dadd( &co->TotalRunTime, &co->TotalRunTime, &TimeSince); } /* End if Running */ o->Running = co->Running = *o->RunningP; /* Calculate usage % */ if ( co->TotalRunTime.tv_sec) co->TotalUsage = ((float)co->TotalRunTime.tv_sec) / co->TotalTime.tv_sec * 100; if ( co->TripTime.tv_sec) co->TripUsage = ((float)co->TripRunTime.tv_sec) / co->TripTime.tv_sec * 100; o->OldReset = *o->ResetP; }
static int tlog_checktime( pwr_tDeltaTime *time_new, pwr_tDeltaTime *time_old, float maxdiff) { pwr_tDeltaTime tim_maxdiff; pwr_tDeltaTime tim_limlow; pwr_tDeltaTime tim_limhigh; int sts; time_FloatToD( &tim_maxdiff, maxdiff); time_Dadd( &tim_limhigh, time_new, &tim_maxdiff); time_Dsub( &tim_limlow, time_new, &tim_maxdiff); if ( time_Dcomp( time_old, &tim_limlow) == -1) return TLOG__TIME_LT; if ( time_Dcomp( time_old, &tim_limhigh) == 1) return TLOG__TIME_GT; return TLOG__TIME_EQ; /************* tim_maxdiff.high = -1; tim_maxdiff.low = -maxdiff * 10000000; if ( maxdiff == 0) tim_maxdiff.low = -1; sts = lib$add_times( time_new, &tim_maxdiff, &tim_limhigh); sts = lib$sub_times( time_new, &tim_maxdiff, &tim_limlow); if ( sts == LIB$_NEGTIM) { tim_limlow.high = -1; tim_limlow.low = -1; } sts = lib$sub_times( time_old, &tim_limlow, &testtime); if ( sts == LIB$_NEGTIM) return TLOG__TIME_LT; sts = lib$sub_times( &tim_limhigh, time_old, &testtime); if ( sts == LIB$_NEGTIM) return TLOG__TIME_GT; return TLOG__TIME_EQ; ************/ }
void time_Sleep( float time) { #ifdef OS_VMS int sts; sts = lib$wait(&time); #elif OS_ELN LARGE_INTEGER l_time; l_time.high = -1; l_time.low = - time * 10000000; ker$wait_any( NULL, NULL, &l_time); #elif defined OS_POSIX pwr_tDeltaTime p_time; struct timespec ts; time_FloatToD( &p_time, time); ts.tv_sec = p_time.tv_sec; ts.tv_nsec = p_time.tv_nsec; nanosleep( &ts, NULL); #endif }
pwr_tStatus sutl_sleep( float time) { #ifdef OS_VMS int sts; sts = lib$wait(&time); #elif OS_ELN LARGE_INTEGER l_time; l_time.high = -1; l_time.low = - time * 10000000; ker$wait_any( NULL, NULL, &l_time); #elif defined(OS_LYNX) || defined (OS_LINUX) pwr_tDeltaTime p_time; struct timespec p_time_ts; time_FloatToD( &p_time, time); p_time_ts.tv_sec = p_time.tv_sec; p_time_ts.tv_nsec = p_time.tv_nsec; nanosleep( &p_time_ts, NULL); #endif return 1; }
int main (int argc, char **argv) { pwr_tStatus sts; pwr_tObjid ObjId; pwr_sClass_DsTrendConf *TConfP; pwr_tBoolean InitOK; pwr_tTime CurrentTime, LastScan, NextScan; pwr_tDeltaTime ScanDeltaTime, WaitTime; qcom_sQid qini; qcom_sQattr qAttr; int tmo; char mp[2000]; qcom_sQid qid = qcom_cNQid; qcom_sGet get; int swap = 0; trend_tCtx ctx; errh_Init("pwr_trend", errh_eAnix_trend); errh_SetStatus( PWR__SRVSTARTUP); sts = gdh_Init("ds_trend"); If_Error_Log_Exit(sts, "gdh_Init"); if (!qcom_Init(&sts, 0, "pwr_trend")) { errh_Fatal("qcom_Init, %m", sts); exit(sts); } qAttr.type = qcom_eQtype_private; qAttr.quota = 100; if (!qcom_CreateQ(&sts, &qid, &qAttr, "events")) { errh_Fatal("qcom_CreateQ, %m", sts); exit(sts); } qini = qcom_cQini; if (!qcom_Bind(&sts, &qid, &qini)) { errh_Fatal("qcom_Bind(Qini), %m", sts); exit(-1); } ctx = (trend_tCtx) calloc( 1, sizeof(trend_sCtx)); /* Wait until local nethandler has started */ while(EVEN(gdh_NethandlerRunning())) sleep(1); /* Fetch ScanTime */ sts = gdh_GetClassList(pwr_cClass_DsTrendConf, &ObjId); if (EVEN(sts)) { errh_Info("Couldn't get the DsTrendConf object. Used ScanTime = 1 s"); ctx->scantime = 1; ctx->scantime_tc = 1.0; } else { gdh_ObjidToPointer(ObjId, (pwr_tAddress *)&TConfP); ctx->scantime = TConfP->ScanTime; if ( ctx->scantime > 3600) ctx->scantime = 3600; else if ( ctx->scantime < 1) ctx->scantime = 1; ctx->scantime_tc = TConfP->ScanTime; if ( ctx->scantime_tc > 3600) ctx->scantime_tc = 3600; } ctx->dstrend_multiple = (int) (ctx->scantime / ctx->scantime_tc + 0.5); aproc_RegisterObject( ObjId); InitOK = FALSE; sts = InitTrendList( ctx); if ( EVEN(sts)) { /* This should be removed when we can wait for init messages. */ errh_SetStatus(0); errh_Info("No DsTrend objects configured"); exit(0); } /* If even sts, just wait for init message */ time_GetTimeMonotonic(&LastScan); time_FloatToD( &ScanDeltaTime, ctx->scantime_tc); aproc_TimeStamp( ctx->scantime, 5.0); errh_SetStatus( PWR__SRUN); for (;;) { time_GetTimeMonotonic(&CurrentTime); time_Aadd(&NextScan, &LastScan, &ScanDeltaTime); if (time_Acomp(&CurrentTime, &NextScan) < 0) { time_Adiff(&WaitTime, &NextScan, &CurrentTime); tmo = 1000 * time_DToFloat( 0, &WaitTime); get.maxSize = sizeof(mp); get.data = mp; qcom_Get( &sts, &qid, &get, tmo); if (sts == QCOM__TMO || sts == QCOM__QEMPTY) { if ( !swap) StoreData( ctx); } else { ini_mEvent new_event; qcom_sEvent *ep = (qcom_sEvent*) get.data; new_event.m = ep->mask; if (new_event.b.oldPlcStop && !swap) { swap = 1; errh_SetStatus( PWR__SRVRESTART); CloseTrendList( ctx); } else if (new_event.b.swapDone && swap) { swap = 0; sts = InitTrendList( ctx); errh_SetStatus( PWR__SRUN); errh_Info("Warm restart completed"); } else if (new_event.b.terminate) { exit(0); } } } else if ( !swap) StoreData( ctx); LastScan = NextScan; aproc_TimeStamp( ctx->scantime, 5.0); } return 1; }