From ec2ea1e8505cbca96db1a4b0575fe178ff426fda Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 24 Sep 2019 03:15:36 -0700 Subject: [PATCH] libstrat: namespace hossynch.hpp --- Makefile | 2 +- include/stratosphere.hpp | 6 +- include/stratosphere/event.hpp | 4 +- include/stratosphere/hossynch.hpp | 299 ------------------ include/stratosphere/iwaitable.hpp | 6 +- .../kvdb/kvdb_file_key_value_store.hpp | 3 +- include/stratosphere/message_queue.hpp | 73 ----- include/stratosphere/{services.hpp => os.hpp} | 11 +- include/stratosphere/os/os_condvar.hpp | 69 ++++ include/stratosphere/os/os_event.hpp | 113 +++++++ include/stratosphere/os/os_message_queue.hpp | 77 +++++ include/stratosphere/os/os_mutex.hpp | 103 ++++++ include/stratosphere/os/os_semaphore.hpp | 49 +++ include/stratosphere/os/os_thread.hpp | 51 +++ include/stratosphere/os/os_timeout_helper.hpp | 63 ++++ include/stratosphere/utilities.hpp | 10 +- include/stratosphere/waitable_manager.hpp | 21 +- source/cfg/cfg_privileged_process.cpp | 6 +- source/cfg/cfg_sd_card.cpp | 6 +- source/hid/hid_api.cpp | 4 +- source/message_queue.cpp | 235 -------------- source/mitm_server.cpp | 6 +- source/os/os_message_queue.cpp | 235 ++++++++++++++ source/pm/pm_info_api.cpp | 8 +- source/sm/sm_utils.cpp | 8 +- source/sm/sm_utils.hpp | 8 +- source/utilities.cpp | 10 +- 27 files changed, 818 insertions(+), 668 deletions(-) delete mode 100644 include/stratosphere/hossynch.hpp delete mode 100644 include/stratosphere/message_queue.hpp rename include/stratosphere/{services.hpp => os.hpp} (73%) create mode 100644 include/stratosphere/os/os_condvar.hpp create mode 100644 include/stratosphere/os/os_event.hpp create mode 100644 include/stratosphere/os/os_message_queue.hpp create mode 100644 include/stratosphere/os/os_mutex.hpp create mode 100644 include/stratosphere/os/os_semaphore.hpp create mode 100644 include/stratosphere/os/os_thread.hpp create mode 100644 include/stratosphere/os/os_timeout_helper.hpp delete mode 100644 source/message_queue.cpp create mode 100644 source/os/os_message_queue.cpp diff --git a/Makefile b/Makefile index add6a081..c3f1c90d 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules # INCLUDES is a list of directories containing header files #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) -SOURCES := source source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb +SOURCES := source source/os source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb DATA := data INCLUDES := include diff --git a/include/stratosphere.hpp b/include/stratosphere.hpp index 78832a5d..2192ff1d 100644 --- a/include/stratosphere.hpp +++ b/include/stratosphere.hpp @@ -26,24 +26,20 @@ #include "stratosphere/version_check.hpp" #include "stratosphere/auto_handle.hpp" -#include "stratosphere/hossynch.hpp" -#include "stratosphere/message_queue.hpp" #include "stratosphere/iwaitable.hpp" #include "stratosphere/event.hpp" #include "stratosphere/waitable_manager.hpp" #include "stratosphere/ipc.hpp" - #include "stratosphere/mitm.hpp" -#include "stratosphere/services.hpp" - #include "stratosphere/results.hpp" #include "stratosphere/on_crash.hpp" #include "stratosphere/svc.hpp" +#include "stratosphere/os.hpp" #include "stratosphere/cfg.hpp" #include "stratosphere/fatal.hpp" #include "stratosphere/hid.hpp" diff --git a/include/stratosphere/event.hpp b/include/stratosphere/event.hpp index aa33419c..326bf935 100644 --- a/include/stratosphere/event.hpp +++ b/include/stratosphere/event.hpp @@ -53,7 +53,7 @@ class IEvent : public IWaitable { } void Clear() { - std::scoped_lock lock(this->sig_lock); + std::scoped_lock lock(this->sig_lock); this->is_signaled = false; if (this->w_h != INVALID_HANDLE) { svcClearEvent(this->w_h); @@ -63,7 +63,7 @@ class IEvent : public IWaitable { } void Signal() { - std::scoped_lock lock(this->sig_lock); + std::scoped_lock lock(this->sig_lock); if (this->w_h == INVALID_HANDLE && this->r_h != INVALID_HANDLE) { /* We can't signal an event if we only have a read handle. */ diff --git a/include/stratosphere/hossynch.hpp b/include/stratosphere/hossynch.hpp deleted file mode 100644 index 2b654a74..00000000 --- a/include/stratosphere/hossynch.hpp +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include -#include -#include "results.hpp" -#include "auto_handle.hpp" - -class HosMutex { - private: - Mutex m; - Mutex *GetMutex() { - return &this->m; - } - public: - HosMutex() { - mutexInit(GetMutex()); - } - - void lock() { - mutexLock(GetMutex()); - } - - void unlock() { - mutexUnlock(GetMutex()); - } - - bool try_lock() { - return mutexTryLock(GetMutex()); - } - - void Lock() { - lock(); - } - - void Unlock() { - unlock(); - } - - bool TryLock() { - return try_lock(); - } - - friend class HosCondVar; -}; - -class HosRecursiveMutex { - private: - RMutex m; - RMutex *GetMutex() { - return &this->m; - } - public: - HosRecursiveMutex() { - rmutexInit(GetMutex()); - } - - void lock() { - rmutexLock(GetMutex()); - } - - void unlock() { - rmutexUnlock(GetMutex()); - } - - bool try_lock() { - return rmutexTryLock(GetMutex()); - } - - void Lock() { - lock(); - } - - void Unlock() { - unlock(); - } - - bool TryLock() { - return try_lock(); - } -}; - -class HosCondVar { - private: - CondVar cv; - public: - HosCondVar() { - condvarInit(&cv); - } - - Result TimedWait(u64 timeout, HosMutex *hm) { - return TimedWait(timeout, hm->GetMutex()); - } - - Result Wait(HosMutex *hm) { - return Wait(hm->GetMutex()); - } - - Result TimedWait(u64 timeout, Mutex *m) { - return condvarWaitTimeout(&cv, m, timeout); - } - - Result Wait(Mutex *m) { - return condvarWait(&cv, m); - } - - Result Wake(int num) { - return condvarWake(&cv, num); - } - - Result WakeOne() { - return condvarWakeOne(&cv); - } - - Result WakeAll() { - return condvarWakeAll(&cv); - } -}; - -class HosSemaphore { - private: - Semaphore s; - public: - HosSemaphore() { - semaphoreInit(&s, 0); - } - - HosSemaphore(u64 c) { - semaphoreInit(&s, c); - } - - void Signal() { - semaphoreSignal(&s); - } - - void Wait() { - semaphoreWait(&s); - } - - bool TryWait() { - return semaphoreTryWait(&s); - } -}; - -class TimeoutHelper { - private: - u64 end_tick; - public: - TimeoutHelper(u64 ns) { - /* Special case zero-time timeouts. */ - if (ns == 0) { - end_tick = 0; - return; - } - - u64 cur_tick = armGetSystemTick(); - this->end_tick = cur_tick + NsToTick(ns) + 1; - } - - static inline u64 NsToTick(u64 ns) { - return (ns * 12) / 625; - } - - static inline u64 TickToNs(u64 tick) { - return (tick * 625) / 12; - } - - u64 NsUntilTimeout() { - u64 diff = TickToNs(this->end_tick - armGetSystemTick()); - - if (TimedOut()) { - return 0; - } - - return diff; - } - - bool TimedOut() { - if (this->end_tick == 0) { - return true; - } - - return armGetSystemTick() >= this->end_tick; - } -}; - -class HosSignal { - private: - CondVar cv; - Mutex m; - bool signaled; - public: - HosSignal() { - condvarInit(&cv); - mutexInit(&m); - signaled = false; - } - - void Signal() { - mutexLock(&m); - signaled = true; - condvarWakeAll(&cv); - mutexUnlock(&m); - } - - void Reset() { - mutexLock(&m); - signaled = false; - mutexUnlock(&m); - } - - void Wait(bool reset = false) { - mutexLock(&m); - - while (!signaled) { - condvarWait(&cv, &m); - } - - if (reset) { - this->signaled = false; - } - - mutexUnlock(&m); - } - - bool TryWait(bool reset = false) { - mutexLock(&m); - - bool success = signaled; - if (reset) { - this->signaled = false; - } - - mutexUnlock(&m); - return success; - } - - Result TimedWait(u64 ns, bool reset = false) { - mutexLock(&m); - TimeoutHelper timeout_helper(ns); - - while (!signaled) { - if (R_FAILED(condvarWaitTimeout(&cv, &m, timeout_helper.NsUntilTimeout()))) { - return false; - } - } - - if (reset) { - this->signaled = false; - } - - mutexUnlock(&m); - return true; - } -}; - -class HosThread { - private: - Thread thr = {}; - public: - HosThread() {} - - Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) { - return threadCreate(&this->thr, entry, arg, stack_sz, prio, cpuid); - } - - Handle GetHandle() const { - return this->thr.handle; - } - - Result Start() { - return threadStart(&this->thr); - } - - Result Join() { - R_TRY(threadWaitForExit(&this->thr)); - R_TRY(threadClose(&this->thr)); - return ResultSuccess; - } - - Result CancelSynchronization() { - return svcCancelSynchronization(this->thr.handle); - } -}; \ No newline at end of file diff --git a/include/stratosphere/iwaitable.hpp b/include/stratosphere/iwaitable.hpp index 9997a42e..b5b20650 100644 --- a/include/stratosphere/iwaitable.hpp +++ b/include/stratosphere/iwaitable.hpp @@ -17,9 +17,9 @@ #pragma once #include +#include "os.hpp" #include "waitable_manager_base.hpp" -#include "hossynch.hpp" class IWaitable { private: @@ -27,7 +27,7 @@ class IWaitable { bool is_deferred = false; WaitableManagerBase *manager = nullptr; protected: - HosMutex sig_lock; + sts::os::Mutex sig_lock; bool is_signaled = false; public: virtual ~IWaitable() = default; @@ -38,7 +38,7 @@ class IWaitable { } bool IsSignaled() { - std::scoped_lock lock(this->sig_lock); + std::scoped_lock lock(this->sig_lock); return this->is_signaled; } diff --git a/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp b/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp index 708de515..ea06860b 100644 --- a/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp +++ b/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp @@ -17,6 +17,7 @@ #pragma once #include #include +#include "../os.hpp" #include "kvdb_bounded_string.hpp" @@ -66,7 +67,7 @@ namespace sts::kvdb { bool Contains(const void *key, size_t key_size); }; private: - HosMutex lock; + os::Mutex lock; Path dir_path; Cache cache; private: diff --git a/include/stratosphere/message_queue.hpp b/include/stratosphere/message_queue.hpp deleted file mode 100644 index cd9dc743..00000000 --- a/include/stratosphere/message_queue.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include "hossynch.hpp" -#include - -class HosMessageQueue { - private: - HosMutex queue_lock; - HosCondVar cv_not_full; - HosCondVar cv_not_empty; - std::unique_ptr buffer; - size_t capacity; - - size_t count = 0; - size_t offset = 0; - public: - HosMessageQueue(size_t c) : capacity(c) { - this->buffer = std::make_unique(this->capacity); - } - - HosMessageQueue(std::unique_ptr buf, size_t c) : buffer(std::move(buf)), capacity(c) { } - - /* Sending (FIFO functionality) */ - void Send(uintptr_t data); - bool TrySend(uintptr_t data); - bool TimedSend(uintptr_t data, u64 timeout); - - /* Sending (LIFO functionality) */ - void SendNext(uintptr_t data); - bool TrySendNext(uintptr_t data); - bool TimedSendNext(uintptr_t data, u64 timeout); - - /* Receive functionality */ - void Receive(uintptr_t *out); - bool TryReceive(uintptr_t *out); - bool TimedReceive(uintptr_t *out, u64 timeout); - - /* Peek functionality */ - void Peek(uintptr_t *out); - bool TryPeek(uintptr_t *out); - bool TimedPeek(uintptr_t *out, u64 timeout); - private: - bool IsFull() { - return this->count >= this->capacity; - } - - bool IsEmpty() { - return this->count == 0; - } - - void SendInternal(uintptr_t data); - void SendNextInternal(uintptr_t data); - uintptr_t ReceiveInternal(); - uintptr_t PeekInternal(); - -}; - diff --git a/include/stratosphere/services.hpp b/include/stratosphere/os.hpp similarity index 73% rename from include/stratosphere/services.hpp rename to include/stratosphere/os.hpp index fdd292ab..b3a53469 100644 --- a/include/stratosphere/services.hpp +++ b/include/stratosphere/os.hpp @@ -15,7 +15,12 @@ */ #pragma once +#include -#include "ipc.hpp" - -#include "services/dmntcht.h" \ No newline at end of file +#include "os/os_mutex.hpp" +#include "os/os_condvar.hpp" +#include "os/os_semaphore.hpp" +#include "os/os_timeout_helper.hpp" +#include "os/os_event.hpp" +#include "os/os_thread.hpp" +#include "os/os_message_queue.hpp" \ No newline at end of file diff --git a/include/stratosphere/os/os_condvar.hpp b/include/stratosphere/os/os_condvar.hpp new file mode 100644 index 00000000..eed8e16c --- /dev/null +++ b/include/stratosphere/os/os_condvar.hpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "os_mutex.hpp" + +namespace sts::os { + + class ConditionVariable { + NON_COPYABLE(ConditionVariable); + NON_MOVEABLE(ConditionVariable); + private: + CondVar cv; + public: + ConditionVariable() { + condvarInit(&cv); + } + + Result TimedWait(::Mutex *m, u64 timeout) { + return condvarWaitTimeout(&cv, m, timeout); + } + + Result Wait(::Mutex *m) { + return condvarWait(&cv, m); + } + + Result TimedWait(os::Mutex *m, u64 timeout) { + return TimedWait(m->GetMutex(), timeout); + } + + Result Wait(os::Mutex *m) { + return Wait(m->GetMutex()); + } + + Result Wake(int num) { + return condvarWake(&cv, num); + } + + Result WakeOne() { + return condvarWakeOne(&cv); + } + + Result WakeAll() { + return condvarWakeAll(&cv); + } + + Result Signal() { + return this->WakeOne(); + } + + Result Broadcast() { + return this->WakeAll(); + } + }; + +} \ No newline at end of file diff --git a/include/stratosphere/os/os_event.hpp b/include/stratosphere/os/os_event.hpp new file mode 100644 index 00000000..e287db6c --- /dev/null +++ b/include/stratosphere/os/os_event.hpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "os_mutex.hpp" +#include "os_condvar.hpp" +#include "os_timeout_helper.hpp" + +namespace sts::os { + + class Event { + NON_COPYABLE(Event); + NON_MOVEABLE(Event); + private: + Mutex m; + ConditionVariable cv; + bool auto_clear; + bool signaled; + u64 counter = 0; + public: + Event(bool a = true, bool s = false) : auto_clear(a), signaled(s) {} + + void Signal() { + std::scoped_lock lk(this->m); + + /* If we're already signaled, nothing more to do. */ + if (this->signaled) { + return; + } + + this->signaled = true; + + /* Signal! */ + if (this->auto_clear) { + /* If we're auto clear, signal one thread, which will clear. */ + this->cv.Signal(); + } else { + /* If we're manual clear, increment counter and wake all. */ + this->counter++; + this->cv.Broadcast(); + } + + /* TODO: Waitable auto-wakeup. */ + } + + void Reset() { + std::scoped_lock lk(this->m); + this->signaled = false; + } + + void Wait() { + std::scoped_lock lk(this->m); + + u64 cur_counter = this->counter; + while (!this->signaled) { + if (this->counter != cur_counter) { + break; + } + this->cv.Wait(&this->m); + } + + if (this->auto_clear) { + this->signaled = false; + } + } + + bool TryWait() { + std::scoped_lock lk(this->m); + + const bool success = this->signaled; + if (this->auto_clear) { + this->signaled = false; + } + + return success; + } + + bool TimedWait(u64 ns) { + TimeoutHelper timeout_helper(ns); + std::scoped_lock lk(this->m); + + u64 cur_counter = this->counter; + while (!this->signaled) { + if (this->counter != cur_counter) { + break; + } + if (R_FAILED(this->cv.TimedWait(&this->m, timeout_helper.NsUntilTimeout()))) { + return false; + } + } + + if (this->auto_clear) { + this->signaled = false; + } + + return true; + } + }; + +} diff --git a/include/stratosphere/os/os_message_queue.hpp b/include/stratosphere/os/os_message_queue.hpp new file mode 100644 index 00000000..7c9f8bad --- /dev/null +++ b/include/stratosphere/os/os_message_queue.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include "os_mutex.hpp" +#include "os_condvar.hpp" + +namespace sts::os { + + class MessageQueue { + NON_COPYABLE(MessageQueue); + NON_MOVEABLE(MessageQueue); + private: + Mutex queue_lock; + ConditionVariable cv_not_full; + ConditionVariable cv_not_empty; + std::unique_ptr buffer; + size_t capacity; + + size_t count = 0; + size_t offset = 0; + private: + bool IsFull() const { + return this->count >= this->capacity; + } + + bool IsEmpty() const { + return this->count == 0; + } + + void SendInternal(uintptr_t data); + void SendNextInternal(uintptr_t data); + uintptr_t ReceiveInternal(); + uintptr_t PeekInternal(); + public: + MessageQueue(size_t c) : capacity(c) { + this->buffer = std::make_unique(this->capacity); + } + + MessageQueue(std::unique_ptr buf, size_t c) : buffer(std::move(buf)), capacity(c) { } + + /* Sending (FIFO functionality) */ + void Send(uintptr_t data); + bool TrySend(uintptr_t data); + bool TimedSend(uintptr_t data, u64 timeout); + + /* Sending (LIFO functionality) */ + void SendNext(uintptr_t data); + bool TrySendNext(uintptr_t data); + bool TimedSendNext(uintptr_t data, u64 timeout); + + /* Receive functionality */ + void Receive(uintptr_t *out); + bool TryReceive(uintptr_t *out); + bool TimedReceive(uintptr_t *out, u64 timeout); + + /* Peek functionality */ + void Peek(uintptr_t *out); + bool TryPeek(uintptr_t *out); + bool TimedPeek(uintptr_t *out, u64 timeout); + }; + +} diff --git a/include/stratosphere/os/os_mutex.hpp b/include/stratosphere/os/os_mutex.hpp new file mode 100644 index 00000000..c17038d8 --- /dev/null +++ b/include/stratosphere/os/os_mutex.hpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include "../util.hpp" + +namespace sts::os { + + class ConditionVariable; + + class Mutex { + NON_COPYABLE(Mutex); + NON_MOVEABLE(Mutex); + friend class sts::os::ConditionVariable; + private: + ::Mutex m; + private: + ::Mutex *GetMutex() { + return &this->m; + } + public: + Mutex() { + mutexInit(GetMutex()); + } + + void lock() { + mutexLock(GetMutex()); + } + + void unlock() { + mutexUnlock(GetMutex()); + } + + bool try_lock() { + return mutexTryLock(GetMutex()); + } + + void Lock() { + lock(); + } + + void Unlock() { + unlock(); + } + + bool TryLock() { + return try_lock(); + } + }; + + class RecursiveMutex { + private: + ::RMutex m; + private: + ::RMutex *GetMutex() { + return &this->m; + } + public: + RecursiveMutex() { + rmutexInit(GetMutex()); + } + + void lock() { + rmutexLock(GetMutex()); + } + + void unlock() { + rmutexUnlock(GetMutex()); + } + + bool try_lock() { + return rmutexTryLock(GetMutex()); + } + + void Lock() { + lock(); + } + + void Unlock() { + unlock(); + } + + bool TryLock() { + return try_lock(); + } + }; + +} \ No newline at end of file diff --git a/include/stratosphere/os/os_semaphore.hpp b/include/stratosphere/os/os_semaphore.hpp new file mode 100644 index 00000000..3b8ac706 --- /dev/null +++ b/include/stratosphere/os/os_semaphore.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +namespace sts::os { + + class Semaphore { + NON_COPYABLE(Semaphore); + NON_MOVEABLE(Semaphore); + private: + ::Semaphore s; + public: + Semaphore() { + semaphoreInit(&s, 0); + } + + Semaphore(u64 c) { + semaphoreInit(&s, c); + } + + void Signal() { + semaphoreSignal(&s); + } + + void Wait() { + semaphoreWait(&s); + } + + bool TryWait() { + return semaphoreTryWait(&s); + } + }; + +} diff --git a/include/stratosphere/os/os_thread.hpp b/include/stratosphere/os/os_thread.hpp new file mode 100644 index 00000000..e659ac3c --- /dev/null +++ b/include/stratosphere/os/os_thread.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +namespace sts::os { + + class Thread { + private: + ::Thread thr = {}; + public: + Thread() {} + + Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) { + return threadCreate(&this->thr, entry, arg, stack_sz, prio, cpuid); + } + + Handle GetHandle() const { + return this->thr.handle; + } + + Result Start() { + return threadStart(&this->thr); + } + + Result Join() { + R_TRY(threadWaitForExit(&this->thr)); + R_TRY(threadClose(&this->thr)); + return ResultSuccess; + } + + Result CancelSynchronization() { + return svcCancelSynchronization(this->thr.handle); + } + }; + +} diff --git a/include/stratosphere/os/os_timeout_helper.hpp b/include/stratosphere/os/os_timeout_helper.hpp new file mode 100644 index 00000000..31c52b38 --- /dev/null +++ b/include/stratosphere/os/os_timeout_helper.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace sts::os { + + class TimeoutHelper { + private: + u64 end_tick; + public: + TimeoutHelper(u64 ns) { + /* Special case zero-time timeouts. */ + if (ns == 0) { + end_tick = 0; + return; + } + + u64 cur_tick = armGetSystemTick(); + this->end_tick = cur_tick + NsToTick(ns) + 1; + } + + static constexpr inline u64 NsToTick(u64 ns) { + return (ns * 12) / 625; + } + + static constexpr inline u64 TickToNs(u64 tick) { + return (tick * 625) / 12; + } + + bool TimedOut() const { + if (this->end_tick == 0) { + return true; + } + + return armGetSystemTick() >= this->end_tick; + } + + u64 NsUntilTimeout() const { + u64 diff = TickToNs(this->end_tick - armGetSystemTick()); + + if (this->TimedOut()) { + return 0; + } + + return diff; + } + }; + +} diff --git a/include/stratosphere/utilities.hpp b/include/stratosphere/utilities.hpp index a9f993f7..4de68dc1 100644 --- a/include/stratosphere/utilities.hpp +++ b/include/stratosphere/utilities.hpp @@ -16,9 +16,9 @@ #pragma once #include -#include - -#include "hossynch.hpp" +#include "defines.hpp" +#include "results.hpp" +#include "os.hpp" static inline uintptr_t GetIoMapping(const u64 io_addr, const u64 io_size) { u64 vaddr; @@ -115,11 +115,11 @@ static inline bool ShouldBlankProdInfo() { return should_blank_prodinfo; } -HosRecursiveMutex &GetSmSessionMutex(); +sts::os::RecursiveMutex &GetSmSessionMutex(); template static void DoWithSmSession(F f) { - std::scoped_lock lk(GetSmSessionMutex()); + std::scoped_lock lk(GetSmSessionMutex()); { R_ASSERT(smInitialize()); f(); diff --git a/include/stratosphere/waitable_manager.hpp b/include/stratosphere/waitable_manager.hpp index 556a1c44..7edc4b52 100644 --- a/include/stratosphere/waitable_manager.hpp +++ b/include/stratosphere/waitable_manager.hpp @@ -21,6 +21,7 @@ #include #include "results.hpp" +#include "os.hpp" #include "waitable_manager_base.hpp" #include "event.hpp" #include "ipc.hpp" @@ -47,7 +48,7 @@ template class WaitableManager : public SessionManagerBase { private: /* Domain Manager */ - HosMutex domain_lock; + sts::os::Mutex domain_lock; std::array domain_keys; std::array is_domain_allocated; std::array domain_objects; @@ -58,13 +59,13 @@ class WaitableManager : public SessionManagerBase { std::vector deferred_waitables; u32 num_extra_threads = 0; - HosThread *threads = nullptr; + sts::os::Thread *threads = nullptr; - HosMutex process_lock; - HosMutex signal_lock; - HosMutex add_lock; - HosMutex cur_thread_lock; - HosMutex deferred_lock; + sts::os::Mutex process_lock; + sts::os::Mutex signal_lock; + sts::os::Mutex add_lock; + sts::os::Mutex cur_thread_lock; + sts::os::Mutex deferred_lock; bool has_new_waitables = false; std::atomic should_stop = false; @@ -75,7 +76,7 @@ class WaitableManager : public SessionManagerBase { WaitableManager(u32 n, u32 ss = 0x8000) : num_extra_threads(n-1) { u32 prio; if (num_extra_threads) { - threads = new HosThread[num_extra_threads]; + threads = new sts::os::Thread[num_extra_threads]; R_ASSERT(svcGetThreadPriority(&prio, CUR_THREAD_HANDLE)); for (unsigned int i = 0; i < num_extra_threads; i++) { R_ASSERT(threads[i].Initialize(&WaitableManager::ProcessLoop, this, ss, prio)); @@ -132,12 +133,12 @@ class WaitableManager : public SessionManagerBase { } private: void SetProcessingThreadHandle(Handle h) { - std::scoped_lock lk{this->cur_thread_lock}; + std::scoped_lock lk{this->cur_thread_lock}; this->cur_thread_handle = h; } Handle GetProcessingThreadHandle() { - std::scoped_lock lk{this->cur_thread_lock}; + std::scoped_lock lk{this->cur_thread_lock}; return this->cur_thread_handle; } diff --git a/source/cfg/cfg_privileged_process.cpp b/source/cfg/cfg_privileged_process.cpp index cab6469b..b12c5237 100644 --- a/source/cfg/cfg_privileged_process.cpp +++ b/source/cfg/cfg_privileged_process.cpp @@ -27,7 +27,7 @@ namespace sts::cfg { constexpr u64 InitialProcessIdMaxDeprecated = 0x50; /* Privileged process globals. */ - HosMutex g_lock; + os::Mutex g_lock; bool g_got_privileged_process_status = false; u64 g_min_initial_process_id = 0, g_max_initial_process_id = 0; u64 g_cur_process_id = 0; @@ -69,7 +69,7 @@ namespace sts::cfg { /* Privileged Process utilities. */ bool IsInitialProcess() { - std::scoped_lock lk(g_lock); + std::scoped_lock lk(g_lock); /* If we've not detected, do detection. */ if (!g_got_privileged_process_status) { @@ -81,7 +81,7 @@ namespace sts::cfg { } void GetInitialProcessRange(u64 *out_min, u64 *out_max) { - std::scoped_lock lk(g_lock); + std::scoped_lock lk(g_lock); /* If we've not detected, do detection. */ if (!g_got_privileged_process_status) { diff --git a/source/cfg/cfg_sd_card.cpp b/source/cfg/cfg_sd_card.cpp index 9543cf67..e2276fac 100644 --- a/source/cfg/cfg_sd_card.cpp +++ b/source/cfg/cfg_sd_card.cpp @@ -33,7 +33,7 @@ namespace sts::cfg { constexpr size_t NumRequiredServicesForSdCardAccess = util::size(RequiredServicesForSdCardAccess); /* SD card globals. */ - HosMutex g_sd_card_lock; + os::Mutex g_sd_card_lock; bool g_sd_card_initialized = false; FsFileSystem g_sd_card_filesystem = {}; @@ -64,7 +64,7 @@ namespace sts::cfg { /* SD card utilities. */ bool IsSdCardInitialized() { - std::scoped_lock lk(g_sd_card_lock); + std::scoped_lock lk(g_sd_card_lock); if (!g_sd_card_initialized) { if (R_SUCCEEDED(TryInitializeSdCard())) { @@ -75,7 +75,7 @@ namespace sts::cfg { } void WaitSdCardInitialized() { - std::scoped_lock lk(g_sd_card_lock); + std::scoped_lock lk(g_sd_card_lock); InitializeSdCard(); } diff --git a/source/hid/hid_api.cpp b/source/hid/hid_api.cpp index b4f47675..7f1fc7f5 100644 --- a/source/hid/hid_api.cpp +++ b/source/hid/hid_api.cpp @@ -24,7 +24,7 @@ namespace sts::hid { namespace { /* Global lock. */ - HosMutex g_hid_lock; + os::Mutex g_hid_lock; bool g_initialized_hid = false; /* Helper. */ @@ -53,7 +53,7 @@ namespace sts::hid { } Result GetKeysHeld(u64 *out) { - std::scoped_lock lk(g_hid_lock); + std::scoped_lock lk(g_hid_lock); R_TRY(EnsureHidInitialized()); diff --git a/source/message_queue.cpp b/source/message_queue.cpp deleted file mode 100644 index d972e53e..00000000 --- a/source/message_queue.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - - -void HosMessageQueue::Send(uintptr_t data) { - /* Acquire mutex, wait sendable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsFull()) { - this->cv_not_full.Wait(&this->queue_lock); - } - - /* Send, signal. */ - this->SendInternal(data); - this->cv_not_empty.WakeAll(); -} - -bool HosMessageQueue::TrySend(uintptr_t data) { - std::scoped_lock lock(this->queue_lock); - if (this->IsFull()) { - return false; - } - - /* Send, signal. */ - this->SendInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -bool HosMessageQueue::TimedSend(uintptr_t data, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsFull()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_full.TimedWait(timeout, &this->queue_lock); - } - - /* Send, signal. */ - this->SendInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -void HosMessageQueue::SendNext(uintptr_t data) { - /* Acquire mutex, wait sendable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsFull()) { - this->cv_not_full.Wait(&this->queue_lock); - } - - /* Send, signal. */ - this->SendNextInternal(data); - this->cv_not_empty.WakeAll(); -} - -bool HosMessageQueue::TrySendNext(uintptr_t data) { - std::scoped_lock lock(this->queue_lock); - if (this->IsFull()) { - return false; - } - - /* Send, signal. */ - this->SendNextInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -bool HosMessageQueue::TimedSendNext(uintptr_t data, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsFull()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_full.TimedWait(timeout, &this->queue_lock); - } - - /* Send, signal. */ - this->SendNextInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -void HosMessageQueue::Receive(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsEmpty()) { - this->cv_not_empty.Wait(&this->queue_lock); - } - - /* Receive, signal. */ - *out = this->ReceiveInternal(); - this->cv_not_full.WakeAll(); -} -bool HosMessageQueue::TryReceive(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - if (this->IsEmpty()) { - return false; - } - - /* Receive, signal. */ - *out = this->ReceiveInternal(); - this->cv_not_full.WakeAll(); - return true; -} - -bool HosMessageQueue::TimedReceive(uintptr_t *out, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsEmpty()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_empty.TimedWait(timeout, &this->queue_lock); - } - - /* Receive, signal. */ - *out = this->ReceiveInternal(); - this->cv_not_full.WakeAll(); - return true; -} - -void HosMessageQueue::Peek(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsEmpty()) { - this->cv_not_empty.Wait(&this->queue_lock); - } - - /* Peek. */ - *out = this->PeekInternal(); -} - -bool HosMessageQueue::TryPeek(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - if (this->IsEmpty()) { - return false; - } - - /* Peek. */ - *out = this->PeekInternal(); - return true; -} - -bool HosMessageQueue::TimedPeek(uintptr_t *out, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsEmpty()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_empty.TimedWait(timeout, &this->queue_lock); - } - - /* Peek. */ - *out = this->PeekInternal(); - return true; -} - -void HosMessageQueue::SendInternal(uintptr_t data) { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count >= this->capacity) { - std::abort(); - } - - /* Write data to tail of queue. */ - this->buffer[(this->count++ + this->offset) % this->capacity] = data; -} - -void HosMessageQueue::SendNextInternal(uintptr_t data) { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count >= this->capacity) { - std::abort(); - } - - /* Write data to head of queue. */ - this->offset = (this->offset + this->capacity - 1) % this->capacity; - this->buffer[this->offset] = data; - this->count++; -} - -uintptr_t HosMessageQueue::ReceiveInternal() { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count == 0) { - std::abort(); - } - - uintptr_t data = this->buffer[this->offset]; - this->offset = (this->offset + 1) % this->capacity; - this->count--; - return data; -} - -uintptr_t HosMessageQueue::PeekInternal() { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count == 0) { - std::abort(); - } - - return this->buffer[this->offset]; -} \ No newline at end of file diff --git a/source/mitm_server.cpp b/source/mitm_server.cpp index d090584e..7f9f74cb 100644 --- a/source/mitm_server.cpp +++ b/source/mitm_server.cpp @@ -18,8 +18,8 @@ #include #include -static HosMutex g_server_query_mutex; -static HosThread g_server_query_manager_thread; +static sts::os::Mutex g_server_query_mutex; +static sts::os::Thread g_server_query_manager_thread; static SessionManagerBase *g_server_query_manager = nullptr; static void ServerQueryManagerThreadFunc(void *arg) { @@ -27,7 +27,7 @@ static void ServerQueryManagerThreadFunc(void *arg) { } void RegisterMitmServerQueryHandle(Handle query_h, ServiceObjectHolder &&service) { - std::scoped_lock lock(g_server_query_mutex); + std::scoped_lock lock(g_server_query_mutex); const bool exists = g_server_query_manager != nullptr; if (!exists) { diff --git a/source/os/os_message_queue.cpp b/source/os/os_message_queue.cpp new file mode 100644 index 00000000..2008ed7b --- /dev/null +++ b/source/os/os_message_queue.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace sts::os { + + void MessageQueue::SendInternal(uintptr_t data) { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count >= this->capacity) { + std::abort(); + } + + /* Write data to tail of queue. */ + this->buffer[(this->count++ + this->offset) % this->capacity] = data; + } + + void MessageQueue::SendNextInternal(uintptr_t data) { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count >= this->capacity) { + std::abort(); + } + + /* Write data to head of queue. */ + this->offset = (this->offset + this->capacity - 1) % this->capacity; + this->buffer[this->offset] = data; + this->count++; + } + + uintptr_t MessageQueue::ReceiveInternal() { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count == 0) { + std::abort(); + } + + uintptr_t data = this->buffer[this->offset]; + this->offset = (this->offset + 1) % this->capacity; + this->count--; + return data; + } + + uintptr_t MessageQueue::PeekInternal() { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count == 0) { + std::abort(); + } + + return this->buffer[this->offset]; + } + + void MessageQueue::Send(uintptr_t data) { + /* Acquire mutex, wait sendable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsFull()) { + this->cv_not_full.Wait(&this->queue_lock); + } + + /* Send, signal. */ + this->SendInternal(data); + this->cv_not_empty.WakeAll(); + } + + bool MessageQueue::TrySend(uintptr_t data) { + std::scoped_lock lock(this->queue_lock); + if (this->IsFull()) { + return false; + } + + /* Send, signal. */ + this->SendInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + bool MessageQueue::TimedSend(uintptr_t data, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsFull()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_full.TimedWait(&this->queue_lock, timeout); + } + + /* Send, signal. */ + this->SendInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + void MessageQueue::SendNext(uintptr_t data) { + /* Acquire mutex, wait sendable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsFull()) { + this->cv_not_full.Wait(&this->queue_lock); + } + + /* Send, signal. */ + this->SendNextInternal(data); + this->cv_not_empty.WakeAll(); + } + + bool MessageQueue::TrySendNext(uintptr_t data) { + std::scoped_lock lock(this->queue_lock); + if (this->IsFull()) { + return false; + } + + /* Send, signal. */ + this->SendNextInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + bool MessageQueue::TimedSendNext(uintptr_t data, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsFull()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_full.TimedWait(&this->queue_lock, timeout); + } + + /* Send, signal. */ + this->SendNextInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + void MessageQueue::Receive(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsEmpty()) { + this->cv_not_empty.Wait(&this->queue_lock); + } + + /* Receive, signal. */ + *out = this->ReceiveInternal(); + this->cv_not_full.WakeAll(); + } + bool MessageQueue::TryReceive(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + if (this->IsEmpty()) { + return false; + } + + /* Receive, signal. */ + *out = this->ReceiveInternal(); + this->cv_not_full.WakeAll(); + return true; + } + + bool MessageQueue::TimedReceive(uintptr_t *out, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsEmpty()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_empty.TimedWait(&this->queue_lock, timeout); + } + + /* Receive, signal. */ + *out = this->ReceiveInternal(); + this->cv_not_full.WakeAll(); + return true; + } + + void MessageQueue::Peek(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsEmpty()) { + this->cv_not_empty.Wait(&this->queue_lock); + } + + /* Peek. */ + *out = this->PeekInternal(); + } + + bool MessageQueue::TryPeek(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + if (this->IsEmpty()) { + return false; + } + + /* Peek. */ + *out = this->PeekInternal(); + return true; + } + + bool MessageQueue::TimedPeek(uintptr_t *out, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsEmpty()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_empty.TimedWait(&this->queue_lock, timeout); + } + + /* Peek. */ + *out = this->PeekInternal(); + return true; + } + +} diff --git a/source/pm/pm_info_api.cpp b/source/pm/pm_info_api.cpp index 379d49c1..9f3c8b7d 100644 --- a/source/pm/pm_info_api.cpp +++ b/source/pm/pm_info_api.cpp @@ -25,26 +25,26 @@ namespace sts::pm::info { namespace { /* Global lock. */ - HosMutex g_info_lock; + os::Mutex g_info_lock; std::set g_cached_launched_titles; } /* Information API. */ Result GetTitleId(ncm::TitleId *out_title_id, u64 process_id) { - std::scoped_lock lk(g_info_lock); + std::scoped_lock lk(g_info_lock); return pminfoGetTitleId(reinterpret_cast(out_title_id), process_id); } Result GetProcessId(u64 *out_process_id, ncm::TitleId title_id) { - std::scoped_lock lk(g_info_lock); + std::scoped_lock lk(g_info_lock); return pminfoAtmosphereGetProcessId(out_process_id, static_cast(title_id)); } Result WEAK HasLaunchedTitle(bool *out, ncm::TitleId title_id) { - std::scoped_lock lk(g_info_lock); + std::scoped_lock lk(g_info_lock); if (g_cached_launched_titles.find(static_cast(title_id)) != g_cached_launched_titles.end()) { *out = true; diff --git a/source/sm/sm_utils.cpp b/source/sm/sm_utils.cpp index c2cd1c25..460fce33 100644 --- a/source/sm/sm_utils.cpp +++ b/source/sm/sm_utils.cpp @@ -21,17 +21,17 @@ namespace sts::sm::impl { namespace { /* Globals. */ - HosRecursiveMutex g_user_session_mutex; - HosRecursiveMutex g_mitm_session_mutex; + os::RecursiveMutex g_user_session_mutex; + os::RecursiveMutex g_mitm_session_mutex; } /* Utilities. */ - HosRecursiveMutex &GetUserSessionMutex() { + os::RecursiveMutex &GetUserSessionMutex() { return g_user_session_mutex; } - HosRecursiveMutex &GetMitmSessionMutex() { + os::RecursiveMutex &GetMitmSessionMutex() { return g_mitm_session_mutex; } diff --git a/source/sm/sm_utils.hpp b/source/sm/sm_utils.hpp index 410806f0..11bb9940 100644 --- a/source/sm/sm_utils.hpp +++ b/source/sm/sm_utils.hpp @@ -25,12 +25,12 @@ namespace sts::sm::impl { /* Utilities. */ - HosRecursiveMutex &GetUserSessionMutex(); - HosRecursiveMutex &GetMitmSessionMutex(); + os::RecursiveMutex &GetUserSessionMutex(); + os::RecursiveMutex &GetMitmSessionMutex(); template Result DoWithUserSession(F f) { - std::scoped_lock lk(GetUserSessionMutex()); + std::scoped_lock lk(GetUserSessionMutex()); { R_ASSERT(smInitialize()); ON_SCOPE_EXIT { smExit(); }; @@ -41,7 +41,7 @@ namespace sts::sm::impl { template Result DoWithMitmSession(F f) { - std::scoped_lock lk(GetMitmSessionMutex()); + std::scoped_lock lk(GetMitmSessionMutex()); { R_ASSERT(smAtmosphereMitmInitialize()); ON_SCOPE_EXIT { smAtmosphereMitmExit(); }; diff --git a/source/utilities.cpp b/source/utilities.cpp index 1494dd03..af8d221d 100644 --- a/source/utilities.cpp +++ b/source/utilities.cpp @@ -17,14 +17,8 @@ #include #include -static HosRecursiveMutex g_sm_session_lock; -static HosRecursiveMutex g_sm_mitm_session_lock; +static sts::os::RecursiveMutex g_sm_session_lock; - -HosRecursiveMutex &GetSmSessionMutex() { +sts::os::RecursiveMutex &GetSmSessionMutex() { return g_sm_session_lock; } - -HosRecursiveMutex &GetSmMitmSessionMutex() { - return g_sm_mitm_session_lock; -}