1 use crate::mem::MaybeUninit;
2 use crate::time::Duration;
6 error::{expect_success, fail},
10 const CLEAR: abi::FLGPTN = 0;
11 const RAISED: abi::FLGPTN = 1;
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.
20 /// Creates a new wait flag.
21 pub fn new() -> WaitFlag {
22 let flag = expect_success(
24 abi::acre_flg(&abi::T_CFLG {
25 flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR,
35 /// Wait for the wait flag to be raised.
37 let mut token = MaybeUninit::uninit();
39 unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) },
44 /// Wait for the wait flag to be raised or the timeout to occur.
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)
55 abi::E_TMOUT => false,
56 error => fail(error, &"twai_flg"),
60 /// Raise the wait flag.
62 /// Calls to this function should be balanced with the number of successful waits.
64 expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg");
68 impl Drop for WaitFlag {
70 expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg");