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(());