While using SCHED_FIFO (or any other RT scheduling types) on PREEMPT_RT, std::mutex does not support priority inheritance and therefore does not work correctly and can easily cause priority inversion and deadlock. This class should be replaced with a wrapper around a pthread mutex with its protocol manually set to PTHREAD_PRIO_INHERIT and a priority ceiling set to (most likely) ::sched_get_priority_max(SCHED_FIFO). As long as the wrapper class meets the BasicLockable requirements, it can still be used just fine with std::lock_guard. Other STL mutex management facilities may have additional requirements.
Additionally, condition variables (std::condition_variable or pthread condvars) cannot be used safely on PREEMPT_RT systems at all. POSIX condition variables do not support priority inheritance, so you get unbounded priority inversion using them (relevant glibc bug report).
Aside: the mutex and timestamp defined here are not actually thread-safe, as each source file including this header will define its own copy of each. I suggest marking these extern and placing their definitions in GT_Common.cpp.
|
static std::chrono::time_point<std::chrono::steady_clock> time_of_start = std::chrono::steady_clock::now(); |
|
static std::mutex mtx_print; |
(I would also use std::string_view instead of std::string for the string constants below and define them directly in the header: inline constexpr std::string_view version{"1.2.3"}. std::string_view is not guaranteed to be null-terminated, but in this case, you can rely on that being the case since a string literal is always null-terminated. You could also just use const char* instead. This is a matter of style and opinion, but I personally would avoid the allocation of std::string.)
While using
SCHED_FIFO(or any other RT scheduling types) on PREEMPT_RT,std::mutexdoes not support priority inheritance and therefore does not work correctly and can easily cause priority inversion and deadlock. This class should be replaced with a wrapper around a pthread mutex with its protocol manually set toPTHREAD_PRIO_INHERITand a priority ceiling set to (most likely)::sched_get_priority_max(SCHED_FIFO). As long as the wrapper class meets the BasicLockable requirements, it can still be used just fine withstd::lock_guard. Other STL mutex management facilities may have additional requirements.Additionally, condition variables (
std::condition_variableor pthread condvars) cannot be used safely on PREEMPT_RT systems at all. POSIX condition variables do not support priority inheritance, so you get unbounded priority inversion using them (relevant glibc bug report).Aside: the mutex and timestamp defined here are not actually thread-safe, as each source file including this header will define its own copy of each. I suggest marking these
externand placing their definitions in GT_Common.cpp.GenericTarget/core/code/GenericTarget/GT_Common.hpp
Lines 65 to 66 in 5713dec
(I would also use
std::string_viewinstead ofstd::stringfor the string constants below and define them directly in the header:inline constexpr std::string_view version{"1.2.3"}.std::string_viewis not guaranteed to be null-terminated, but in this case, you can rely on that being the case since a string literal is always null-terminated. You could also just useconst char*instead. This is a matter of style and opinion, but I personally would avoid the allocation ofstd::string.)