os: adopt multiwait naming over waitable
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct EventType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
void InitializeEvent(EventType *event, bool signaled, EventClearMode clear_mode);
|
||||
void FinalizeEvent(EventType *event);
|
||||
@@ -32,6 +32,6 @@ namespace ams::os {
|
||||
bool TimedWaitEvent(EventType *event, TimeSpan timeout);
|
||||
void ClearEvent(EventType *event);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, EventType *event);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, EventType *event);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableObjectList;
|
||||
class MultiWaitObjectList;
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ams::os {
|
||||
State_Initialized = 1,
|
||||
};
|
||||
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitable_object_list_storage;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> multi_wait_object_list_storage;
|
||||
bool signaled;
|
||||
bool initially_signaled;
|
||||
u8 clear_mode;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct InterruptEventType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
void InitializeInterruptEvent(InterruptEventType *event, InterruptName name, EventClearMode clear_mode);
|
||||
void FinalizeInterruptEvent(InterruptEventType *event);
|
||||
@@ -31,6 +31,6 @@ namespace ams::os {
|
||||
bool TimedWaitInterruptEvent(InterruptEventType *event, TimeSpan timeout);
|
||||
void ClearInterruptEvent(InterruptEventType *event);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, InterruptEventType *event);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, InterruptEventType *event);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableObjectList;
|
||||
class MultiWaitObjectList;
|
||||
class InterruptEventImpl;
|
||||
|
||||
}
|
||||
@@ -34,7 +34,7 @@ namespace ams::os {
|
||||
State_Initialized = 1,
|
||||
};
|
||||
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitable_object_list_storage;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> multi_wait_object_list_storage;
|
||||
|
||||
u8 clear_mode;
|
||||
u8 state;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct MessageQueueType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
void InitializeMessageQueue(MessageQueueType *mq, uintptr_t *buffer, size_t count);
|
||||
void FinalizeMessageQueue(MessageQueueType *mq);
|
||||
@@ -46,6 +46,6 @@ namespace ams::os {
|
||||
bool TryPeekMessageQueue(uintptr_t *out, const MessageQueueType *mq);
|
||||
bool TimedPeekMessageQueue(uintptr_t *out, const MessageQueueType *mq, TimeSpan timeout);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, MessageQueueType *event, MessageQueueWaitType wait_type);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, MessageQueueType *event, MessageQueueWaitType wait_type);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableObjectList;
|
||||
class MultiWaitObjectList;
|
||||
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace ams::os {
|
||||
State_Initialized = 1,
|
||||
};
|
||||
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist_not_full;
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist_not_empty;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist_not_full;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist_not_empty;
|
||||
uintptr_t *buffer;
|
||||
s32 capacity;
|
||||
s32 count;
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere/os/os_waitable_types.hpp>
|
||||
#include <stratosphere/os/os_waitable_api.hpp>
|
||||
#include <stratosphere/os/os_waitable_utils.hpp>
|
||||
#include <stratosphere/os/os_multiple_wait_types.hpp>
|
||||
#include <stratosphere/os/os_multiple_wait_api.hpp>
|
||||
#include <stratosphere/os/os_multiple_wait_utils.hpp>
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 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 <vapours.hpp>
|
||||
#include <stratosphere/os/os_message_queue_common.hpp>
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
struct MultiWaitHolderType;
|
||||
struct MultiWaitType;
|
||||
|
||||
void InitializeMultiWait(MultiWaitType *multi_wait);
|
||||
void FinalizeMultiWait(MultiWaitType *multi_wait);
|
||||
|
||||
MultiWaitHolderType *WaitAny(MultiWaitType *multi_wait);
|
||||
MultiWaitHolderType *TryWaitAny(MultiWaitType *multi_wait);
|
||||
MultiWaitHolderType *TimedWaitAny(MultiWaitType *multi_wait, TimeSpan timeout);
|
||||
|
||||
void FinalizeMultiWaitHolder(MultiWaitHolderType *holder);
|
||||
|
||||
void LinkMultiWaitHolder(MultiWaitType *multi_wait, MultiWaitHolderType *holder);
|
||||
void UnlinkMultiWaitHolder(MultiWaitHolderType *holder);
|
||||
void UnlinkAllMultiWaitHolder(MultiWaitType *multi_wait);
|
||||
|
||||
void MoveAllMultiWaitHolder(MultiWaitType *dst, MultiWaitType *src);
|
||||
|
||||
void SetMultiWaitHolderUserData(MultiWaitHolderType *holder, uintptr_t user_data);
|
||||
uintptr_t GetMultiWaitHolderUserData(const MultiWaitHolderType *holder);
|
||||
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *holder, Handle handle);
|
||||
|
||||
}
|
||||
@@ -21,12 +21,12 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableManagerImpl;
|
||||
struct WaitableHolderImpl;
|
||||
class MultiWaitImpl;
|
||||
struct MultiWaitHolderImpl;
|
||||
|
||||
}
|
||||
|
||||
struct WaitableManagerType {
|
||||
struct MultiWaitType {
|
||||
enum State {
|
||||
State_NotInitialized,
|
||||
State_Initialized,
|
||||
@@ -34,14 +34,14 @@ namespace ams::os {
|
||||
|
||||
u8 state;
|
||||
bool is_waiting;
|
||||
util::TypedStorage<impl::WaitableManagerImpl, sizeof(util::IntrusiveListNode) + sizeof(impl::InternalCriticalSection) + 2 * sizeof(void *) + sizeof(Handle), alignof(void *)> impl_storage;
|
||||
util::TypedStorage<impl::MultiWaitImpl, sizeof(util::IntrusiveListNode) + sizeof(impl::InternalCriticalSection) + 2 * sizeof(void *) + sizeof(Handle), alignof(void *)> impl_storage;
|
||||
};
|
||||
static_assert(std::is_trivial<WaitableManagerType>::value);
|
||||
static_assert(std::is_trivial<MultiWaitType>::value);
|
||||
|
||||
struct WaitableHolderType {
|
||||
util::TypedStorage<impl::WaitableHolderImpl, 2 * sizeof(util::IntrusiveListNode) + 3 * sizeof(void *), alignof(void *)> impl_storage;
|
||||
struct MultiWaitHolderType {
|
||||
util::TypedStorage<impl::MultiWaitHolderImpl, 2 * sizeof(util::IntrusiveListNode) + 3 * sizeof(void *), alignof(void *)> impl_storage;
|
||||
uintptr_t user_data;
|
||||
};
|
||||
static_assert(std::is_trivial<WaitableHolderType>::value);
|
||||
static_assert(std::is_trivial<MultiWaitHolderType>::value);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 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 <vapours.hpp>
|
||||
#include <stratosphere/os/os_message_queue_common.hpp>
|
||||
#include <stratosphere/os/os_multiple_wait_api.hpp>
|
||||
#include <stratosphere/os/os_multiple_wait_types.hpp>
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class AutoMultiWaitHolder {
|
||||
private:
|
||||
MultiWaitHolderType m_holder;
|
||||
public:
|
||||
template<typename T>
|
||||
ALWAYS_INLINE explicit AutoMultiWaitHolder(MultiWaitType *multi_wait, T &&arg) {
|
||||
InitializeMultiWaitHolder(std::addressof(m_holder), std::forward<T>(arg));
|
||||
LinkMultiWaitHolder(multi_wait, std::addressof(m_holder));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~AutoMultiWaitHolder() {
|
||||
UnlinkMultiWaitHolder(std::addressof(m_holder));
|
||||
FinalizeMultiWaitHolder(std::addressof(m_holder));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE std::pair<MultiWaitHolderType *, int> ConvertResult(const std::pair<MultiWaitHolderType *, int> result, int index) {
|
||||
if (result.first == std::addressof(m_holder)) {
|
||||
return std::make_pair(static_cast<MultiWaitHolderType *>(nullptr), index);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
inline std::pair<MultiWaitHolderType *, int> WaitAnyImpl(F &&func, MultiWaitType *multi_wait, int) {
|
||||
return std::pair<MultiWaitHolderType *, int>(func(multi_wait), -1);
|
||||
}
|
||||
|
||||
template<typename F, typename T, typename... Args>
|
||||
inline std::pair<MultiWaitHolderType *, int> WaitAnyImpl(F &&func, MultiWaitType *multi_wait, int index, T &&x, Args &&... args) {
|
||||
AutoMultiWaitHolder holder(multi_wait, std::forward<T>(x));
|
||||
return holder.ConvertResult(WaitAnyImpl(std::forward<F>(func), multi_wait, index + 1, std::forward<Args>(args)...), index);
|
||||
}
|
||||
|
||||
template<typename F, typename... Args>
|
||||
inline std::pair<MultiWaitHolderType *, int> WaitAnyImpl(F &&func, MultiWaitType *multi_wait, Args &&... args) {
|
||||
return WaitAnyImpl(std::forward<F>(func), multi_wait, 0, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
class TempMultiWait {
|
||||
private:
|
||||
MultiWaitType m_multi_wait;
|
||||
public:
|
||||
ALWAYS_INLINE TempMultiWait() {
|
||||
os::InitializeMultiWait(std::addressof(m_multi_wait));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~TempMultiWait() {
|
||||
os::FinalizeMultiWait(std::addressof(m_multi_wait));
|
||||
}
|
||||
|
||||
MultiWaitType *Get() {
|
||||
return std::addressof(m_multi_wait);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename... Args>
|
||||
inline std::pair<MultiWaitHolderType *, int> WaitAnyImpl(F &&func, Args &&... args) {
|
||||
TempMultiWait temp_multi_wait;
|
||||
return WaitAnyImpl(std::forward<F>(func), temp_multi_wait.Get(), 0, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
using WaitAnyFunction = MultiWaitHolderType * (*)(MultiWaitType *);
|
||||
|
||||
class NotBoolButInt {
|
||||
private:
|
||||
int m_value;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE NotBoolButInt(int v) : m_value(v) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE operator int() const { return m_value; }
|
||||
|
||||
explicit operator bool() const = delete;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline std::pair<MultiWaitHolderType *, int> WaitAny(MultiWaitType *multi_wait, Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::WaitAny), multi_wait, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline int WaitAny(Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::WaitAny), std::forward<Args>(args)...).second;
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline std::pair<MultiWaitHolderType *, int> TryWaitAny(MultiWaitType *multi_wait, Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::TryWaitAny), multi_wait, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline impl::NotBoolButInt TryWaitAny(Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::TryWaitAny), std::forward<Args>(args)...).second;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
struct WaitableHolderType;
|
||||
struct WaitableManagerType;
|
||||
struct MultiWaitHolderType;
|
||||
struct MultiWaitType;
|
||||
|
||||
Result SdkReplyAndReceive(os::WaitableHolderType **out, Handle reply_target, WaitableManagerType *manager);
|
||||
Result SdkReplyAndReceive(os::MultiWaitHolderType **out, Handle reply_target, MultiWaitType *multi_wait);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct SemaphoreType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
void InitializeSemaphore(SemaphoreType *sema, s32 count, s32 max_count);
|
||||
void FinalizeSemaphore(SemaphoreType *sema);
|
||||
@@ -34,6 +34,6 @@ namespace ams::os {
|
||||
|
||||
s32 GetCurrentSemaphoreCount(const SemaphoreType *sema);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, SemaphoreType *sema);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, SemaphoreType *sema);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableObjectList;
|
||||
class MultiWaitObjectList;
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ams::os {
|
||||
State_Initialized = 1,
|
||||
};
|
||||
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist;
|
||||
u8 state;
|
||||
s32 count;
|
||||
s32 max_count;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct SystemEventType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
Result CreateSystemEvent(SystemEventType *event, EventClearMode clear_mode, bool inter_process);
|
||||
void DestroySystemEvent(SystemEventType *event);
|
||||
@@ -42,6 +42,6 @@ namespace ams::os {
|
||||
bool TimedWaitSystemEvent(SystemEventType *event, TimeSpan timeout);
|
||||
void ClearSystemEvent(SystemEventType *event);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, SystemEventType *event);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, SystemEventType *event);
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ams::os {
|
||||
State_Initialized = 1,
|
||||
};
|
||||
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitable_object_list_storage;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> multi_wait_object_list_storage;
|
||||
|
||||
bool auto_clear;
|
||||
u8 state;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct ThreadType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
Result CreateThread(ThreadType *thread, ThreadFunction function, void *argument, void *stack, size_t stack_size, s32 priority, s32 ideal_core);
|
||||
Result CreateThread(ThreadType *thread, ThreadFunction function, void *argument, void *stack, size_t stack_size, s32 priority);
|
||||
@@ -62,6 +62,6 @@ namespace ams::os {
|
||||
|
||||
ThreadId GetThreadId(const ThreadType *thread);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *holder, ThreadType *thread);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *holder, ThreadType *thread);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableObjectList;
|
||||
class MultiWaitObjectList;
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ams::os {
|
||||
};
|
||||
|
||||
util::TypedStorage<util::IntrusiveListNode> all_threads_node;
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitlist;
|
||||
uintptr_t reserved[4];
|
||||
u8 state;
|
||||
u8 suspend_count;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace ams::os {
|
||||
|
||||
struct TimerEventType;
|
||||
struct WaitableHolderType;
|
||||
struct MultiWaitHolderType;
|
||||
|
||||
void InitializeTimerEvent(TimerEventType *event, EventClearMode clear_mode);
|
||||
void FinalizeTimerEvent(TimerEventType *event);
|
||||
@@ -36,6 +36,6 @@ namespace ams::os {
|
||||
void SignalTimerEvent(TimerEventType *event);
|
||||
void ClearTimerEvent(TimerEventType *event);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *waitable_holder, TimerEventType *event);
|
||||
void InitializeMultiWaitHolder(MultiWaitHolderType *multi_wait_holder, TimerEventType *event);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class WaitableObjectList;
|
||||
class MultiWaitObjectList;
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace ams::os {
|
||||
TimerState_Periodic = 2,
|
||||
};
|
||||
|
||||
util::TypedStorage<impl::WaitableObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> waitable_object_list_storage;
|
||||
util::TypedStorage<impl::MultiWaitObjectList, sizeof(util::IntrusiveListNode), alignof(util::IntrusiveListNode)> multi_wait_object_list_storage;
|
||||
|
||||
u8 state;
|
||||
u8 clear_mode;
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 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 <vapours.hpp>
|
||||
#include <stratosphere/os/os_message_queue_common.hpp>
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
struct WaitableHolderType;
|
||||
struct WaitableManagerType;
|
||||
|
||||
void InitializeWaitableManager(WaitableManagerType *manager);
|
||||
void FinalizeWaitableManager(WaitableManagerType *manager);
|
||||
|
||||
WaitableHolderType *WaitAny(WaitableManagerType *manager);
|
||||
WaitableHolderType *TryWaitAny(WaitableManagerType *manager);
|
||||
WaitableHolderType *TimedWaitAny(WaitableManagerType *manager, TimeSpan timeout);
|
||||
|
||||
void FinalizeWaitableHolder(WaitableHolderType *holder);
|
||||
|
||||
void LinkWaitableHolder(WaitableManagerType *manager, WaitableHolderType *holder);
|
||||
void UnlinkWaitableHolder(WaitableHolderType *holder);
|
||||
void UnlinkAllWaitableHolder(WaitableManagerType *manager);
|
||||
|
||||
void MoveAllWaitableHolder(WaitableManagerType *dst, WaitableManagerType *src);
|
||||
|
||||
void SetWaitableHolderUserData(WaitableHolderType *holder, uintptr_t user_data);
|
||||
uintptr_t GetWaitableHolderUserData(const WaitableHolderType *holder);
|
||||
|
||||
void InitializeWaitableHolder(WaitableHolderType *holder, Handle handle);
|
||||
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 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 <vapours.hpp>
|
||||
#include <stratosphere/os/os_message_queue_common.hpp>
|
||||
#include <stratosphere/os/os_waitable_api.hpp>
|
||||
#include <stratosphere/os/os_waitable_types.hpp>
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class AutoWaitableHolder {
|
||||
private:
|
||||
WaitableHolderType m_holder;
|
||||
public:
|
||||
template<typename T>
|
||||
ALWAYS_INLINE explicit AutoWaitableHolder(WaitableManagerType *manager, T &&arg) {
|
||||
InitializeWaitableHolder(std::addressof(m_holder), std::forward<T>(arg));
|
||||
LinkWaitableHolder(manager, std::addressof(m_holder));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~AutoWaitableHolder() {
|
||||
UnlinkWaitableHolder(std::addressof(m_holder));
|
||||
FinalizeWaitableHolder(std::addressof(m_holder));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE std::pair<WaitableHolderType *, int> ConvertResult(const std::pair<WaitableHolderType *, int> result, int index) {
|
||||
if (result.first == std::addressof(m_holder)) {
|
||||
return std::make_pair(static_cast<WaitableHolderType *>(nullptr), index);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
inline std::pair<WaitableHolderType *, int> WaitAnyImpl(F &&func, WaitableManagerType *manager, int) {
|
||||
return std::pair<WaitableHolderType *, int>(func(manager), -1);
|
||||
}
|
||||
|
||||
template<typename F, typename T, typename... Args>
|
||||
inline std::pair<WaitableHolderType *, int> WaitAnyImpl(F &&func, WaitableManagerType *manager, int index, T &&x, Args &&... args) {
|
||||
AutoWaitableHolder holder(manager, std::forward<T>(x));
|
||||
return holder.ConvertResult(WaitAnyImpl(std::forward<F>(func), manager, index + 1, std::forward<Args>(args)...), index);
|
||||
}
|
||||
|
||||
template<typename F, typename... Args>
|
||||
inline std::pair<WaitableHolderType *, int> WaitAnyImpl(F &&func, WaitableManagerType *manager, Args &&... args) {
|
||||
return WaitAnyImpl(std::forward<F>(func), manager, 0, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
class TempWaitableManager {
|
||||
private:
|
||||
WaitableManagerType m_manager;
|
||||
public:
|
||||
ALWAYS_INLINE TempWaitableManager() {
|
||||
os::InitializeWaitableManager(std::addressof(m_manager));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~TempWaitableManager() {
|
||||
os::FinalizeWaitableManager(std::addressof(m_manager));
|
||||
}
|
||||
|
||||
WaitableManagerType *Get() {
|
||||
return std::addressof(m_manager);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename... Args>
|
||||
inline std::pair<WaitableHolderType *, int> WaitAnyImpl(F &&func, Args &&... args) {
|
||||
TempWaitableManager temp_manager;
|
||||
return WaitAnyImpl(std::forward<F>(func), temp_manager.Get(), 0, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
using WaitAnyFunction = WaitableHolderType * (*)(WaitableManagerType *);
|
||||
|
||||
class NotBoolButInt {
|
||||
private:
|
||||
int m_value;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE NotBoolButInt(int v) : m_value(v) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE operator int() const { return m_value; }
|
||||
|
||||
explicit operator bool() const = delete;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline std::pair<WaitableHolderType *, int> WaitAny(WaitableManagerType *manager, Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::WaitAny), manager, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline int WaitAny(Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::WaitAny), std::forward<Args>(args)...).second;
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline std::pair<WaitableHolderType *, int> TryWaitAny(WaitableManagerType *manager, Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::TryWaitAny), manager, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args> requires (sizeof...(Args) > 0)
|
||||
inline impl::NotBoolButInt TryWaitAny(Args &&... args) {
|
||||
return impl::WaitAnyImpl(static_cast<impl::WaitAnyFunction>(&::ams::os::TryWaitAny), std::forward<Args>(args)...).second;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user