~ubuntu-branches/ubuntu/natty/qemu-linaro/natty

« back to all changes in this revision

Viewing changes to qemu-timer.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek, Loïc Minier, Steve Langasek
  • Date: 2011-03-07 22:55:03 UTC
  • Revision ID: package-import@ubuntu.com-20110307225503-3opjapw0ksg7glo6
[ Loïc Minier ]
* Also pass -fno-var-tracking on armhf.

[ Steve Langasek ]
* New upstream release.
* Build with -marm on armel/armhf; Peter Maydell reports that building for
  Thumb-2 gives an emulator that doesn't work.
* Add support for cross-compiling the package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
112
112
 
113
113
static int64_t qemu_icount_delta(void)
114
114
{
115
 
    if (!use_icount) {
116
 
        return 5000 * (int64_t) 1000000;
117
 
    } else if (use_icount == 1) {
 
115
    if (use_icount == 1) {
118
116
        /* When not using an adaptive execution frequency
119
117
           we tend to get badly out of sync with real time,
120
118
           so just delay for a reasonable amount of time.  */
197
195
    t->rearm(t);
198
196
}
199
197
 
200
 
/* TODO: MIN_TIMER_REARM_US should be optimized */
201
 
#define MIN_TIMER_REARM_US 250
 
198
/* TODO: MIN_TIMER_REARM_NS should be optimized */
 
199
#define MIN_TIMER_REARM_NS 250000
202
200
 
203
201
#ifdef _WIN32
204
202
 
635
633
    qemu_run_timers(host_clock);
636
634
}
637
635
 
 
636
static int64_t qemu_next_alarm_deadline(void);
 
637
 
638
638
#ifdef _WIN32
639
639
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
640
640
                                        DWORD_PTR dwUser, DWORD_PTR dw1,
677
677
    }
678
678
#endif
679
679
    if (alarm_has_dynticks(t) ||
680
 
        (!use_icount &&
681
 
            qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
682
 
                               qemu_get_clock(vm_clock))) ||
683
 
        qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],
684
 
                           qemu_get_clock(rt_clock)) ||
685
 
        qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],
686
 
                           qemu_get_clock(host_clock))) {
687
 
 
 
680
        qemu_next_alarm_deadline () <= 0) {
688
681
        t->expired = alarm_has_dynticks(t);
689
682
        t->pending = 1;
690
683
        qemu_notify_event();
698
691
 
699
692
    if (active_timers[QEMU_CLOCK_VIRTUAL]) {
700
693
        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
701
 
                     qemu_get_clock(vm_clock);
 
694
                     qemu_get_clock_ns(vm_clock);
702
695
    }
703
696
    if (active_timers[QEMU_CLOCK_HOST]) {
704
697
        int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
705
 
                 qemu_get_clock(host_clock);
 
698
                 qemu_get_clock_ns(host_clock);
706
699
        if (hdelta < delta)
707
700
            delta = hdelta;
708
701
    }
713
706
    return delta;
714
707
}
715
708
 
716
 
#ifndef _WIN32
717
 
 
718
 
#if defined(__linux__)
719
 
 
720
 
#define RTC_FREQ 1024
721
 
 
722
 
static uint64_t qemu_next_deadline_dyntick(void)
 
709
static int64_t qemu_next_alarm_deadline(void)
723
710
{
724
711
    int64_t delta;
725
712
    int64_t rtdelta;
726
713
 
727
 
    if (use_icount)
 
714
    if (!use_icount && active_timers[QEMU_CLOCK_VIRTUAL]) {
 
715
        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
 
716
                     qemu_get_clock(vm_clock);
 
717
    } else {
728
718
        delta = INT32_MAX;
729
 
    else
730
 
        delta = (qemu_next_deadline() + 999) / 1000;
731
 
 
 
719
    }
 
720
    if (active_timers[QEMU_CLOCK_HOST]) {
 
721
        int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
 
722
                 qemu_get_clock_ns(host_clock);
 
723
        if (hdelta < delta)
 
724
            delta = hdelta;
 
725
    }
732
726
    if (active_timers[QEMU_CLOCK_REALTIME]) {
733
 
        rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
734
 
                 qemu_get_clock(rt_clock))*1000;
 
727
        rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 1000000 -
 
728
                 qemu_get_clock_ns(rt_clock));
735
729
        if (rtdelta < delta)
736
730
            delta = rtdelta;
737
731
    }
738
732
 
739
 
    if (delta < MIN_TIMER_REARM_US)
740
 
        delta = MIN_TIMER_REARM_US;
741
 
 
742
733
    return delta;
743
734
}
744
735
 
 
736
#if defined(__linux__)
 
737
 
 
738
#define RTC_FREQ 1024
 
739
 
