Revision f3fc6e2e

b/qemu-timer.c
153 153
    char const *name;
154 154
    int (*start)(struct qemu_alarm_timer *t);
155 155
    void (*stop)(struct qemu_alarm_timer *t);
156
    void (*rearm)(struct qemu_alarm_timer *t);
156
    void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
157 157
#if defined(__linux__)
158 158
    int fd;
159 159
    timer_t timer;
......
181 181
    return !!t->rearm;
182 182
}
183 183

  
184
static int64_t qemu_next_alarm_deadline(void)
185
{
186
    int64_t delta;
187
    int64_t rtdelta;
188

  
189
    if (!use_icount && vm_clock->active_timers) {
190
        delta = vm_clock->active_timers->expire_time -
191
                     qemu_get_clock_ns(vm_clock);
192
    } else {
193
        delta = INT32_MAX;
194
    }
195
    if (host_clock->active_timers) {
196
        int64_t hdelta = host_clock->active_timers->expire_time -
197
                 qemu_get_clock_ns(host_clock);
198
        if (hdelta < delta) {
199
            delta = hdelta;
200
        }
201
    }
202
    if (rt_clock->active_timers) {
203
        rtdelta = (rt_clock->active_timers->expire_time -
204
                 qemu_get_clock_ns(rt_clock));
205
        if (rtdelta < delta) {
206
            delta = rtdelta;
207
        }
208
    }
209

  
210
    return delta;
211
}
212

  
184 213
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
185 214
{
186
    if (!alarm_has_dynticks(t))
215
    int64_t nearest_delta_ns;
216
    assert(alarm_has_dynticks(t));
217
    if (!rt_clock->active_timers &&
218
        !vm_clock->active_timers &&
219
        !host_clock->active_timers) {
187 220
        return;
188

  
189
    t->rearm(t);
221
    }
222
    nearest_delta_ns = qemu_next_alarm_deadline();
223
    t->rearm(t, nearest_delta_ns);
190 224
}
191 225

  
192 226
/* TODO: MIN_TIMER_REARM_NS should be optimized */
......
196 230

  
197 231
static int mm_start_timer(struct qemu_alarm_timer *t);
198 232
static void mm_stop_timer(struct qemu_alarm_timer *t);
199
static void mm_rearm_timer(struct qemu_alarm_timer *t);
233
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
200 234

  
201 235
static int win32_start_timer(struct qemu_alarm_timer *t);
202 236
static void win32_stop_timer(struct qemu_alarm_timer *t);
203
static void win32_rearm_timer(struct qemu_alarm_timer *t);
237
static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
204 238

  
205 239
#else
206 240

  
207 241
static int unix_start_timer(struct qemu_alarm_timer *t);
208 242
static void unix_stop_timer(struct qemu_alarm_timer *t);
209
static void unix_rearm_timer(struct qemu_alarm_timer *t);
243
static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
210 244

  
211 245
#ifdef __linux__
212 246

  
213 247
static int dynticks_start_timer(struct qemu_alarm_timer *t);
214 248
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
215
static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
249
static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
216 250

  
217 251
#endif /* __linux__ */
218 252

  
......
715 749
    qemu_run_timers(host_clock);
716 750
}
717 751

  
718
static int64_t qemu_next_alarm_deadline(void);
719

  
720 752
#ifdef _WIN32
721 753
static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
722 754
#else
......
781 813
    return delta;
782 814
}
783 815

  
784
static int64_t qemu_next_alarm_deadline(void)
785
{
786
    int64_t delta;
787
    int64_t rtdelta;
788

  
789
    if (!use_icount && vm_clock->active_timers) {
790
        delta = vm_clock->active_timers->expire_time -
791
                     qemu_get_clock_ns(vm_clock);
792
    } else {
793
        delta = INT32_MAX;
794
    }
795
    if (host_clock->active_timers) {
796
        int64_t hdelta = host_clock->active_timers->expire_time -
797
                 qemu_get_clock_ns(host_clock);
798
        if (hdelta < delta)
799
            delta = hdelta;
800
    }
801
    if (rt_clock->active_timers) {
802
        rtdelta = (rt_clock->active_timers->expire_time -
803
                 qemu_get_clock_ns(rt_clock));
804
        if (rtdelta < delta)
805
            delta = rtdelta;
806
    }
807

  
808
    return delta;
809
}
810

  
811 816
#if defined(__linux__)
812 817

  
813 818
#include "compatfd.h"
......
860 865
    timer_delete(host_timer);
