libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
thread.hpp
1#pragma once
2
3#include <climits>
4
5#include <cstring>
6
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),
91 arg_(arg)
92 {
93 std::memset(name_, 0, sizeof(name_));
94 if (name != nullptr)
95 {
96 std::strncpy(name_, name, sizeof(name_) - 1);
97 }
98 }
99
107 static void *Port(void *arg)
108 {
109 ThreadBlock *block = static_cast<ThreadBlock *>(arg);
110
111 if (block->name_[0] != '\0')
112 {
113 pthread_setname_np(pthread_self(), block->name_);
114 }
115
116 block->fun_(block->arg_);
117 delete block;
118 return static_cast<void *>(nullptr);
119 }
120
121 decltype(function) fun_;
122 ArgType arg_;
123 char name_[16];
124 };
125
126 auto block = new ThreadBlock(function, arg, name);
127
128 // 创建线程
129 int ans = pthread_create(&this->thread_handle_, &attr, ThreadBlock::Port, block);
130
131 if (ans != 0)
132 {
133 XR_LOG_WARN("Failed to create thread: %s (%s), retrying with default attributes.",
134 name, strerror(ans));
135
136 // 完全使用系统默认属性(attr = nullptr)
137 ans = pthread_create(&this->thread_handle_, nullptr, ThreadBlock::Port, block);
138
139 if (ans != 0)
140 {
141 XR_LOG_ERROR("Failed to create thread: %s (%s)", name, strerror(ans));
142 delete block;
143 }
144 }
145
146 pthread_attr_destroy(&attr);
147 }
148
154 static Thread Current(void);
155
161 static uint32_t GetTime();
162
168 static void Sleep(uint32_t milliseconds);
169
176 static void SleepUntil(MillisecondTimestamp &last_waskup_time, uint32_t time_to_sleep);
177
182 static void Yield();
183
189 operator libxr_thread_handle() { return thread_handle_; }
190
191 private:
192 static void ConfigureAttributes(pthread_attr_t& attr, size_t stack_depth,
193 Thread::Priority priority)
194 {
195 const size_t stack_size = LibXR::max(static_cast<size_t>(PTHREAD_STACK_MIN), stack_depth);
196 pthread_attr_setstacksize(&attr, stack_size);
197 ConfigureScheduling(attr, priority);
198 }
199
200 static void ConfigureScheduling(pthread_attr_t& attr, Thread::Priority priority)
201 {
202 const int min_priority = sched_get_priority_min(SCHED_FIFO);
203 const int max_priority = sched_get_priority_max(SCHED_FIFO);
204 if (max_priority - min_priority < static_cast<int>(Priority::REALTIME))
205 {
206 XR_LOG_WARN(
207 "SCHED_FIFO not supported or insufficient range. Using default policy.");
208 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
209 return;
210 }
211
212 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
213 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
214
215 struct sched_param sp;
216 Memory::FastSet(&sp, 0, sizeof(sp));
217 sp.sched_priority = min_priority + static_cast<int>(priority);
218
219 if (pthread_attr_setschedparam(&attr, &sp) == 0)
220 {
221 return;
222 }
223
224 XR_LOG_WARN("Failed to set thread priority. Falling back to default policy.");
225 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
226 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
227 }
228
229 libxr_thread_handle thread_handle_;
230};
231
232} // namespace LibXR
static void FastSet(void *dst, uint8_t value, size_t size)
快速内存填充 / Fast memory fill
表示毫秒级时间戳的类。Class representing a timestamp in milliseconds.
线程管理类,封装 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:229
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
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:40
LibXR 命名空间
Definition ch32_can.hpp:14
constexpr auto max(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最大值