int devIocStatsInitCpuUsage(void) { int nBurnNoContention = 0; double tToWait = SECONDS_TO_BURN; epicsTimeStamp tStart, tEnd; if (cpuUsage.startSem) return 0; /* Initialize only if OS wants to spin */ if (tToWait > 0) { /*wait for a tick*/ epicsTimeGetCurrent(&tStart); do { epicsTimeGetCurrent(&tEnd); } while ( epicsTimeDiffInSeconds(&tEnd, &tStart) <= 0.0 ); epicsTimeGetCurrent(&tStart); while(TRUE) { cpuBurn(); epicsTimeGetCurrent(&tEnd); cpuUsage.tNow = epicsTimeDiffInSeconds(&tEnd, &tStart); if (cpuUsage.tNow >= tToWait ) break; nBurnNoContention++; } cpuUsage.nBurnNoContention = nBurnNoContention; cpuUsage.nBurnNow = nBurnNoContention; cpuUsage.startSem = epicsEventMustCreate(epicsEventFull); cpuUsage.tNoContention = cpuUsage.tNow; /* * FIXME: epicsThreadPriorityMin is not really the lowest * priority. We could use a native call to * lower our priority further but OTOH there is not * much going on at these low levels... */ epicsThreadCreate("cpuUsageTask", epicsThreadPriorityMin, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)cpuUsageTask, 0); } else { cpuUsage.startSem = 0; } return 0; }
static void cpuUsageTask(void *parm) { while(TRUE) { int i; epicsTimeStamp tStart, tEnd; epicsEventWait(cpuUsage.startSem); cpuUsage.nBurnNow=0; epicsTimeGetCurrent(&tStart); for(i=0; i< cpuUsage.nBurnNoContention; i++) { cpuBurn(); epicsTimeGetCurrent(&tEnd); cpuUsage.tNow = epicsTimeDiffInSeconds(&tEnd, &tStart); ++cpuUsage.nBurnNow; } cpuUsage.didNotComplete = FALSE; } }
static void cpuUsageTask() { while(TRUE) { int i; unsigned long tickStart,tickEnd; semTake(pcpuUsage->startSem,WAIT_FOREVER); pcpuUsage->ticksNow=0; pcpuUsage->nBurnNow=0; tickStart = tickGet(); for(i=0; i< pcpuUsage->nBurnNoContention; i++) { cpuBurn(); pcpuUsage->ticksNow = tickGet() - tickStart; ++pcpuUsage->nBurnNow; } tickEnd = tickGet(); pcpuUsage->didNotComplete = FALSE; pcpuUsage->ticksNow = tickEnd - tickStart; } }
static void cpuUsageInit(void) { unsigned long tickStart,tickNow; int nBurnNoContention=0; int ticksToWait; ticksToWait = SECONDS_TO_BURN*sysClkRateGet(); pcpuUsage = calloc(1,sizeof(cpuUsage)); tickStart = tickGet(); /*wait for a tick*/ while(tickStart==(tickNow = tickGet())) {;} tickStart = tickNow; while(TRUE) { if((tickGet() - tickStart)>=ticksToWait) break; cpuBurn(); nBurnNoContention++; } pcpuUsage->nBurnNoContention = nBurnNoContention; pcpuUsage->startSem = semBCreate (SEM_Q_FIFO,SEM_FULL); pcpuUsage->ticksNoContention = ticksToWait; taskSpawn("cpuUsageTask",255,VX_FP_TASK,1000,(FUNCPTR)cpuUsageTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); }