Closed hyuuko1 closed 4 years ago
谢谢!怎么调用的时候发现溢出了?
_delay
函数改成:
/* Busy-wait for approximately NUM/DENOM seconds. */
static void _delay(unsigned num, unsigned denom)
{
/* Scale the numerator and denominator down by 1000 to avoid
the possibility of overflow. */
int overflow = loops_per_tick * num / 1000 * HZ / (denom / 1000);
int not_overflow = loops_per_tick / (denom / 1000) * num / 1000 * HZ;
printk("\n overflow: %d", overflow);
printk("\n not overflow: %d\n", not_overflow);
//busy_wait (loops_per_tick / (denom / 1000) * num / 1000 * HZ);
}
在main
函数中调用nanosleep
:
void main(void* pv) {
printf("task #%d: I'm the first user task(pv=0x%08x)!\r\n", task_getid(), pv);
// TODO: Your code goes here
struct timespec ts = { 0, 5000000 }; // 5 毫秒
nanosleep(&ts, NULL);
while (1)
;
task_exit(0);
}
输出:
加个括号,这样还会溢出吗?loops_per_tick (num / 1000) HZ / (denom / 1000);
会,我的机器上loops_per_tick大概等于7*10^7
,num为5*10^6
,loops_per_tick * (num / 1000)
的结果就是3.5*10^11
,超出了unsigned int的最大值4,294,967,296
linux-1.2.0是这样处理a*b*c
的:
extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
{
__asm__("mull %1 ; divl %2"
:"=a" (a)
:"d" (b),
"r" (c),
"0" (a)
:"dx");
return a;
}
哦。那我在你的基础上,改为loops_per_tick / (denom / 1000) (num / 1000) HZ;应该也可以吧?
应该可以
OK,那我修改一下提交了。
我看你对OS也有兴趣,加我QQ私聊。
好的!
做实验二的时候发现以下代码出了问题: https://github.com/hongmingjian/epos/blob/a55c8dfc8fb0b09996f20327e869c475f2d7c197/kernel/timer.c#L128-L134
其中的
loops_per_tick * num
溢出。修改为:
可解决问题