861 866
}
862 867

  
863
static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
868
static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
869
                                 int64_t nearest_delta_ns)
864 870
{
865 871
    timer_t host_timer = t->timer;
866 872
    struct itimerspec timeout;
867
    int64_t nearest_delta_ns = INT64_MAX;
868 873
    int64_t current_ns;
869 874

  
870
    assert(alarm_has_dynticks(t));
871
    if (!rt_clock->active_timers &&
872
        !vm_clock->active_timers &&
873
        !host_clock->active_timers)
874
        return;
875

  
876
    nearest_delta_ns = qemu_next_alarm_deadline();
877 875
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
878 876
        nearest_delta_ns = MIN_TIMER_REARM_NS;
879 877

  
......
915 913
    return 0;
916 914
}
917 915

  
918
static void unix_rearm_timer(struct qemu_alarm_timer *t)
916
static void unix_rearm_timer(struct qemu_alarm_timer *t,
917
                             int64_t nearest_delta_ns)
919 918
{
920 919
    struct itimerval itv;
921
    int64_t nearest_delta_ns = INT64_MAX;
922 920
    int err;
923 921

  
924
    assert(alarm_has_dynticks(t));
925
    if (!rt_clock->active_timers &&
926
        !vm_clock->active_timers &&
927
        !host_clock->active_timers)
928
        return;
929

  
930
    nearest_delta_ns = qemu_next_alarm_deadline();
931 922
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
932 923
        nearest_delta_ns = MIN_TIMER_REARM_NS;
933 924

  
......
1014 1005
    timeEndPeriod(mm_period);
1015 1006
}
1016 1007

  
1017
static void mm_rearm_timer(struct qemu_alarm_timer *t)
1008
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
1018 1009
{
1019
    int nearest_delta_ms;
1020

  
1021
    assert(alarm_has_dynticks(t));
1022
    if (!rt_clock->active_timers &&
1023
        !vm_clock->active_timers &&
1024
        !host_clock->active_timers) {
1025
        return;
1026
    }
1027

  
1028
    timeKillEvent(mm_timer);
1029

  
1030
    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
1010
    int nearest_delta_ms = (delta + 999999) / 1000000;
1031 1011
    if (nearest_delta_ms < 1) {
1032 1012
        nearest_delta_ms = 1;
1033 1013
    }
1014

  
1015
    timeKillEvent(mm_timer);
1034 1016
    mm_timer = timeSetEvent(nearest_delta_ms,
1035 1017
                            mm_period,
1036 1018
                            mm_alarm_handler,
......
1082 1064
    }
1083 1065
}
1084 1066

  
1085
static void win32_rearm_timer(struct qemu_alarm_timer *t)
1067
static void win32_rearm_timer(struct qemu_alarm_timer *t,
1068
                              int64_t nearest_delta_ns)
1086 1069
{
1087 1070
    HANDLE hTimer = t->timer;
1088 1071
    int nearest_delta_ms;
1089 1072
    BOOLEAN success;
1090 1073

  
1091
    assert(alarm_has_dynticks(t));
1092
    if (!rt_clock->active_timers &&
1093
        !vm_clock->active_timers &&
1094
        !host_clock->active_timers)
1095
        return;
1096

  
1097
    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
1074
    nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000;
1098 1075
    if (nearest_delta_ms < 1) {
1099 1076
        nearest_delta_ms = 1;
1100 1077
    }

Also available in: Unified diff