sas
Modularised monitoring, logging, and control of robots.
Loading...
Searching...
No Matches
marinholab::sas::core::ThreadManager Class Reference

Public Types

enum class  PRIORITY {
  LOWEST = 0 , BACKGROUND = 10 , NORMAL = 50 , HIGH = 80 ,
  REALTIME = 90 , CRITICAL = 99
}
 Abstract priority levels for thread_manager threads. More...

Public Member Functions

 ~ThreadManager ()
 ThreadManager::~ThreadManager destructor of the class.
 ThreadManager (const ThreadManager &)=delete
ThreadManager & operator= (const ThreadManager &)=delete
 ThreadManager (ThreadManager &&)=delete
ThreadManager & operator= (ThreadManager &&)=delete
 ThreadManager (const std::string &thread_name, const double &period, std::function< void()> callback, PRIORITY priority=PRIORITY::NORMAL, int cpu_core=-1)
 Constructor for ThreadManager.
const marinholab::sas::core::Clock & get_clock () const
 Get a const reference to the internal clock instance.
void start ()
 Start the thread execution.
void stop ()
 Stop the thread execution and wait for completion.
bool is_running () const
 Check if the thread is currently running.
std::string get_thread_name () const
 Get the thread name.
PRIORITY get_priority () const
 Get the priority level of this thread.
int get_cpu_core () const
 Get the CPU core that this thread is pinned to.
double get_period () const
 Get the desired loop period (sampling time).

Protected Member Functions

void run ()
 Main thread entry function.

Protected Attributes

marinholab::sas::core::Clock clock_
std::function< void()> loop_callback_
std::thread thread_
std::string thread_name_
std::atomic< bool > running_ {false}
std::atomic< bool > stop_requested_ {false}

Member Enumeration Documentation

◆ PRIORITY

Abstract priority levels for thread_manager threads.

These levels are mapped to concrete Linux scheduling policies and priority/nice values in apply_priority(). The enum values themselves (0, 10, 50, 80, 90, 99) are NOT passed directly to the OS in most cases — they exist purely to establish a monotonic ordering (LOWEST < ... CRITICAL) that is easy to read and compare in application code. The actual OS-level values used for each level are documented per-enumerator below, and are applied in sas_thread_manager.cpp.

Linux scheduling background:

  • SCHED_OTHER (the default, non-realtime policy) does not use sched_priority (it must be 0); differentiation between SCHED_OTHER threads is done via the nice value, range -20 (highest priority) to 19 (lowest), see setpriority(2).
  • SCHED_FIFO and SCHED_RR (realtime policies) use sched_priority directly, range 1 (low) to 99 (high) on Linux, see sched(7). Using these policies requires root or the CAP_SYS_NICE capability.
Note
The specific numeric choices below (nice 19/10/0, sched_priority 80/90/99) are this library's own convention, not values mandated by POSIX or Linux. Only the range (nice: -20..19, real-time sched_priority: 1..99) and the meaning of SCHED_OTHER's priority field being 0 are OS-defined. CRITICAL uses 99 specifically because that is the maximum legal sched_priority for SCHED_FIFO/ SCHED_RR on Linux (sched_get_priority_max()), i.e. "as high as the OS allows." HIGH (80) and REALTIME (90) are spaced below that ceiling to preserve headroom and a clear ordering, not because those exact numbers carry any special OS meaning.
Warning
Real-time priorities are Linux static priorities: within a given policy, EQUAL priorities are round-robined (SCHED_RR) or run strictly FIFO (SCHED_FIFO) — see sched(7). Two threads both at REALTIME or CRITICAL can starve each other under SCHED_FIFO if neither blocks or yields.
See also
apply_priority() for the concrete Linux policy/value mapping.
Enumerator
LOWEST 

SCHED_OTHER, nice 19 (least favorable, lowest priority).

BACKGROUND 

SCHED_OTHER, nice 10.

NORMAL 

SCHED_OTHER, nice 0 (default OS priority).

HIGH 

SCHED_RR, sched_priority 80 (requires root/CAP_SYS_NICE).

REALTIME 

SCHED_FIFO, sched_priority 90 (requires root/CAP_SYS_NICE).

CRITICAL 

SCHED_FIFO, sched_priority 99 — the OS-defined maximum.

Constructor & Destructor Documentation

◆ ThreadManager()

marinholab::sas::core::ThreadManager::ThreadManager ( const std::string & thread_name,
const double & period,
std::function< void()> callback,
PRIORITY priority = PRIORITY::NORMAL,
int cpu_core = -1 )

