libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
thread.hpp
1#pragma once
2
3#include <atomic>
4#include <climits>
5#include <cstring>
6
7#include "libxr_mem.hpp"
8#include "libxr_system.hpp"
9#include "libxr_time.hpp"
10#include "logger.hpp"
11
12namespace LibXR
13{
18class Thread
19{
20 public:
25 enum class Priority : uint8_t
26 {
27 IDLE,
28 LOW,
29 MEDIUM,
30 HIGH,
31 REALTIME,
32 NUMBER,
33 };
34
39 Thread() {};
40
46 Thread(libxr_thread_handle handle) : thread_handle_(handle) {};
47
73 template <typename ArgType>
74 void Create(ArgType arg, void (*function)(ArgType arg), const char* name,
75 size_t stack_depth, Thread::Priority priority)
76 {
77 pthread_attr_t attr;
78 pthread_attr_init(&attr);
79 ConfigureAttributes(attr, stack_depth, priority);
80
81 // 线程数据封装类 / Thread data encapsulation class
82 class ThreadBlock
83 {
84 public:
85 // 存储线程函数、参数和名称 / Store the thread function, argument and name
86 ThreadBlock(decltype(function) fun, ArgType arg, const char* name)
87 : fun_(fun), arg_(arg)
88 {
89 std::memset(name_, 0, sizeof(name_));
90 if (name != nullptr)
91 {
92 std::strncpy(name_, name, sizeof(name_) - 1);
93 }
94 }
95
96 // 线程入口:执行用户函数后释放 ThreadBlock,返回 nullptr / Thread entry: runs the
97 // user function, frees the ThreadBlock and returns nullptr
98 static void* Port(void* arg)
99 {
100 ThreadBlock* block = static_cast<ThreadBlock*>(arg);
101
102 if (block->name_[0] != '\0')
103 {
104 pthread_setname_np(pthread_self(), block->name_);
105 }
106
107 block->fun_(block->arg_);
108 delete block;
109 return static_cast<void*>(nullptr);
110 }
111
112 decltype(function) fun_; // 线程执行的函数 / Function executed by the thread
113 ArgType arg_; // 线程函数的参数 / Argument passed to the thread function
114 char name_[16]; // 线程名称 / Thread name
115 };
116
117 auto block = new ThreadBlock(function, arg, name);
118
119 // 创建线程
120 int ans = pthread_create(&this->thread_handle_, &attr, ThreadBlock::Port, block);
121
122 if (ans != 0)
123 {
124 if (FirstDefaultAttributeRetry())
125 {
126 XR_LOG_WARN(
127 "Failed to create thread: %s (%s), retrying with default attributes. Later "
128 "threads that fail the same way retry without this warning.",
129 name, strerror(ans));
130 }
131
132 // 完全使用系统默认属性(attr = nullptr)
133 ans = pthread_create(&this->thread_handle_, nullptr, ThreadBlock::Port, block);
134
135 if (ans != 0)
136 {
137 XR_LOG_ERROR("Failed to create thread: %s (%s)", name, strerror(ans));
138 delete block;
139 }
140 }
141
142 pthread_attr_destroy(&attr);
143 }
144
150 static Thread Current(void);
151
157 static uint32_t GetTime();
158
164 static void Sleep(uint32_t milliseconds);
165
172 static void SleepUntil(MillisecondTimestamp& last_wakeup_time, uint32_t time_to_sleep);
173
178 static void Yield();
179
184 ErrorCode Join();
185
191 operator libxr_thread_handle() { return thread_handle_; }
192
193 private:
200 static bool FirstDefaultAttributeRetry()
201 {
202 static std::atomic_flag retried = ATOMIC_FLAG_INIT;
203 return !retried.test_and_set(std::memory_order_relaxed);
204 }
205
206 static void ConfigureAttributes(pthread_attr_t& attr, size_t stack_depth,
207 Thread::Priority priority)
208 {
209 const size_t stack_size =
210 LibXR::max(static_cast<size_t>(PTHREAD_STACK_MIN), stack_depth);
211 pthread_attr_setstacksize(&attr, stack_size);
212 ConfigureScheduling(attr, priority);
213 }
214
215 static void ConfigureScheduling(pthread_attr_t& attr, Thread::Priority priority)
216 {
217 const int min_priority = sched_get_priority_min(SCHED_FIFO);
218 const int max_priority = sched_get_priority_max(SCHED_FIFO);
219 if (max_priority - min_priority < static_cast<int>(Priority::REALTIME))
220 {
221 XR_LOG_WARN(
222 "SCHED_FIFO not supported or insufficient range. Using default policy.");
223 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
224 return;
225 }
226
227 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
228 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
229
230 struct sched_param sp;
231 Memory::FastSet(&sp, 0, sizeof(sp));
232 sp.sched_priority = min_priority + static_cast<int>(priority);
233
234 if (pthread_attr_setschedparam(&attr, &sp) == 0)
235 {
236 return;
237 }
238
239 XR_LOG_WARN("Failed to set thread priority. Falling back to default policy.");
240 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
241 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
242 }
243
244 libxr_thread_handle thread_handle_;
245};
246
247} // namespace LibXR
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
毫秒时间戳 / Millisecond timestamp
线程管理类,封装 POSIX 线程创建和调度 Thread management class encapsulating POSIX thread creation and scheduling
Definition thread.hpp:19
Thread(libxr_thread_handle handle)
通过 POSIX 线程句柄创建线程对象 Constructor to create a thread object from a POSIX thread handle
Definition thread.hpp:46
static void SleepUntil(MillisecondTimestamp &last_wakeup_time, uint32_t time_to_sleep)
让线程休眠直到指定时间点 Puts the thread to sleep until a specified time
Definition thread.cpp:23
Thread()
默认构造函数,初始化空线程 Default constructor initializing an empty thread
Definition thread.hpp:39
static uint32_t GetTime()
获取当前系统时间(毫秒) Gets the current system time in milliseconds
Definition thread.cpp:35
Priority
线程优先级枚举 Enumeration for thread priorities
Definition thread.hpp:26
@ NUMBER
优先级数量 / Number of priority levels
@ LOW
低优先级 / Low priority
@ REALTIME
实时优先级 / Realtime priority
@ IDLE
空闲优先级 / Idle priority
@ HIGH
高优先级 / High priority
@ MEDIUM
中等优先级 / Medium priority
static Thread Current(void)
获取当前线程对象 Gets the current thread object
Definition thread.cpp:13
void Create(ArgType arg, void(*function)(ArgType arg), const char *name, size_t stack_depth, Thread::Priority priority)
创建新线程 Creates a new thread
Definition thread.hpp:74
ErrorCode Join()
Waits for this POSIX thread to terminate and releases its resources.
Definition thread.cpp:39
static void Sleep(uint32_t milliseconds)
让线程进入休眠状态 Puts the thread to sleep
Definition thread.cpp:15
static void Yield()
让出 CPU 以执行其他线程 Yields CPU execution to allow other threads to run
Definition thread.cpp:37
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
constexpr auto max(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最大值 / Computes the maximum of two numbers