From 9b29c391ca7822ad88e39eeef0f11f9a538f051e Mon Sep 17 00:00:00 2001 From: angie Date: Tue, 11 Jun 2024 13:13:48 -0400 Subject: [PATCH] Fix `pthread_setname_np` not liking names longer than 16 bytes --- ultramodern/include/ultramodern/threads.hpp | 6 ++++-- ultramodern/src/threads.cpp | 15 +++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ultramodern/include/ultramodern/threads.hpp b/ultramodern/include/ultramodern/threads.hpp index 00da6ba..2a82b24 100644 --- a/ultramodern/include/ultramodern/threads.hpp +++ b/ultramodern/include/ultramodern/threads.hpp @@ -8,11 +8,13 @@ namespace ultramodern { namespace threads { struct callbacks_t { - using get_game_thread_name_t = std::string(OSThread* t); + using get_game_thread_name_t = std::string(const OSThread* t); /** * Allows to specifyin a custom name for each thread. Mainly for debugging purposes. * + * For maximum cross-platform compatibility the returned name should be at most 15 bytes long (16 bytes including the null terminator). + * * If this function is not provided then the thread id will be used as the name of the thread. */ get_game_thread_name_t *get_game_thread_name; @@ -20,7 +22,7 @@ namespace ultramodern { void set_callbacks(const callbacks_t& callbacks); - std::string get_game_thread_name(OSThread* t); + std::string get_game_thread_name(const OSThread* t); } } diff --git a/ultramodern/src/threads.cpp b/ultramodern/src/threads.cpp index 624fe87..f9161d4 100644 --- a/ultramodern/src/threads.cpp +++ b/ultramodern/src/threads.cpp @@ -20,9 +20,9 @@ void ultramodern::threads::set_callbacks(const callbacks_t& callbacks) { threads_callbacks = callbacks; } -std::string ultramodern::threads::get_game_thread_name(OSThread* t) { +std::string ultramodern::threads::get_game_thread_name(const OSThread* t) { if (threads_callbacks.get_game_thread_name == nullptr) { - return std::to_string(t->id); + return "Game Thread " + std::to_string(t->id); } return threads_callbacks.get_game_thread_name(t); } @@ -96,7 +96,13 @@ void ultramodern::set_native_thread_priority(ThreadPriority pri) { } #elif defined(__linux__) void ultramodern::set_native_thread_name(const std::string& name) { - pthread_setname_np(pthread_self(), name.c_str()); + // `pthread_setname_np` only accepts up to 16 characters including the null terminator. + if (name.length() > 15) { + debug_printf("[Threads] Truncating '%s' thread name up to 15 characters", name.c_str()); + } + std::string new_name = name.substr(0, 15); + + pthread_setname_np(pthread_self(), new_name.c_str()); } void ultramodern::set_native_thread_priority(ThreadPriority pri) { @@ -128,6 +134,7 @@ void ultramodern::set_native_thread_priority(ThreadPriority pri) { } #elif defined(__APPLE__) void ultramodern::set_native_thread_name(const std::string& name) { + // TODO: figure out if Mac imposses similar restrictions to thread names like Linux does pthread_setname_np(name.c_str()); } @@ -177,7 +184,7 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry is_game_thread = true; // Set the thread name - ultramodern::set_native_thread_name("Game Thread " + ultramodern::threads::get_game_thread_name(self)); + ultramodern::set_native_thread_name(ultramodern::threads::get_game_thread_name(self)); ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::High); // Signal the initialized semaphore to indicate that this thread can be started.