2013-04-17 19 views
2

在Ubuntu 12.04 LTS下面的代碼:ntp_gettime()實際上是否返回納秒精度?

#include <stdio.h> 
#include <sys/timex.h> 
#include <sys/time.h> 

int main(int argc, char **argv) 
{ 
    struct timeval tv; 
    gettimeofday(&tv, NULL); 

    struct ntptimeval ntptv; 
    ntp_gettime(&ntptv); 

    printf("gettimeofday: tv_sec = %ld, tv_usec = %ld\n", 
       tv.tv_sec, tv.tv_usec); 
    printf("ntp_gettime: tv_sec = %ld, tv_usec = %ld\n", 
       ntptv.time.tv_sec, ntptv.time.tv_usec); 
} 

回報:

gettimeofday: tv_sec = 1366209548, tv_usec = 137736 
ntp_gettime: tv_sec = 1366209548, tv_usec = 137743081 

這是一種奇怪的,因爲tv_usec價值,如果它確實是微秒計,應不超過100萬更大。上面顯示的結果讓我認爲ntp_gettime()實際上返回納秒精度。

ntp_gettime()聯機幫助頁(確切地說)在http://manpages.ubuntu.com/manpages/precise/man2/ntp_gettime.2freebsd.html 並沒有真正說太多。

較早的聯機幫助版本(代) http://manpages.ubuntu.com/manpages/hardy/man2/ntp_gettime.2.html索賠它可能是依賴於STA_NANO位是否被通過ntp_adjtime()返回status詞集要麼納秒或微秒。

任何人都知道明確嗎?短缺的是,ntp_gettime()ntp_adjtime()以及它們在12.04源代碼中定義的所有各種內部函數在哪裏?

回答

3

ntp_gettimentp_adjtime都在C庫中定義。在Linux和glibc上,ntp_adjtime只是adjtimex系統調用的包裝,而ntp_gettime使用相同的系統調用,並將struct timexmodes設置爲0.您可以在the glibc LXR上瀏覽它們的定義。

系統調用implementation調用_do_adjtimex這就要求getnstimeofday得到的時間(納秒),然後遞給__do_adjtimex。這裏是一個有趣的現象:

txc->time.tv_sec = ts->tv_sec; 
txc->time.tv_usec = ts->tv_nsec; 
if (!(time_status & STA_NANO)) 
     txc->time.tv_usec /= NSEC_PER_USEC; 

所以,如果STA_NANO設置它只是把納秒值tv_usec,這是你已經遇到的行爲。如果你想取消設置這個標誌,你可以做這樣的事情:

struct timex tmx; 
tmx.modes = 0 | ADJ_MICRO; 
ntp_adjtime(&tmx); 

,然後從tmx.time.tv_usec讀你的微秒值。如果你想這樣做,你必須使用sudo來運行你的代碼,但是要注意,標誌在內核中將保持未設置,直到你重置它(使用ADJ_NANO)或重啓。