Refactoring to enable future time scaling, coordinated clocks, etc.

This commit is contained in:
Ben Vanik
2015-05-26 22:20:46 -07:00
parent 05f2577fb7
commit 8244409501
19 changed files with 213 additions and 57 deletions

View File

@@ -11,6 +11,7 @@
#include <gflags/gflags.h>
#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<uint32_t>(p + 0x09C, 0xFDFFD7FF);
xe::store_and_swap<uint32_t>(
p + 0x0D0, thread_state_->stack_address() + thread_state_->stack_size());
FILETIME t;
GetSystemTimeAsFileTime(&t);
xe::store_and_swap<uint64_t>(
p + 0x130, ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime);
xe::store_and_swap<uint64_t>(p + 0x130, Clock::QueryGuestSystemTime());
xe::store_and_swap<uint32_t>(p + 0x144, thread_state_address_ + 0x144);
xe::store_and_swap<uint32_t>(p + 0x148, thread_state_address_ + 0x144);
xe::store_and_swap<uint32_t>(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:

View File

@@ -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 =

View File

@@ -10,6 +10,7 @@
#define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr
#include <winsock2.h>
#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<long>(SHIM_MEM_32(timeout_ptr + 0)),
static_cast<long>(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,

View File

@@ -11,6 +11,7 @@
#include <gflags/gflags.h>
#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<uint64_t>(lpKeTimeStampBundle + 0, 0);
xe::store_and_swap<uint64_t>(lpKeTimeStampBundle + 8, 0);
xe::store_and_swap<uint32_t>(lpKeTimeStampBundle + 16, GetTickCount());
xe::store_and_swap<uint32_t>(lpKeTimeStampBundle + 16,
Clock::QueryGuestUptimeMillis());
xe::store_and_swap<uint32_t>(lpKeTimeStampBundle + 20, 0);
CreateTimerQueueTimer(
&timestamp_timer_, nullptr,
[](PVOID param, BOOLEAN timer_or_wait_fired) {
auto timestamp_bundle = reinterpret_cast<uint8_t*>(param);
xe::store_and_swap<uint32_t>(timestamp_bundle + 16, GetTickCount());
xe::store_and_swap<uint32_t>(timestamp_bundle + 16,
Clock::QueryGuestUptimeMillis());
},
lpKeTimeStampBundle, 0,
1, // 1ms

View File

@@ -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);

View File

@@ -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);