VxWorks平台下计算cpu的利用率
1、VxWorks的spyLib庫提供的spy工具的實現原理。
?
Spy利用輔助定時器來產生中斷,并且為每個任務維護一個計數器。然后記下被中斷的任務,并且將該任務的計數器加一。經過一段時間后,每個任務的計數器反映了該任務占用CPU利用率的情況。很明顯,這是利用抽樣技術。并且得到的CPU利用率的準確程度取決于任務的持續性和周期性。
?
通過查找spyLib.h的文件,我們發現除了spy()函數外,還有一spyCommon函數,帶一函數指針參數。推測函數指針類型為(int)(*p)(char * fmtStr,…)(經過驗證確實如此)。所以可以寫一自己的函數去接受spy需要打印的數據,Spy調用該函數按行打印結果。我們可以不斷分析一行字符串來得到我們需要的結果。
int SpyPtnFunc(const char * fmtPtn,...)
{
??char buf[128];
??CPUUSAGEDATAMSG data;
?
??va_list vl;
??va_start(vl,fmtPtn);
??vsprintf(buf,fmtPtn,vl);??//得到一行字符串。
??va_end(vl);
?
??//分析buf,得到一個任務的CPU的使用情況。
??return 0;
}
?
另外一種方法是利用一特殊任務,該任務的優先級比系統中的所有任務的優先級都低,該任務是死循環,該任務的目的就是消耗cpu資源,占用cpu空閑時間,因為當系統中其它任務都被掛其時,該任務才能得到cpu的使用權。假設一段時間total內,該任務的運行時間為idle,cpu利用率的計算公式為(total-idle)%total。這一種方法實現起來很簡單,但是它只能算得整個系統的cpu使用情況,不能得到單個任務的cpu使用情況!同時它會使cpu滿負荷工作。源代碼如下
#include "VxWorks.h"
#include "semLib.h"
#include "taskLib.h"
?
#define SECONDS_TO_BURN 60
?
typedef struct cpuUsage {
????SEM_ID????????startSem;
????int???????????didNotComplete;
????unsigned long ticksNoContention;
????int???????????nBurnNoContention;
????unsigned long ticksNow;
????int???????????nBurnNow;
????double????????usage;
} cpuUsage;
?
static cpuUsage *pcpuUsage=0;
?
static double cpuBurn()
{
????int i;
????double result = 0.0;
?
????for(i=0;i<5; i++) result += sqrt((double)i);
????return(result);
}
?
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;
????}
}
?
?double getCpu()
{
????if(pcpuUsage->didNotComplete && pcpuUsage->nBurnNow==0) {
????????pcpuUsage->usage = 0.0;
????} else {
????????double temp;
????????double ticksNow,nBurnNow;
?
????????ticksNow = (double)pcpuUsage->ticksNow;
????????nBurnNow = (double)pcpuUsage->nBurnNow;
????????ticksNow *= (double)pcpuUsage->nBurnNoContention/nBurnNow;
????????temp = ticksNow - (double)pcpuUsage->ticksNoContention;
????????temp = 100.0 * temp/ticksNow;
????????if(temp<0.0 || temp>100.0) temp=0.0; /*handle tick overflow*/
????????pcpuUsage->usage = temp;
????}
????pcpuUsage->didNotComplete = TRUE;
????semGive(pcpuUsage->startSem);
????printf("CPU usage:%f/r/n",pcpuUsage->usage);
????return(pcpuUsage->usage);
}
?
?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_EMPTY);
????pcpuUsage->ticksNoContention = ticksToWait;
????pcpuUsage->didNotComplete = TRUE;
????taskSpawn("cpuUsageTask",255,VX_FP_TASK,1000,(FUNCPTR)cpuUsageTask,
????????0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
總結
以上是生活随笔為你收集整理的VxWorks平台下计算cpu的利用率的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高考首日 雷军周鸿祎为高考生送祝福
- 下一篇: 在CF卡上实现TrueFFS