]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/itron/wait_flag.rs
Merge commit 'b52fb5234cd7c11ecfae51897a6f7fa52e8777fc' into clippyup
[rust.git] / library / std / src / sys / itron / wait_flag.rs
1 use crate::mem::MaybeUninit;
2 use crate::time::Duration;
3
4 use super::{
5     abi,
6     error::{expect_success, fail},
7     time::with_tmos,
8 };
9
10 const CLEAR: abi::FLGPTN = 0;
11 const RAISED: abi::FLGPTN = 1;
12
13 /// A thread parking primitive that is not susceptible to race conditions,
14 /// but provides no atomic ordering guarantees and allows only one `raise` per wait.
15 pub struct WaitFlag {
16     flag: abi::ID,
17 }
18
19 impl WaitFlag {
20     /// Creates a new wait flag.
21     pub fn new() -> WaitFlag {
22         let flag = expect_success(
23             unsafe {
24                 abi::acre_flg(&abi::T_CFLG {
25                     flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR,
26                     iflgptn: CLEAR,
27                 })
28             },
29             &"acre_flg",
30         );
31
32         WaitFlag { flag }
33     }
34
35     /// Wait for the wait flag to be raised.
36     pub fn wait(&self) {
37         let mut token = MaybeUninit::uninit();
38         expect_success(
39             unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) },
40             &"wai_flg",
41         );
42     }
43
44     /// Wait for the wait flag to be raised or the timeout to occur.
45     ///
46     /// Returns whether the flag was raised (`true`) or the operation timed out (`false`).
47     pub fn wait_timeout(&self, dur: Duration) -> bool {
48         let mut token = MaybeUninit::uninit();
49         let res = with_tmos(dur, |tmout| unsafe {
50             abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout)
51         });
52
53         match res {
54             abi::E_OK => true,
55             abi::E_TMOUT => false,
56             error => fail(error, &"twai_flg"),
57         }
58     }
59
60     /// Raise the wait flag.
61     ///
62     /// Calls to this function should be balanced with the number of successful waits.
63     pub fn raise(&self) {
64         expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg");
65     }
66 }
67
68 impl Drop for WaitFlag {
69     fn drop(&mut self) {
70         expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg");
71     }
72 }