Skip to main content

xwrust/xwos/
cthd.rs

1//! XWOS RUST:当前线程
2//! ========
3//!
4//! 此模块中的方法,只会对代码所运行的线程起作用。命名中的 **c** 是 **current** 的意思。
5//!
6//!
7//! # 获取自身的线程描述符
8//!
9//! 线程可通过方法 [`i()`] 获取自身的线程描述符。
10//!
11//! # 通知调度器重新调度线程
12//!
13//! 线程可通过方法 [`yield_now()`] 主动让出CPU的使用权。
14//!
15//! # 判断当前线程是否可被冻结
16//!
17//! 线程可通过方法 [`shld_frz()`] 判断是否需要冻结,如果是,可调用 [`freeze()`] 冻结自身。
18//!
19//! 线程的冻结只会发生在一些特殊的条件下:
20//!
21//! + 系统开始低功耗流程;
22//! + 线程在CPU之间迁移。
23//!
24//! # 判断当前线程是否可退出
25//!
26//! 线程可通过方法 [`shld_stop()`] 判断是否被设置了 **退出状态** ,**退出状态** 是其他线程通过 [`DThdHandle::stop()`] 方法设置的。
27//!
28//! # 线程睡眠
29//!
30//! ## 睡眠
31//!
32//! 线程可以通过方法 [`sleep()`] 指定需要睡眠多长时间,线程唤醒的时间可能会略微超过指定的时长。
33//!
34//! ## 睡眠到指定的时间点
35//!
36//! 当需要到某个时间点唤醒时,可以通过 [`sleep_to()`] 方法睡眠。此方法不关心睡眠多长时间,只关心到哪个时间唤醒。
37//!
38//! ## 从一个时间起点睡眠到另一个时间点
39//!
40//! 方法 [`sleep_from()`] 可以指定从某个时间点开始睡眠,持续多长时间。
41//!
42//! # 冻结线程
43//!
44//! 当线程通过方法 [`shld_frz()`] 判断出需要冻结时,可通过方法 [`freeze()`] 冻结自身。冻结之前需要释放掉所有资源。
45//!
46//!
47//! [`DThdHandle::stop()`]: crate::xwos::thd::DThdHandle::stop
48
49extern crate core;
50use core::ffi::*;
51use core::ptr;
52
53use crate::types::*;
54use super::thd::ThdD;
55
56extern "C" {
57    fn xwrustffi_cthd_self(thd: *mut *mut c_void, tik: *mut XwSq);
58    fn xwrustffi_cthd_yield();
59    fn xwrustffi_cthd_shld_frz() -> bool;
60    fn xwrustffi_cthd_shld_stop() -> bool;
61    fn xwrustffi_cthd_sleep(time: XwTm) -> XwEr;
62    fn xwrustffi_cthd_sleep_to(to: XwTm) -> XwEr;
63    fn xwrustffi_cthd_sleep_from(origin: *mut XwTm,
64                                 inc: XwTm) -> XwEr;
65    fn xwrustffi_cthd_freeze() -> XwEr;
66}
67
68
69/// 获取当前线程的对象描述符
70///
71/// # 上下文
72///
73/// + 线程
74///
75/// # 示例
76///
77/// ```rust
78/// use use xwrust::xwos::cthd;
79///
80/// let thdd = cthd::i();
81/// ```
82pub fn i() -> ThdD {
83    let mut thd: *mut c_void = ptr::null_mut();
84    let mut tik: XwSq = 0;
85    unsafe {
86        xwrustffi_cthd_self(&mut thd, &mut tik);
87    }
88    ThdD {thd, tik}
89}
90
91
92/// 通知调度器重新调度线程
93///
94/// # 上下文
95///
96/// + 线程
97///
98/// # 示例
99///
100/// ```rust
101/// use use xwrust::xwos::cthd;
102///
103/// cthd::yield_now();
104/// ```
105pub fn yield_now() {
106    unsafe { xwrustffi_cthd_yield(); }
107}
108
109
110/// 判断当前线程是否可被冻结
111///
112/// # 上下文
113///
114/// + 线程
115///
116/// # 示例
117///
118/// ```rust
119/// use use xwrust::xwos::cthd;
120///
121/// if cthd::shld_frz() {
122///     cthd::freeze();
123/// }
124/// ```
125pub fn shld_frz() -> bool {
126    unsafe { xwrustffi_cthd_shld_frz() }
127}
128
129
130/// 判断当前线程是否可退出
131///
132/// # 上下文
133///
134/// + 线程
135///
136/// # 示例
137///
138/// ```rust
139/// use use xwrust::xwos::cthd;
140///
141/// if cthd::shld_stop() {
142///     return result;
143/// }
144/// ```
145pub fn shld_stop() -> bool {
146    unsafe { xwrustffi_cthd_shld_stop() }
147}
148
149
150/// 线程睡眠一段时间
151///
152/// 调用此方法的线程会睡眠 **dur** 后被唤醒。
153///
154/// 此方法等价于 `cthd::sleep_to(xwtm::ft(xwtm::s(dur)))` 。
155///
156/// # 参数说明
157///
158/// + dur: 期望睡眠的时间
159///
160/// # 返回值
161///
162/// 0: 睡眠成功
163/// -EINTR: 睡眠被中断
164///
165/// # 上下文
166///
167/// + 线程
168///
169/// # 示例
170///
171/// ```rust
172/// use use xwrust::xwos::cthd;
173/// use use xwrust::xwtx;
174///
175/// let rc = cthd::sleep(xwtm::s(1)); // 睡眠1s
176/// ```
177pub fn sleep(dur: XwTm) -> XwEr {
178    unsafe { xwrustffi_cthd_sleep(dur) }
179}
180
181
182/// 线程睡眠到一个时间点
183///
184/// 调用此方法的线程会睡眠到时间点 **to** 后被唤醒。
185/// 如果 **to** 是过去的时间点,将直接返回 `-ETIMEDOUT` 。
186///
187/// # 参数说明
188///
189/// + to: 期望唤醒的时间点
190///
191/// # 返回值
192///
193/// + 0: 睡眠成功
194/// + -EINTR: 睡眠被中断
195/// + -ETIMEDOUT: 时间点是过去
196///
197/// # 上下文
198///
199/// + 线程
200///
201/// # 示例
202///
203/// ```rust
204/// use use xwrust::xwos::cthd;
205/// use use xwrust::xwtx;
206///
207/// let rc = cthd::sleep_to(xwtm::ft(xwtm::s(1))); // 睡眠1s
208/// ```
209pub fn sleep_to(to: XwTm) -> XwEr {
210    unsafe { xwrustffi_cthd_sleep_to(to) }
211}
212
213
214/// 线程从一个时间起点睡眠到另一个时间点
215///
216/// 调用此方法前,需要先确定一个时间起点 `from` ,可以通过 `xwtm::now()` 获取当前的系统时间作为起点。
217/// 唤醒时间为 `from` + `dur` 。
218/// 此方法会将线程唤醒时的系统时间返回,可作为下一次调用的时间起点。
219/// 由此,循环调用,可以形成周期为 `dur` ,更为精确的周期性睡眠唤醒。
220///
221/// # 参数说明
222///
223/// + from: 时间起点
224/// + dur: 期望被唤醒的时间增量
225///
226/// # 返回值 (rc, from)
227///
228/// + rc
229///   + 0: 睡眠成功
230///   + -EINTR: 睡眠被中断
231///   + -ETIMEDOUT: 时间点是过去
232/// + from: 线程唤醒时的系统时间
233///
234/// # 上下文
235///
236/// + 线程
237///
238/// # 示例
239///
240/// ```rust
241/// use use xwrust::xwos::cthd;
242/// use use xwrust::xwtx;
243///
244/// let mut from = xwtm::now();
245/// loop {
246///     let mut (rc, from) = cthd::sleep_from(from, xwtm::s(1)); // 从from开始睡眠1s
247/// }
248/// ```
249pub fn sleep_from(from: XwTm, dur: XwTm) -> (XwEr, XwTm) {
250    let mut origin: XwTm = from;
251    unsafe {
252        let rc = xwrustffi_cthd_sleep_from(&mut origin, dur);
253        (rc, origin)
254    }
255}
256
257
258/// 冻结当前线程
259///
260/// 线程并不能随时冻结,必须满足下列条件之一:
261///
262/// + 系统已经开始准备进入低功耗;
263/// + 线程正准备开始迁移。
264///
265/// 线程可通过 [`shld_frz()`] 判断是否满足冻结条件。
266///
267/// 通常冻结操作之前,还需要对资源进行释放,以防止线程阻碍系统进入低功耗;
268/// 通常解冻操作之后,还需要重新获取资源。
269///
270/// # 返回值
271///
272/// + 0: 睡眠成功
273/// + -EPERM: 当前不需要冻结线程
274///
275/// # 上下文
276///
277/// + 线程
278///
279/// # 示例
280///
281/// ```rust
282/// use use xwrust::xwos::cthd;
283///
284/// if cthd::shld_frz() {
285///     let rc = cthd::freeze();
286/// }
287/// ```
288pub fn freeze() -> XwEr {
289    unsafe { xwrustffi_cthd_freeze() }
290}