libstrat: namespace hossynch.hpp

This commit is contained in:
Michael Scire
2019-09-24 03:15:36 -07:00
committed by SciresM
parent 73d904036d
commit bb223eb5ae
57 changed files with 923 additions and 773 deletions

View File

@@ -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"

View File

@@ -53,7 +53,7 @@ class IEvent : public IWaitable {
}
void Clear() {
std::scoped_lock<HosMutex> 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<HosMutex> 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. */

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <switch/arm/counter.h>
#include <mutex>
#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);
}
};

View File

@@ -17,9 +17,9 @@
#pragma once
#include <switch.h>
#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<HosMutex> lock(this->sig_lock);
std::scoped_lock lock(this->sig_lock);
return this->is_signaled;
}

View File

@@ -17,6 +17,7 @@
#pragma once
#include <optional>
#include <switch.h>
#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:

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include "hossynch.hpp"
#include <memory>
class HosMessageQueue {
private:
HosMutex queue_lock;
HosCondVar cv_not_full;
HosCondVar cv_not_empty;
std::unique_ptr<uintptr_t[]> buffer;
size_t capacity;
size_t count = 0;
size_t offset = 0;
public:
HosMessageQueue(size_t c) : capacity(c) {
this->buffer = std::make_unique<uintptr_t[]>(this->capacity);
}
HosMessageQueue(std::unique_ptr<uintptr_t[]> 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();
};

View File

@@ -15,7 +15,12 @@
*/
#pragma once
#include <switch.h>
#include "ipc.hpp"
#include "services/dmntcht.h"
#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"

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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();
}
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#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<uintptr_t[]> 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<uintptr_t[]>(this->capacity);
}
MessageQueue(std::unique_ptr<uintptr_t[]> 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);
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <mutex>
#include <switch.h>
#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();
}
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
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);
}
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
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);
}
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
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;
}
};
}

View File

@@ -16,9 +16,9 @@
#pragma once
#include <switch.h>
#include <cstdlib>
#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<typename F>
static void DoWithSmSession(F f) {
std::scoped_lock<HosRecursiveMutex &> lk(GetSmSessionMutex());
std::scoped_lock lk(GetSmSessionMutex());
{
R_ASSERT(smInitialize());
f();

View File

@@ -21,6 +21,7 @@
#include <functional>
#include "results.hpp"
#include "os.hpp"
#include "waitable_manager_base.hpp"
#include "event.hpp"
#include "ipc.hpp"
@@ -47,7 +48,7 @@ template<typename ManagerOptions = DefaultManagerOptions>
class WaitableManager : public SessionManagerBase {
private:
/* Domain Manager */
HosMutex domain_lock;
sts::os::Mutex domain_lock;
std::array<uintptr_t, ManagerOptions::MaxDomains> domain_keys;
std::array<bool, ManagerOptions::MaxDomains> is_domain_allocated;
std::array<DomainEntry, ManagerOptions::MaxDomainObjects> domain_objects;
@@ -58,13 +59,13 @@ class WaitableManager : public SessionManagerBase {
std::vector<IWaitable *> 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<bool> 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<HosMutex> lk{this->cur_thread_lock};
std::scoped_lock lk{this->cur_thread_lock};
this->cur_thread_handle = h;
}
Handle GetProcessingThreadHandle() {
std::scoped_lock<HosMutex> lk{this->cur_thread_lock};
std::scoped_lock lk{this->cur_thread_lock};
return this->cur_thread_handle;
}