1. QEMUTimerList的結構體
struct QEMUTimerList {
QEMUClock *clock; //timer的鏈表會對應一個qemuclock
QemuMutex active_timers_lock;
QEMUTimer *active_timers;
QLIST_ENTRY(QEMUTimerList) list;
QEMUTimerListNotifyCB *notify_cb;//cb函數
void *notify_opaque;
/* lightweight method to mark the end of timerlist's running */
QemuEvent timers_done_ev;
};
2.qemu_init_main_loop 函數分析
int qemu_init_main_loop(Error **errp)
{
int ret;
GSource *src;
Error *local_error = NULL;
init_clocks(qemu_timer_notify_cb);
ret = qemu_signal_init();
if (ret) {
return ret;
}
qemu_aio_context = aio_context_new(&local_error);
if (!qemu_aio_context) {
error_propagate(errp, local_error);
return -EMFILE;
}
qemu_notify_bh = qemu_bh_new(notify_event_cb, NULL);
gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
src = aio_get_g_source(qemu_aio_context);
g_source_set_name(src, "aio-context");
g_source_attach(src, NULL);
g_source_unref(src);
src = iohandler_get_g_source();
g_source_set_name(src, "io-handler");
g_source_attach(src, NULL);
g_source_unref(src);
return 0;
}
2.1 初始化時鐘 init_clocks
void init_clocks(QEMUTimerListNotifyCB *notify_cb)
{
QEMUClockType type;
for (type = 0; type < QEMU_CLOCK_MAX; type++) {
qemu_clock_init(type, notify_cb);
}
}
2.1.1 qemu_clock_init創建每一種類型的CLOCK進行初始化
static void qemu_clock_init(QEMUClockType type, QEMUTimerListNotifyCB *notify_cb)
{
QEMUClock *clock = qemu_clock_ptr(type);
/*確保這個類型的clock沒有被初始化,若被初始化了,則直接報錯退出*/
/* Assert that the clock of type TYPE has not been initialized yet. */
assert(main_loop_tlg.tl[type] == NULL);
/*對QEMUClock中的成員變量初始化*/
clock->type = type;
clock->enabled = (type == QEMU_CLOCK_VIRTUAL ? false : true);
clock->last = INT64_MIN;
/*初始化這個類型的clock的timerlist鏈表*/
QLIST_INIT(&clock->timerlists);
/*初始化notifier的鏈表*/
notifier_list_init(&clock->reset_notifiers);
main_loop_tlg.tl[type] = timerlist_new(type, notify_cb, NULL);
}
2.1.2創建每一個類型的CLOCK的qemutimerlist鏈表,並完成元素的初始化
QEMUTimerList *timerlist_new(QEMUClockType type,
QEMUTimerListNotifyCB *cb,
void *opaque)
{
QEMUTimerList *timer_list;
QEMUClock *clock = qemu_clock_ptr(type);
timer_list = g_malloc0(sizeof(QEMUTimerList));
qemu_event_init(&timer_list->timers_done_ev, true);
timer_list->clock = clock;
timer_list->notify_cb = cb;
timer_list->notify_opaque = opaque;
qemu_mutex_init(&timer_list->active_timers_lock);
QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
return timer_list;
}
2.1.3使用windowsAPI爲qemutimerlist創建無名事件對象
/**初始化事件/
void qemu_event_init(QemuEvent *ev, bool init)
{
/* Manual reset. */
/*初始狀態爲有信號狀態*/
ev->event = CreateEvent(NULL, TRUE, TRUE, NULL);
ev->value = (init ? EV_SET : EV_FREE);
ev->initialized = true;
}
3. 總體結構關係圖