如果过期,hrtimer不会返回负值

时间:2014-04-05 11:56:55

标签: c timer kernel linux-device-driver kernel-module

timeval v = ktime_to_timeval(hrtimer_get_remaining(timer));

而不是在计时器到期时得到一个负值(我期望〜减去100毫秒),我得到加800毫秒,这是非常关闭,我不能在预期结果和实际结果之间建立任何连接。 /> 我的第一个教导是hrtimer_get_remaining或ktime_to_timeval做错了,所以我使用了ktime_to_timespec和hrtimer_expires_remaining,但结果是一样的。

还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

短暂的解开

可能你得到了正确的结果,但你的解释是错误的。您的代码只检查tv_nsec忽略tv_sec,它可能包含-1。如果您添加-1秒而不是800ms,则会获得〜-100ms值。

更长的解释

即使ns_to_timespec没有像前一段时间那样调用set_normalized_timespec,它仍然以相同的方式规范化timespec值。这是此函数的当前版本:

struct timespec ns_to_timespec(const s64 nsec)
{
        struct timespec ts;
        s32 rem;

        if (!nsec)
                return (struct timespec) {0, 0};

        ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
        if (unlikely(rem < 0)) {               // <-- here is normalization
                ts.tv_sec--;
                rem += NSEC_PER_SEC;
        }
        ts.tv_nsec = rem;

        return ts;
}

仅供参考,几年前这种规范化就是这样做的:

if (unlikely(nsec < 0))
    set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec);

我之所以提到这一点是因为set_normalized_timespec函数上面有一条评论说:

Note: The tv_nsec part is always in the range of
0 <= tv_nsec < NSEC_PER_SEC
For negative values only the tv_sec field is negative !

此行为由POSIX标准定义。以下是关于nanosleep()函数rqtp struct timespec *类型[EINVAL] The rqtp argument specified a nanosecond value less than zero or greater than or equal to 1000 millio )后可以获得的错误的what it says例如{/ 3}}:

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

The value of the nanoseconds field must be in the range 0 to 999999999. 

这里有来自nanosleep(2) Linux手册页的类似定义:

结构timespec用于指定具有纳秒精度的时间间隔。它的定义如下:

tv_sec

请注意,在这两种情况下都没有关于否定#include <linux/module.h> #include <linux/kernel.h> int init_module(void) { struct timeval v = ktime_to_timeval((ktime_t){.tv64 = -200000000}); printk(KERN_INFO "v= %ld, %ld\n", v.tv_sec, v.tv_usec); return -1; } 无效的信息。

简单证明

这是一个简单的内核模块,证明了我的观点:

v= -1, 800000

插入后,这是内核日志的输出:

{{1}}