os: refactor/rewrite entire namespace.
This commit is contained in:
@@ -15,21 +15,19 @@
|
||||
*/
|
||||
#include "os_waitable_manager_impl.hpp"
|
||||
#include "os_waitable_object_list.hpp"
|
||||
#include "os_tick_manager.hpp"
|
||||
|
||||
namespace ams::os::impl{
|
||||
|
||||
WaitableHolderBase *WaitableManagerImpl::WaitAnyImpl(bool infinite, u64 timeout) {
|
||||
/* Set processing thread handle while in scope. */
|
||||
this->waiting_thread_handle = threadGetCurHandle();
|
||||
ON_SCOPE_EXIT { this->waiting_thread_handle = INVALID_HANDLE; };
|
||||
namespace ams::os::impl {
|
||||
|
||||
WaitableHolderBase *WaitableManagerImpl::WaitAnyImpl(bool infinite, TimeSpan timeout) {
|
||||
/* Prepare for processing. */
|
||||
this->signaled_holder = nullptr;
|
||||
this->target_impl.SetCurrentThreadHandleForCancelWait();
|
||||
WaitableHolderBase *result = this->LinkHoldersToObjectList();
|
||||
|
||||
/* Check if we've been signaled. */
|
||||
{
|
||||
std::scoped_lock lk(this->lock);
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
if (this->signaled_holder != nullptr) {
|
||||
result = this->signaled_holder;
|
||||
}
|
||||
@@ -43,36 +41,42 @@ namespace ams::os::impl{
|
||||
/* Unlink holders from the current object list. */
|
||||
this->UnlinkHoldersFromObjectList();
|
||||
|
||||
this->target_impl.ClearCurrentThreadHandleForCancelWait();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WaitableHolderBase *WaitableManagerImpl::WaitAnyHandleImpl(bool infinite, u64 timeout) {
|
||||
WaitableHolderBase *WaitableManagerImpl::WaitAnyHandleImpl(bool infinite, TimeSpan timeout) {
|
||||
Handle object_handles[MaximumHandleCount];
|
||||
WaitableHolderBase *objects[MaximumHandleCount];
|
||||
|
||||
const size_t count = this->BuildHandleArray(object_handles, objects);
|
||||
const u64 end_time = infinite ? std::numeric_limits<u64>::max() : armTicksToNs(armGetSystemTick());
|
||||
const s32 count = this->BuildHandleArray(object_handles, objects, MaximumHandleCount);
|
||||
const TimeSpan end_time = infinite ? TimeSpan::FromNanoSeconds(std::numeric_limits<s64>::max()) : GetCurrentTick().ToTimeSpan() + timeout;
|
||||
|
||||
while (true) {
|
||||
this->current_time = armTicksToNs(armGetSystemTick());
|
||||
this->current_time = GetCurrentTick().ToTimeSpan();
|
||||
|
||||
u64 min_timeout = 0;
|
||||
TimeSpan min_timeout = 0;
|
||||
WaitableHolderBase *min_timeout_object = this->RecalculateNextTimeout(&min_timeout, end_time);
|
||||
|
||||
s32 index;
|
||||
if (count == 0 && min_timeout == 0) {
|
||||
index = WaitTimedOut;
|
||||
if (infinite && min_timeout_object == nullptr) {
|
||||
index = this->target_impl.WaitAny(object_handles, MaximumHandleCount, count);
|
||||
} else {
|
||||
index = this->WaitSynchronization(object_handles, count, min_timeout);
|
||||
AMS_ABORT_UNLESS(index != WaitInvalid);
|
||||
if (count == 0 && min_timeout == 0) {
|
||||
index = WaitTimedOut;
|
||||
} else {
|
||||
index = this->target_impl.TimedWaitAny(object_handles, MaximumHandleCount, count, min_timeout);
|
||||
AMS_ABORT_UNLESS(index != WaitInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case WaitTimedOut:
|
||||
if (min_timeout_object) {
|
||||
this->current_time = armTicksToNs(armGetSystemTick());
|
||||
this->current_time = GetCurrentTick().ToTimeSpan();
|
||||
if (min_timeout_object->IsSignaled() == TriBool::True) {
|
||||
std::scoped_lock lk(this->lock);
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
this->signaled_holder = min_timeout_object;
|
||||
return this->signaled_holder;
|
||||
}
|
||||
@@ -86,7 +90,7 @@ namespace ams::os::impl{
|
||||
continue;
|
||||
default: /* 0 - 0x3F, valid. */
|
||||
{
|
||||
std::scoped_lock lk(this->lock);
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
this->signaled_holder = objects[index];
|
||||
return this->signaled_holder;
|
||||
}
|
||||
@@ -94,28 +98,12 @@ namespace ams::os::impl{
|
||||
}
|
||||
}
|
||||
|
||||
s32 WaitableManagerImpl::WaitSynchronization(Handle *handles, size_t count, u64 timeout) {
|
||||
s32 index = WaitInvalid;
|
||||
|
||||
R_TRY_CATCH(svcWaitSynchronization(&index, handles, count, timeout)) {
|
||||
R_CATCH(svc::ResultTimedOut) { return WaitTimedOut; }
|
||||
R_CATCH(svc::ResultCancelled) { return WaitCancelled; }
|
||||
/* All other results are critical errors. */
|
||||
/* svc::ResultThreadTerminating */
|
||||
/* svc::ResultInvalidHandle. */
|
||||
/* svc::ResultInvalidPointer */
|
||||
/* svc::ResultOutOfRange */
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
size_t WaitableManagerImpl::BuildHandleArray(Handle *out_handles, WaitableHolderBase **out_objects) {
|
||||
size_t count = 0;
|
||||
s32 WaitableManagerImpl::BuildHandleArray(Handle out_handles[], WaitableHolderBase *out_objects[], s32 num) {
|
||||
s32 count = 0;
|
||||
|
||||
for (WaitableHolderBase &holder_base : this->waitable_list) {
|
||||
if (Handle handle = holder_base.GetHandle(); handle != INVALID_HANDLE) {
|
||||
AMS_ABORT_UNLESS(count < MaximumHandleCount);
|
||||
if (Handle handle = holder_base.GetHandle(); handle != svc::InvalidHandle) {
|
||||
AMS_ASSERT(count < num);
|
||||
|
||||
out_handles[count] = handle;
|
||||
out_objects[count] = &holder_base;
|
||||
@@ -146,12 +134,12 @@ namespace ams::os::impl{
|
||||
}
|
||||
}
|
||||
|
||||
WaitableHolderBase *WaitableManagerImpl::RecalculateNextTimeout(u64 *out_min_timeout, u64 end_time) {
|
||||
WaitableHolderBase *WaitableManagerImpl::RecalculateNextTimeout(TimeSpan *out_min_timeout, TimeSpan end_time) {
|
||||
WaitableHolderBase *min_timeout_holder = nullptr;
|
||||
u64 min_time = end_time;
|
||||
TimeSpan min_time = end_time;
|
||||
|
||||
for (WaitableHolderBase &holder_base : this->waitable_list) {
|
||||
if (const u64 cur_time = holder_base.GetWakeupTime(); cur_time < min_time) {
|
||||
if (const TimeSpan cur_time = holder_base.GetAbsoluteWakeupTime(); cur_time < min_time) {
|
||||
min_timeout_holder = &holder_base;
|
||||
min_time = cur_time;
|
||||
}
|
||||
@@ -166,11 +154,11 @@ namespace ams::os::impl{
|
||||
}
|
||||
|
||||
void WaitableManagerImpl::SignalAndWakeupThread(WaitableHolderBase *holder_base) {
|
||||
std::scoped_lock lk(this->lock);
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
|
||||
if (this->signaled_holder == nullptr) {
|
||||
this->signaled_holder = holder_base;
|
||||
R_ABORT_UNLESS(svcCancelSynchronization(this->waiting_thread_handle));
|
||||
this->target_impl.CancelWait();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user