static uint64_t calculate_next(struct AspeedTimer *t) { uint64_t next = 0; uint32_t rate = calculate_rate(t); while (!next) { /* We don't know the relationship between the values in the match * registers, so sort using MAX/MIN/zero. We sort in that order as the * timer counts down to zero. */ uint64_t seq[] = { calculate_time(t, MAX(t->match[0], t->match[1])), calculate_time(t, MIN(t->match[0], t->match[1])), calculate_time(t, 0), }; uint64_t reload_ns; uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); if (now < seq[0]) { next = seq[0]; } else if (now < seq[1]) { next = seq[1]; } else if (now < seq[2]) { next = seq[2]; } else if (t->reload) { reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate); t->start = now - ((now - t->start) % reload_ns); } else { /* no reload value, return 0 */ break; } } return next; }
static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns) { uint64_t delta_ns = now_ns - MIN(now_ns, t->start); uint32_t rate = calculate_rate(t); uint64_t ticks = muldiv64(delta_ns, rate, NANOSECONDS_PER_SECOND); return t->reload - MIN(t->reload, ticks); }
static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks) { uint64_t delta_ns; uint64_t delta_ticks; delta_ticks = t->reload - MIN(t->reload, ticks); delta_ns = muldiv64(delta_ticks, NANOSECONDS_PER_SECOND, calculate_rate(t)); return t->start + delta_ns; }
GHOST_TSuccess GHOST_DisplayManagerX11:: getDisplaySetting( GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const { Display *dpy = m_system->getXDisplay(); if (dpy == NULL) return GHOST_kFailure; (void)display; #ifdef WITH_X11_XF86VMODE int majorVersion, minorVersion; GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); majorVersion = minorVersion = 0; if (XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { XF86VidModeModeInfo **vidmodes; int numSettings; if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes)) { GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n"); setting.xPixels = vidmodes[index]->hdisplay; setting.yPixels = vidmodes[index]->vdisplay; setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); setting.frequency = calculate_rate(vidmodes[index]); XFree(vidmodes); return GHOST_kSuccess; } } else { fprintf(stderr, "Warning: XF86VidMode extension missing!\n"); /* fallback to non xf86vmode below */ } #endif /* WITH_X11_XF86VMODE */ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); (void)index; setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy)); setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy)); setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy)); setting.frequency = 60.0f; return GHOST_kSuccess; }
void TestZeroRateWith32BitsCounter(CuTest *tc) { time_t cur_time = time(NULL); time_t prev_time = cur_time - 60; unsigned long long prev_counter = 1000000; unsigned long long cur_counter = prev_counter; unsigned long long counter_diff; unsigned rate; calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 32, &counter_diff, &rate); CuAssertIntEquals(tc, 0u, counter_diff); CuAssertIntEquals(tc, 0u, rate); }
void TestGaugeValueChanged(CuTest *tc) { time_t cur_time = time(NULL); time_t prev_time = cur_time - 60; unsigned long long prev_counter = 1000000; unsigned long long cur_counter = 1000000 + 1000; unsigned long long counter_diff; unsigned rate; calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 0, &counter_diff, &rate); CuAssertIntEquals(tc, 1000000u + 1000, counter_diff); CuAssertIntEquals(tc, 1000000u + 1000, rate); }
void TestOneKbpsRateWith64BitsCounterThatWraps(CuTest *tc) { time_t cur_time = time(NULL); time_t prev_time = cur_time - 60; unsigned long long prev_counter = 18446744073709551000ull; unsigned long long cur_counter = prev_counter + 60 * 1000 / 8; unsigned long long counter_diff; unsigned rate; calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 64, &counter_diff, &rate); CuAssertIntEquals(tc, 60u * 1000 / 8, counter_diff); CuAssertIntEquals(tc, 1000u / 8, rate); }
void TestOneKbpsRateWith32BitsCounterThatWraps(CuTest *tc) { time_t cur_time = time(NULL); time_t prev_time = cur_time - 60; unsigned int prev_counter = 4294967000u; unsigned int cur_counter = prev_counter + 60 * 1000 / 8; unsigned long long counter_diff; unsigned rate; calculate_rate(prev_time, prev_counter, cur_time, cur_counter, 32, &counter_diff, &rate); CuAssertIntEquals(tc, 60u * 1000 / 8, counter_diff); CuAssertIntEquals(tc, 1000u / 8, rate); }
static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg, uint32_t value) { AspeedTimer *t; uint32_t old_reload; trace_aspeed_timer_set_value(timer, reg, value); t = &s->timers[timer]; switch (reg) { case TIMER_REG_RELOAD: old_reload = t->reload; t->reload = value; /* If the reload value was not previously set, or zero, and * the current value is valid, try to start the timer if it is * enabled. */ if (old_reload || !t->reload) { break; } case TIMER_REG_STATUS: if (timer_enabled(t)) { uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now); uint32_t rate = calculate_rate(t); t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate); aspeed_timer_mod(t); } break; case TIMER_REG_MATCH_FIRST: case TIMER_REG_MATCH_SECOND: t->match[reg - 2] = value; if (timer_enabled(t)) { aspeed_timer_mod(t); } break; default: qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n", __func__, reg); break; } }
GHOST_TSuccess GHOST_DisplayManagerX11:: setCurrentDisplaySetting( GHOST_TUns8 /*display*/, const GHOST_DisplaySetting& setting) { #ifdef WITH_X11_XF86VMODE /* Mode switching code ported from SDL: * See: src/video/x11/SDL_x11modes.c:set_best_resolution */ int majorVersion, minorVersion; XF86VidModeModeInfo **vidmodes; Display *dpy = m_system->getXDisplay(); int scrnum, num_vidmodes; if (dpy == NULL) return GHOST_kFailure; scrnum = DefaultScreen(dpy); /* Get video mode list */ majorVersion = minorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { fprintf(stderr, "Error: XF86VidMode extension missing!\n"); return GHOST_kFailure; } # ifdef DEBUG printf("Using XFree86-VidModeExtension Version %d.%d\n", majorVersion, minorVersion); # endif if (XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes)) { int best_fit = -1; for (int i = 0; i < num_vidmodes; i++) { if (vidmodes[i]->hdisplay < setting.xPixels || vidmodes[i]->vdisplay < setting.yPixels) { continue; } if (best_fit == -1 || (vidmodes[i]->hdisplay < vidmodes[best_fit]->hdisplay) || (vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay && vidmodes[i]->vdisplay < vidmodes[best_fit]->vdisplay)) { best_fit = i; continue; } if ((vidmodes[i]->hdisplay == vidmodes[best_fit]->hdisplay) && (vidmodes[i]->vdisplay == vidmodes[best_fit]->vdisplay)) { if (!setting.frequency) { /* Higher is better, right? */ if (calculate_rate(vidmodes[i]) > calculate_rate(vidmodes[best_fit])) { best_fit = i; } } else { if (abs(calculate_rate(vidmodes[i]) - (int)setting.frequency) < abs(calculate_rate(vidmodes[best_fit]) - (int)setting.frequency)) { best_fit = i; } } } } if (best_fit != -1) { # ifdef DEBUG printf("Switching to video mode %dx%d %dx%d %d\n", vidmodes[best_fit]->hdisplay, vidmodes[best_fit]->vdisplay, vidmodes[best_fit]->htotal, vidmodes[best_fit]->vtotal, calculate_rate(vidmodes[best_fit])); # endif /* change to the mode */ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); /* Move the viewport to top left */ XF86VidModeSetViewPort(dpy, scrnum, 0, 0); } XFree(vidmodes); } else { return GHOST_kFailure; } XFlush(dpy); return GHOST_kSuccess; #else /* Just pretend the request was successful. */ return GHOST_kSuccess; #endif }