745
740
static void enable_sigio_timer(int fd)
746
741
{
747
742
    struct sigaction act;
887
882
{
888
883
    timer_t host_timer = (timer_t)(long)t->priv;
889
884
    struct itimerspec timeout;
890
 
    int64_t nearest_delta_us = INT64_MAX;
891
 
    int64_t current_us;
 
885
    int64_t nearest_delta_ns = INT64_MAX;
 
886
    int64_t current_ns;
892
887
 
893
888
    assert(alarm_has_dynticks(t));
894
889
    if (!active_timers[QEMU_CLOCK_REALTIME] &&
896
891
        !active_timers[QEMU_CLOCK_HOST])
897
892
        return;
898
893
 
899
 
    nearest_delta_us = qemu_next_deadline_dyntick();
 
894
    nearest_delta_ns = qemu_next_alarm_deadline();
 
895
    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
 
896
        nearest_delta_ns = MIN_TIMER_REARM_NS;
900
897
 
901
898
    /* check whether a timer is already running */
902
899
    if (timer_gettime(host_timer, &timeout)) {
904
901
        fprintf(stderr, "Internal timer error: aborting\n");
905
902
        exit(1);
906
903
    }
907
 
    current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
908
 
    if (current_us && current_us <= nearest_delta_us)
 
904
    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
 
905
    if (current_ns && current_ns <= nearest_delta_ns)
909
906
        return;
910
907
 
911
908
    timeout.it_interval.tv_sec = 0;
912
909
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
913
 
    timeout.it_value.tv_sec =  nearest_delta_us / 1000000;
914
 
    timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
 
910
    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
 
911
    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
915
912
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
916
913
        perror("settime");
917
914
        fprintf(stderr, "Internal timer error: aborting\n");
921
918
 
922
919
#endif /* defined(__linux__) */
923
920
 
 
921
#if !defined(_WIN32)
 
922
 
924
923
static int unix_start_timer(struct qemu_alarm_timer *t)
925
924
{
926
925
    struct sigaction act;
1076
1075
int qemu_calculate_timeout(void)
1077
1076
{
1078
1077
    int timeout;
 
1078
    int64_t add;
 
1079
    int64_t delta;
1079
1080
 
1080
 
#ifdef CONFIG_IOTHREAD
1081
1081
    /* When using icount, making forward progress with qemu_icount when the
1082
1082
       guest CPU is idle is critical. We only use the static io-thread timeout
1083
1083
       for non icount runs.  */
1084
 
    if (!use_icount) {
1085
 
        return 1000;
 
1084
    if (!use_icount || !vm_running) {
 
1085
        return 5000;
1086
1086
    }
1087
 
#endif
1088
1087
 
1089
 
    if (!vm_running)
1090
 
        timeout = 5000;
1091
 
    else {
1092
 
     /* XXX: use timeout computed from timers */
1093
 
        int64_t add;
1094
 
        int64_t delta;
1095
 
        /* Advance virtual time to the next event.  */
1096
 
        delta = qemu_icount_delta();
1097
 
        if (delta > 0) {
1098
 
            /* If virtual time is ahead of real time then just
1099
 
               wait for IO.  */
1100
 
            timeout = (delta + 999999) / 1000000;
1101
 
        } else {
1102
 
            /* Wait for either IO to occur or the next
1103
 
               timer event.  */
1104
 
            add = qemu_next_deadline();
1105
 
            /* We advance the timer before checking for IO.
1106
 
               Limit the amount we advance so that early IO
1107
 
               activity won't get the guest too far ahead.  */
1108
 
            if (add > 10000000)
1109
 
                add = 10000000;
1110
 
            delta += add;
1111
 
            qemu_icount += qemu_icount_round (add);
1112
 
            timeout = delta / 1000000;
1113
 
            if (timeout < 0)
1114
 
                timeout = 0;
1115
 
        }
 
1088
    /* Advance virtual time to the next event.  */
 
1089
    delta = qemu_icount_delta();
 
1090
    if (delta > 0) {
 
1091
        /* If virtual time is ahead of real time then just
 
1092
           wait for IO.  */
 
1093
        timeout = (delta + 999999) / 1000000;
 
1094
    } else {
 
1095
        /* Wait for either IO to occur or the next
 
1096
           timer event.  */
 
1097
        add = qemu_next_deadline();
 
1098
        /* We advance the timer before checking for IO.
 
1099
           Limit the amount we advance so that early IO
 
1100
           activity won't get the guest too far ahead.  */
 
1101
        if (add > 10000000)
 
1102
            add = 10000000;
 
1103
        delta += add;
 
1104
        qemu_icount += qemu_icount_round (add);
 
1105
        timeout = delta / 1000000;
 
1106
        if (timeout < 0)
 
1107
            timeout = 0;
1116
1108
    }
1117
1109
 
1118
1110
    return timeout;