On 14/10/2018 16:55, Artem Pisarenko wrote:
> +            qemu_mutex_lock(&timer_list->active_timers_lock);
> +            ts = timer_list->active_timers;
> +            while (timer_expired_ns(ts, current_time)) {
> +                if (!(ts->attributes & QEMU_TIMER_ATTR(EXTERNAL))) {
> +                    need_replay_checkpoint = true;
> +                    break;
> +                }
> +                ts = ts->next;
> +            }
> +            qemu_mutex_unlock(&timer_list->active_timers_lock);

This can be applied to all the timerlists, it doesn't have to be limited
to the "virtual" clock, something like (untested):

    qemu_mutex_lock(&timer_list->active_timers_lock);
    current_time = qemu_clock_get_ns(timer_list->clock->type);
    ts = timer_list->active_timers;
    if (replay_mode != REPLAY_MODE_NONE) {
         while (timer_expired_ns(ts, current_time)) {
             if (!(ts->attributes & QEMU_TIMER_ATTR(EXTERNAL))) {
                 qemu_mutex_unlock(&timer_list->active_timers_lock);
                 timerlist_checkpoint(timer_list);
                 qemu_mutex_lock(&timer_list->active_timers_lock);
                 break;
              }
              ts = ts->next;
         }
        ts = timer_list->active_timers;
    }

    while (timer_expired_ns(ts, current_time)) {
        /* remove timer from the list before calling the callback */
        timer_list->active_timers = ts->next;
        ts->next = NULL;
        ts->expire_time = -1;
        cb = ts->cb;
        opaque = ts->opaque;

        /* run the callback (the timer list can be modified) */
        qemu_mutex_unlock(&timer_list->active_timers_lock);
        cb(opaque);
        qemu_mutex_lock(&timer_list->active_timers_lock);
        progress = true;
        ts = timer_list->active_timers;
    }
    qemu_mutex_unlock(&timer_list->active_timers_lock);

Thanks,

Paolo

Reply via email to