diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 42f25075ee..43d8c8c02f 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -594,6 +594,7 @@ serializables setaffinity setinheritsched SETLOGGING +setname setprotocol setschedparam setschedpolicy diff --git a/Os/Posix/Task.cpp b/Os/Posix/Task.cpp index 4b607d5196..0ae21a4bc0 100644 --- a/Os/Posix/Task.cpp +++ b/Os/Posix/Task.cpp @@ -10,6 +10,7 @@ #include "Fw/Logger/Logger.hpp" #include "Fw/Types/Assert.hpp" +#include "Fw/Types/StringUtils.hpp" #include "Os/Posix/Task.hpp" #include "Os/Posix/error.hpp" #include "Os/Task.hpp" @@ -22,9 +23,17 @@ static const int SCHED_POLICY = SCHED_RR; typedef void* (*pthread_func_ptr)(void*); +// Forward declaration +int set_task_name(pthread_t thread, char* name); + void* pthread_entry_wrapper(void* wrapper_pointer) { FW_ASSERT(wrapper_pointer != nullptr); + // Both downcasts are safe because we know the types Os::Task::TaskRoutineWrapper& wrapper = *reinterpret_cast(wrapper_pointer); + auto handle = reinterpret_cast(wrapper.m_task.getHandle()); + FW_ASSERT(handle != nullptr); + // Task name is on a best effort basis + (void)set_task_name(handle->m_task_descriptor, handle->m_name); wrapper.run(&wrapper); return nullptr; } @@ -115,6 +124,20 @@ int set_cpu_affinity(pthread_attr_t& attributes, const Os::Task::Arguments& argu return status; } +int set_task_name(pthread_t thread, char* name) { + int status = 0; +// pthread_setname_np is a non-POSIX function. +// Limit its use to builds that involve glibc, on Linux, with _GNU_SOURCE defined. +// That's the circumstance in which we expect this feature to work. +#if defined(TGT_OS_TYPE_LINUX) && defined(__GLIBC__) && defined(_GNU_SOURCE) && defined(POSIX_THREADS_ENABLE_NAMES) && \ + POSIX_THREADS_ENABLE_NAMES + // Force safe name usage + name[Os::Posix::Task::PosixTaskHandle::PTHREAD_NAME_LENGTH - 1] = '\0'; + status = pthread_setname_np(thread, name); +#endif + return status; +} + Os::Task::Status PosixTask::create(const Os::Task::Arguments& arguments, const PosixTask::PermissionExpectation permissions) { int pthread_status = PosixTaskHandle::SUCCESS; @@ -145,6 +168,10 @@ Os::Task::Status PosixTask::create(const Os::Task::Arguments& arguments, handle.m_is_valid = true; } +#if defined(POSIX_THREADS_ENABLE_NAMES) && POSIX_THREADS_ENABLE_NAMES + Fw::StringUtils::string_copy(handle.m_name, arguments.m_name.toChar(), sizeof(handle.m_name)); +#endif + (void)pthread_attr_destroy(&attributes); return Posix::posix_status_to_task_status(pthread_status); } diff --git a/Os/Posix/Task.hpp b/Os/Posix/Task.hpp index 911e149bed..b38c4c1df2 100644 --- a/Os/Posix/Task.hpp +++ b/Os/Posix/Task.hpp @@ -22,12 +22,16 @@ namespace Task { //! TaskHandle class definition for posix implementations. //! struct PosixTaskHandle : public TaskHandle { + static constexpr FwSizeType PTHREAD_NAME_LENGTH = 16; //!< Length of pthread name static constexpr int SUCCESS = 0; //! Posix task descriptor pthread_t m_task_descriptor; //! Is the above descriptor valid bool m_is_valid = false; +#if defined(POSIX_THREADS_ENABLE_NAMES) && POSIX_THREADS_ENABLE_NAMES + char m_name[PosixTaskHandle::PTHREAD_NAME_LENGTH]; +#endif }; //! Posix task implementation as driven by pthreads implementation diff --git a/default/config/FpConfig.h b/default/config/FpConfig.h index 6db0bcae58..9547109207 100644 --- a/default/config/FpConfig.h +++ b/default/config/FpConfig.h @@ -148,6 +148,12 @@ extern "C" { #define FW_AMPCS_COMPATIBLE 0 //!< Whether or not JPL AMPCS ground system support is enabled. #endif +// Posix thread names are limited to 16 characters, this can lead to collisions. In the event of a +// collision, set this to 0. +#ifndef POSIX_THREADS_ENABLE_NAMES +#define POSIX_THREADS_ENABLE_NAMES 1 //!< Enable/Disable assigning names to threads +#endif + // *** NOTE configuration checks are in Fw/Cfg/ConfigCheck.cpp in order to have // the type definitions in Fw/Types/BasicTypes available. #ifdef __cplusplus diff --git a/default/config/PlatformCfg.fpp b/default/config/PlatformCfg.fpp index 3aa26c630d..754c6aeaef 100644 --- a/default/config/PlatformCfg.fpp +++ b/default/config/PlatformCfg.fpp @@ -6,7 +6,7 @@ constant FW_CONSOLE_HANDLE_MAX_SIZE = 24 @ Maximum size of a handle for Os::Task -constant FW_TASK_HANDLE_MAX_SIZE = 24 +constant FW_TASK_HANDLE_MAX_SIZE = 40 @ Maximum size of a handle for Os::File constant FW_FILE_HANDLE_MAX_SIZE = 16