From fb0a3388c348588ae2ae2f7645595cd981d066ac Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sat, 31 Jan 2026 07:22:49 +0000 Subject: [PATCH 1/2] split out platform thread implementation --- CMakeLists.txt | 1 + source/common/thread.cpp | 99 ++++++++++++++++++++++++++++++++++++++ source/switch/platform.cpp | 93 ----------------------------------- 3 files changed, 100 insertions(+), 93 deletions(-) create mode 100644 source/common/thread.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f8a523..1f8b3b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,6 +158,7 @@ if(NINTENDO_SWITCH) target_sources(${FTPD_TARGET} PRIVATE source/switch/init.c source/switch/platform.cpp + source/common/thread.cpp ) if(FTPD_CLASSIC) diff --git a/source/common/thread.cpp b/source/common/thread.cpp new file mode 100644 index 0000000..70ff51e --- /dev/null +++ b/source/common/thread.cpp @@ -0,0 +1,99 @@ +#include "platform.h" + +#include +#include + + +/////////////////////////////////////////////////////////////////////////// +/// \brief Platform thread pimpl +class platform::Thread::privateData_t +{ +public: + privateData_t () = default; + + /// \brief Parameterized constructor + /// \param func_ Thread entry point + privateData_t (std::function &&func_) : thread (std::move (func_)) + { + } + + /// \brief Underlying thread + std::thread thread; +}; + +/////////////////////////////////////////////////////////////////////////// +platform::Thread::~Thread () = default; + +platform::Thread::Thread () : m_d (new privateData_t ()) +{ +} + +platform::Thread::Thread (std::function &&func_) + : m_d (new privateData_t (std::move (func_))) +{ +} + +platform::Thread::Thread (Thread &&that_) : m_d (new privateData_t ()) +{ + std::swap (m_d, that_.m_d); +} + +platform::Thread &platform::Thread::operator= (Thread &&that_) +{ + std::swap (m_d, that_.m_d); + return *this; +} + +void platform::Thread::join () +{ + m_d->thread.join (); +} + +void platform::Thread::sleep (std::chrono::milliseconds const timeout_) +{ + std::this_thread::sleep_for (timeout_); +} + +/////////////////////////////////////////////////////////////////////////// +#define USE_STD_MUTEX 1 + +/// \brief Platform mutex pimpl +class platform::Mutex::privateData_t +{ +public: +#if USE_STD_MUTEX + /// \brief Underlying mutex + std::mutex mutex; +#else + /// \brief Underlying mutex + ::Mutex mutex; +#endif +}; + +/////////////////////////////////////////////////////////////////////////// +platform::Mutex::~Mutex () = default; + +platform::Mutex::Mutex () : m_d (new privateData_t ()) +{ +#if !USE_STD_MUTEX + mutexInit (&m_d->mutex); +#endif +} + +void platform::Mutex::lock () +{ +#if USE_STD_MUTEX + m_d->mutex.lock (); +#else + mutexLock (&m_d->mutex); +#endif +} + +void platform::Mutex::unlock () +{ +#if USE_STD_MUTEX + m_d->mutex.unlock (); +#else + mutexUnlock (&m_d->mutex); +#endif +} \ No newline at end of file diff --git a/source/switch/platform.cpp b/source/switch/platform.cpp index 4a6a41a..3471fcf 100644 --- a/source/switch/platform.cpp +++ b/source/switch/platform.cpp @@ -922,96 +922,3 @@ void platform::exit () } } -/////////////////////////////////////////////////////////////////////////// -/// \brief Platform thread pimpl -class platform::Thread::privateData_t -{ -public: - privateData_t () = default; - - /// \brief Parameterized constructor - /// \param func_ Thread entry point - privateData_t (std::function &&func_) : thread (std::move (func_)) - { - } - - /// \brief Underlying thread - std::thread thread; -}; - -/////////////////////////////////////////////////////////////////////////// -platform::Thread::~Thread () = default; - -platform::Thread::Thread () : m_d (new privateData_t ()) -{ -} - -platform::Thread::Thread (std::function &&func_) - : m_d (new privateData_t (std::move (func_))) -{ -} - -platform::Thread::Thread (Thread &&that_) : m_d (new privateData_t ()) -{ - std::swap (m_d, that_.m_d); -} - -platform::Thread &platform::Thread::operator= (Thread &&that_) -{ - std::swap (m_d, that_.m_d); - return *this; -} - -void platform::Thread::join () -{ - m_d->thread.join (); -} - -void platform::Thread::sleep (std::chrono::milliseconds const timeout_) -{ - std::this_thread::sleep_for (timeout_); -} - -/////////////////////////////////////////////////////////////////////////// -#define USE_STD_MUTEX 1 - -/// \brief Platform mutex pimpl -class platform::Mutex::privateData_t -{ -public: -#if USE_STD_MUTEX - /// \brief Underlying mutex - std::mutex mutex; -#else - /// \brief Underlying mutex - ::Mutex mutex; -#endif -}; - -/////////////////////////////////////////////////////////////////////////// -platform::Mutex::~Mutex () = default; - -platform::Mutex::Mutex () : m_d (new privateData_t ()) -{ -#if !USE_STD_MUTEX - mutexInit (&m_d->mutex); -#endif -} - -void platform::Mutex::lock () -{ -#if USE_STD_MUTEX - m_d->mutex.lock (); -#else - mutexLock (&m_d->mutex); -#endif -} - -void platform::Mutex::unlock () -{ -#if USE_STD_MUTEX - m_d->mutex.unlock (); -#else - mutexUnlock (&m_d->mutex); -#endif -} From 8eb8c326262507cf0c16519d2b4356b7ec849f17 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Fri, 30 Jan 2026 23:39:07 +0000 Subject: [PATCH 2/2] move log print behind mutex --- source/log.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/log.cpp b/source/log.cpp index 63d85a4..96a5c97 100644 --- a/source/log.cpp +++ b/source/log.cpp @@ -243,16 +243,19 @@ void addLog (LogLevel const level_, char const *const fmt_, va_list ap_) return; #endif -#ifndef __NDS__ - thread_local +#if HAVE_MUTEX + auto const lock = std::scoped_lock (s_lock); #endif - static char buffer[1024]; - - std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_); #ifndef __NDS__ auto const lock = std::scoped_lock (s_lock); + #define BUFFER_SIZE 1024 +#else + #define BUFFER_SIZE 256 #endif + static char buffer[BUFFER_SIZE]; + std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_); + #ifndef NDEBUG // std::fprintf (stderr, "%s", s_prefix[level_]); // std::fputs (buffer, stderr);