mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 12:46:12 +00:00
u/linux: Add helpers to raise thread scheduling priority
This commit is contained in:
parent
50bc6c0731
commit
cd10b487e2
|
@ -117,6 +117,11 @@ if(WIN32)
|
||||||
target_sources(aux_util PRIVATE u_windows.c u_windows.h)
|
target_sources(aux_util PRIVATE u_windows.c u_windows.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Only uses POSIX/Linux libraries, doesn't add anything extra.
|
||||||
|
if(XRT_HAVE_LINUX OR ANDROID)
|
||||||
|
target_sources(aux_util PRIVATE u_linux.c u_linux.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Is basically used everywhere, unavoidable.
|
# Is basically used everywhere, unavoidable.
|
||||||
if(XRT_HAVE_SYSTEM_CJSON)
|
if(XRT_HAVE_SYSTEM_CJSON)
|
||||||
target_link_libraries(aux_util PUBLIC cJSON::cJSON)
|
target_link_libraries(aux_util PUBLIC cJSON::cJSON)
|
||||||
|
|
139
src/xrt/auxiliary/util/u_linux.c
Normal file
139
src/xrt/auxiliary/util/u_linux.c
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
// Copyright 2023, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Various helpers for doing Linux specific things.
|
||||||
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||||
|
*
|
||||||
|
* @ingroup aux_util
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "util/u_linux.h"
|
||||||
|
#include "util/u_pretty_print.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define LOG_D(...) U_LOG_IFL_D(log_level, __VA_ARGS__)
|
||||||
|
#define LOG_I(...) U_LOG_IFL_I(log_level, __VA_ARGS__)
|
||||||
|
#define LOG_W(...) U_LOG_IFL_W(log_level, __VA_ARGS__)
|
||||||
|
#define LOG_E(...) U_LOG_IFL_E(log_level, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define NAME_LENGTH 32
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Helper functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
policy_to_string(int policy)
|
||||||
|
{
|
||||||
|
switch (policy) {
|
||||||
|
case SCHED_FIFO: return "SCHED_FIFO";
|
||||||
|
case SCHED_RR: return "SCHED_RR";
|
||||||
|
case SCHED_OTHER: return "SCHED_OTHER(normal)";
|
||||||
|
case SCHED_IDLE: return "SCHED_IDLE";
|
||||||
|
case SCHED_BATCH: return "SCHED_BATCH";
|
||||||
|
default: return "SCHED_<UNKNOWN>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_name(char *str, size_t count)
|
||||||
|
{
|
||||||
|
assert(str != NULL);
|
||||||
|
assert(count > 0);
|
||||||
|
|
||||||
|
// First init.
|
||||||
|
str[0] = '\0';
|
||||||
|
|
||||||
|
// Get name of thread.
|
||||||
|
pthread_t this_thread = pthread_self();
|
||||||
|
pthread_getname_np(this_thread, str, count);
|
||||||
|
|
||||||
|
if (str[0] == '\0') {
|
||||||
|
snprintf(str, count, "tid(%i)", gettid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_thread_info(struct u_pp_delegate dg, enum u_logging_level log_level, pthread_t thread)
|
||||||
|
{
|
||||||
|
struct sched_param params;
|
||||||
|
int policy = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
// Get the policy and scheduling priority.
|
||||||
|
ret = pthread_getschedparam(thread, &policy, ¶ms);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_E("pthread_getschedparam: %i", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_pp(dg, "policy: '%s', priority: '%i'", policy_to_string(policy), params.sched_priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 'Exported' functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
u_linux_try_to_set_realtime_priority_on_thread(enum u_logging_level log_level, const char *name)
|
||||||
|
{
|
||||||
|
pthread_t this_thread = pthread_self();
|
||||||
|
struct u_pp_sink_stack_only sink;
|
||||||
|
struct sched_param params;
|
||||||
|
char str[NAME_LENGTH];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// Add printing delegate.
|
||||||
|
struct u_pp_delegate dg = u_pp_sink_stack_only_init(&sink);
|
||||||
|
|
||||||
|
// Always have some name.
|
||||||
|
if (name == NULL) {
|
||||||
|
get_name(str, ARRAY_SIZE(str));
|
||||||
|
name = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_level <= U_LOGGING_DEBUG) {
|
||||||
|
u_pp(dg, "Trying to raise priority on thread '%s'\n\t", name);
|
||||||
|
u_pp(dg, "before: ");
|
||||||
|
print_thread_info(dg, log_level, this_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the maximum on this platform.
|
||||||
|
params.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
||||||
|
|
||||||
|
// Here we try to set the realtime scheduling with the max priority available.
|
||||||
|
ret = pthread_setschedparam(this_thread, SCHED_FIFO, ¶ms);
|
||||||
|
|
||||||
|
// Print different amount depending on log level.
|
||||||
|
if (log_level <= U_LOGGING_DEBUG) {
|
||||||
|
u_pp(dg, "after: ");
|
||||||
|
print_thread_info(dg, log_level, this_thread);
|
||||||
|
u_pp(dg, "\n\tResult: %i", ret);
|
||||||
|
} else {
|
||||||
|
if (ret != 0) {
|
||||||
|
u_pp(dg, "Could not raise priority for thread '%s'", name);
|
||||||
|
} else {
|
||||||
|
u_pp(dg, "Raised priority of thread '%s' to ", name);
|
||||||
|
print_thread_info(dg, log_level, this_thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always print as warning or information.
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_W("%s", sink.buffer);
|
||||||
|
} else {
|
||||||
|
LOG_I("%s", sink.buffer);
|
||||||
|
}
|
||||||
|
}
|
39
src/xrt/auxiliary/util/u_linux.h
Normal file
39
src/xrt/auxiliary/util/u_linux.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2023, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Various helpers for doing Linux specific things.
|
||||||
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||||
|
*
|
||||||
|
* @ingroup aux_util
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xrt/xrt_compiler.h"
|
||||||
|
#include "xrt/xrt_windows.h"
|
||||||
|
#include "util/u_logging.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Try to set realtime priority on this thread. Passing in log_level to control
|
||||||
|
* how chatty this function is, the name is to make the logging pretty, can be
|
||||||
|
* NULL and the code will try to figure out the name itself.
|
||||||
|
*
|
||||||
|
* @param name Thread name to be used in logging.
|
||||||
|
* @param log_level Logging level to control chattiness.
|
||||||
|
*
|
||||||
|
* @aux_util
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u_linux_try_to_set_realtime_priority_on_thread(enum u_logging_level log_level, const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in a new issue