From 372fd97821e2877c979c851aa70bf19d10947596 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 5 Jan 2014 01:22:08 -0800 Subject: [PATCH] Moving Wait() to XObject base. --- src/xenia/kernel/objects/xevent.cc | 36 ------------------ src/xenia/kernel/objects/xevent.h | 3 +- src/xenia/kernel/objects/xfile.cc | 7 +--- src/xenia/kernel/objects/xfile.h | 5 +-- src/xenia/kernel/objects/xnotify_listener.cc | 37 ------------------- src/xenia/kernel/objects/xnotify_listener.h | 3 +- src/xenia/kernel/objects/xsemaphore.cc | 37 ------------------- src/xenia/kernel/objects/xsemaphore.h | 3 +- src/xenia/kernel/objects/xthread.cc | 9 ++--- src/xenia/kernel/objects/xthread.h | 5 +-- src/xenia/kernel/xobject.cc | 39 +++++++++++++++++++- src/xenia/kernel/xobject.h | 7 +++- 12 files changed, 56 insertions(+), 135 deletions(-) diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index 6d8997fc4..cf1242a8d 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -63,39 +63,3 @@ int32_t XEvent::Reset() { void XEvent::Clear() { ResetEvent(handle_); } - -X_STATUS XEvent::Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - DWORD timeout_ms; - if (opt_timeout) { - int64_t timeout_ticks = (int64_t)(*opt_timeout); - if (timeout_ticks > 0) { - // Absolute time, based on January 1, 1601. - // TODO(benvanik): convert time to relative time. - XEASSERTALWAYS(); - timeout_ms = 0; - } else if (timeout_ticks < 0) { - // Relative time. - timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS - } else { - timeout_ms = 0; - } - } else { - timeout_ms = INFINITE; - } - - DWORD result = WaitForSingleObjectEx(handle_, timeout_ms, alertable); - switch (result) { - case WAIT_OBJECT_0: - return X_STATUS_SUCCESS; - case WAIT_IO_COMPLETION: - // Or X_STATUS_ALERTED? - return X_STATUS_USER_APC; - case WAIT_TIMEOUT: - return X_STATUS_TIMEOUT; - default: - case WAIT_FAILED: - case WAIT_ABANDONED: - return X_STATUS_ABANDONED_WAIT_0; - } -} diff --git a/src/xenia/kernel/objects/xevent.h b/src/xenia/kernel/objects/xevent.h index c8401e4e8..f9c7fea44 100644 --- a/src/xenia/kernel/objects/xevent.h +++ b/src/xenia/kernel/objects/xevent.h @@ -31,8 +31,7 @@ public: int32_t Reset(); void Clear(); - virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); + virtual void* GetWaitHandle() { return handle_; } private: HANDLE handle_; diff --git a/src/xenia/kernel/objects/xfile.cc b/src/xenia/kernel/objects/xfile.cc index 6b07529d7..4a9df78e3 100644 --- a/src/xenia/kernel/objects/xfile.cc +++ b/src/xenia/kernel/objects/xfile.cc @@ -30,11 +30,8 @@ XFile::~XFile() { async_event_->Delete(); } -X_STATUS XFile::Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - // Wait until some async operation completes. - return async_event_->Wait( - wait_reason, processor_mode, alertable, opt_timeout); +void* XFile::GetWaitHandle() { + return async_event_->GetWaitHandle(); } X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset, diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index 6a00cbf6d..49743a6ff 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -52,9 +52,6 @@ public: size_t position() const { return position_; } void set_position(size_t value) { position_ = value; } - virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); - virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0; X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset, @@ -62,6 +59,8 @@ public: X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset, XAsyncRequest* request); + virtual void* GetWaitHandle(); + protected: XFile(KernelState* kernel_state, uint32_t desired_access); virtual X_STATUS ReadSync( diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index afc8d7e71..b9d45dafb 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -86,40 +86,3 @@ bool XNotifyListener::DequeueNotification( xe_mutex_unlock(lock_); return dequeued; } - -// TODO(benvanik): move this to common class -X_STATUS XNotifyListener::Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - DWORD timeout_ms; - if (opt_timeout) { - int64_t timeout_ticks = (int64_t)(*opt_timeout); - if (timeout_ticks > 0) { - // Absolute time, based on January 1, 1601. - // TODO(benvanik): convert time to relative time. - XEASSERTALWAYS(); - timeout_ms = 0; - } else if (timeout_ticks < 0) { - // Relative time. - timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS - } else { - timeout_ms = 0; - } - } else { - timeout_ms = INFINITE; - } - - DWORD result = WaitForSingleObjectEx(wait_handle_, timeout_ms, alertable); - switch (result) { - case WAIT_OBJECT_0: - return X_STATUS_SUCCESS; - case WAIT_IO_COMPLETION: - // Or X_STATUS_ALERTED? - return X_STATUS_USER_APC; - case WAIT_TIMEOUT: - return X_STATUS_TIMEOUT; - default: - case WAIT_FAILED: - case WAIT_ABANDONED: - return X_STATUS_ABANDONED_WAIT_0; - } -} diff --git a/src/xenia/kernel/objects/xnotify_listener.h b/src/xenia/kernel/objects/xnotify_listener.h index f5248c5fd..a7aa16eee 100644 --- a/src/xenia/kernel/objects/xnotify_listener.h +++ b/src/xenia/kernel/objects/xnotify_listener.h @@ -36,8 +36,7 @@ public: bool DequeueNotification(XNotificationID* out_id, uint32_t* out_data); bool DequeueNotification(XNotificationID id, uint32_t* out_data); - virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); + virtual void* GetWaitHandle() { return wait_handle_; } private: HANDLE wait_handle_; diff --git a/src/xenia/kernel/objects/xsemaphore.cc b/src/xenia/kernel/objects/xsemaphore.cc index 1f22f5c7d..642a88181 100644 --- a/src/xenia/kernel/objects/xsemaphore.cc +++ b/src/xenia/kernel/objects/xsemaphore.cc @@ -43,40 +43,3 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_count) { ::ReleaseSemaphore(handle_, release_count, &previous_count); return previous_count; } - -X_STATUS XSemaphore::Wait( - uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - DWORD timeout_ms; - if (opt_timeout) { - int64_t timeout_ticks = (int64_t)(*opt_timeout); - if (timeout_ticks > 0) { - // Absolute time, based on January 1, 1601. - // TODO(benvanik): convert time to relative time. - XEASSERTALWAYS(); - timeout_ms = 0; - } else if (timeout_ticks < 0) { - // Relative time. - timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS - } else { - timeout_ms = 0; - } - } else { - timeout_ms = INFINITE; - } - - DWORD result = WaitForSingleObjectEx(handle_, timeout_ms, alertable); - switch (result) { - case WAIT_OBJECT_0: - return X_STATUS_SUCCESS; - case WAIT_IO_COMPLETION: - // Or X_STATUS_ALERTED? - return X_STATUS_USER_APC; - case WAIT_TIMEOUT: - return X_STATUS_TIMEOUT; - default: - case WAIT_FAILED: - case WAIT_ABANDONED: - return X_STATUS_ABANDONED_WAIT_0; - } -} diff --git a/src/xenia/kernel/objects/xsemaphore.h b/src/xenia/kernel/objects/xsemaphore.h index 397eb1764..1d58d1de1 100644 --- a/src/xenia/kernel/objects/xsemaphore.h +++ b/src/xenia/kernel/objects/xsemaphore.h @@ -29,8 +29,7 @@ public: int32_t ReleaseSemaphore(int32_t release_count); - virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); + virtual void* GetWaitHandle() { return handle_; } private: HANDLE handle_; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 8901d85c7..f0539b4eb 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -324,11 +324,6 @@ void XThread::Execute() { } } -X_STATUS XThread::Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - return event_->Wait(wait_reason, processor_mode, alertable, opt_timeout); -} - void XThread::EnterCriticalRegion() { // Global critical region. This isn't right, but is easy. xe_mutex_lock(critical_region_); @@ -383,3 +378,7 @@ X_STATUS XThread::Delay( return X_STATUS_ALERTED; } } + +void* XThread::GetWaitHandle() { + return event_->GetWaitHandle(); +} diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 05fc13783..a5c160666 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -52,9 +52,6 @@ public: void Execute(); - virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); - static void EnterCriticalRegion(); static void LeaveCriticalRegion(); uint32_t RaiseIrql(uint32_t new_irql); @@ -64,6 +61,8 @@ public: X_STATUS Delay( uint32_t processor_mode, uint32_t alertable, uint64_t interval); + virtual void* GetWaitHandle(); + private: X_STATUS PlatformCreate(); void PlatformDestroy(); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 5c8868404..f659cbe72 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -72,7 +72,44 @@ X_STATUS XObject::Delete() { X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout) { - return X_STATUS_SUCCESS; + void* wait_handle = GetWaitHandle(); + if (!wait_handle) { + // Object doesn't support waiting. + return X_STATUS_SUCCESS; + } + + DWORD timeout_ms; + if (opt_timeout) { + int64_t timeout_ticks = (int64_t)(*opt_timeout); + if (timeout_ticks > 0) { + // Absolute time, based on January 1, 1601. + // TODO(benvanik): convert time to relative time. + XEASSERTALWAYS(); + timeout_ms = 0; + } else if (timeout_ticks < 0) { + // Relative time. + timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS + } else { + timeout_ms = 0; + } + } else { + timeout_ms = INFINITE; + } + + DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable); + switch (result) { + case WAIT_OBJECT_0: + return X_STATUS_SUCCESS; + case WAIT_IO_COMPLETION: + // Or X_STATUS_ALERTED? + return X_STATUS_USER_APC; + case WAIT_TIMEOUT: + return X_STATUS_TIMEOUT; + default: + case WAIT_FAILED: + case WAIT_ABANDONED: + return X_STATUS_ABANDONED_WAIT_0; + } } void XObject::LockType() { diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 8660fcc0c..b4731bb0f 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -57,14 +57,17 @@ public: // Reference() // Dereference() - virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); + X_STATUS Wait( + uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout); static void LockType(); static void UnlockType(); static XObject* GetObject(KernelState* kernel_state, void* native_ptr, int32_t as_type = -1); + virtual void* GetWaitHandle() { return 0; } + protected: Memory* memory() const; void SetNativePointer(uint32_t native_ptr);