Skip to main content

xwrust/xwos/
thd.rs

1//! XWOS RUST:线程
2//! ========
3//!
4//! XWOS的线程分为 **分离态** 或 **连接态** :
5//!
6//! + **分离态(detached)** :分离态的线程退出后由操作系统自动回收其内存资源;
7//! + **连接态(joinable)** :连接态的线程退出后需要被其他线程 `join()` ,之后才会被操作系统回收内存资源。
8//!
9//! XWOS RUST的线程分为 **动态线程** 与 **静态线程** 。无论哪种线程创建时,都是 **连接态(joinable)** 的。
10//! 线程创建后,将返回线程的 **Handle** 。如果未将线程的 **Handle** 绑定到变量上,线程将自动转变为 **分离态(detached)** 。
11//!
12//!
13//! # 动态线程
14//!
15//! **动态线程** 是指通过动态内存分配器创建的线程。
16//!
17//! 动态线程的对象结构体、栈、线程闭包等资源都是通过内存申请的接口动态创建的。
18//!
19//! XWOS RUST的动态线程库是仿照 [`std::thread`] 来编写的。
20//!
21//! ```rust
22//! use xwrust::xwos::thd;
23//!
24//! thd::spawn(|_| {
25//!     // 线程代码;
26//! });
27//! ```
28//!
29//! 在上述代码中,[`spawn()`] 方法会返回 [`DThdHandle`] ,但由于 [`DThdHandle`] 没有被绑定到任何变量名上,
30//! 其生命周期结束后的 [`drop()`] 方法会自动将动态线程转变为 **分离态(detached)** 。此线程运行结束后,其资源会被系统自动回收。
31//!
32//!
33//! 动态线程也可以是 **可连接的(joinable)** ,可以将返回的 [`DThdHandle`] 绑定在变量上。
34//! 然后通过 [`DThdHandle::join()`] 方法等待线程运行结束。
35//!
36//! ```rust
37//! use xwrust::xwos::thd;
38//!
39//! let res = thd::spawn(|_| {
40//!     // 线程代码;
41//!     // 返回值
42//! });
43//! match res {
44//!     Ok(handler) => {
45//!         match handler.join() {
46//!             Ok(r) => {
47//!                 // `r` 是线程闭包的返回值。
48//!             },
49//!             Err(e) => {
50//!                 // `join()` 失败时的错误码可通过 `e.state()` 获取。
51//!                 // `e` 是 `DThdHandle<R>` ,重新被返回。
52//!             },
53//!         };
54//!     },
55//!     Err(rc) => {
56//!         // `rc` 是 `spawn()` 失败时的错误码。
57//!     },
58//! };
59//! ```
60//!
61//! [`DThdHandle::join()`] 方法会返回 [`Result<R, Self>`] , `R` 是返回值的类型,并放在 [`Ok()`] 中,
62//! 方法调用失败时,会将 [`DThdHandle`] 放在 [`Err()`] 中重新返回。此时,用户可以通过 [`DThdHandle::state()`] 获取失败原因,
63//! 并且在合适的时机重新调用方法 [`DThdHandle::join()`] 。
64//!
65//!
66//! ## 动态线程的线程函数
67//!
68//! 动态线程可以使用 [`FnOnce()`] 闭包作为线程函数。其原型是: `FnOnce(Arc<DThdElement>) -> R` ,
69//! 动态线程函数运行时,参数是动态线程的元素 [`DThdElement`] ,返回值为泛型 `R` 。
70//!
71//!
72//! ## 动态线程的工厂模式
73//!
74//! 可以通过线程工厂 [`DThdBuilder`] 设置线程属性后,再创建动态线程:
75//!
76//! ```rust
77//! use xwrust::xwos::thd;
78//!
79//! let builder = thd::DThdBuilder::new()
80//!                                .name("foo".into()) // 设置线程的名称
81//!                                .stack_size(8 * 1024) // 设置线程栈大小
82//!                                .privileged(true); // 设置系统权限
83//!
84//! builder.spawn(|_| {
85//!     // 线程代码;
86//!     // 返回值
87//! });
88//! ```
89//!
90//! #### 线程的名称
91//!
92//! 线程工厂可以通过 [`DThdBuilder::name()`] 为线程指定一个字符串名字。可以为空,默认为 `"anon"` 。
93//!
94//! #### 线程的栈大小
95//!
96//! 线程工厂可以通过 [`DThdBuilder::stack_size()`] 为线程指定栈内存大小,默认为XWOS的内核配置 `XWMMCFG_STACK_SIZE_MIN` 。
97//!
98//! #### 线程的系统权限
99//!
100//! 某些SOC内部的寄存器,只有拥有系统权限的线程才可以访问。线程工厂可以通过 [`DThdBuilder::privileged()`] 为线程指定是否具有系统特权,默认为拥有系统权限。
101//!
102//!
103//! ## 动态线程的元素
104//!
105//! 动态线程的元素 [`DThdElement`] 是存放与线程相关的信息的内存空间。
106//! 动态线程工厂 [`DThdBuilder`] 中设置的信息会被转移到 [`DThdElement`] 中。
107//! 动态线程运行时, `Arc<DThdElement>` 作为参数被传递到闭包内。以 [`Arc<T>`] 进行封装是因为要将其放在堆上。
108//!
109//!
110//! ## 动态线程的句柄
111//!
112//! 静态线程的句柄 [`DThdHandle`] 功能类似于 [`std::thread::JoinHandle`] ,可用于控制动态子线程的退出。
113//!
114//! #### 中断动态线程的阻塞态和睡眠态
115//!
116//! 方法 [`DThdHandle::intr()`] 可用于中断线程的 **阻塞态** 和 **睡眠态** 。
117//! 阻塞和睡眠的方法将以返回值 **负** 的 [`EINTR`] 退出。错误码 [`EINTR`] 会被转换为各个可阻塞线程的操作系统对象的错误码:
118//!
119//! + [`MutexError::Interrupt`]
120//! + [`SemError::Interrupt`]
121//! + [`CondError::Interrupt`]
122//! + [`FlgError::Interrupt`]
123//! + [`BrError::Interrupt`]
124//! + [`SelError::Interrupt`]
125//!
126//! 方法 [`DThdHandle::intr()`] 是基于 [`ThdD::intr()`] 实现的,调用后者与前者在功能上没有区别。
127//! 动态线程自身的 [`ThdD`] 可通过 [`cthd::i()`] 获取。
128//!
129//! #### 通知动态线程退出
130//!
131//! 方法 [`DThdHandle::quit()`] 可用于父线程通知动态子线程退出。此方法不会等待动态子线程退出。
132//!
133//! 方法 [`DThdHandle::quit()`] 会为动态子线程设置 **退出状态** ,并中断 **阻塞状态** 和 **睡眠状态** 。
134//! 阻塞和睡眠的方法将以返回值负的 [`EINTR`] 退出。错误码 [`EINTR`] 会被转换为各个可阻塞线程的操作系统对象的错误码:
135//!
136//! + [`MutexError::Interrupt`]
137//! + [`SemError::Interrupt`]
138//! + [`CondError::Interrupt`]
139//! + [`FlgError::Interrupt`]
140//! + [`BrError::Interrupt`]
141//! + [`SelError::Interrupt`]
142//!
143//! 但是,当动态子线程的 **阻塞状态** 是不可被中断的,方法 [`DThdHandle::quit()`] 只会为动态子线程设置 **退出状态** ,不会发生中断。
144//!
145//! 动态子线程可以通过 [`cthd::shld_stop()`] 判断是否被设置了 **退出状态** ,可以作为结束线程循环的条件。
146//!
147//! 方法 [`DThdHandle::quit()`] 是基于 [`ThdD::quit()`] 实现的,调用后者与前者在功能上没有区别。
148//! 动态线程自身的 [`ThdD`] 可通过 [`cthd::i()`] 获取。
149//!
150//! #### 等待动态线程退出
151//!
152//! 当父线程需要等待动态子线程退出,并捕获其返回值时,需要使用方法 [`DThdHandle::join()`] 。
153//!
154//! + 如果动态子线程还在运行,此方法会阻塞父线程直到动态子线程退出。
155//! + 如果动态子线程已经提前运行至退出,此方法可立即返回动态子线程的返回值。
156//!
157//! 此方法会消费 [`DThdHandle`] :
158//!
159//! + 如果此方法执行成功,会消费掉 [`DThdHandle`] ,并将动态子线程的返回值放在 [`Ok()`] 中返回,因为线程已经结束,其 [`DThdHandle`] 的生命周期也应该结束;
160//! + 如果此方法执行失败,会重新在 [`Err()`] 中返回 [`DThdHandle`] ,用户可通过 [`DThdHandle::state()`] 方法获取失败的原因,并且在合适的重新调用 [`DThdHandle::join()`] 方法。
161//!
162//! #### 通知并等待动态线程退出
163//!
164//! 方法 [`DThdHandle::stop()`] 等价于 [`DThdHandle::quit()`] + [`DThdHandle::join()`]
165//!
166//!
167//! ## 动态线程的示例
168//!
169//! [XWOS/xwam/xwrust-example/xwrust_example_dthd](https://gitee.com/xwos/XWOS/blob/main/xwam/xwrust-example/xwrust_example_dthd/src/lib.rs)
170//!
171//!
172//! ## 对比 [`std::thread`]
173//!
174//! #### 闭包原型不同
175//!
176//! + [`std::thread`] 的闭包原型是 `FnOnce() -> R` 。
177//! + `xwrust::xwos::thd` 的闭包原型是 `FnOnce(Arc<DThdElement>) -> R` 。
178//! + 【举例】 [`std::thread`] 通过 `thread::current()` 获取线程自己的`handle`,然后获取线程的名称:
179//!
180//! ```rust
181//! use std::thread;
182//!
183//! let handler = thread::DThdBuilder::new()
184//!     .name("named thread".into())
185//!     .spawn(|| {
186//!         let handle = thread::current();
187//!         assert_eq!(handle.name(), Some("named thread"));
188//!     }).unwrap();
189//!
190//! handler.join().unwrap();
191//! ```
192//!
193//! + 【举例】 `xwrust::xwos::thd` 通过闭包参数 [`ele.name()`] 获取线程的名称:
194//!
195//! ```rust
196//! use xwrust::xwos::thd;
197//! use libc_print::std_name::println;
198//!
199//! thd::DThdBuilder::new()
200//!     .name("foo".into())
201//!     .spawn(|ele| {
202//!         println!("Thread name: {}", ele.name());
203//!     });
204//! ```
205//!
206//! 若不需要使用 `Arc<DThdElement>` ,可使用 `_` 占位。
207//!
208//! ```rust
209//! use xwrust::xwos::thd;
210//! use libc_print::std_name::println;
211//!
212//! thd::DThdBuilder::new()
213//!     .name("foo".into())
214//!     .spawn(|_| {
215//!         // 线程闭包
216//!     });
217//! ```
218//!
219//! #### **spawn()** 失败时的处理方式不同
220//!
221//! + [`std::thread`] **spawn()** 失败时,会直接 [`panic!()`] ;
222//! + XWOS是RTOS,运行环境是 `#![no_std]` , [`panic!()`] 意味着死机,因此需要处理 [`Err()`] ;
223//!
224//! ```rust
225//! use xwrust::xwos::thd;
226//!
227//! match thd::DThdBuilder::new()
228//!     .name("child".into())
229//!     .spawn(|ele| {
230//!         // 子线程闭包
231//!     }) {
232//!         Ok(h) => { // 新建子线程成功
233//!         },
234//!         Err(rc) => { // 新建子线程失败
235//!         },
236//!     };
237//! ```
238//!
239//! #### 子线程 [`panic!()`] 的处理方式不同
240//!
241//! + [`std::thread`] 可捕获子线程的 [`panic!()`] 。
242//! + `xwrust::xwos::thd` 的子线程 [`panic!()`] 后会导致整个系统 **halt** 。
243//! 目前 `#![no_std]` 环境的 **unwind** 支持还不完善,暂时无法实现类似于 [`std::thread`] 的捕获机制。
244//!
245//!
246//! # 静态线程
247//!
248//! **静态线程** 是指 **不** 通过动态内存分配器创建的线程,所需内存全部由编译器在编译链接阶段分配。
249//! 设计 **静态线程** 的目的是为了避免使用动态内存分配。在功能安全的场合,动态内存分配是禁止使用的。
250//!
251//! 因为无法确定线程会运行多长时间,只能将 **静态线程** 定义为 **静态生命周期** 的全局变量。
252//!
253//!
254//! ```rust
255//! use xwrust::xwos::thd::*;
256//!
257//! static STHD: SThd<1024, &str> = SThd::new("SThd", true);
258//! pub fn xwrust_example_sthd() {
259//!     let h = STHD.run(|sthd| { // 子线程
260//!         // 线程功能
261//!         "OK" // 返回值
262//!     });
263//!     let res = h.join();
264//!     match res {
265//!         Ok(r) => {
266//!             // `r` 是线程的返回值。
267//!         },
268//!         Err(e) => {
269//!             h = e;
270//!             // `join()` 失败时的错误码可通过 `e.state()` 获取。
271//!             // `e` 是 `SThdHandle` ,重新被返回。
272//!         },
273//!     };
274//!
275//! }
276//! ```
277//!
278//! 静态线程可以是 **可连接的(joinable)** 。当另一线程通过 [`SThd::run()`] 启动静态线程后,
279//! 可将返回的 [`SThdHandle`] 绑定在变量上,然后通过 [`SThdHandle::join()`] 方法等待静态线程运行结束并获取返回值。
280//!
281//!
282//! 当 [`SThdHandle`] 生命周期结束前, [`SThdHandle::join()`] 未被调用过,其 [`drop()`] 方法会将静态线程自动变成 **分离的(detached)** 。
283//!
284//!
285//! ## 静态线程的线程函数
286//!
287//! 定义RUST闭包时,实际上会生成一个隐藏的结构体,隐藏结构体中包括捕获的外部变量以及闭包函数。
288//! 闭包其实是这个隐藏结构体类型的变量,并且是在栈上建立的,其生命周期只限于函数局部。
289//! 因此,不能将闭包直接转移到静态线程的线程函数内部。
290//!
291//! 如何延长闭包生命周期?RUST语言的常用技巧是借助于 [`Box<T>`] 或 [`Arc<T>`] 将其放入堆中。
292//! 但若使用了 [`Box<T>`] 或 [`Arc<T>`] 就违背了 **不使用动态内存分配** 的初衷。
293//!
294//! 综上,静态线程的线程函数只能是 **普通函数** 或 **不捕获任何环境的闭包** 。
295//!
296//!
297//! 静态线程只能访问 **静态生命周期的全局变量** 。
298//! 其原型是 `fn(&Self) -> R` 。其中 `&Self` 是指向静态线程自身的引用, `R` 是泛型返回值。
299//!
300//!
301//! ## 静态线程的句柄
302//!
303//! 静态线程的句柄 [`SThdHandle`] 由方法 [`SThd::run()`] 返回,功能类似于 [`std::thread::JoinHandle`] ,可用于控制静态子线程的退出。
304//!
305//! #### 中断静态线程的阻塞态和睡眠态
306//!
307//! 方法 [`SThdHandle::intr()`] 可用于中断线程的 **阻塞态** 和 **睡眠态** 。
308//! 阻塞和睡眠的方法将以返回值 **负** 的 [`EINTR`] 退出。错误码 [`EINTR`] 会被转换为各个可阻塞线程的操作系统对象的错误码:
309//!
310//! + [`MutexError::Interrupt`]
311//! + [`SemError::Interrupt`]
312//! + [`CondError::Interrupt`]
313//! + [`FlgError::Interrupt`]
314//! + [`BrError::Interrupt`]
315//! + [`SelError::Interrupt`]
316//!
317//! 方法 [`SThdHandle::intr()`] 是基于 [`ThdD::intr()`] 实现的,调用后者与前者在功能上没有区别。
318//! 动态线程自身的 [`ThdD`] 可通过 [`cthd::i()`] 获取。
319//!
320//! #### 通知动态线程退出
321//!
322//! 方法 [`SThdHandle::quit()`] 可用于父线程通知静态子线程退出。此方法不会等待静态子线程退出。
323//!
324//! 方法 [`SThdHandle::quit()`] 是基于 [`SThd::quit()`] 实现的,调用后者与前者在功能上没有区别。后者可以由静态现在自己调用,自己通知自己退出。
325//!
326//! 方法 [`ThdD::quit()`] 也可达到同样的效果。静态态线程自身的 [`ThdD`] 可通过 [`cthd::i()`] 获取。
327//!
328//!
329//! 通知静态线程退出的方法会为静态子线程设置 **退出状态** ,并中断 **阻塞状态** 和 **睡眠状态** 。
330//! 阻塞和睡眠的方法将以返回值负的 [`EINTR`] 退出。错误码 [`EINTR`] 会被转换为各个可阻塞线程的操作系统对象的错误码:
331//!
332//! + [`MutexError::Interrupt`]
333//! + [`SemError::Interrupt`]
334//! + [`CondError::Interrupt`]
335//! + [`FlgError::Interrupt`]
336//! + [`BrError::Interrupt`]
337//! + [`SelError::Interrupt`]
338//!
339//! 但是,当静态子线程的 **阻塞状态** 是不可被中断的,方法 [`SThdHandle::quit()`] 只会为静态子线程设置 **退出状态** ,不会发生中断。
340//!
341//! 静态子线程可以通过 [`cthd::shld_stop()`] 判断是否被设置了 **退出状态** ,可以作为结束线程循环的条件。
342//!
343//! #### 等待动态线程退出
344//!
345//! 当父线程需要等待静态子线程退出,并捕获其返回值,需要使用方法 [`SThdHandle::join()`] 。
346//!
347//! + 如果静态子线程还在运行,此方法会阻塞父线程直到静态子线程退出。父线程的阻塞状态可被中断;
348//! + 如果静态子线程已经提前运行至退出,此方法可立即返回静态子线程的返回值。
349//!
350//! 此方法会消费 [`SThdHandle`] :
351//!
352//! + 如果此方法执行成功,会消费掉 [`SThdHandle`] ,并将静态子线程的返回值放在 [`Ok()`] 中返回,因为线程已经结束,其 [`SThdHandle`] 的生命周期也应该结束;
353//! + 如果此方法执行失败,会重新在 [`Err()`] 中返回 [`SThdHandle`] ,用户可通过 [`SThdHandle::state()`] 方法获取失败的原因,
354//!   并且在合适的时机重新调用 [`SThdHandle::join()`] 方法。
355//!
356//! #### 通知并等待动态线程退出
357//!
358//! 方法 [`SThdHandle::stop()`] 等价于 [`SThdHandle::quit()`] + [`SThdHandle::join()`]
359//!
360//!
361//! ## 静态线程的示例
362//!
363//! [XWOS/xwam/xwrust-example/xwrust_example_sthd](https://gitee.com/xwos/XWOS/blob/main/xwam/xwrust-example/xwrust_example_sthd/src/lib.rs)
364//!
365//!
366//! # 只可在线程自身函数内部调用的方法
367//!
368//! XWOS RUST有一组方法,只会对调用线程自身起作用,被实现在 [`xwrust::xwos::cthd`] 。命名中的 **c** 是 **current** 的意思。
369//!
370//!
371//! [`drop()`]: <https://doc.rust-lang.org/core/ops/trait.Drop.html#tymethod.drop>
372//! [`std::thread`]: <https://doc.rust-lang.org/std/thread/index.html>
373//! [`std::thread::JoinHandle`]: <https://doc.rust-lang.org/std/thread/struct.JoinHandle.html>
374//! [`panic!()`]: <https://doc.rust-lang.org/std/macro.panic.html>
375//! [`Ok()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok>
376//! [`Err()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err>
377//! [`FnOnce()`]: <https://doc.rust-lang.org/core/ops/trait.FnOnce.html>
378//! [`ele.name()`]: DThdElement::name
379//! [`EINTR`]: crate::errno::EINTR
380//! [`MutexError::Interrupt`]: crate::xwos::lock::mtx::MutexError::Interrupt
381//! [`SemError::Interrupt`]: crate::xwos::sync::sem::SemError::Interrupt
382//! [`CondError::Interrupt`]: crate::xwos::sync::cond::CondError::Interrupt
383//! [`FlgError::Interrupt`]: crate::xwos::sync::flg::FlgError::Interrupt
384//! [`BrError::Interrupt`]: crate::xwos::sync::br::BrError::Interrupt
385//! [`SelError::Interrupt`]: crate::xwos::sync::sel::SelError::Interrupt
386//! [`cthd::i()`]: crate::xwos::cthd::i
387//! [`cthd::shld_stop()`]: crate::xwos::cthd::shld_stop
388//! [`xwrust::xwos::cthd`]: crate::xwos::cthd
389//! [`Box<T>`]: <https://doc.rust-lang.org/alloc/boxed/struct.Box.html>
390//! [`Arc<T>`]: <https://doc.rust-lang.org/alloc/sync/struct.Arc.html>
391
392extern crate core;
393use core::ffi::*;
394use core::option::Option;
395use core::result::Result;
396use core::cell::UnsafeCell;
397use core::ptr;
398use core::mem;
399use core::str;
400use core::fmt;
401
402extern crate alloc;
403use alloc::boxed::Box;
404use alloc::string::String;
405use alloc::sync::Arc;
406
407use crate::types::*;
408
409extern "C" {
410    fn xwrustffi_thd_stack_size_default() -> XwSz;
411    fn xwrustffi_thd_attr_init(attr: *mut ThdAttr);
412    fn xwrustffi_thd_create(thd: *mut *mut c_void, tik: *mut XwSq,
413                            attr: *mut ThdAttr,
414                            mainfunc: extern "C" fn(*mut c_void) -> XwEr,
415                            arg: *mut c_void) -> XwEr;
416    fn xwrustffi_thd_init(thd: *mut c_void, tik: *mut XwSq,
417                          attr: *const ThdAttr,
418                          mainfunc: extern "C" fn(*mut c_void) -> XwEr,
419                          arg: *mut c_void) -> XwEr;
420    fn xwrustffi_thd_acquire(thd: *mut c_void, tik: XwSq) -> XwEr;
421    fn xwrustffi_thd_release(thd: *mut c_void, tik: XwSq) -> XwEr;
422    fn xwrustffi_thd_intr(thd: *mut c_void, tik: XwSq) -> XwEr;
423    fn xwrustffi_thd_quit(thd: *mut c_void, tik: XwSq) -> XwEr;
424    fn xwrustffi_thd_join(thd: *mut c_void, tik: XwSq, trc: *mut XwEr) -> XwEr;
425    fn xwrustffi_thd_stop(thd: *mut c_void, tik: XwSq, trc: *mut XwEr) -> XwEr;
426    fn xwrustffi_thd_detach(thd: *mut c_void, tik: XwSq) -> XwEr;
427    fn xwrustffi_thd_migrate(thd: *mut c_void, tik: XwSq, cpuid: XwId) -> XwEr;
428}
429
430/// XWOS线程的属性
431///
432/// 完全等价于C语言头文件 `xwos/osal/thd.h` 中的 `struct xwos_thd_attr`
433#[repr(C)]
434pub(crate) struct ThdAttr {
435    /// 线程的名字
436    pub(crate) name: *const c_char,
437    /// 线程栈的首地址
438    pub(crate) stack: *mut XwStk,
439    /// 线程栈的大小,以字节(byte)为单位
440    pub(crate) stack_size: XwSz,
441    /// 栈内存警戒线位置
442    pub(crate) stack_guard_size: XwSz,
443    /// 优先级
444    pub(crate) priority: XwPr,
445    /// 是否为分离态
446    pub(crate) detached: bool,
447    /// 是否为特权线程
448    pub(crate) privileged: bool,
449}
450
451/// XWOS的线程对象描述符
452///
453/// 用于调用XWOS-CAPI
454pub struct ThdD {
455    /// XWOS线程对象的指针
456    pub thd: *mut c_void,
457    /// XWOS线程对象的标签
458    pub tik: XwSq,
459}
460
461unsafe impl Send for ThdD {}
462unsafe impl Sync for ThdD {}
463
464impl ThdD {
465    unsafe fn new(attr: &mut ThdAttr, func: Box<dyn FnOnce()>) -> Result<ThdD, XwEr> {
466        let boxboxfunc = Box::new(func);
467        let rawboxfunc = Box::into_raw(boxboxfunc);
468        let mut thd: *mut c_void = ptr::null_mut();
469        let mut tik: XwSq = 0;
470        let rc = xwrustffi_thd_create(&mut thd, &mut tik, attr,
471                                      ThdD::xwrust_dthd_entry, rawboxfunc as *mut _);
472        return if rc < 0 {
473            drop(Box::from_raw(rawboxfunc)); // 创建失败,需要释放f
474            Err(rc)
475        } else {
476            Ok(ThdD {thd: thd, tik: tik})
477        };
478    }
479
480    extern "C" fn xwrust_dthd_entry(main: *mut c_void) -> XwEr {
481        unsafe {
482            let func = Box::from_raw(main as *mut Box<dyn FnOnce()>);
483            func();
484        }
485        0
486    }
487
488    /// 中断线程的阻塞态和睡眠态
489    pub fn intr(&self) -> XwEr {
490        unsafe {
491            xwrustffi_thd_intr(self.thd, self.tik)
492        }
493    }
494
495    /// 通知线程退出
496    pub fn quit(&self) -> XwEr {
497        unsafe {
498            xwrustffi_thd_quit(self.thd, self.tik)
499        }
500    }
501
502    fn join(&mut self) ->XwEr {
503        unsafe {
504            xwrustffi_thd_join(self.thd, self.tik, ptr::null_mut())
505        }
506    }
507
508    fn stop(&mut self) -> XwEr {
509        unsafe {
510            xwrustffi_thd_stop(self.thd, self.tik, ptr::null_mut())
511        }
512    }
513
514    fn detach(&mut self) -> XwEr {
515        unsafe {
516            xwrustffi_thd_detach(self.thd, self.tik)
517        }
518    }
519
520    /// 将线程迁移到目标CPU
521    ///
522    /// # 参数说明
523    ///
524    /// + cpuid: 目标CPU的ID
525    pub fn migrate(&self, cpuid: XwId) -> XwEr {
526        unsafe {
527            xwrustffi_thd_migrate(self.thd, self.tik, cpuid)
528        }
529    }
530}
531
532impl fmt::Debug for ThdD {
533    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
534        f.debug_struct("ThdD")
535            .field("thd", &self.thd)
536            .field("tik", &self.tik)
537            .finish()
538    }
539}
540
541/// 线程的 `join()/stop()` 状态
542#[derive(Debug)]
543pub enum ThdJoinState {
544    /// 已经被连接
545    Joined,
546    /// 可被连接的
547    Joinable,
548    /// 连接错误
549    JoinErr(XwEr),
550}
551
552
553////////////////////////////////////////////////////////////////////////////////
554// 动态线程
555////////////////////////////////////////////////////////////////////////////////
556
557/// 动态线程的工厂模式结构体,可用于配置新线程的属性
558///
559/// + [`name`] 设置线程的名字
560/// + [`stack_size`] 设置线程的栈大小
561/// + [`privileged`] 设置线程的系统权限
562///
563/// [`spawn`] 方法将获取构建器的所有权,并使用给定的配置创建线程,返回 [`Result`] 。
564///
565/// [`thd::spawn`] 独立的函数,并使用默认配置的 `DThdBuilder`创建线程,返回 [`Result`] 。
566///
567///
568/// # 示例
569///
570/// ```rust
571/// use xwrust::xwos::thd;
572///
573/// let builder = thd::DThdBuilder::new();
574///
575/// builder.spawn(|_| {
576///     // 线程代码;
577///     // 返回值
578/// });
579/// ```
580///
581/// [`name`]: DThdBuilder::name
582/// [`stack_size`]: DThdBuilder::stack_size
583/// [`privileged`]: DThdBuilder::privileged
584/// [`spawn`]: DThdBuilder::spawn
585/// [`thd::spawn`]: spawn
586/// [`Result`]: <https://doc.rust-lang.org/core/result/enum.Result.html>
587pub struct DThdBuilder {
588    /// 线程的名字
589    name: Option<String>,
590    /// 线程栈的大小,以字节(byte)为单位
591    stack_size: Option<XwSz>,
592    /// 是否为特权线程
593    privileged: Option<bool>,
594}
595
596impl DThdBuilder {
597    /// 新建用于创建动态线程的工厂
598    ///
599    /// # 示例
600    ///
601    /// ```rust
602    /// use xwrust::xwos::thd;
603    ///
604    /// let builder = thd::DThdBuilder::new()
605    ///                                .name("foo".into()) // 设置线程的名称
606    ///                                .stack_size(8 * 1024) // 设置线程栈大小
607    ///                                .privileged(true); // 设置系统权限
608    ///
609    /// builder.spawn(|_| {
610    ///     // 线程代码;
611    ///     // 返回值
612    /// });
613    /// ```
614    pub fn new() -> DThdBuilder {
615        DThdBuilder {
616            name: None,
617            stack_size: None,
618            privileged: None,
619        }
620    }
621
622    /// 设置动态线程的名称
623    ///
624    /// # 示例
625    ///
626    /// ```rust
627    /// use xwrust::xwos::thd;
628    /// use libc_print::std_name::println;
629    ///
630    /// let builder = thd::DThdBuilder::new()
631    ///                                .name("foo".into()); // 设置线程的名称
632    ///
633    /// builder.spawn(|ele| {
634    ///     println!("My name is {}.", ele.name().unwrap());
635    ///     // 线程代码;
636    ///     // 返回值
637    /// });
638    /// ```
639    pub fn name(mut self, name: String) -> DThdBuilder {
640        self.name = Some(name);
641        self
642    }
643
644    /// 设置动态线程栈的大小
645    ///
646    /// # 示例
647    ///
648    /// ```rust
649    /// use xwrust::xwos::thd;
650    ///
651    /// let builder = thd::DThdBuilder::new()
652    ///                                .stack_size(8 * 1024); // 设置线程栈大小
653    ///
654    /// builder.spawn(|_| {
655    ///     // 线程代码;
656    ///     // 返回值
657    /// });
658    /// ```
659    pub fn stack_size(mut self, size: XwSz) -> DThdBuilder {
660        self.stack_size = Some(size);
661        self
662    }
663
664    /// 设置动态线程栈的系统权限
665    ///
666    /// # 示例
667    ///
668    /// ```rust
669    /// use xwrust::xwos::thd;
670    ///
671    /// let builder = thd::DThdBuilder::new()
672    ///                                .privileged(true); // 设置系统权限
673    ///
674    /// builder.spawn(|_| {
675    ///     // 线程代码;
676    ///     // 返回值
677    /// });
678    /// ```
679    pub fn privileged(mut self, privileged: bool) -> DThdBuilder {
680        self.privileged = Some(privileged);
681        self
682    }
683
684    /// 消费 `DThdBuilder` ,并新建一个动态线程
685    ///
686    /// + 创建线程成功,返回一个包含 [`DThdHandle`] 的 [`Result`] ;
687    /// + 创建线程失败,返回一个包含 [`XwEr`] 的 [`Result`] , [`XwEr`] 指示错误的原因。
688    ///
689    /// 方法的签名:
690    ///
691    /// + [`'static`] 约束是因为新建的线程可能比调用者的生命周期更长,因此线程的闭包和返回值的生命周期限定为静态生命周期;
692    /// + [`Send`] 约束是因为闭包和返回值需要在线程之间进行转移。并且被移动到 [`Send`] 约束的闭包的变量也必须是 [`Send`] 的,否则编译器会报错。
693    ///   RUSTC是通过 [`Send`] 约束来区分闭包是不是另一线程的代码的。
694    ///
695    /// # 参数说明
696    ///
697    /// + f: 线程的闭包
698    ///
699    /// # 示例
700    ///
701    /// ```rust
702    /// use xwrust::xwos::thd;
703    ///
704    /// let builder = thd::DThdBuilder::new()
705    ///     .name("foo".into()) // 设置线程的名称
706    ///     .stack_size(8 * 1024) // 设置线程栈大小
707    ///     .privileged(true); // 设置系统权限
708    /// match builder.spawn(|_| {
709    ///     // 线程代码;
710    ///     // 返回值
711    /// }) {
712    ///     Ok(handler) => {
713    ///         match handler.join() {
714    ///             Ok(r) => {
715    ///                 // r 是线程闭包的返回值。
716    ///             },
717    ///             Err(e) => {
718    ///                 // `join()` 失败的错误码可通过 `e.state()` 获取。
719    ///                 // `e` 是 `DThdHandle<R>` ,重新被返回。
720    ///             },
721    ///         };
722    ///     },
723    ///     Err(rc) => {
724    ///         // `rc` 是 `spawn()` 失败时的错误码。
725    ///     }
726    /// };
727    /// ```
728    /// [`Result`]: <https://doc.rust-lang.org/core/result/enum.Result.html>
729    /// [`'static`]: <https://doc.rust-lang.org/std/keyword.static.html>
730    /// [`Send`]: <https://doc.rust-lang.org/core/marker/trait.Send.html>
731    pub fn spawn<F, R>(self, f: F) -> Result<DThdHandle<R>, XwEr>
732    where
733        F: FnOnce(Arc<DThdElement>) -> R,
734        F: Send + 'static,
735        R: Send + 'static,
736    {
737        unsafe { self.spawn_unchecked(f) }
738    }
739
740    /// 消费 `DThdBuilder` ,并产生一个新的动态线程
741    ///
742    /// + 创建线程成功,返回一个包含 [`DThdHandle`] 的 [`Result`] ;
743    /// + 创建线程失败,返回一个包含 [`XwEr`] 的 [`Result`] , [`XwEr`] 指示错误的原因。
744    ///
745    /// 此方法只要求闭包 `F` 和 返回值 `R` 的生命周期一样长,然后不做其他限制,因此是 `unsafe` 的。
746    ///
747    /// # 参数说明
748    ///
749    /// + f: 线程的闭包
750    ///
751    /// # 示例
752    ///
753    /// ```rust
754    /// use xwrust::xwos::thd;
755    ///
756    /// let builder = thd::DThdBuilder::new()
757    ///     .name("foo".into()) // 设置线程的名称
758    ///     .stack_size(8 * 1024) // 设置线程栈大小
759    ///     .privileged(true); // 设置系统权限
760    /// match unsafe { builder.spawn_unchecked(|_| {
761    ///     // 线程代码;
762    ///     // 返回值
763    /// })} {
764    ///     Ok(handler) => {
765    ///         match handler.join() {
766    ///             Ok(r) => {
767    ///                 // r 是线程闭包的返回值。
768    ///             },
769    ///             Err(e) => {
770    ///                 // join() 失败时的错误码可通过 e.state() 获取。
771    ///                 // e 是 DThdHandle<R> ,重新被返回。
772    ///             },
773    ///         };
774    ///     },
775    ///     Err(rc) => {
776    ///         // rc 是 spawn() 失败时的错误码。
777    ///     }
778    /// };
779    /// ```
780    /// [`Result`]: <https://doc.rust-lang.org/core/result/enum.Result.html>
781    pub unsafe fn spawn_unchecked<'a, F, R>(self, f: F) -> Result<DThdHandle<R>, XwEr>
782    where
783        F: FnOnce(Arc<DThdElement>) -> R,
784        F: Send + 'a,
785        R: Send + 'a,
786    {
787        Ok(DThdHandle{inner: self.spawn_unchecked_(f)?})
788    }
789
790    unsafe fn spawn_unchecked_<'a, F, R>(self, f: F) -> Result<DThdHandleInner<R>, XwEr>
791    where
792        F: FnOnce(Arc<DThdElement>) -> R,
793        F: Send + 'a,
794        R: Send + 'a,
795    {
796        let mut attr: ThdAttr = mem::zeroed();
797        xwrustffi_thd_attr_init(&mut attr);
798        let name = self.name.unwrap_or("anon".into());
799        attr.stack_size = self.stack_size.unwrap_or(xwrustffi_thd_stack_size_default());
800        attr.privileged = self.privileged.unwrap_or(true);
801        let element: Arc<DThdElement> =
802            Arc::new(DThdElement::new(name, attr.stack_size, attr.privileged));
803        let thd_element = element.clone();
804
805        let retval: Arc<DThdReturnValue<R>> =
806            Arc::new(DThdReturnValue { result: UnsafeCell::new(None) });
807        let thd_retval = retval.clone();
808
809        let main = move || {
810            let result = f(thd_element);
811            *thd_retval.result.get() = Some(result);
812        };
813
814        Ok(DThdHandleInner {
815            thdd: ThdD::new(&mut attr,
816                            mem::transmute::<Box<dyn FnOnce() + 'a>, Box<dyn FnOnce() + 'static>>(Box::new(main)))?,
817            state: ThdJoinState::Joinable,
818            element: element,
819            rv: retval,
820        })
821    }
822}
823
824/// 新建一个动态线程
825///
826/// + 创建线程成功,返回一个包含 [`DThdHandle`] 的 [`Result`] ;
827/// + 创建线程失败,返回一个包含 [`XwEr`] 的 [`Result`] , [`XwEr`] 指示错误的原因。
828///
829/// 此方法使用默认的线程工厂创建线程。
830///
831/// 当 [`DThdHandle`] 被 [`drop()`] 时,新建的线程会变成 **detached(分离的)** 。此时,新建的线程不能再被 [`join()`] 。
832///
833/// 方法的签名:
834///
835/// + [`'static`] 约束是因为新建的线程可能比调用者的生命周期更长,因此线程的闭包和返回值的生命周期限定为静态生命周期;
836/// + [`Send`] 约束是因为闭包和返回值需要在线程之间进行转移。并且被移动到 [`Send`] 约束的闭包的变量也必须是 [`Send`] 的,否则编译器会报错。
837///   RUSTC是通过 [`Send`] 约束来区分闭包是不是另一线程的代码的。
838///
839/// # 参数说明
840///
841/// + f: 线程的闭包
842///
843/// # 示例
844///
845/// ```rust
846/// use xwrust::xwos::thd;
847///
848/// match thd::spawn(|_| {
849///     // 线程代码;
850///     // 返回值
851/// }) {
852///     Ok(handler) => {
853///         match handler.join() {
854///             Ok(r) => {
855///                 // r 是线程闭包的返回值。
856///             },
857///             Err(e) => {
858///                 // join() 失败时的错误码可通过 e.state() 获取。
859///                 // e 是 DThdHandle<R> ,重新被返回。
860///             },
861///         };
862///     },
863///     Err(rc) => {
864///         // rc 是 spawn() 失败时的错误码。
865///     },
866/// };
867/// ```
868/// [`Result`]: <https://doc.rust-lang.org/core/result/enum.Result.html>
869/// [`drop()`]: <https://doc.rust-lang.org/core/ops/trait.Drop.html#tymethod.drop>
870/// [`join()`]: DThdHandle::join
871/// [`'static`]: <https://doc.rust-lang.org/std/keyword.static.html>
872/// [`Send`]: <https://doc.rust-lang.org/core/marker/trait.Send.html>
873pub fn spawn<F, R>(f: F) -> Result<DThdHandle<R>, XwEr>
874where
875    F: FnOnce(Arc<DThdElement>) -> R,
876    F: Send + 'static,
877    R: Send + 'static,
878{
879    DThdBuilder::new().spawn(f)
880}
881
882/// 动态线程的元素
883///
884/// 动态线程的元素中的数据需跨线程共享,因此在定义时需要使用 [`Arc`] 进行封装。
885///
886/// [`Arc`]: <https://doc.rust-lang.org/alloc/sync/struct.Arc.html>
887pub struct DThdElement {
888    /// 线程的名字
889    name: String,
890    /// 线程栈的大小,以字节(byte)为单位
891    stack_size: XwSz,
892    /// 是否为特权线程
893    privileged: bool,
894}
895
896impl DThdElement {
897    pub(crate) fn new(name: String,
898                      stack_size: XwSz,
899                      privileged: bool) -> DThdElement {
900        DThdElement {
901            name,
902            stack_size,
903            privileged
904        }
905    }
906
907    /// 返回动态线程名字的引用
908    ///
909    /// # 示例
910    ///
911    /// ```rust
912    /// use xwrust::xwos::thd;
913    /// use libc_print::std_name::println;
914    ///
915    /// let handler = thd::DThdBuilder::new()
916    ///     .name("foo".into())
917    ///     .spawn(|ele| {
918    ///         println!("Thread name: {}", ele.name());
919    ///     });
920    /// ```
921    pub fn name(&self) -> &str {
922        &self.name
923    }
924
925    /// 返回动态线程的栈大小
926    ///
927    /// # 示例
928    ///
929    /// ```rust
930    /// use xwrust::xwos::thd;
931    /// use libc_print::std_name::println;
932    ///
933    /// let handler = thd::DThdBuilder::new()
934    ///     .spawn(|ele| {
935    ///         println!("Thread stack size: {}", ele.stack_size()); // 将返回默认线程大小
936    ///     });
937    /// ```
938    pub fn stack_size(&self) -> XwSz {
939        self.stack_size
940    }
941
942    /// 返回动态线程是否具有特权
943    ///
944    /// # 示例
945    ///
946    /// ```rust
947    /// use xwrust::xwos::thd;
948    /// use libc_print::std_name::println;
949    ///
950    /// let handler = thd::DThdBuilder::new()
951    ///     .privileged(true);
952    ///     .spawn(|ele| {
953    ///         println!("Thread is privileged: {} .", ele.privileged());
954    ///     });
955    /// ```
956    pub fn privileged(&self) -> bool {
957        self.privileged
958    }
959}
960
961impl fmt::Debug for DThdElement {
962    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
963        f.debug_struct("DThdElement")
964            .field("name", &self.name)
965            .finish()
966    }
967}
968
969/// 动态线程的返回值
970///
971/// 动态线程的返回值中的数据需跨线程共享,因此在定义时需要使用 [`Arc`] 进行封装。
972///
973/// [`Arc`]: <https://doc.rust-lang.org/alloc/sync/struct.Arc.html>
974struct DThdReturnValue<R> {
975    result: UnsafeCell<Option<R>>,
976}
977
978unsafe impl<R: Sync> Sync for DThdReturnValue<R> {}
979
980
981struct DThdHandleInner<R> {
982    /// XWOS线程的描述符
983    thdd: ThdD,
984    /// 线程的 `join()/stop()` 状态
985    state: ThdJoinState,
986    /// 线程的元素
987    element: Arc<DThdElement>,
988    /// 线程的返回值
989    rv: Arc<DThdReturnValue<R>>,
990}
991
992impl<R> DThdHandleInner<R> {
993    fn intr(&self) -> XwEr {
994        self.thdd.intr()
995    }
996
997    fn quit(&self) -> XwEr {
998        self.thdd.quit()
999    }
1000
1001    fn join(mut self) -> Result<R, Self> {
1002        let rc = self.thdd.join();
1003        if rc == 0 {
1004            self.state = ThdJoinState::Joined;
1005            Ok(Arc::get_mut(&mut self.rv).unwrap().result.get_mut().take().unwrap())
1006        } else {
1007            self.state = ThdJoinState::JoinErr(rc);
1008            Err(self)
1009        }
1010    }
1011
1012    fn stop(mut self) -> Result<R, Self> {
1013        let rc = self.thdd.stop();
1014        if rc == 0 {
1015            self.state = ThdJoinState::Joined;
1016            Ok(Arc::get_mut(&mut self.rv).unwrap().result.get_mut().take().unwrap())
1017        } else {
1018            self.state = ThdJoinState::JoinErr(rc);
1019            Err(self)
1020        }
1021    }
1022}
1023
1024impl<R> Drop for DThdHandleInner<R> {
1025    fn drop(&mut self) {
1026        match self.state {
1027            ThdJoinState::Joined => {
1028            },
1029            _ => {
1030                self.thdd.detach();
1031            },
1032        };
1033    }
1034}
1035
1036impl<R> fmt::Debug for DThdHandleInner<R> {
1037    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1038        f.debug_struct("DThdHandleInner")
1039            .field("thdd", &self.thdd)
1040            .field("state", &self.state)
1041            .field("element", &self.element)
1042            .finish_non_exhaustive()
1043    }
1044}
1045
1046/// 动态线程的句柄
1047pub struct DThdHandle<R> {
1048    inner: DThdHandleInner<R>
1049}
1050
1051unsafe impl<R> Send for DThdHandle<R> {}
1052unsafe impl<R> Sync for DThdHandle<R> {}
1053
1054impl<R> DThdHandle<R> {
1055    /// 返回XWOS的线程对象描述符
1056    ///
1057    /// 线程对象描述符用于与C语言交互。
1058    pub fn thdd(&self) -> &ThdD {
1059        &self.inner.thdd
1060    }
1061
1062    /// 返回线程的元素
1063    pub fn element(&self) -> &DThdElement {
1064        &self.inner.element
1065    }
1066
1067    /// 中断线程的阻塞态和睡眠态
1068    ///
1069    /// 此方法用于中断线程的 **阻塞态** 和 **睡眠态** 。
1070    ///
1071    /// # 上下文
1072    ///
1073    /// + 线程、中断、中断底半部、空闲任务
1074    pub fn intr(&self) -> XwEr {
1075        self.inner.intr()
1076    }
1077
1078    /// 通知动态线程退出
1079    ///
1080    /// 此方法用于向线程设置 **退出状态** 。
1081    ///
1082    /// 调用此方法的线程不会等待被设置 **退出状态** 的线程退出。
1083    ///
1084    /// 此方法可被重复调用,线程的 **退出状态** 一旦被设置,不可被清除。
1085    ///
1086    /// # 上下文
1087    ///
1088    /// + 线程、中断、中断底半部、空闲任务
1089    pub fn quit(&self) -> XwEr {
1090        self.inner.quit()
1091    }
1092
1093    /// 等待动态线程运行至退出,并返回线程的返回值
1094    ///
1095    /// + 如果动态子线程还在运行,此方法会阻塞父线程直到动态子线程退出。父线程的阻塞状态可被中断;
1096    /// + 如果动态子线程已经提前运行至退出,此方法可立即返回动态子线程的返回值。
1097    ///
1098    /// 此方法会消费 [`self`] :
1099    ///
1100    /// + 如果此方法执行成功,会消费掉 [`self`] ,并将动态子线程的返回值放在 [`Ok()`] 中返回,因为线程已经结束,其 [`DThdHandle`] 的生命周期也应该结束;
1101    /// + 如果此方法执行失败,会重新在 [`Err()`] 中返回 [`self`] ,并可通过 [`DThdHandle::state()`] 方法获取失败的原因。
1102    ///
1103    /// # 上下文
1104    ///
1105    /// + 线程
1106    ///
1107    /// # 示例
1108    ///
1109    /// ```rust
1110    /// use xwrust::xwos::thd;
1111    ///
1112    /// match thd::spawn(|_| {
1113    ///     // 线程代码;
1114    ///     // 返回值
1115    /// }) {
1116    ///     Ok(handler) => {
1117    ///         match handler.join() {
1118    ///             Ok(r) => {
1119    ///                 // r 是线程闭包的返回值。
1120    ///             },
1121    ///             Err(e) => {
1122    ///                 // `join()` 失败时的错误码可通过 `e.state()` 获取。
1123    ///                 // `e` 是 `DThdHandle<R>` ,重新被返回。
1124    ///             },
1125    ///         };
1126    ///     },
1127    ///     Err(rc) => {
1128    ///         // rc 是 spawn() 失败时的错误码。
1129    ///     },
1130    /// };
1131    /// ```
1132    ///
1133    /// [`Ok()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok>
1134    /// [`Err()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err>
1135    pub fn join(self) -> Result<R, Self> {
1136        match self.inner.join() {
1137            Ok(r) => Ok(r),
1138            Err(e) => Err(Self{inner: e}),
1139        }
1140    }
1141
1142    /// 终止动态线程并等待线程运行至退出,并返回线程的返回值
1143    ///
1144    /// + 如果动态子线程还在运行,此方法会阻塞父线程直到动态子线程退出。父线程的阻塞状态可被中断;
1145    /// + 如果动态子线程已经提前运行至退出,此方法可立即返回动态子线程的返回值。
1146    ///
1147    /// 此方法 = [`DThdHandle::quit()`] + [`DThdHandle::join()`]
1148    ///
1149    ///
1150    /// 此方法会消费 [`self`] :
1151    ///
1152    /// + 如果此方法执行成功,会消费掉 [`self`] ,并将动态子线程的返回值放在 [`Ok()`] 中返回,因为线程已经结束,其 [`DThdHandle`] 的生命周期也应该结束;
1153    /// + 如果此方法执行失败,会重新在 [`Err()`] 中返回 [`self`] ,并可通过 [`DThdHandle::state()`] 方法获取失败的原因。
1154    ///
1155    /// # 上下文
1156    ///
1157    /// + 线程
1158    ///
1159    /// # 示例
1160    ///
1161    /// ```rust
1162    /// use xwrust::xwos::thd;
1163    ///
1164    /// match thd::spawn(|_| {
1165    ///     // 线程代码;
1166    ///     // 返回值
1167    /// }) {
1168    ///     Ok(handler) => {
1169    ///         match handler.stop() {
1170    ///             Ok(r) => {
1171    ///                 // r 是线程闭包的返回值。
1172    ///             },
1173    ///             Err(e) => {
1174    ///                 // `stop()` 失败时的错误码可通过 `e.state()` 获取。
1175    ///                 // `e` 是 `DThdHandle<R>` ,重新被返回。
1176    ///             },
1177    ///         };
1178    ///     },
1179    ///     Err(rc) => {
1180    ///         // rc 是 spawn() 失败时的错误码。
1181    ///     },
1182    /// };
1183    /// ```
1184    ///
1185    /// [`Ok()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok>
1186    /// [`Err()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err>
1187    pub fn stop(self) -> Result<R, Self> {
1188        match self.inner.stop() {
1189            Ok(r) => Ok(r),
1190            Err(e) => Err(Self{inner: e}),
1191        }
1192    }
1193
1194    /// 返回动态线程的 `join()/stop()` 状态
1195    pub fn state<'a>(&'a self) -> &'a ThdJoinState {
1196        &self.inner.state
1197    }
1198
1199    /// 检查关联的动态线程是否运行结束
1200    ///
1201    /// 此方法不会阻塞调用者。
1202    pub fn finished(&self) -> bool {
1203        Arc::strong_count(&self.inner.rv) == 1
1204    }
1205}
1206
1207impl<R> fmt::Debug for DThdHandle<R> {
1208    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1209        f.debug_struct("DThdHandle")
1210            .field("inner", &self.inner)
1211            .finish_non_exhaustive()
1212    }
1213}
1214
1215
1216////////////////////////////////////////////////////////////////////////////////
1217// 静态线程
1218////////////////////////////////////////////////////////////////////////////////
1219/// XWOS线程对象占用的内存大小
1220#[cfg(target_pointer_width = "32")]
1221pub const SIZEOF_XWOS_THD: usize = 280;
1222
1223/// XWOS线程占用的内存大小
1224#[cfg(target_pointer_width = "64")]
1225pub const SIZEOF_XWOS_THD: usize = 560;
1226
1227/// 用于构建线程对象的内存数组类型
1228#[repr(C)]
1229#[cfg_attr(target_pointer_width = "32", repr(align(8)))]
1230#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
1231pub(crate) struct XwosThd
1232{
1233    pub(crate) obj: [u8; SIZEOF_XWOS_THD],
1234}
1235
1236/// 用于构建线程栈的内存数组类型
1237#[repr(C)]
1238#[cfg_attr(target_pointer_width = "32", repr(align(8)))]
1239#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
1240pub(crate) struct XwosThdStack<const N: XwSz>
1241where
1242    [XwStk; N]: Sized
1243{
1244    pub(crate) stk: [XwStk; N],
1245}
1246
1247/// 静态线程对象结构体
1248///
1249/// 此结构体用于创建具有 [`'static`] 生命周期的线程对象。
1250///
1251/// [`'static`]: <https://doc.rust-lang.org/std/keyword.static.html>
1252pub struct SThd<const N: XwSz, R>
1253where
1254    [XwStk; N]: Sized,
1255    R: Send
1256{
1257    /// 线程对象
1258    pub(crate) thd: UnsafeCell<XwosThd>,
1259    /// 线程的栈
1260    pub(crate) stk: UnsafeCell<XwosThdStack<N>>,
1261    /// 线程的名字
1262    pub(crate) name: &'static str,
1263    /// 线程是否为特权线程
1264    pub(crate) privileged: UnsafeCell<bool>,
1265    /// 线程的函数
1266    pub(crate) func: UnsafeCell<Option<fn(&Self) -> R>>,
1267    /// 线程对象的标签
1268    pub(crate) tik: UnsafeCell<XwSq>,
1269    /// 线程的执行结果
1270    pub(crate) result: UnsafeCell<Option<R>>,
1271}
1272
1273impl<const N: XwSz, R> SThd<N, R>
1274where
1275    [XwStk; N]: Sized,
1276    R: Send
1277{
1278    /// 新建静态线程对象
1279    ///
1280    /// 此方法是编译期方法。
1281    ///
1282    /// # 参数说明
1283    ///
1284    /// + name: 线程的名字
1285    /// + privileged: 线程的是否具有系统特权
1286    ///
1287    /// # 示例
1288    ///
1289    /// ```rust
1290    /// use xwrust::xwos::thd::*;
1291    ///
1292    /// // 线程栈:1024 * 4; 线程返回值类型:&str;线程名字:"SThd";是否为特权线程:true;
1293    /// static STHD: SThd<1024, &str> = SThd::new("SThd", true);
1294    /// ```
1295    pub const fn new(name: &'static str, privileged: bool) -> Self {
1296        Self {
1297            thd: UnsafeCell::new(XwosThd{obj: [0; SIZEOF_XWOS_THD]}),
1298            stk: UnsafeCell::new(XwosThdStack{stk: [0; N]}),
1299            name: name,
1300            privileged: UnsafeCell::new(privileged),
1301            func: UnsafeCell::new(None),
1302            tik: UnsafeCell::new(0),
1303            result: UnsafeCell::new(None),
1304        }
1305    }
1306
1307    /// 以线程函数 `f` 启动静态线程
1308    ///
1309    /// 此方法限定了参数的 [`&'static self`] ,因此若试图在函数局部定义静态线程,
1310    /// 调用此方法时,编译器会提示错误:生命周期不够长。
1311    ///
1312    /// 此约束的目的是让用户只能在函数外部定义静态线程对象。
1313    ///
1314    ///
1315    /// # 线程函数
1316    ///
1317    /// 线程函数的原型为 `fn(&Self) -> R` ,线程运行时,系统会以静态线程自身的引用作为参数调用线程函数 `f` 。
1318    ///
1319    /// 用户可通过此引用调用线程的方法或访问线程的名字,栈大小等信息。
1320    ///
1321    /// # 返回值
1322    ///
1323    /// 此方法会返回静态线程的句柄 [`SThdHandle<'a, N, R>`] ,通过此句柄,其他线程可通知此线程退出并获取返回值。
1324    ///
1325    ///
1326    /// # 上下文
1327    ///
1328    /// + 线程、中断、中断底半部、空闲任务
1329    ///
1330    ///
1331    /// # 示例
1332    ///
1333    /// ```rust
1334    /// use xwrust::xwos::thd::*;
1335    ///
1336    /// static STHD: SThd<1024, &str> = SThd::new("SThd", true);
1337    /// pub fn xwrust_example_sthd() {
1338    ///     STHD.run(|sthd| { // 子线程
1339    ///         // 线程功能
1340    ///         "OK" // 返回值
1341    ///     });
1342    /// }
1343    /// ```
1344    pub fn run<'a>(&'static self, f: fn(&Self) -> R) -> SThdHandle<'a, N, R> {
1345        unsafe {
1346            let mut attr: ThdAttr = mem::zeroed();
1347            xwrustffi_thd_attr_init(&mut attr);
1348            attr.stack = self.stk.get() as _;
1349            attr.stack_size = N * (XwStk::BITS / 8) as XwSz;
1350            attr.privileged = *self.privileged.get();
1351            (*self.func.get()) = Some(f);
1352            xwrustffi_thd_init(self.thd.get() as _, self.tik.get(), &attr,
1353                               SThd::<N, R>::xwrust_sthd_entry,
1354                               self as *const Self as *mut c_void);
1355
1356            SThdHandle {
1357                sthd: UnsafeCell::new(self),
1358                state: ThdJoinState::Joinable,
1359            }
1360        }
1361    }
1362
1363    extern "C" fn xwrust_sthd_entry(arg: *mut c_void) -> XwEr {
1364        unsafe {
1365            let thd: &Self = &*(arg as *const Self);
1366            let func = (*thd.func.get()).unwrap_or_else(|| unreachable!());
1367            *(thd.result.get()) = Some(func(thd));
1368        }
1369        0
1370    }
1371
1372    /// 返回静态线程名字的引用
1373    ///
1374    /// # 上下文
1375    ///
1376    /// + 任意
1377    pub fn name(&self) -> &str {
1378        self.name
1379    }
1380
1381    /// 返回静态线程是否具有特权
1382    ///
1383    /// # 上下文
1384    ///
1385    /// + 任意
1386    pub fn privileged(&self) -> bool {
1387        unsafe {
1388            *self.privileged.get()
1389        }
1390    }
1391
1392    /// 返回静态线程的栈大小
1393    ///
1394    /// # 上下文
1395    ///
1396    /// + 任意
1397    pub const fn stack_size(&self) -> XwSz {
1398        N * (XwStk::BITS / 8) as XwSz
1399    }
1400
1401    /// 中断线程的阻塞态和睡眠态
1402    ///
1403    /// 此方法用于中断线程的 **阻塞状态** 和 **睡眠状态** 。
1404    ///
1405    /// # 上下文
1406    ///
1407    /// + 线程、中断、中断底半部、空闲任务
1408    pub fn intr(&self) -> XwEr {
1409        unsafe {
1410            xwrustffi_thd_intr(self.thd.get() as _, *self.tik.get())
1411        }
1412    }
1413
1414    /// 通知静态线程退出
1415    ///
1416    /// 此方法用于向线程设置 **退出状态** 。
1417    ///
1418    /// 调用此方法的线程不会等待被设置 **退出状态** 的线程退出。
1419    ///
1420    /// 此方法可被重复调用,线程的 **退出状态** 一旦被设置,不可被清除。
1421    ///
1422    /// # 上下文
1423    ///
1424    /// + 线程、中断、中断底半部、空闲任务
1425    pub fn quit(&self) -> XwEr {
1426        unsafe {
1427            xwrustffi_thd_quit(self.thd.get() as _, *self.tik.get())
1428        }
1429    }
1430
1431    fn join(&self) ->XwEr {
1432        unsafe {
1433            xwrustffi_thd_join(self.thd.get() as _, *self.tik.get(), ptr::null_mut())
1434        }
1435    }
1436
1437    fn stop(&self) -> XwEr {
1438        unsafe {
1439            xwrustffi_thd_stop(self.thd.get() as _, *self.tik.get(), ptr::null_mut())
1440        }
1441    }
1442
1443    fn detach(&self) -> XwEr {
1444        unsafe {
1445            xwrustffi_thd_detach(self.thd.get() as _, *self.tik.get())
1446        }
1447    }
1448
1449    /// 将线程迁移到目标CPU。
1450    pub fn migrate(&self, cpuid: XwId) -> XwEr {
1451        unsafe {
1452            xwrustffi_thd_migrate(self.thd.get() as _, *self.tik.get(), cpuid)
1453        }
1454    }
1455}
1456
1457impl<const N: XwSz, R> !Send for SThd<N, R>
1458where
1459    [XwStk; N]: Sized,
1460    R: Send
1461{}
1462
1463unsafe impl<const N: XwSz, R> Sync for SThd<N, R>
1464where
1465    [XwStk; N]: Sized,
1466    R: Send
1467{}
1468
1469/// 静态线程的句柄
1470pub struct SThdHandle<'a, const N: XwSz, R>
1471where
1472    [XwStk; N]: Sized,
1473    R: Send
1474{
1475    /// 线程的引用
1476    sthd: UnsafeCell<&'a SThd<N, R>>,
1477    /// 静态线程的 `join()/stop()` 状态
1478    state: ThdJoinState,
1479}
1480
1481unsafe impl<'a, const N: XwSz, R> Send for SThdHandle<'a, N, R>
1482where
1483    [XwStk; N]: Sized,
1484    R: Send
1485{}
1486
1487unsafe impl<'a, const N: XwSz, R> Sync for SThdHandle<'a, N, R>
1488where
1489    [XwStk; N]: Sized,
1490    R: Send
1491{}
1492
1493impl<'a, const N: XwSz, R> SThdHandle<'a, N, R>
1494where
1495    [XwStk; N]: Sized,
1496    R: Send
1497{
1498    /// 中断线程的阻塞态和睡眠态
1499    ///
1500    /// 此方法用于中断线程的 **阻塞状态** 和 **睡眠状态** 。
1501    ///
1502    /// # 上下文
1503    ///
1504    /// + 线程、中断、中断底半部、空闲任务
1505    pub fn intr(&self) -> XwEr {
1506        unsafe {
1507            (*(self.sthd.get())).intr()
1508        }
1509    }
1510
1511    /// 通知静态线程退出
1512    ///
1513    /// 此方法用于向线程设置 **退出状态** 。
1514    ///
1515    /// 调用此方法的线程不会等待被设置 **退出状态** 的线程退出。
1516    ///
1517    /// 此方法可被重复调用,线程的 **退出状态** 一旦被设置,不可被清除。
1518    ///
1519    /// # 上下文
1520    ///
1521    /// + 线程、中断、中断底半部、空闲任务
1522    pub fn quit(&self) -> XwEr {
1523        unsafe {
1524            (*(self.sthd.get())).quit()
1525        }
1526    }
1527
1528    /// 等待静态线程运行至退出,并返回线程的返回值
1529    ///
1530    /// + 如果静态子线程还在运行,此方法会阻塞父线程直到静态子线程退出。父线程的阻塞状态可被中断;
1531    /// + 如果静态子线程已经提前运行至退出,此方法可立即返回静态子线程的返回值。
1532    ///
1533    /// 此方法会消费 [`self`] :
1534    ///
1535    /// + 如果此方法执行成功,会消费掉 [`self`] ,并将静态子线程的返回值放在 [`Ok()`] 中返回,因为线程已经结束,其 [`SThdHandle`] 的生命周期也应该结束;
1536    /// + 如果此方法执行失败,会重新在 [`Err()`] 中返回 [`self`] ,并可通过 [`SThdHandle::state()`] 方法获取失败的原因。
1537    ///
1538    /// # 上下文
1539    ///
1540    /// + 线程
1541    ///
1542    /// # 示例
1543    ///
1544    /// ```rust
1545    /// use xwrust::xwos::thd::*;
1546    ///
1547    /// static STHD: SThd<1024, &str> = SThd::new("SThd", true);
1548    ///
1549    /// pub fn xwrust_example_sthd() {
1550    ///     let mut h = STHD.run(|_| {
1551    ///         // 线程功能
1552    ///         "Ok" // 返回值
1553    ///     });
1554    ///     let res = h.join();
1555    ///     match res {
1556    ///         Ok(r) => {
1557    ///             // `r` 是线程的返回值。
1558    ///         },
1559    ///         Err(e) => {
1560    ///             h = e;
1561    ///             // `join()` 失败时的错误码可通过 `e.state()` 获取。
1562    ///             // `e` 是 `SThdHandle<'a, N, R>` ,重新被返回。
1563    ///         },
1564    ///     };
1565    /// }
1566    /// ```
1567    ///
1568    /// [`Ok()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok>
1569    /// [`Err()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err>
1570    pub fn join(mut self) -> Result<R, Self> {
1571        unsafe {
1572            let rc = (*(self.sthd.get())).join();
1573            if rc == 0 {
1574                self.state = ThdJoinState::Joined;
1575                Ok((*(self.sthd.get_mut().result.get())).take().unwrap())
1576            } else {
1577                self.state = ThdJoinState::JoinErr(rc);
1578                Err(self)
1579            }
1580        }
1581    }
1582
1583    /// 终止静态线程并等待线程运行至退出,并返回线程的返回值
1584    ///
1585    /// + 如果静态子线程还在运行,此方法会阻塞父线程直到静态子线程退出。父线程的阻塞状态可被中断;
1586    /// + 如果静态子线程已经提前运行至退出,此方法可立即返回静态子线程的返回值。
1587    ///
1588    /// 此方法 = [`SThdHandle::quit()`] + [`SThdHandle::join()`]
1589    ///
1590    ///
1591    /// 此方法会消费 [`self`] :
1592    ///
1593    /// + 如果此方法执行成功,会消费掉 [`self`] ,并将静态子线程的返回值放在 [`Ok()`] 中返回,因为线程已经结束,其 [`SThdHandle`] 的生命周期也应该结束;
1594    /// + 如果此方法执行失败,会重新在 [`Err()`] 中返回 [`self`] ,并可通过 [`SThdHandle::state()`] 方法获取失败的原因。
1595    ///
1596    /// # 上下文
1597    ///
1598    /// + 线程
1599    ///
1600    /// # 示例
1601    ///
1602    /// ```rust
1603    /// use xwrust::xwos::thd::*;
1604    ///
1605    /// static STHD: SThd<1024, &str> = SThd::new("SThd", true);
1606    ///
1607    /// pub fn xwrust_example_sthd() {
1608    ///     let mut h = STHD.run(|_| {
1609    ///         // 线程代码;
1610    ///         "Ok"
1611    ///     });
1612    ///     let res = h.stop();
1613    ///     match res {
1614    ///         Ok(r) => {
1615    ///             // `r` 是线程的返回值。
1616    ///         },
1617    ///         Err(e) => {
1618    ///             h = e;
1619    ///             // `stop()` 失败时的错误码可通过 `e.state()` 获取。
1620    ///             // `e` 是 `SThdHandle<'a, N, R>` ,重新被返回。
1621    ///         },
1622    ///     };
1623    /// }
1624    /// ```
1625    ///
1626    /// [`Ok()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok>
1627    /// [`Err()`]: <https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err>
1628    pub fn stop(mut self) -> Result<R, Self> {
1629        unsafe {
1630            let rc = (*(self.sthd.get())).stop();
1631            if rc == 0 {
1632                self.state = ThdJoinState::Joined;
1633                Ok((*(self.sthd.get_mut().result.get())).take().unwrap())
1634            } else {
1635                self.state = ThdJoinState::JoinErr(rc);
1636                Err(self)
1637            }
1638        }
1639    }
1640
1641    /// 返回线程的 `join()/stop()` 状态
1642    pub fn state(&self) -> &ThdJoinState {
1643        &self.state
1644    }
1645}
1646
1647impl<'a, const N: XwSz, R>Drop for SThdHandle<'a, N, R>
1648where
1649    [XwStk; N]: Sized,
1650    R: Send
1651{
1652    fn drop(&mut self) {
1653        match self.state {
1654            ThdJoinState::Joined => {
1655            },
1656            _ => {
1657                unsafe {
1658                    (*(self.sthd.get())).detach();
1659                }
1660            },
1661        };
1662    }
1663}