libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
thread.hpp
1#pragma once
2
3#include <climits>
4#include <cstring>
5
6#include "libxr_mem.hpp"
7#include "libxr_system.hpp"
8#include "libxr_time.hpp"
9#include "logger.hpp"
10
11namespace LibXR
12{
17class Thread
18{
19 public:
24 enum class Priority : uint8_t
25 {
26 IDLE,
27 LOW,
28 MEDIUM,
29 HIGH,
30 REALTIME,
31 NUMBER,
32 };
33
38 Thread() {};
39
45 Thread(libxr_thread_handle handle) : thread_handle_(handle) {};
46
67 template <typename ArgType>
68 void Create(ArgType arg, void (*function)(ArgType arg), const char* name,
69 size_t stack_depth, Thread::Priority priority)
70 {
71 pthread_attr_t attr;
72 pthread_attr_init(&attr);
73 ConfigureAttributes(attr, stack_depth, priority);
74
79 class ThreadBlock
80 {
81 public:
89 ThreadBlock(decltype(function) fun, ArgType arg, const char* name)
90 : fun_(fun), arg_(arg)
91 {
92 std::memset(name_, 0, sizeof(name_));
93 if (name != nullptr)
94 {
95 std::strncpy(name_, name, sizeof(name_) - 1);
96 }
97 }
98
106 static void* Port(void* arg)
107 {
108 ThreadBlock* block = static_cast<ThreadBlock*>(arg);
109
110 if (block->name_[0] != '\0')
111 {
112 pthread_setname_np(pthread_self(), block->name_);
113 }
114
115 block->fun_(block->arg_);
116 delete block;
117 return static_cast<void*>(nullptr);
118 }
119
120 decltype(function) fun_;
121 ArgType arg_;
122 char name_[16];
123 };
124
125 auto block = new ThreadBlock(function, arg, name);
126
127 // 创建线程
128 int ans = pthread_create(&this->thread_handle_, &attr, ThreadBlock::Port, block);
129
130 if (ans != 0)
131 {
132 XR_LOG_WARN("Failed to create thread: %s (%s), retrying with default attributes.",
133 name, strerror(ans));
134
135 // 完全使用系统默认属性(attr = nullptr)
136 ans = pthread_create(&this->thread_handle_, nullptr, ThreadBlock::Port, block);
137
138 if (ans != 0)
139 {
140 XR_LOG_ERROR("Failed to create thread: %s (%s)", name, strerror(ans));
141 delete block;
142 }
143 }
144
145 pthread_attr_destroy(&attr);
146 }
147
153 static Thread Current(void);
154
160 static uint32_t GetTime();
161
167 static void Sleep(uint32_t milliseconds);
168
175 static void SleepUntil(MillisecondTimestamp& last_waskup_time, uint32_t time_to_sleep);
176
181 static void Yield();
182
187 ErrorCode Join();
188
194 operator libxr_thread_handle() { return thread_handle_; }
195
196 private:
197 static void ConfigureAttributes(pthread_attr_t& attr, size_t stack_depth,
198 Thread::Priority priority)
199 {
200 const size_t stack_size =
201 LibXR::max(static_cast<size_t>(PTHREAD_STACK_MIN), stack_depth);
202 pthread_attr_setstacksize(&attr, stack_size);
203 ConfigureScheduling(attr, priority);
204 }
205
206 static void ConfigureScheduling(pthread_attr_t& attr, Thread::Priority priority)
207 {
208 const int min_priority = sched_get_priority_min(SCHED_FIFO);
209 const int max_priority = sched_get_priority_max(SCHED_FIFO);
210 if (max_priority - min_priority < static_cast<int>(Priority::REALTIME))
211 {
212 XR_LOG_WARN(
213 "SCHED_FIFO not supported or insufficient range. Using default policy.");
214 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
215 return;
216 }
217
218 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
219 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
220
221 struct sched_param sp;
222 Memory::FastSet(&sp, 0, sizeof(sp));
223 sp.sched_priority = min_priority + static_cast<int>(priority);
224
225 if (pthread_attr_setschedparam(&attr, &sp) == 0)
226 {
227 return;
228 }
229
230 XR_LOG_WARN("Failed to set thread priority. Falling back to default policy.");
231 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
232 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
233 }
234
235 libxr_thread_handle thread_handle_;
236};
237
238} // 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:18
Thread(libxr_thread_handle handle)
通过 POSIX 线程句柄创建线程对象 Constructor to create a thread object from a POSIX thread handle
Definition thread.hpp:45
Thread()
默认构造函数,初始化空线程 Default constructor initializing an empty thread
Definition thread.hpp:38
static uint32_t GetTime()
获取当前系统时间(毫秒) Gets the current system time in milliseconds
Definition thread.cpp:35
Priority
线程优先级枚举 Enumeration for thread priorities
Definition thread.hpp:25
@ NUMBER
优先级数量 Number of priority levels
@ LOW
低优先级 Low priority
@ REALTIME
实时优先级 Realtime priority
@ IDLE
空闲优先级 Idle priority
@ HIGH
高优先级 High priority
@ MEDIUM
中等优先级 Medium priority
libxr_thread_handle thread_handle_
POSIX 线程句柄 POSIX thread handle.
Definition thread.hpp:235
static void SleepUntil(MillisecondTimestamp &last_waskup_time, uint32_t time_to_sleep)
让线程休眠直到指定时间点 Puts the thread to sleep until a specified time
Definition thread.cpp:23
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:68
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 命名空间
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举
constexpr auto max(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最大值