From 50c07872ff61c19ba8cf19f6fd77bc229bff0c0f Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Mon, 4 Sep 2023 07:33:02 +0200 Subject: [PATCH] Platform implementations for set_name_to_current_thread (#3823) * Refs #17492. Added pthread implementation for set_name_to_current_thread Signed-off-by: Miguel Company * Refs #17492. Added implementation for Windows. Signed-off-by: Miguel Company * Refs #17492. Added implementation for Mac. Signed-off-by: Miguel Company * Refs #17492. Added doxygen to threading.hpp Signed-off-by: Miguel Company * Refs #17492. Using pthread implementation for Android. Signed-off-by: Miguel Company * Refs #17492. Fix build error on snprintf. Signed-off-by: Miguel Company --------- Signed-off-by: Miguel Company --- src/cpp/utils/SystemInfo.cpp | 8 +++ src/cpp/utils/threading.hpp | 26 +++++++++ src/cpp/utils/threading/threading_osx.ipp | 51 +++++++++++++++++ src/cpp/utils/threading/threading_pthread.ipp | 52 +++++++++++++++++ src/cpp/utils/threading/threading_win32.ipp | 56 +++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 src/cpp/utils/threading/threading_osx.ipp create mode 100644 src/cpp/utils/threading/threading_pthread.ipp create mode 100644 src/cpp/utils/threading/threading_win32.ipp diff --git a/src/cpp/utils/SystemInfo.cpp b/src/cpp/utils/SystemInfo.cpp index ac231d43743..74fd688ba51 100644 --- a/src/cpp/utils/SystemInfo.cpp +++ b/src/cpp/utils/SystemInfo.cpp @@ -278,4 +278,12 @@ std::string SystemInfo::environment_file_; } // eprosima // threading.hpp implementations +#ifdef _WIN32 +#include "threading/threading_win32.ipp" +#elif defined(__APPLE__) +#include "threading/threading_osx.ipp" +#elif defined(_POSIX_SOURCE) || defined(__QNXNTO__) || defined(__ANDROID__) +#include "threading/threading_pthread.ipp" +#else #include "threading/threading_empty.ipp" +#endif // Platform selection diff --git a/src/cpp/utils/threading.hpp b/src/cpp/utils/threading.hpp index 974fff639ad..dc28df06dc7 100644 --- a/src/cpp/utils/threading.hpp +++ b/src/cpp/utils/threading.hpp @@ -17,13 +17,39 @@ namespace eprosima { +/** + * @brief Give a name to the thread calling this function. + * + * @param[in] name A null-terminated string with the name to give to the calling thread. + * The implementation for certain platforms may truncate the final thread + * name if there is a limit on the length of the name of a thread. + */ void set_name_to_current_thread( const char* name); +/** + * @brief Give a name to the thread calling this function. + * + * @param[in] fmt A null-terminated string to be used as the format argument of + * a `snprintf` like function, in order to accomodate the restrictions of + * the OS. Those restrictions may truncate the final thread name if there + * is a limit on the length of the name of a thread. + * @param[in] arg Single variadic argument passed to the formatting function. + */ void set_name_to_current_thread( const char* fmt, uint32_t arg); +/** + * @brief Give a name to the thread calling this function. + * + * @param[in] fmt A null-terminated string to be used as the format argument of + * a `snprintf` like function, in order to accomodate the restrictions of + * the OS. Those restrictions may truncate the final thread name if there + * is a limit on the length of the name of a thread. + * @param[in] arg1 First variadic argument passed to the formatting function. + * @param[in] arg2 Second variadic argument passed to the formatting function. + */ void set_name_to_current_thread( const char* fmt, uint32_t arg1, diff --git a/src/cpp/utils/threading/threading_osx.ipp b/src/cpp/utils/threading/threading_osx.ipp new file mode 100644 index 00000000000..efb215bd99b --- /dev/null +++ b/src/cpp/utils/threading/threading_osx.ipp @@ -0,0 +1,51 @@ +// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +namespace eprosima { + +template +static void set_name_to_current_thread_impl( + const char* fmt, Args... args) +{ + char thread_name[16]{}; + snprintf(thread_name, 16, fmt, args...); + pthread_setname_np(thread_name); +} + +void set_name_to_current_thread( + const char* name) +{ + set_name_to_current_thread_impl("%s", name); +} + +void set_name_to_current_thread( + const char* fmt, + uint32_t arg) +{ + set_name_to_current_thread_impl(fmt, arg); +} + +void set_name_to_current_thread( + const char* fmt, + uint32_t arg1, + uint32_t arg2) +{ + set_name_to_current_thread_impl(fmt, arg1, arg2); +} + +} // namespace eprosima diff --git a/src/cpp/utils/threading/threading_pthread.ipp b/src/cpp/utils/threading/threading_pthread.ipp new file mode 100644 index 00000000000..1090d9939c0 --- /dev/null +++ b/src/cpp/utils/threading/threading_pthread.ipp @@ -0,0 +1,52 @@ +// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +namespace eprosima { + +template +static void set_name_to_current_thread_impl( + const char* fmt, Args... args) +{ + char thread_name[16]{}; + snprintf(thread_name, 16, fmt, args...); + auto id = pthread_self(); + pthread_setname_np(id, thread_name); +} + +void set_name_to_current_thread( + const char* name) +{ + set_name_to_current_thread_impl("%s", name); +} + +void set_name_to_current_thread( + const char* fmt, + uint32_t arg) +{ + set_name_to_current_thread_impl(fmt, arg); +} + +void set_name_to_current_thread( + const char* fmt, + uint32_t arg1, + uint32_t arg2) +{ + set_name_to_current_thread_impl(fmt, arg1, arg2); +} + +} // namespace eprosima diff --git a/src/cpp/utils/threading/threading_win32.ipp b/src/cpp/utils/threading/threading_win32.ipp new file mode 100644 index 00000000000..1a9f683bd0f --- /dev/null +++ b/src/cpp/utils/threading/threading_win32.ipp @@ -0,0 +1,56 @@ +// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +namespace eprosima { + +template +static void set_name_to_current_thread_impl( + const char* fmt, Args... args) +{ + char thread_name[16]{}; + snprintf(thread_name, 16, fmt, args...); + + std::wstringstream stream; + stream << thread_name; + std::wstring w_thread_name = stream.str(); + + SetThreadDescription(GetCurrentThread(), w_thread_name.c_str()); +} + +void set_name_to_current_thread( + const char* name) +{ + set_name_to_current_thread_impl("%s", name); +} + +void set_name_to_current_thread( + const char* fmt, + uint32_t arg) +{ + set_name_to_current_thread_impl(fmt, arg); +} + +void set_name_to_current_thread( + const char* fmt, + uint32_t arg1, + uint32_t arg2) +{ + set_name_to_current_thread_impl(fmt, arg1, arg2); +} + +} // namespace eprosima