Timers were wrong. Fixing.

This commit is contained in:
Ben Vanik
2014-01-07 22:47:35 -08:00
parent 5a4f738a37
commit 73200ff0bc
5 changed files with 56 additions and 24 deletions

View File

@@ -9,6 +9,8 @@
#include <xenia/kernel/objects/xtimer.h>
#include <xenia/cpu/processor.h>
using namespace xe;
using namespace xe::kernel;
@@ -44,14 +46,36 @@ void XTimer::Initialize(uint32_t timer_type) {
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;
due_time_li.QuadPart = due_time;
if (SetWaitableTimer(handle_, &due_time_li, period_ms, NULL, NULL, TRUE)) {
return X_STATUS_SUCCESS;
} else {
return X_STATUS_UNSUCCESSFUL;
BOOL result = SetWaitableTimer(
handle_, &due_time_li, period_ms,
routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL, this,
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() {

View File

@@ -27,13 +27,20 @@ public:
void Initialize(uint32_t timer_type);
// 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();
virtual void* GetWaitHandle() { return handle_; }
private:
HANDLE handle_;
uint32_t current_routine_;
uint32_t current_routine_arg_;
static void CompletionRoutine(
XTimer* timer, DWORD timer_low, DWORD timer_high);
};