qemu-omap3 信号丢失问题的解决
经过几天的debug,在很多地方加入 判断是否有SIG pending的语句,结果都是没有信号pending。那么唯一的可能就根本没有产生SIGALRM信号!
继续追踪。Qemu中提供了很多中定时器的实现方法,见数组alarm_timers。
1: static struct qemu_alarm_timer alarm_timers[] = {2: #ifndef _WIN323: #ifdef __linux__4: {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,5: dynticks_stop_timer, dynticks_rearm_timer, NULL},6: /* HPET - if available - is preferred */7: {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},8: /* ...otherwise try RTC */9: {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},10: #endif11: {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},12: #else13: {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,14: win32_stop_timer, win32_rearm_timer, &alarm_win32_data},15: {"win32", 0, win32_start_timer,16: win32_stop_timer, NULL, &alarm_win32_data},17: #endif18: {NULL, }19: };
在初始化的时候,qemu会依次读取这个数组中所有的timer类型,只到某一个timer被初始化成功。在qemu-omap3中,dyntics会被初始化成功。也就是说,负责产生SIGALRM信号的就是dynticks。其启动timer和重新设置超时时间的是函数 dynticks_start_timer和dynticks_rearm_timer。
在dynticks_rearm_timer中会计算并设置超时时间,函数为qemu_next_deadline_dyntick。问题就在 qemu_next_deadline_dyntick中。
这个函数一开始计算virtualtime的超时时间,然后在存在 realtime的timer的时候,才计算realtime的超时时间,然后取两者最小值。关键在于当没有realtime的timer的时候,得到的 virtualtimer值过大,然后设置了这个很多的值作为下一次的超时时间。导致很长时间都不会出现超时信号。现在在函数 qemu_next_deadline_dyntick中增加了一个最大值的限制。
1: if (delta>MAX_TIMER_REARM_US)2: delta = MAX_TIMER_REARM_US;
问题解决了。现在qemu-omap3可以接收键盘输入了。