clock_gettime无法立即更新

时间:2012-06-26 14:52:12

标签: android c linux timer arm

更新

在检查时间分辨率后,我们尝试在内核空间中调试问题。

unsigned long long task_sched_runtime(struct task_struct *p)
{
    unsigned long flags;
    struct rq *rq;
    u64 ns = 0;

    rq = task_rq_lock(p, &flags);
    ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
    task_rq_unlock(rq, &flags);

    //printk("task_sched runtime\n");
    return ns; 
}

我们的新实验表明时间p->se.sum_exec_runtime不会立即更新。但是如果我们在函数中添加printk()。时间会立即更新。

我们正在开发一个Android程序。 但是,函数threadCpuTimenanos()测量的时间在我们的平台上并不总是正确的。

经过实验,我们发现从clock_gettime返回的时间不会立即更新。 即使经过几次while循环迭代,我们得到的时间也不会改变。

以下是我们的示例代码:

while(1)
{
    test = 1;
    test = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);

    printf(" clock gettime test 1 %lx, %lx , ret = %d\n",now.tv_sec , now.tv_nsec,test );

    pre = now.tv_nsec;
    sleep(1);
}

此代码在x86 PC上运行正常。但它在内核2.6.35.13的嵌入式平台ARM Cortex-A9中无法正常运行。

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

我更改了clock_gettime以使用CLOCK_MONOTONIC_RAW,将线程分配给一个CPU并获得不同的值。 我也在使用双皮质-A9

while(1)
{
    test = 1;
    test = clock_gettime(CLOCK_MONOTONIC_RAW, &now);

    printf(" clock gettime test 1 %lx, %lx , ret = %d\n",now.tv_sec , now.tv_nsec, test );

    pre = now.tv_nsec;
    sleep(1);
}

答案 1 :(得分:1)

clock_gettime的分辨率取决于平台。使用clock_getres()在您的平台上查找解决方案。根据您的实验结果,pc-x86和目标平台上的时钟分辨率是不同的。

答案 2 :(得分:1)

在android CTS中,有一个案例有同样的问题。读取计时器两次,但它们是相同的

testThreadCpuTimeNanos失败junit.framework.AssertionFailedError at android.os.cts.DebugTest.testThreadCpuTimeNanos

答案 3 :(得分:1)

  

$ man clock_gettime

     

...

     

SMP系统注意事项

     

CLOCK_PROCESS_CPUTIME_ID和CLOCK_THREAD_CPUTIME_ID时钟在许多平台上使用来自CPU的计时器(i386上的TSC,Itanium上的AR.ITC)实现。这些寄存器在CPU之间可能不同,因此如果进程迁移到另一个CPU ,这些时钟可能会返回虚假结果。

     

如果SMP系统中的CPU具有不同的时钟源,则无法保持定时器寄存器之间的相关性,因为每个CPU将以稍微不同的频率运行。如果是这种情况,则clock_getcpuclockid(0)将返回ENOENT以表示此情况。只有在可以确保进程停留在某个CPU上时,这两个时钟才有用。

     

SMP系统中的处理器并非完全同时启动,因此定时器寄存器通常以偏移量运行。某些体系结构包括试图在启动时限制这些偏移的代码。但是,代码无法保证准确调整偏移量。 Glibc没有处理这些偏移的规定(与Linux内核不同)。通常这些偏移很小,因此在大多数情况下效果可以忽略不计。

答案 4 :(得分:0)

CLOCK_THREAD_CPUTIME_ID时钟测量CPU花费的时间,而非实时,并且您花费的时间几乎为零。此外,CLOCK_THREAD_CPUTIME_ID(特定于线程的CPU时间)在Linux / glibc上实现不正确,甚至可能在glibc上根本不起作用。 CLOCK_PROCESS_CPUTIME_ID或者其中任何人应该更好地工作。