Revision 06d9f2f7 vl.c
b/vl.c | ||
---|---|---|
518 | 518 |
|
519 | 519 |
int64_t cpu_get_real_ticks(void) |
520 | 520 |
{ |
521 |
#ifdef _WIN32 |
|
522 |
LARGE_INTEGER ti; |
|
523 |
QueryPerformanceCounter(&ti); |
|
524 |
return ti.QuadPart; |
|
525 |
#else |
|
521 | 526 |
int64_t val; |
522 | 527 |
asm volatile ("rdtsc" : "=A" (val)); |
523 | 528 |
return val; |
529 |
#endif |
|
524 | 530 |
} |
525 | 531 |
|
526 | 532 |
#elif defined(__x86_64__) |
... | ... | |
598 | 604 |
} |
599 | 605 |
} |
600 | 606 |
|
601 |
static int64_t get_clock(void) |
|
602 |
{ |
|
603 | 607 |
#ifdef _WIN32 |
604 |
struct _timeb tb; |
|
605 |
_ftime(&tb); |
|
606 |
return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000; |
|
608 |
void cpu_calibrate_ticks(void) |
|
609 |
{ |
|
610 |
LARGE_INTEGER freq; |
|
611 |
int ret; |
|
612 |
|
|
613 |
ret = QueryPerformanceFrequency(&freq); |
|
614 |
if (ret == 0) { |
|
615 |
fprintf(stderr, "Could not calibrate ticks\n"); |
|
616 |
exit(1); |
|
617 |
} |
|
618 |
ticks_per_sec = freq.QuadPart; |
|
619 |
} |
|
620 |
|
|
607 | 621 |
#else |
622 |
static int64_t get_clock(void) |
|
623 |
{ |
|
608 | 624 |
struct timeval tv; |
609 | 625 |
gettimeofday(&tv, NULL); |
610 | 626 |
return tv.tv_sec * 1000000LL + tv.tv_usec; |
611 |
#endif |
|
612 | 627 |
} |
613 | 628 |
|
614 | 629 |
void cpu_calibrate_ticks(void) |
... | ... | |
617 | 632 |
|
618 | 633 |
usec = get_clock(); |
619 | 634 |
ticks = cpu_get_real_ticks(); |
620 |
#ifdef _WIN32 |
|
621 |
Sleep(50); |
|
622 |
#else |
|
623 | 635 |
usleep(50 * 1000); |
624 |
#endif |
|
625 | 636 |
usec = get_clock() - usec; |
626 | 637 |
ticks = cpu_get_real_ticks() - ticks; |
627 | 638 |
ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec; |
628 | 639 |
} |
640 |
#endif /* !_WIN32 */ |
|
629 | 641 |
|
630 | 642 |
/* compute with 96 bit intermediate result: (a*b)/c */ |
631 | 643 |
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) |
... | ... | |
673 | 685 |
static QEMUTimer *active_timers[2]; |
674 | 686 |
#ifdef _WIN32 |
675 | 687 |
static MMRESULT timerID; |
688 |
static HANDLE host_alarm = NULL; |
|
689 |
static unsigned int period = 1; |
|
676 | 690 |
#else |
677 | 691 |
/* frequency of the times() clock tick */ |
678 | 692 |
static int timer_freq; |
... | ... | |
895 | 909 |
qemu_get_clock(vm_clock)) || |
896 | 910 |
qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME], |
897 | 911 |
qemu_get_clock(rt_clock))) { |
912 |
#ifdef _WIN32 |
|
913 |
SetEvent(host_alarm); |
|
914 |
#endif |
|
898 | 915 |
CPUState *env = cpu_single_env; |
899 | 916 |
if (env) { |
900 | 917 |
/* stop the currently executing cpu because a timer occured */ |
... | ... | |
955 | 972 |
#ifdef _WIN32 |
956 | 973 |
{ |
957 | 974 |
int count=0; |
975 |
TIMECAPS tc; |
|
976 |
|
|
977 |
ZeroMemory(&tc, sizeof(TIMECAPS)); |
|
978 |
timeGetDevCaps(&tc, sizeof(TIMECAPS)); |
|
979 |
if (period < tc.wPeriodMin) |
|
980 |
period = tc.wPeriodMin; |
|
981 |
timeBeginPeriod(period); |
|
958 | 982 |
timerID = timeSetEvent(1, // interval (ms) |
959 |
0, // resolution
|
|
983 |
period, // resolution
|
|
960 | 984 |
host_alarm_handler, // function |
961 | 985 |
(DWORD)&count, // user parameter |
962 | 986 |
TIME_PERIODIC | TIME_CALLBACK_FUNCTION); |
... | ... | |
964 | 988 |
perror("failed timer alarm"); |
965 | 989 |
exit(1); |
966 | 990 |
} |
991 |
host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL); |
|
992 |
if (!host_alarm) { |
|
993 |
perror("failed CreateEvent"); |
|
994 |
exit(1); |
|
995 |
} |
|
996 |
ResetEvent(host_alarm); |
|
967 | 997 |
} |
968 | 998 |
pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000; |
969 | 999 |
#else |
... | ... | |
1023 | 1053 |
{ |
1024 | 1054 |
#ifdef _WIN32 |
1025 | 1055 |
timeKillEvent(timerID); |
1056 |
timeEndPeriod(period); |
|
1057 |
if (host_alarm) { |
|
1058 |
CloseHandle(host_alarm); |
|
1059 |
host_alarm = NULL; |
|
1060 |
} |
|
1026 | 1061 |
#endif |
1027 | 1062 |
} |
1028 | 1063 |
|
... | ... | |
4383 | 4418 |
} |
4384 | 4419 |
#ifdef _WIN32 |
4385 | 4420 |
if (ret == 0 && timeout > 0) { |
4386 |
Sleep(timeout); |
|
4421 |
int err; |
|
4422 |
HANDLE hEvents[1]; |
|
4423 |
|
|
4424 |
hEvents[0] = host_alarm; |
|
4425 |
ret = WaitForMultipleObjects(1, hEvents, FALSE, timeout); |
|
4426 |
switch(ret) { |
|
4427 |
case WAIT_OBJECT_0 + 0: |
|
4428 |
break; |
|
4429 |
case WAIT_TIMEOUT: |
|
4430 |
break; |
|
4431 |
default: |
|
4432 |
err = GetLastError(); |
|
4433 |
fprintf(stderr, "Wait error %d %d\n", ret, err); |
|
4434 |
break; |
|
4435 |
} |
|
4387 | 4436 |
} |
4388 | 4437 |
#endif |
4389 | 4438 |
/* poll any events */ |
Also available in: Unified diff