os: adopt multiwait naming over waitable

This commit is contained in:
Michael Scire
2021-09-30 19:00:47 -07:00
parent d9b4009f82
commit 7444a68cd1
79 changed files with 869 additions and 869 deletions

View File

@@ -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);
}

View File

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

View File

@@ -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);
}

View File

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

View File

@@ -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);
}

View File

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

View File

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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

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

View File

@@ -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);
}

View File

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

View File

@@ -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);
}

View File

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

View File

@@ -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);
}

View File

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

View File

@@ -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);
}

View File

@@ -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;
}
}