Timers were wrong. Fixing.
This commit is contained in:
parent
5a4f738a37
commit
73200ff0bc
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include <xenia/kernel/objects/xtimer.h>
|
#include <xenia/kernel/objects/xtimer.h>
|
||||||
|
|
||||||
|
#include <xenia/cpu/processor.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
|
@ -44,14 +46,36 @@ void XTimer::Initialize(uint32_t timer_type) {
|
||||||
handle_ = CreateWaitableTimer(NULL, manual_reset, NULL);
|
handle_ = CreateWaitableTimer(NULL, manual_reset, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XTimer::SetTimer(int64_t due_time, uint32_t period_ms) {
|
X_STATUS XTimer::SetTimer(
|
||||||
|
int64_t due_time, uint32_t period_ms,
|
||||||
|
uint32_t routine, uint32_t routine_arg, bool resume) {
|
||||||
|
// Stash routine for callback.
|
||||||
|
current_routine_ = routine;
|
||||||
|
current_routine_arg_ = routine_arg;
|
||||||
|
|
||||||
LARGE_INTEGER due_time_li;
|
LARGE_INTEGER due_time_li;
|
||||||
due_time_li.QuadPart = due_time;
|
due_time_li.QuadPart = due_time;
|
||||||
if (SetWaitableTimer(handle_, &due_time_li, period_ms, NULL, NULL, TRUE)) {
|
BOOL result = SetWaitableTimer(
|
||||||
return X_STATUS_SUCCESS;
|
handle_, &due_time_li, period_ms,
|
||||||
} else {
|
routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL, this,
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
resume ? TRUE : FALSE);
|
||||||
|
|
||||||
|
// Caller is checking for STATUS_TIMER_RESUME_IGNORED.
|
||||||
|
// This occurs if result == TRUE but error is set.
|
||||||
|
if (!result && GetLastError() == ERROR_NOT_SUPPORTED) {
|
||||||
|
return X_STATUS_TIMER_RESUME_IGNORED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XTimer::CompletionRoutine(
|
||||||
|
XTimer* timer, DWORD timer_low, DWORD timer_high) {
|
||||||
|
XEASSERT(timer->current_routine_);
|
||||||
|
|
||||||
|
// Queue APC to call back routine with (arg, low, high).
|
||||||
|
// TODO(benvanik): APC dispatch.
|
||||||
|
XELOGE("Timer needs APC!");
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XTimer::Cancel() {
|
X_STATUS XTimer::Cancel() {
|
||||||
|
|
|
@ -27,13 +27,20 @@ public:
|
||||||
void Initialize(uint32_t timer_type);
|
void Initialize(uint32_t timer_type);
|
||||||
|
|
||||||
// completion routine, arg to completion routine
|
// completion routine, arg to completion routine
|
||||||
X_STATUS SetTimer(int64_t due_time, uint32_t period_ms);
|
X_STATUS SetTimer(int64_t due_time, uint32_t period_ms,
|
||||||
|
uint32_t routine, uint32_t routine_arg, bool resume);
|
||||||
X_STATUS Cancel();
|
X_STATUS Cancel();
|
||||||
|
|
||||||
virtual void* GetWaitHandle() { return handle_; }
|
virtual void* GetWaitHandle() { return handle_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE handle_;
|
HANDLE handle_;
|
||||||
|
|
||||||
|
uint32_t current_routine_;
|
||||||
|
uint32_t current_routine_arg_;
|
||||||
|
|
||||||
|
static void CompletionRoutine(
|
||||||
|
XTimer* timer, DWORD timer_low, DWORD timer_high);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ SHIM_CALL RtlRaiseException_shim(
|
||||||
|
|
||||||
// TODO(benvanik): unwinding.
|
// TODO(benvanik): unwinding.
|
||||||
// This is going to suck.
|
// This is going to suck.
|
||||||
XEASSERTALWAYS();
|
DebugBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -977,24 +977,23 @@ SHIM_CALL NtCreateTimer_shim(
|
||||||
SHIM_CALL NtSetTimerEx_shim(
|
SHIM_CALL NtSetTimerEx_shim(
|
||||||
PPCContext* ppc_state, KernelState* state) {
|
PPCContext* ppc_state, KernelState* state) {
|
||||||
uint32_t timer_handle = SHIM_GET_ARG_32(0);
|
uint32_t timer_handle = SHIM_GET_ARG_32(0);
|
||||||
uint32_t info_class = SHIM_GET_ARG_32(1);
|
uint32_t due_time_ptr = SHIM_GET_ARG_32(1);
|
||||||
uint32_t info_ptr = SHIM_GET_ARG_32(2);
|
uint32_t routine = SHIM_GET_ARG_32(2); // PTIMERAPCROUTINE
|
||||||
uint32_t info_length = SHIM_GET_ARG_32(3);
|
uint32_t unk_one = SHIM_GET_ARG_32(3);
|
||||||
|
uint32_t routine_arg = SHIM_GET_ARG_32(4);
|
||||||
|
uint32_t resume = SHIM_GET_ARG_32(5);
|
||||||
|
uint32_t period_ms = SHIM_GET_ARG_32(6);
|
||||||
|
uint32_t unk_zero = SHIM_GET_ARG_32(7);
|
||||||
|
|
||||||
// UNVERIFIED
|
XEASSERT(unk_one == 1);
|
||||||
XEASSERTALWAYS();
|
XEASSERT(unk_zero == 0);
|
||||||
|
|
||||||
|
uint64_t due_time = SHIM_MEM_64(due_time_ptr);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtSetTimerEx(%.8X, %.8X, %.8X, %d)",
|
"NtSetTimerEx(%.8X, %.8X(%lld), %.8X, %.8X, %.8X, %.1X, %d, %.8X)",
|
||||||
timer_handle, info_class, info_ptr, info_length);
|
timer_handle, due_time_ptr, due_time, routine, unk_one,
|
||||||
|
routine_arg, resume, period_ms, unk_zero);
|
||||||
// TIMER_BASIC_INFORMATION
|
|
||||||
XEASSERT(info_class == 0);
|
|
||||||
XEASSERT(info_length == 12);
|
|
||||||
|
|
||||||
uint64_t due_time = SHIM_MEM_64(info_ptr + 0);
|
|
||||||
uint32_t timer_state = SHIM_MEM_32(info_ptr + 8); // unused?
|
|
||||||
uint32_t period_ms = 0; // Not repeating.
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -1002,7 +1001,8 @@ SHIM_CALL NtSetTimerEx_shim(
|
||||||
result = state->object_table()->GetObject(
|
result = state->object_table()->GetObject(
|
||||||
timer_handle, (XObject**)&timer);
|
timer_handle, (XObject**)&timer);
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
result = timer->SetTimer(due_time, period_ms);
|
result = timer->SetTimer(
|
||||||
|
due_time, period_ms, routine, routine_arg, resume ? true : false);
|
||||||
timer->Release();
|
timer->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1016,7 +1016,7 @@ SHIM_CALL NtCancelTimer_shim(
|
||||||
uint32_t current_state_ptr = SHIM_GET_ARG_32(1);
|
uint32_t current_state_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
// UNVERIFIED
|
// UNVERIFIED
|
||||||
XEASSERTALWAYS();
|
DebugBreak();
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtCancelTimer(%.8X, %.8X)",
|
"NtCancelTimer(%.8X, %.8X)",
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef uint32_t X_STATUS;
|
||||||
#define X_STATUS_ALERTED ((X_STATUS)0x00000101L)
|
#define X_STATUS_ALERTED ((X_STATUS)0x00000101L)
|
||||||
#define X_STATUS_TIMEOUT ((X_STATUS)0x00000102L)
|
#define X_STATUS_TIMEOUT ((X_STATUS)0x00000102L)
|
||||||
#define X_STATUS_PENDING ((X_STATUS)0x00000103L)
|
#define X_STATUS_PENDING ((X_STATUS)0x00000103L)
|
||||||
|
#define X_STATUS_TIMER_RESUME_IGNORED ((X_STATUS)0x40000025L)
|
||||||
#define X_STATUS_UNSUCCESSFUL ((X_STATUS)0xC0000001L)
|
#define X_STATUS_UNSUCCESSFUL ((X_STATUS)0xC0000001L)
|
||||||
#define X_STATUS_NOT_IMPLEMENTED ((X_STATUS)0xC0000002L)
|
#define X_STATUS_NOT_IMPLEMENTED ((X_STATUS)0xC0000002L)
|
||||||
#define X_STATUS_INFO_LENGTH_MISMATCH ((X_STATUS)0xC0000004L)
|
#define X_STATUS_INFO_LENGTH_MISMATCH ((X_STATUS)0xC0000004L)
|
||||||
|
|
Loading…
Reference in New Issue