From 4c78a66e826fdfa263fe11118318680f9d40a39a Mon Sep 17 00:00:00 2001 From: TurtleP Date: Mon, 18 Dec 2023 11:40:45 -0500 Subject: [PATCH] 3ds: use std::thread, Channels use std::recursive_mutex --- include/objects/channel/channel.hpp | 4 +- include/utilities/threads/threads.hpp | 14 + .../include/utilities/threads/threads.hpp | 12 - .../ctr/include/utilities/threads/threads.hpp | 10 - platform/ctr/libraries/thread/ctr_thread.h | 382 ------------------ .../hac/include/utilities/threads/threads.hpp | 12 - 6 files changed, 16 insertions(+), 418 deletions(-) create mode 100644 include/utilities/threads/threads.hpp delete mode 100644 platform/cafe/include/utilities/threads/threads.hpp delete mode 100644 platform/ctr/include/utilities/threads/threads.hpp delete mode 100644 platform/ctr/libraries/thread/ctr_thread.h delete mode 100644 platform/hac/include/utilities/threads/threads.hpp diff --git a/include/objects/channel/channel.hpp b/include/objects/channel/channel.hpp index bf6b0bd2b..4a3d4a75e 100644 --- a/include/objects/channel/channel.hpp +++ b/include/objects/channel/channel.hpp @@ -53,8 +53,8 @@ namespace love uint64_t sent; uint64_t received; - love::mutex mutex; - love::conditional condition; + love::recursive_mutex mutex; + love::condvar_any condition; std::queue queue; }; diff --git a/include/utilities/threads/threads.hpp b/include/utilities/threads/threads.hpp new file mode 100644 index 000000000..331644e67 --- /dev/null +++ b/include/utilities/threads/threads.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +namespace love +{ + using mutex = std::mutex; + using conditional = std::condition_variable; + using thread = std::thread; + using recursive_mutex = std::recursive_mutex; + using condvar_any = std::condition_variable_any; +} // namespace love diff --git a/platform/cafe/include/utilities/threads/threads.hpp b/platform/cafe/include/utilities/threads/threads.hpp deleted file mode 100644 index 47d538f4b..000000000 --- a/platform/cafe/include/utilities/threads/threads.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace love -{ - using mutex = std::mutex; - using conditional = std::condition_variable; - using thread = std::thread; -} // namespace love diff --git a/platform/ctr/include/utilities/threads/threads.hpp b/platform/ctr/include/utilities/threads/threads.hpp deleted file mode 100644 index 89647a7fb..000000000 --- a/platform/ctr/include/utilities/threads/threads.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -namespace love -{ - using mutex = ctr::mutex; - using conditional = ctr::condition_variable; - using thread = ctr::thread; -} // namespace love diff --git a/platform/ctr/libraries/thread/ctr_thread.h b/platform/ctr/libraries/thread/ctr_thread.h deleted file mode 100644 index dfde5effc..000000000 --- a/platform/ctr/libraries/thread/ctr_thread.h +++ /dev/null @@ -1,382 +0,0 @@ -#ifndef THREAD3DS_INC -#define THREAD3DS_INC - -/* - * Public domain C++ -ish implementation for libctru - * VER 20220902060500 - */ - -#include <3ds.h> -#include -#include -#include -#include -#include -#include - -namespace ctr -{ - - struct thread_id - { - friend class thread; - friend class this_thread; - - thread_id() = default; - - bool operator==(thread_id rhs) const noexcept - { - return m_id == rhs.m_id; - } - - bool operator!=(thread_id rhs) const noexcept - { - return m_id != rhs.m_id; - } - - bool operator<(thread_id rhs) const noexcept - { - return m_id < rhs.m_id; - } - - bool operator<=(thread_id rhs) const noexcept - { - return m_id <= rhs.m_id; - } - - bool operator>(thread_id rhs) const noexcept - { - return m_id > rhs.m_id; - } - - bool operator>=(thread_id rhs) const noexcept - { - return m_id >= rhs.m_id; - } - - private: - Thread m_id {}; - }; - - struct thread_base - { - template - static void sleep_for(const std::chrono::duration& length) - { - svcSleepThread(std::chrono::duration_cast(length).count()); - } - }; - - struct this_thread : public thread_base - { - using id = thread_id; - - static thread_id get_id() - { - thread_id out; - out.m_id = native_handle(); - return out; - } - - static Thread native_handle() - { - return threadGetCurrent(); - } - - static void yield() noexcept - { - svcSleepThread(1); - } - }; - - class thread - { - public: - struct meta - { - std::size_t stack_size; - int prio; - int core_id; - }; - - private: - Thread m_th {}; - - template - static void trampoline(void* v_arg) - { - auto const thread_arg = std::unique_ptr(static_cast(v_arg)); - std::apply(thread_arg->first, - std::forward(thread_arg->second)); - } - - public: - using id = thread_id; - - static constexpr inline meta basic_meta { - 64 * 1024, - 0x30, - 0, - }; - - template - thread(const meta& info, F&& func, Args&&... args) - { - static_assert(std::is_invocable_v...>, - "Can not call this function with these argument."); - using P_t = std::pair...>>; - auto arg = std::make_unique(std::forward(func), - std::forward_as_tuple(std::forward(args)...)); - m_th = threadCreate(&thread::trampoline, arg.get(), info.stack_size, info.prio, - info.core_id, false); - if (m_th) - { - svcSleepThread(1000 * 1000); - arg.release(); - } - } - - template>>> - thread(F&& func, Args&&... args) : - thread(basic_meta, std::forward(func), std::forward(args)...) - {} - - thread() = default; - - thread(thread&& other) : m_th(std::exchange(other.m_th, nullptr)) - {} - - thread(const thread&) = delete; - - thread& operator=(thread&& other) - { - if (this != &other) - { - if (joinable()) - throw std::runtime_error("Moving to a thread already running."); - m_th = std::exchange(other.m_th, nullptr); - } - return *this; - } - - thread& operator=(const thread&) = delete; - - ~thread() - { - if (m_th) - { - svcBreak(USERBREAK_ASSERT); - } - } - - operator bool() const - { - return m_th != nullptr; - } - - bool joinable() const noexcept - { - return m_th != threadGetCurrent(); - } - - thread_id get_id() - { - thread_id out; - out.m_id = m_th; - return out; - } - - Thread native_handle() const - { - return m_th; - } - - void join_timeout(const u64 timeout) - { - if (R_SUCCEEDED(threadJoin(m_th, timeout))) - { - threadFree(m_th); - m_th = nullptr; - } - } - - void join() - { - join_timeout(U64_MAX); - } - - void swap(thread& other) noexcept - { - std::swap(m_th, other.m_th); - } - - static unsigned int hardware_concurrency() noexcept - { - return 1; - } - }; - - class mutex - { - LightLock m_lock; - - public: - mutex() noexcept - { - LightLock_Init(&m_lock); - } - - mutex(const mutex&) = delete; - mutex& operator=(const mutex&) = delete; - mutex(mutex&&) = delete; - mutex& operator=(mutex&&) = delete; - - void lock() noexcept - { - LightLock_Lock(&m_lock); - } - - bool try_lock() noexcept - { - return LightLock_TryLock(&m_lock) == 0; - } - - void unlock() noexcept - { - LightLock_Unlock(&m_lock); - } - - LightLock* native_handle() - { - return &m_lock; - } - }; - - class recursive_mutex - { - RecursiveLock m_lock; - - public: - recursive_mutex() noexcept - { - RecursiveLock_Init(&m_lock); - } - - recursive_mutex(const recursive_mutex&) = delete; - recursive_mutex& operator=(const recursive_mutex&) = delete; - recursive_mutex(recursive_mutex&&) = delete; - recursive_mutex& operator=(recursive_mutex&&) = delete; - - void lock() noexcept - { - RecursiveLock_Lock(&m_lock); - } - - bool try_lock() noexcept - { - return RecursiveLock_TryLock(&m_lock) == 0; - } - - void unlock() noexcept - { - RecursiveLock_Unlock(&m_lock); - } - - RecursiveLock* native_handle() - { - return &m_lock; - } - }; - - enum class cv_status - { - no_timeout, - timeout - }; - - class condition_variable - { - CondVar m_cv; - - public: - condition_variable() - { - CondVar_Init(&m_cv); - } - - condition_variable(const condition_variable&) = delete; - - void notify_one() noexcept - { - CondVar_Signal(&m_cv); - } - - void notify_all() noexcept - { - CondVar_Broadcast(&m_cv); - } - - void wait(std::unique_lock& lock) - { - CondVar_Wait(&m_cv, lock.mutex()->native_handle()); - } - - template - void wait(std::unique_lock& lock, Predicate stop_waiting) - { - while (!stop_waiting()) - { - wait(lock); - } - } - - template - cv_status wait_for(std::unique_lock& lock, - const std::chrono::duration& rel_time) - { - const int r = CondVar_WaitTimeout( - &m_cv, lock.mutex()->native_handle(), - std::chrono::duration_cast(rel_time).count()); - return r == 0 ? cv_status::no_timeout : cv_status::timeout; - } - - template - bool wait_for(std::unique_lock& lock, - const std::chrono::duration& rel_time, Predicate stop_waiting) - { - return wait_until(lock, std::chrono::steady_clock::now() + rel_time, - std::move(stop_waiting)); - } - - template - cv_status wait_until(std::unique_lock& lock, - const std::chrono::duration& abs_time) - { - return wait_for(lock, abs_time - std::chrono::steady_clock::now()); - } - - template - bool wait_until(std::unique_lock& lock, - const std::chrono::time_point& timeout_time, - Predicate stop_waiting) - { - while (!stop_waiting()) - { - if (wait_until(lock, timeout_time) == cv_status::timeout) - { - return stop_waiting(); - } - } - return true; - } - - CondVar* native_handle() - { - return &m_cv; - } - }; - -} // namespace ctr - -#endif diff --git a/platform/hac/include/utilities/threads/threads.hpp b/platform/hac/include/utilities/threads/threads.hpp deleted file mode 100644 index 47d538f4b..000000000 --- a/platform/hac/include/utilities/threads/threads.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace love -{ - using mutex = std::mutex; - using conditional = std::condition_variable; - using thread = std::thread; -} // namespace love