Linux内核模块中规避浮点运算实现时间计算的解决办法
内核模块计算流逝时间的浮点运算错误解决办法
问题背景
需要在Linux内核模块中计算从加载到卸载的流逝秒数,尝试通过jiffies和HZ实现,但因内核禁用浮点运算编译报错。原代码如下:
#include <linux/jiffies.h> unsigned long int first_jiff; int start_init(void){ first_jiff = jiffies; printk(KERN_INFO "loading kernel module\n"); return 0; } void exit_init(void){ float elapsed_seconds; // 计算初始jiffies与当前值的差值 first_jiff = jiffies - first_jiff; elapsed_seconds = (float)(first_jiff / HZ); printk(KERN_INFO "elapsed_time:%f", elapsed_seconds); } module_init(start_init); module_exit(exit_init);
编译时触发错误:
/include/linux/printk.h:464:44: error: SSE register return with SSE disabled
解决办法
内核环境严格禁止浮点类型(float/double)及相关运算,可通过整数运算模拟小数输出实现需求,全程规避浮点操作:
修正后代码
#include <linux/jiffies.h> #include <linux/kernel.h> unsigned long int first_jiff; int start_init(void){ first_jiff = jiffies; printk(KERN_INFO "loading kernel module\n"); return 0; } void exit_init(void){ unsigned long int jiff_diff = jiffies - first_jiff; unsigned int full_seconds = jiff_diff / HZ; unsigned int remaining_jiff = jiff_diff % HZ; // 用整数乘法将剩余jiffies转换为三位小数的整数形式 unsigned int decimal_part = (remaining_jiff * 1000) / HZ; printk(KERN_INFO "elapsed_time: %u.%03u seconds\n", full_seconds, decimal_part); } module_init(start_init); module_exit(exit_init);
核心逻辑说明
- 用独立变量
jiff_diff存储jiffies差值,避免污染初始值first_jiff - 通过整数除法
jiff_diff / HZ得到完整的秒数 - 用取模运算
jiff_diff % HZ得到剩余的jiffies数 - 将剩余jiffies乘以1000(对应保留三位小数)再除以
HZ,得到小数部分的整数表示,最后通过%03u格式化补零,模拟小数输出效果
内容的提问来源于stack exchange,提问作者th3plus
相关产品推荐
相关产品推荐

