usleepの正確性を確認するためのロジック
久々にlinuxを探ってみたら、昔に書いた検証コードがあったので、適度に乗せておく。
コンテキストスイッチなどの要因により、usleepが正確ではないことがある。
その誤差を検出するために以下のコードを書いた。
#include <stdio.h> #include <sys/time.h> #include <unistd.h> int main (int argc,char * argv[]) { int iRet = 0; unsigned int uiCnt = 0; clock_t aTimeVals[1000]; //struct timezone tTimeZone; memset(&aTimeVals,0x00,sizeof(aTimeVals)); //memset(&tTimeZone,0x00,sizeof(tTimeZone)); for(uiCnt=0;uiCnt<(sizeof(aTimeVals)/sizeof(aTimeVals[0]));uiCnt++) { aTimeVals[uiCnt] = clock(); usleep(10); } /* calc */ for(uiCnt=(sizeof(aTimeVals)/sizeof(aTimeVals[0]))-1;uiCnt>=1;uiCnt--) { aTimeVals[uiCnt] -= aTimeVals[uiCnt-1]; printf("%03u: %ld\n",uiCnt,aTimeVals[uiCnt]); } return 0; }
別の方法での確認
#include <stdio.h> #include <sys/time.h> #include <unistd.h> #include <time.h> #include <stdlib.h> #include <string.h> #define TARGET_COUNTS 100 int main (int argc,char * argv[]) { struct timeval aTimeVals[TARGET_COUNTS]; clock_t aClockVals[TARGET_COUNTS]; struct timezone tTimeZone; int iRet = 0; unsigned int uiCnt = 0; memset(aClockVals,0x00,sizeof(aClockVals)); memset(aTimeVals,0x00,sizeof(aTimeVals)); memset(&tTimeZone,0x00,sizeof(tTimeZone)); for(uiCnt=0;uiCnt<(sizeof(aTimeVals)/sizeof(aTimeVals[0]));uiCnt++) { aClockVals[uiCnt] = times(); gettimeofday(&(aTimeVals[uiCnt]), &tTimeZone); usleep(100000); } /* calc */ for(uiCnt=(sizeof(aTimeVals)/sizeof(aTimeVals[0]))-1;uiCnt>=1;uiCnt--) { aTimeVals[uiCnt].tv_sec -= aTimeVals[uiCnt-1].tv_sec; if(aTimeVals[uiCnt].tv_usec > aTimeVals[uiCnt-1].tv_usec) { aTimeVals[uiCnt].tv_usec -= aTimeVals[uiCnt-1].tv_usec; } else { //tv_sec aTimeVals[uiCnt].tv_sec -= 1; aTimeVals[uiCnt].tv_usec += 1000000 - aTimeVals[uiCnt-1].tv_usec; } aClockVals[uiCnt] -= aClockVals[uiCnt-1]; printf("%03u: %ld.%ld\t%ld\n",uiCnt,aTimeVals[uiCnt].tv_sec,aTimeVals[uiCnt].tv_usec,aClockVals[uiCnt]); } return 0; }
組み込み機器等で使うことがあるかもしれない。