timeval v = ktime_to_timeval(hrtimer_get_remaining(timer));
而不是在计时器到期时得到一个负值(我期望〜减去100毫秒),我得到加800毫秒,这是非常关闭,我不能在预期结果和实际结果之间建立任何连接。 /> 我的第一个教导是hrtimer_get_remaining或ktime_to_timeval做错了,所以我使用了ktime_to_timespec和hrtimer_expires_remaining,但结果是一样的。
还有其他建议吗?
答案 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}}