mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-15 07:34:23 -04:00
os: refactor/rewrite entire namespace.
This commit is contained in:
parent
6193283f03
commit
065485b971
181 changed files with 5353 additions and 1929 deletions
|
@ -13,99 +13,51 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "impl/os_interrupt_event_impl.hpp"
|
||||
#include "impl/os_waitable_object_list.hpp"
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
Result InterruptEvent::Initialize(u32 interrupt_id, bool autoclear) {
|
||||
AMS_ABORT_UNLESS(!this->is_initialized);
|
||||
this->auto_clear = autoclear;
|
||||
void InitializeInterruptEvent(InterruptEventType *event, InterruptName name, EventClearMode clear_mode) {
|
||||
/* Initialize member variables. */
|
||||
event->clear_mode = static_cast<u8>(clear_mode);
|
||||
|
||||
const auto type = this->auto_clear ? svc::InterruptType_Edge : svc::InterruptType_Level;
|
||||
R_TRY(svcCreateInterruptEvent(this->handle.GetPointer(), interrupt_id, type));
|
||||
/* Initialize implementation. */
|
||||
new (GetPointer(event->impl)) impl::InterruptEventImpl(name, clear_mode);
|
||||
|
||||
this->is_initialized = true;
|
||||
return ResultSuccess();
|
||||
/* Mark initialized. */
|
||||
event->state = InterruptEventType::State_Initialized;
|
||||
}
|
||||
|
||||
void InterruptEvent::Finalize() {
|
||||
AMS_ABORT_UNLESS(this->is_initialized);
|
||||
R_ABORT_UNLESS(svcCloseHandle(this->handle.Move()));
|
||||
this->auto_clear = true;
|
||||
this->is_initialized = false;
|
||||
void FinalizeInterruptEvent(InterruptEventType *event) {
|
||||
AMS_ASSERT(event->state == InterruptEventType::State_Initialized);
|
||||
|
||||
/* Mark uninitialized. */
|
||||
event->state = InterruptEventType::State_NotInitialized;
|
||||
|
||||
/* Destroy objects. */
|
||||
GetReference(event->impl).~InterruptEventImpl();
|
||||
}
|
||||
|
||||
InterruptEvent::InterruptEvent(u32 interrupt_id, bool autoclear) {
|
||||
this->is_initialized = false;
|
||||
R_ABORT_UNLESS(this->Initialize(interrupt_id, autoclear));
|
||||
void WaitInterruptEvent(InterruptEventType *event) {
|
||||
AMS_ASSERT(event->state == InterruptEventType::State_Initialized);
|
||||
return GetReference(event->impl).Wait();
|
||||
}
|
||||
|
||||
void InterruptEvent::Reset() {
|
||||
R_ABORT_UNLESS(svcClearEvent(this->handle.Get()));
|
||||
bool TryWaitInterruptEvent(InterruptEventType *event) {
|
||||
AMS_ASSERT(event->state == InterruptEventType::State_Initialized);
|
||||
return GetReference(event->impl).TryWait();
|
||||
}
|
||||
|
||||
void InterruptEvent::Wait() {
|
||||
AMS_ABORT_UNLESS(this->is_initialized);
|
||||
|
||||
while (true) {
|
||||
/* Continuously wait, until success. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), std::numeric_limits<u64>::max())) {
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
|
||||
/* Clear, if we must. */
|
||||
if (this->auto_clear) {
|
||||
R_TRY_CATCH(svcResetSignal(this->handle.Get())) {
|
||||
/* Some other thread might have caught this before we did. */
|
||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
}
|
||||
return;
|
||||
}
|
||||
bool TimedWaitInterruptEvent(InterruptEventType *event, TimeSpan timeout) {
|
||||
AMS_ASSERT(event->state == InterruptEventType::State_Initialized);
|
||||
AMS_ASSERT(timeout.GetNanoSeconds() >= 0);
|
||||
return GetReference(event->impl).TimedWait(timeout);
|
||||
}
|
||||
|
||||
bool InterruptEvent::TryWait() {
|
||||
AMS_ABORT_UNLESS(this->is_initialized);
|
||||
|
||||
if (this->auto_clear) {
|
||||
/* Auto-clear. Just try to reset. */
|
||||
return R_SUCCEEDED(svcResetSignal(this->handle.Get()));
|
||||
} else {
|
||||
/* Not auto-clear. */
|
||||
while (true) {
|
||||
/* Continuously wait, until success or timeout. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), 0)) {
|
||||
R_CATCH(svc::ResultTimedOut) { return false; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
|
||||
/* We succeeded, so we're signaled. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool InterruptEvent::TimedWait(u64 ns) {
|
||||
AMS_ABORT_UNLESS(this->is_initialized);
|
||||
|
||||
TimeoutHelper timeout_helper(ns);
|
||||
while (true) {
|
||||
/* Continuously wait, until success or timeout. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), timeout_helper.NsUntilTimeout())) {
|
||||
R_CATCH(svc::ResultTimedOut) { return false; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
|
||||
/* Clear, if we must. */
|
||||
if (this->auto_clear) {
|
||||
R_TRY_CATCH(svcResetSignal(this->handle.Get())) {
|
||||
/* Some other thread might have caught this before we did. */
|
||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void ClearInterruptEvent(InterruptEventType *event) {
|
||||
AMS_ASSERT(event->state == InterruptEventType::State_Initialized);
|
||||
return GetReference(event->impl).Clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue