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 "libxr_system.hpp"
6#include "libxr_time.hpp"
7#include "logger.hpp"
8
9namespace LibXR
10{
15class Thread
16{
17 public:
22 enum class Priority : uint8_t
23 {
24 IDLE,
25 LOW,
26 MEDIUM,
27 HIGH,
28 REALTIME,
29 NUMBER,
30 };
31
36 Thread(){};
37
43 Thread(libxr_thread_handle handle) : thread_handle_(handle){};
44
65 template <typename ArgType>
66 void Create(ArgType arg, void (*function)(ArgType arg), const char *name,
67 size_t stack_depth, Thread::Priority priority)
68 {
69 pthread_attr_t attr;
70 pthread_attr_init(&attr);
71
72 // 线程栈大小设定,至少满足 PTHREAD_STACK_MIN
73 size_t stack_size = LibXR::max(static_cast<size_t>(PTHREAD_STACK_MIN), stack_depth);
74 pthread_attr_setstacksize(&attr, stack_size);
75
80 class ThreadBlock
81 {
82 public:
90 ThreadBlock(decltype(function) fun, ArgType arg, const char *name)
91 : fun_(fun),
92 arg_(arg),
93 name_(reinterpret_cast<char *>(malloc(strlen(name) + 1)))
94 {
95 strcpy(name_, name);
96 }
97
98 ~ThreadBlock() { free(name_); }
99
107 static void *Port(void *arg)
108 {
109 ThreadBlock *block = static_cast<ThreadBlock *>(arg);
110
111 if (block->name_ && block->name_[0] != '\0')
112 {
113 char name_buf[16];
114 std::strncpy(name_buf, block->name_, sizeof(name_buf) - 1);
115 name_buf[sizeof(name_buf) - 1] = '\0';
116 pthread_setname_np(pthread_self(), name_buf);
117 }
118
119 volatile const char *thread_name = block->name_;
120 block->fun_(block->arg_);
121
122 UNUSED(thread_name);
123 delete block;
124 return static_cast<void *>(nullptr);
125 }
126
127 decltype(function) fun_;
128 ArgType arg_;
129 char *name_;
130 };
131
132 auto block = new ThreadBlock(function, arg, name);
133
134 // 优先尝试设置 SCHED_FIFO 和线程优先级
135 int min_priority = sched_get_priority_min(SCHED_FIFO);
136 int max_priority = sched_get_priority_max(SCHED_FIFO);
137 bool scheduling_set = false;
138
139 UNUSED(scheduling_set);
140
141 if (max_priority - min_priority >= static_cast<int>(Priority::REALTIME))
142 {
143 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
144 pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
145
146 struct sched_param sp;
147 Memory::FastSet(&sp, 0, sizeof(sp));
148 sp.sched_priority = min_priority + static_cast<int>(priority);
149
150 if (pthread_attr_setschedparam(&attr, &sp) == 0)
151 {
152 scheduling_set = true;
153 }
154 else
155 {
156 XR_LOG_WARN("Failed to set thread priority. Falling back to default policy.");
157 pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
158 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
159 }
160 }
161 else
162 {
163 XR_LOG_WARN(
164 "SCHED_FIFO not supported or insufficient range. Using default policy.");
165 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
166 }
167
168 // 创建线程
169 int ans = pthread_create(&this->thread_handle_, &attr, ThreadBlock::Port, block);
170
171 pthread_attr_destroy(&attr);
172
173 if (ans != 0)
174 {
175 XR_LOG_WARN("Failed to create thread: %s (%s), retrying with default attributes.",
176 name, strerror(ans));
177
178 // 完全使用系统默认属性(attr = nullptr)
179 ans = pthread_create(&this->thread_handle_, nullptr, ThreadBlock::Port, block);
180
181 if (ans != 0)
182 {
183 XR_LOG_ERROR("Failed to create thread: %s (%s)", name, strerror(ans));
184 delete block;
185 }
186 }
187
188 pthread_attr_destroy(&attr);
189 }
190
196 static Thread Current(void);
197
203 static uint32_t GetTime();
204
210 static void Sleep(uint32_t milliseconds);
211
218 static void SleepUntil(MillisecondTimestamp &last_waskup_time, uint32_t time_to_sleep);
219
224 static void Yield();
225
231 operator libxr_thread_handle() { return thread_handle_; }
232
233 private:
234 libxr_thread_handle thread_handle_;
235};
236
237} // 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:16
Thread(libxr_thread_handle handle)
通过 POSIX 线程句柄创建线程对象 Constructor to create a thread object from a POSIX thread handle
Definition thread.hpp:43
Thread()
默认构造函数,初始化空线程 Default constructor initializing an empty thread
Definition thread.hpp:36
static uint32_t GetTime()
获取当前系统时间(毫秒) Gets the current system time in milliseconds
Definition thread.cpp:41
Priority
线程优先级枚举 Enumeration for thread priorities
Definition thread.hpp:23
@ 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:234
static void SleepUntil(MillisecondTimestamp &last_waskup_time, uint32_t time_to_sleep)
让线程休眠直到指定时间点 Puts the thread to sleep until a specified time
Definition thread.cpp:24
static Thread Current(void)
获取当前线程对象 Gets the current thread object
Definition thread.cpp:14
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:66
static void Sleep(uint32_t milliseconds)
让线程进入休眠状态 Puts the thread to sleep
Definition thread.cpp:16
static void Yield()
让出 CPU 以执行其他线程 Yields CPU execution to allow other threads to run
Definition thread.cpp:50
LibXR 命名空间
constexpr auto max(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最大值