Skip to content

Commit

Permalink
Improve ThreadSettingsQoS logging (#4744) (#4755)
Browse files Browse the repository at this point in the history
* Refs #20862: Add BB tests

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #20862: ThreadSettings logging improvements impl

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs #20862: Linter

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs 20862: Apply Miguel suggestions

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs 20862: Apply second rev

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs 20862: Applied third round suggestions

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

* Refs 20862: Remove old method in threading_empty

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>

---------

Signed-off-by: Mario Dominguez <mariodominguez@eprosima.com>
(cherry picked from commit 7832901)

Co-authored-by: Mario Domínguez López <116071334+Mario-DL@users.noreply.github.com>
  • Loading branch information
mergify[bot] and Mario-DL authored May 24, 2024
1 parent 57cceb6 commit e56f749
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 85 deletions.
3 changes: 0 additions & 3 deletions src/cpp/rtps/transport/TCPTransportInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1014,9 +1014,6 @@ void TCPTransportInterface::perform_listen_operation(
{
remote_locator = remote_endpoint_to_locator(channel);

uint32_t port = channel->local_endpoint().port();
set_name_to_current_thread("dds.tcp.%u", port);

if (channel->tcp_connection_type() == TCPChannelResource::TCPConnectionType::TCP_CONNECT_TYPE)
{
rtcp_message_manager->sendConnectionRequest(channel);
Expand Down
44 changes: 27 additions & 17 deletions src/cpp/utils/threading.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#ifndef UTILS__THREADING_HPP_
#define UTILS__THREADING_HPP_

#include <array>

#include "./thread.hpp"

namespace eprosima {
Expand All @@ -29,48 +31,55 @@ struct ThreadSettings;
/**
* @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.
* @param[in, out] thread_name_buffer Buffer to store the name of the thread.
* @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(
std::array<char, 16>& thread_name_buffer,
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.
* @param[in, out] thread_name_buffer Buffer to store the name of the thread.
* @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(
std::array<char, 16>& thread_name_buffer,
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.
* @param[in, out] thread_name_buffer Buffer to store the name of the thread.
* @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(
std::array<char, 16>& thread_name_buffer,
const char* fmt,
uint32_t arg1,
uint32_t arg2);


/**
* @brief Apply thread settings to the thread calling this function.
*
* @param[in] thread_name Name of the thread.
* @param[in] settings Thread settings to apply.
*/
void apply_thread_settings_to_current_thread(
const char* thread_name,
const fastdds::rtps::ThreadSettings& settings);

/**
Expand All @@ -94,8 +103,9 @@ eprosima::thread create_thread(
{
return eprosima::thread(settings.stack_size, [=]()
{
apply_thread_settings_to_current_thread(settings);
set_name_to_current_thread(name, args ...);
std::array<char, 16> thread_name_buffer;
set_name_to_current_thread(thread_name_buffer, name, args ...);
apply_thread_settings_to_current_thread(thread_name_buffer.data(), settings);
func();
});
}
Expand Down
7 changes: 7 additions & 0 deletions src/cpp/utils/threading/threading_empty.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <cstdint>

namespace eprosima {

void set_name_to_current_thread(
std::array<char, 16>& /* thread_name_buffer */,
const char* /* name */)
{
}

void set_name_to_current_thread(
std::array<char, 16>& /* thread_name_buffer */,
const char* /* fmt */,
uint32_t /* arg */)
{
}

void set_name_to_current_thread(
std::array<char, 16>& /* thread_name_buffer */,
const char* /* fmt */,
uint32_t /* arg1 */,
uint32_t /* arg2 */)
{
}

void apply_thread_settings_to_current_thread(
const char* /* thread_name */,
const fastdds::rtps::ThreadSettings& /*settings*/)
{
}
Expand Down
83 changes: 54 additions & 29 deletions src/cpp/utils/threading/threading_osx.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <array>
#include <cstdio>
#include <cstring>
#include <limits>
Expand All @@ -24,37 +25,42 @@

namespace eprosima {

template<typename... Args>
template<typename ... Args>
static void set_name_to_current_thread_impl(
const char* fmt, Args... args)
std::array<char, 16>& thread_name_buffer,
const char* fmt,
Args... args)
{
char thread_name[16]{};
snprintf(thread_name, 16, fmt, args...);
pthread_setname_np(thread_name);
snprintf(thread_name_buffer.data(), 16, fmt, args ...);
pthread_setname_np(thread_name_buffer.data());
}

void set_name_to_current_thread(
std::array<char, 16>& thread_name_buffer,
const char* name)
{
set_name_to_current_thread_impl("%s", name);
set_name_to_current_thread_impl(thread_name_buffer, "%s", name);
}

void set_name_to_current_thread(
std::array<char, 16>& thread_name_buffer,
const char* fmt,
uint32_t arg)
{
set_name_to_current_thread_impl(fmt, arg);
set_name_to_current_thread_impl(thread_name_buffer, fmt, arg);
}

void set_name_to_current_thread(
std::array<char, 16>& thread_name_buffer,
const char* fmt,
uint32_t arg1,
uint32_t arg2)
{
set_name_to_current_thread_impl(fmt, arg1, arg2);
set_name_to_current_thread_impl(thread_name_buffer, fmt, arg1, arg2);
}

static void configure_current_thread_scheduler(
const char* thread_name,
int sched_class,
int sched_priority)
{
Expand All @@ -64,67 +70,86 @@ static void configure_current_thread_scheduler(
int current_class;
int result = 0;
bool change_priority = (std::numeric_limits<int32_t>::min() != sched_priority);

// Get current scheduling parameters
memset(&current_param, 0, sizeof(current_param));
pthread_getschedparam(self_tid, &current_class, &current_param);

memset(&param, 0, sizeof(param));
param.sched_priority = 0;
sched_class = (sched_class == -1) ? current_class : sched_class;

//
// Set Scheduler Class and Priority
// Set Scheduler Class and Priority
//
if(sched_class == SCHED_OTHER)
{

if (sched_class == SCHED_OTHER)
{

//
// Sched OTHER has a nice value, that we pull from the priority parameter.
// - Requires priorty value to be zero (0).
//
//
result = pthread_setschedparam(self_tid, sched_class, &param);
if(0 == result && change_priority)
if (0 == result && change_priority)
{
uint64_t tid;
pthread_threadid_np(NULL, &tid);
result = setpriority(PRIO_PROCESS, tid, sched_priority);
}
if (0 != result)
{
EPROSIMA_LOG_ERROR(SYSTEM, "Problem to set priority of thread with id [" << tid << "," << thread_name << "] to value " << sched_priority << ". Error '" << strerror(
result) << "'");
}
}
else if (0 != result)
{
EPROSIMA_LOG_ERROR(SYSTEM, "Problem to set scheduler of thread with id [" << self_tid << "," << thread_name << "] to value " << sched_class << ". Error '" << strerror(
result) << "'");
}
}
else if((sched_class == SCHED_FIFO) ||
else if ((sched_class == SCHED_FIFO) ||
(sched_class == SCHED_RR))
{
//
// RT Policies use a different priority numberspace.
//

param.sched_priority = change_priority ? sched_priority : current_param.sched_priority;
result = pthread_setschedparam(self_tid, sched_class, &param);
}

if (0 != result)
{
EPROSIMA_LOG_ERROR(SYSTEM, "Error '" << strerror(result) << "' configuring scheduler for thread " << self_tid);
if (0 != result)
{
EPROSIMA_LOG_ERROR(SYSTEM, "Problem to set scheduler of thread with id [" << self_tid << "," << thread_name << "] to value " << sched_class << " with priority " << param.sched_priority << ". Error '" << strerror(
result) << "'");
}
}
}

static void configure_current_thread_affinity(
const char* thread_name,
uint64_t affinity)
{
if (affinity <= static_cast<uint64_t>(std::numeric_limits<integer_t>::max()))
{
int result = 0;
thread_affinity_policy_data_t policy = { static_cast<integer_t>(affinity) };
pthread_t self_tid = pthread_self();
thread_policy_set(pthread_mach_thread_np(self_tid), THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1);
result =
thread_policy_set(pthread_mach_thread_np(self_tid), THREAD_AFFINITY_POLICY, (thread_policy_t)&policy,
1);
if (0 != result)
{
EPROSIMA_LOG_ERROR(SYSTEM, "Problem to set affinity of thread with id [" << self_tid << "," << thread_name << "] to value " << affinity << ". Error '" << strerror(
result) << "'");
}
}
}

void apply_thread_settings_to_current_thread(
const char* thread_name,
const fastdds::rtps::ThreadSettings& settings)
{
configure_current_thread_scheduler(settings.scheduling_policy, settings.priority);
configure_current_thread_affinity(settings.affinity);
configure_current_thread_scheduler(thread_name, settings.scheduling_policy, settings.priority);
configure_current_thread_affinity(thread_name, settings.affinity);
}

} // namespace eprosima
Loading

0 comments on commit e56f749

Please sign in to comment.