Constructor for ThreadManager.

Creates a thread manager that executes a callback function periodically with configurable priority and CPU affinity.

Parameters
thread_nameName of the thread for identification and debugging. On Linux, names are truncated to 15 characters.
periodPeriod in seconds between callback executions. Must be greater than 0.0.
callbackFunction to call periodically. The callback should be thread-safe and should not block for extended periods to avoid missing deadlines.
priorityThread priority level (default: PRIORITY::NORMAL). Higher priorities get more CPU time:
  • LOWEST (0): SCHED_OTHER, nice 19
  • BACKGROUND (10): SCHED_OTHER, nice 10
  • NORMAL (50): SCHED_OTHER, nice 0
  • HIGH (80): SCHED_RR, priority 80 (requires root)
  • REALTIME (90): SCHED_FIFO, priority 90 (requires root)
  • CRITICAL (99): SCHED_FIFO, priority 99 (requires root)
cpu_coreCPU core to pin the thread to (-1 = no affinity, default). Pinning to a specific core improves cache locality and reduces context switching for real-time applications.
Exceptions
std::invalid_argumentif period <= 0.0.
Note
Real-time priorities (HIGH, REALTIME, CRITICAL) require root privileges or CAP_SYS_NICE capability.
Warning
The callback must NEVER call start() or stop() on this same ThreadManager instance, whether directly or indirectly (e.g. through a nested function call). start() and stop() run under an internal mutex that is held while the loop thread is joined; calling either from within the callback (which runs on that same loop thread) will deadlock, since the thread would be waiting to acquire a mutex held by the very call that is waiting for the thread to finish. A stop() call from the callback would additionally attempt to join the thread from within itself, which is undefined behavior regardless of the mutex. If the callback needs to end the loop, it should signal that externally (e.g. via a flag it exposes) and let a different thread call stop().
See also
PRIORITY
start()
apply_priority()
apply_cpu_affinity()
// Create a normal priority thread with no CPU affinity
ThreadManager worker("Worker", 0.01, []() { do_work(); });
// Create a real-time thread pinned to CPU core 2
ThreadManager control(
"Control",
0.001,
[]() { compute_control(); },
2
);
Definition sas_thread_manager.hpp:38
@ CRITICAL
SCHED_FIFO, sched_priority 99 — the OS-defined maximum.
Definition sas_thread_manager.hpp:86

Member Function Documentation

◆ get_clock()

const marinholab::sas::core::Clock & marinholab::sas::core::ThreadManager::get_clock ( ) const

Get a const reference to the internal clock instance.

Returns
Const reference to the marinholab::sas::core::Clock object used for timing and statistics.

Provides access to the clock that manages timing, performance monitoring, and statistics collection for this thread. This is useful for:

  • Reading detailed timing statistics
  • Monitoring thread performance in real-time
  • Accessing clock configuration and state
Note
Returns a const reference to prevent modification of the clock's internal state.
The clock is updated in the thread's main loop via clock_.update_and_sleep().
See also
get_computation_time()
get_sleep_time()
get_effective_sampling_time()
get_overrun_count()
get_statistics()
ThreadManager worker("Worker", 0.01, []() { do_work(); });
worker.start();
// Access clock information
const auto& clock = worker.get_clock();
double mean_computation = clock.get_statistics(Statistics::Mean,
@ Computational
Time spent between when the instant the previous sleep ended and the instant when the current one sta...
Definition sas_clock.hpp:53

◆ get_cpu_core()

int marinholab::sas::core::ThreadManager::get_cpu_core ( ) const

Get the CPU core that this thread is pinned to.

Returns
CPU core number, or -1 if no affinity is set.

◆ get_period()

double marinholab::sas::core::ThreadManager::get_period ( ) const

Get the desired loop period (sampling time).

Returns
Period in seconds.

Returns the target period configured at construction time.

◆ get_priority()

ThreadManager::PRIORITY marinholab::sas::core::ThreadManager::get_priority ( ) const

Get the priority level of this thread.

Returns
The PRIORITY enum value.

◆ get_thread_name()

std::string marinholab::sas::core::ThreadManager::get_thread_name ( ) const

Get the thread name.

Returns
Thread name string

◆ is_running()

bool marinholab::sas::core::ThreadManager::is_running ( ) const

Check if the thread is currently running.

Returns
true if running, false otherwise

The documentation for this class was generated from the following files: