From 82444095017e1f0c457f0d6979f68c0d812ef311 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 26 May 2015 22:20:46 -0700 Subject: [PATCH] Refactoring to enable future time scaling, coordinated clocks, etc. --- libxenia.vcxproj | 2 + libxenia.vcxproj.filters | 6 ++ src/xenia/base/clock.cc | 96 ++++++++++++++++++++++ src/xenia/base/clock.h | 60 ++++++++++++++ src/xenia/base/threading.h | 4 - src/xenia/base/threading_win.cc | 17 ---- src/xenia/cpu/backend/x64/x64_sequences.cc | 3 +- src/xenia/emulator.cc | 16 ++++ src/xenia/gpu/gl4/command_processor.cc | 10 --- src/xenia/gpu/gl4/command_processor.h | 2 - src/xenia/gpu/gl4/gl4_graphics_system.cc | 7 +- src/xenia/gpu/xe-gpu-trace-viewer.cc | 7 +- src/xenia/kernel/objects/xthread.cc | 7 +- src/xenia/kernel/objects/xtimer.cc | 4 + src/xenia/kernel/xam_net.cc | 2 + src/xenia/kernel/xboxkrnl_module.cc | 7 +- src/xenia/kernel/xboxkrnl_threading.cc | 13 +-- src/xenia/kernel/xobject.cc | 4 + src/xenia/memory.cc | 3 +- 19 files changed, 213 insertions(+), 57 deletions(-) create mode 100644 src/xenia/base/clock.cc create mode 100644 src/xenia/base/clock.h diff --git a/libxenia.vcxproj b/libxenia.vcxproj index 2b0bfb2b1..0fa0d6a3c 100644 --- a/libxenia.vcxproj +++ b/libxenia.vcxproj @@ -25,6 +25,7 @@ + @@ -217,6 +218,7 @@ + diff --git a/libxenia.vcxproj.filters b/libxenia.vcxproj.filters index b969ef749..a64a8f85f 100644 --- a/libxenia.vcxproj.filters +++ b/libxenia.vcxproj.filters @@ -706,6 +706,9 @@ src\xenia\apu + + src\xenia\base + @@ -1362,6 +1365,9 @@ src\xenia\base + + src\xenia\base + diff --git a/src/xenia/base/clock.cc b/src/xenia/base/clock.cc new file mode 100644 index 000000000..78f922b3b --- /dev/null +++ b/src/xenia/base/clock.cc @@ -0,0 +1,96 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/base/clock.h" + +#include "xenia/base/platform.h" + +namespace xe { + +double guest_time_scalar_ = 1.0; +uint64_t guest_tick_frequency_ = Clock::host_tick_frequency(); +uint64_t guest_system_time_base_ = Clock::QueryHostSystemTime(); + +uint64_t Clock::host_tick_frequency() { + static LARGE_INTEGER frequency = {0}; + if (!frequency.QuadPart) { + QueryPerformanceFrequency(&frequency); + } + return frequency.QuadPart; +} + +uint64_t Clock::QueryHostTickCount() { + LARGE_INTEGER counter; + uint64_t time = 0; + if (QueryPerformanceCounter(&counter)) { + time = counter.QuadPart; + } + return time; +} + +uint64_t Clock::QueryHostSystemTime() { + FILETIME t; + GetSystemTimeAsFileTime(&t); + return (uint64_t(t.dwHighDateTime) << 32) | t.dwLowDateTime; +} + +uint32_t Clock::QueryHostUptimeMillis() { return ::GetTickCount(); } + +double Clock::guest_time_scalar() { return guest_time_scalar_; } + +void Clock::set_guest_time_scalar(double scalar) { + guest_time_scalar_ = scalar; +} + +uint64_t Clock::guest_tick_frequency() { return guest_tick_frequency_; } + +void Clock::set_guest_tick_frequency(uint64_t frequency) { + guest_tick_frequency_ = frequency; +} + +uint64_t Clock::guest_system_time_base() { return guest_system_time_base_; } + +void Clock::set_guest_system_time_base(uint64_t time_base) { + guest_system_time_base_ = time_base; +} + +uint64_t Clock::QueryGuestTickCount() { + // TODO(benvanik): adjust. + return QueryHostTickCount(); +} + +uint64_t Clock::QueryGuestSystemTime() { + // TODO(benvanik): adjust. + return QueryHostSystemTime(); +} + +uint32_t Clock::QueryGuestUptimeMillis() { + // TODO(benvanik): adjust. + return QueryHostUptimeMillis(); +} + +uint32_t Clock::ScaleGuestDurationMillis(uint32_t guest_ms) { + // TODO(benvanik): adjust. + // if -1, return -1 + // if 0, return 0 + return guest_ms; +} + +int64_t Clock::ScaleGuestDurationFileTime(int64_t guest_file_time) { + // TODO(benvanik): adjust. + // negative = relative times + // positive = absolute times + return guest_file_time; +} + +void Clock::ScaleGuestDurationTimeval(long* tv_sec, long* tv_usec) { + // TODO(benvanik): adjust. +} + +} // namespace xe diff --git a/src/xenia/base/clock.h b/src/xenia/base/clock.h new file mode 100644 index 000000000..31ae5a288 --- /dev/null +++ b/src/xenia/base/clock.h @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_BASE_CLOCK_H_ +#define XENIA_BASE_CLOCK_H_ + +#include + +namespace xe { + +class Clock { + public: + // Host ticks-per-second. + static uint64_t host_tick_frequency(); + // Queries the current host tick count. + static uint64_t QueryHostTickCount(); + // Host time, in FILETIME format. + static uint64_t QueryHostSystemTime(); + // Queries the milliseconds since the host began. + static uint32_t QueryHostUptimeMillis(); + + // Guest time scalar. + static double guest_time_scalar(); + // Sets the guest time scalar, adjusting tick and wall clock speed. + // Ex: 1x=normal, 2x=double speed, 1/2x=half speed. + static void set_guest_time_scalar(double scalar); + // Guest ticks-per-second. + static uint64_t guest_tick_frequency(); + // Sets the guest ticks-per-second. + static void set_guest_tick_frequency(uint64_t frequency); + // Time based used for the guest system time. + static uint64_t guest_system_time_base(); + // Sets the guest time base, used for computing the system time. + // By default this is the current system time. + static void set_guest_system_time_base(uint64_t time_base); + // Queries the current guest tick count, accounting for frequency adjustment + // and scaling. + static uint64_t QueryGuestTickCount(); + // Queries the guest time, in FILETIME format, accounting for scaling. + static uint64_t QueryGuestSystemTime(); + // Queries the milliseconds since the guest began, accounting for scaling. + static uint32_t QueryGuestUptimeMillis(); + + // Scales a time duration in milliseconds, from guest time. + static uint32_t ScaleGuestDurationMillis(uint32_t guest_ms); + // Scales a time duration in 100ns ticks like FILETIME, from guest time. + static int64_t ScaleGuestDurationFileTime(int64_t guest_file_time); + // Scales a time duration represented as a timeval, from guest time. + static void ScaleGuestDurationTimeval(long* tv_sec, long* tv_usec); +}; + +} // namespace xe + +#endif // XENIA_BASE_CLOCK_H_ diff --git a/src/xenia/base/threading.h b/src/xenia/base/threading.h index da2b7bee5..345dc14ab 100644 --- a/src/xenia/base/threading.h +++ b/src/xenia/base/threading.h @@ -43,10 +43,6 @@ class Fence { std::atomic signaled_; }; -// Gets the current high-performance tick count. -uint64_t ticks(); -uint64_t ticks_per_second(); - // TODO(benvanik): processor info API. // Gets a stable thread-specific ID, but may not be. Use for informative diff --git a/src/xenia/base/threading_win.cc b/src/xenia/base/threading_win.cc index 342fbb7de..f8546f099 100644 --- a/src/xenia/base/threading_win.cc +++ b/src/xenia/base/threading_win.cc @@ -14,23 +14,6 @@ namespace xe { namespace threading { -uint64_t ticks() { - LARGE_INTEGER counter; - uint64_t time = 0; - if (QueryPerformanceCounter(&counter)) { - time = counter.QuadPart; - } - return time; -} - -uint64_t ticks_per_second() { - static LARGE_INTEGER freq = {0}; - if (!freq.QuadPart) { - QueryPerformanceFrequency(&freq); - } - return freq.QuadPart; -} - uint32_t current_thread_id() { return static_cast(GetCurrentThreadId()); } diff --git a/src/xenia/cpu/backend/x64/x64_sequences.cc b/src/xenia/cpu/backend/x64/x64_sequences.cc index 9eb4cb074..a3fc19ba1 100644 --- a/src/xenia/cpu/backend/x64/x64_sequences.cc +++ b/src/xenia/cpu/backend/x64/x64_sequences.cc @@ -25,6 +25,7 @@ #include "xenia/cpu/backend/x64/x64_sequences.h" #include "xenia/base/assert.h" +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/threading.h" #include "xenia/cpu/backend/x64/x64_emitter.h" @@ -1086,7 +1087,7 @@ EMITTER(LOAD_CLOCK, MATCH(I>)) { e.mov(i.dest, e.rax); } static uint64_t LoadClock(void* raw_context) { - return xe::threading::ticks(); + return Clock::QueryGuestTickCount(); } }; EMITTER_OPCODE_TABLE( diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 324966cd4..0de7c9fab 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -9,8 +9,11 @@ #include "xenia/emulator.h" +#include + #include "xenia/apu/apu.h" #include "xenia/base/assert.h" +#include "xenia/base/clock.h" #include "xenia/base/string.h" #include "xenia/cpu/cpu.h" #include "xenia/gpu/gpu.h" @@ -22,6 +25,9 @@ #include "xenia/memory.h" #include "xenia/ui/main_window.h" +DEFINE_double(time_scalar, 1.0, + "Scalar used to speed or slow time (1x, 2x, 1/2x, etc)."); + namespace xe { using namespace xe::apu; @@ -64,6 +70,16 @@ Emulator::~Emulator() { X_STATUS Emulator::Setup() { X_STATUS result = X_STATUS_UNSUCCESSFUL; + // Initialize clock. + // 360 uses a 50MHz clock. + // Clock::set_guest_tick_frequency(50000000); + // We could reset this with save state data/constant value to help replays. + Clock::set_guest_system_time_base(Clock::QueryHostSystemTime()); + // This can be adjusted dynamically, as well. + Clock::set_guest_time_scalar(FLAGS_time_scalar); + + // Before we can set thread affinity we must enable the process to use all + // logical processors. HANDLE process_handle = GetCurrentProcess(); DWORD_PTR process_affinity_mask; DWORD_PTR system_affinity_mask; diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 84eb3788a..c4bea0187 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -59,7 +59,6 @@ CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system) trace_state_(TraceState::kDisabled), worker_running_(true), swap_mode_(SwapMode::kNormal), - time_base_(0), counter_(0), primary_buffer_ptr_(0), primary_buffer_size_(0), @@ -83,19 +82,10 @@ CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system) draw_index_count_(0), draw_batcher_(graphics_system_->register_file()), scratch_buffer_(kScratchBufferCapacity, kScratchBufferAlignment) { - LARGE_INTEGER perf_counter; - QueryPerformanceCounter(&perf_counter); - time_base_ = perf_counter.QuadPart; } CommandProcessor::~CommandProcessor() { CloseHandle(write_ptr_index_event_); } -uint64_t CommandProcessor::QueryTime() { - LARGE_INTEGER perf_counter; - QueryPerformanceCounter(&perf_counter); - return perf_counter.QuadPart - time_base_; -} - bool CommandProcessor::Initialize(std::unique_ptr context) { context_ = std::move(context); diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 2f1b782cc..780244cb6 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -62,7 +62,6 @@ class CommandProcessor { typedef std::function SwapHandler; void set_swap_handler(SwapHandler fn) { swap_handler_ = fn; } - uint64_t QueryTime(); uint32_t counter() const { return counter_; } void increment_counter() { counter_++; } @@ -243,7 +242,6 @@ class CommandProcessor { SwapMode swap_mode_; - uint64_t time_base_; uint32_t counter_; uint32_t primary_buffer_ptr_; diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index 072a2aa23..1ab109e10 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -9,6 +9,7 @@ #include "xenia/gpu/gl4/gl4_graphics_system.h" +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/threading.h" #include "xenia/cpu/processor.h" @@ -86,11 +87,11 @@ X_STATUS GL4GraphicsSystem::Setup(cpu::Processor* processor, kernel::object_ref(new kernel::XHostThread( emulator()->kernel_state(), 128 * 1024, 0, [this]() { uint64_t vsync_duration = FLAGS_vsync ? 16 : 1; - uint64_t last_frame_time = xe::threading::ticks(); + uint64_t last_frame_time = Clock::QueryGuestTickCount(); while (worker_running_) { - uint64_t current_time = xe::threading::ticks(); + uint64_t current_time = Clock::QueryGuestTickCount(); uint64_t elapsed = (current_time - last_frame_time) / - (xe::threading::ticks_per_second() / 1000); + (Clock::guest_tick_frequency() / 1000); if (elapsed >= vsync_duration) { MarkVblank(); last_frame_time = current_time; diff --git a/src/xenia/gpu/xe-gpu-trace-viewer.cc b/src/xenia/gpu/xe-gpu-trace-viewer.cc index 5ca724c4d..9c5c06d79 100644 --- a/src/xenia/gpu/xe-gpu-trace-viewer.cc +++ b/src/xenia/gpu/xe-gpu-trace-viewer.cc @@ -11,6 +11,7 @@ #include "third_party/imgui/imgui.h" +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/main.h" #include "xenia/base/mapped_memory.h" @@ -2272,10 +2273,10 @@ int trace_viewer_main(std::vector& args) { imgui_setup = true; } auto& io = ImGui::GetIO(); - auto current_ticks = xe::threading::ticks(); + auto current_ticks = Clock::QueryHostTickCount(); static uint64_t last_ticks = 0; - io.DeltaTime = (current_ticks - last_ticks) / - float(xe::threading::ticks_per_second()); + io.DeltaTime = + (current_ticks - last_ticks) / float(Clock::host_tick_frequency()); last_ticks = current_ticks; io.DisplaySize = diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index a38fe5fb7..6eb162f75 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -11,6 +11,7 @@ #include +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/math.h" #include "xenia/base/mutex.h" @@ -236,10 +237,7 @@ X_STATUS XThread::Create() { xe::store_and_swap(p + 0x09C, 0xFDFFD7FF); xe::store_and_swap( p + 0x0D0, thread_state_->stack_address() + thread_state_->stack_size()); - FILETIME t; - GetSystemTimeAsFileTime(&t); - xe::store_and_swap( - p + 0x130, ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime); + xe::store_and_swap(p + 0x130, Clock::QueryGuestSystemTime()); xe::store_and_swap(p + 0x144, thread_state_address_ + 0x144); xe::store_and_swap(p + 0x148, thread_state_address_ + 0x144); xe::store_and_swap(p + 0x14C, thread_id_); @@ -621,6 +619,7 @@ X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable, } else { timeout_ms = 0; } + timeout_ms = Clock::ScaleGuestDurationMillis(timeout_ms); DWORD result = SleepEx(timeout_ms, alertable ? TRUE : FALSE); switch (result) { case 0: diff --git a/src/xenia/kernel/objects/xtimer.cc b/src/xenia/kernel/objects/xtimer.cc index f96680fc1..fdab85f73 100644 --- a/src/xenia/kernel/objects/xtimer.cc +++ b/src/xenia/kernel/objects/xtimer.cc @@ -9,6 +9,7 @@ #include "xenia/kernel/objects/xtimer.h" +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/cpu/processor.h" @@ -49,6 +50,9 @@ X_STATUS XTimer::SetTimer(int64_t due_time, uint32_t period_ms, current_routine_ = routine; current_routine_arg_ = routine_arg; + due_time = Clock::ScaleGuestDurationFileTime(due_time); + period_ms = Clock::ScaleGuestDurationMillis(period_ms); + LARGE_INTEGER due_time_li; due_time_li.QuadPart = due_time; BOOL result = diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index 3c8e50fd5..8f3df0ada 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -10,6 +10,7 @@ #define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr #include +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/util/shim_utils.h" @@ -373,6 +374,7 @@ SHIM_CALL NetDll_select_shim(PPCContext* ppc_state, KernelState* state) { if (timeout_ptr) { timeout = {static_cast(SHIM_MEM_32(timeout_ptr + 0)), static_cast(SHIM_MEM_32(timeout_ptr + 4))}; + Clock::ScaleGuestDurationTimeval(&timeout.tv_sec, &timeout.tv_usec); timeout_in = &timeout; } int ret = select(nfds, readfds_ptr ? &readfds : nullptr, diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index b42ff95f8..5fcea5ac1 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -11,6 +11,7 @@ #include +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/math.h" #include "xenia/emulator.h" @@ -133,13 +134,15 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) "xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle); xe::store_and_swap(lpKeTimeStampBundle + 0, 0); xe::store_and_swap(lpKeTimeStampBundle + 8, 0); - xe::store_and_swap(lpKeTimeStampBundle + 16, GetTickCount()); + xe::store_and_swap(lpKeTimeStampBundle + 16, + Clock::QueryGuestUptimeMillis()); xe::store_and_swap(lpKeTimeStampBundle + 20, 0); CreateTimerQueueTimer( ×tamp_timer_, nullptr, [](PVOID param, BOOLEAN timer_or_wait_fired) { auto timestamp_bundle = reinterpret_cast(param); - xe::store_and_swap(timestamp_bundle + 16, GetTickCount()); + xe::store_and_swap(timestamp_bundle + 16, + Clock::QueryGuestUptimeMillis()); }, lpKeTimeStampBundle, 0, 1, // 1ms diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 0246833e4..71ec69721 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -8,6 +8,7 @@ */ #include "xenia/base/atomic.h" +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/mutex.h" #include "xenia/cpu/processor.h" @@ -312,13 +313,7 @@ SHIM_CALL KeQueryPerformanceFrequency_shim(PPCContext* ppc_state, // XELOGD( // "KeQueryPerformanceFrequency()"); - // TODO(benvanik): return fixed 50000000? - - uint64_t result = 0; - LARGE_INTEGER frequency; - if (QueryPerformanceFrequency(&frequency)) { - result = frequency.QuadPart; - } + uint64_t result = Clock::guest_tick_frequency(); SHIM_SET_RETURN_64(result); } @@ -351,9 +346,7 @@ SHIM_CALL KeQuerySystemTime_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("KeQuerySystemTime(%.8X)", time_ptr); - FILETIME t; - GetSystemTimeAsFileTime(&t); - uint64_t time = ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime; + uint64_t time = Clock::QueryGuestSystemTime(); if (time_ptr) { SHIM_SET_MEM_64(time_ptr, time); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index e6a7c69d9..1f6ad8d7a 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -9,6 +9,7 @@ #include "xenia/kernel/xobject.h" +#include "xenia/base/clock.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/objects/xevent.h" #include "xenia/kernel/objects/xmutant.h" @@ -109,6 +110,7 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode, } DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE; + timeout_ms = Clock::ScaleGuestDurationMillis(timeout_ms); DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable); switch (result) { @@ -131,6 +133,7 @@ X_STATUS XObject::SignalAndWait(XObject* signal_object, XObject* wait_object, uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout) { DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE; + timeout_ms = Clock::ScaleGuestDurationMillis(timeout_ms); DWORD result = SignalObjectAndWait(signal_object->GetWaitHandle(), wait_object->GetWaitHandle(), timeout_ms, @@ -150,6 +153,7 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects, } DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE; + timeout_ms = Clock::ScaleGuestDurationMillis(timeout_ms); DWORD result = WaitForMultipleObjectsEx( count, wait_handles, wait_type ? FALSE : TRUE, timeout_ms, alertable); diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index dc6c7e133..5a74f7649 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -14,6 +14,7 @@ #include #include +#include "xenia/base/clock.h" #include "xenia/base/logging.h" #include "xenia/base/math.h" #include "xenia/base/threading.h" @@ -114,7 +115,7 @@ Memory::~Memory() { int Memory::Initialize() { wchar_t file_name[256]; - wsprintf(file_name, L"Local\\xenia_memory_%p", xe::threading::ticks()); + wsprintf(file_name, L"Local\\xenia_memory_%p", Clock::QueryHostTickCount()); file_name_ = file_name; // Create main page file-backed mapping. This is all reserved but