2013-04-17 22 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)或重启。