Skip to main content

relibc/sync/
barrier.rs

1use core::num::NonZeroU32;
2
3pub struct Barrier {
4    original_count: NonZeroU32,
5    // 4
6    lock: crate::sync::Mutex<Inner>,
7    // 16
8    cvar: crate::header::pthread::RlctCond,
9    // 24
10}
11#[derive(Debug)]
12struct Inner {
13    count: u32,
14    // TODO: Overflows might be problematic... 64-bit?
15    gen_id: u32,
16}
17
18pub enum WaitResult {
19    Waited,
20    NotifiedAll,
21}
22
23impl Barrier {
24    pub fn new(count: NonZeroU32) -> Self {
25        Self {
26            original_count: count,
27            lock: crate::sync::Mutex::new(Inner {
28                count: 0,
29                gen_id: 0,
30            }),
31            cvar: crate::header::pthread::RlctCond::new(),
32        }
33    }
34    pub fn wait(&self) -> WaitResult {
35        let mut guard = self.lock.lock();
36        let gen_id = guard.gen_id;
37
38        guard.count += 1;
39
40        if guard.count == self.original_count.get() {
41            guard.gen_id = guard.gen_id.wrapping_add(1);
42            guard.count = 0;
43            if let Ok(()) = self.cvar.broadcast() {}; // TODO handle error
44
45            drop(guard);
46
47            WaitResult::NotifiedAll
48        } else {
49            while guard.gen_id == gen_id {
50                guard = self.cvar.wait_inner_typedmutex(guard);
51            }
52
53            WaitResult::Waited
54        }
55        /*
56        let mut guard = self.lock.lock();
57        let Inner { count, gen_id } = *guard;
58
59        let last = self.original_count.get() - 1;
60
61        if count == last {
62            eprintln!("last {:?}", *guard);
63            guard.gen_id = guard.gen_id.wrapping_add(1);
64            guard.count = 0;
65
66            drop(guard);
67
68            self.cvar.broadcast();
69
70            WaitResult::NotifiedAll
71        } else {
72            guard.count += 1;
73
74            while guard.count != last && guard.gen_id == gen_id {
75                eprintln!("before {:?}", *guard);
76                guard = self.cvar.wait_inner_typedmutex(guard);
77                eprintln!("after {:?}", *guard);
78            }
79
80            WaitResult::Waited
81        }
82        */
83    }
84}
85static LOCK: crate::sync::Mutex<()> = crate::sync::Mutex::new(());