From 79dfddf82c192e78f2bf59f0c414d3cf5e8253a7 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 30 Apr 2023 17:33:28 +0200 Subject: [PATCH] Switch to a boring mutex+condvar based barrier. While the atomic version might be better, at the moment the priority is to just to get RLCT working reliably. --- src/sync/barrier.rs | 31 +++++++++++++++++++++++++++++++ src/sync/cond.rs | 8 +++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/sync/barrier.rs b/src/sync/barrier.rs index 9d5aaf9f..48d76143 100644 --- a/src/sync/barrier.rs +++ b/src/sync/barrier.rs @@ -10,8 +10,10 @@ pub struct Barrier { cvar: crate::header::pthread::RlctCond, // 24 } +#[derive(Debug)] struct Inner { count: u32, + // TODO: Overflows might be problematic... 64-bit? gen_id: u32, } @@ -29,14 +31,39 @@ impl Barrier { } } pub fn wait(&self) -> WaitResult { + let mut guard = self.lock.lock(); + let gen_id = guard.gen_id; + + guard.count += 1; + + if guard.count == self.original_count.get() { + guard.gen_id = guard.gen_id.wrapping_add(1); + guard.count = 0; + self.cvar.broadcast(); + + drop(guard); + + WaitResult::NotifiedAll + } else { + while guard.gen_id == gen_id { + guard = self.cvar.wait_inner_typedmutex(guard); + } + + WaitResult::Waited + } + /* let mut guard = self.lock.lock(); let Inner { count, gen_id } = *guard; + let last = self.original_count.get() - 1; if count == last { + eprintln!("last {:?}", *guard); guard.gen_id = guard.gen_id.wrapping_add(1); guard.count = 0; + drop(guard); + self.cvar.broadcast(); WaitResult::NotifiedAll @@ -44,10 +71,14 @@ impl Barrier { guard.count += 1; while guard.count != last && guard.gen_id == gen_id { + eprintln!("before {:?}", *guard); guard = self.cvar.wait_inner_typedmutex(guard); + eprintln!("after {:?}", *guard); } WaitResult::Waited } + */ } } +static LOCK: crate::sync::Mutex<()> = crate::sync::Mutex::new(()); diff --git a/src/sync/cond.rs b/src/sync/cond.rs index f3ab57d1..17e30780 100644 --- a/src/sync/cond.rs +++ b/src/sync/cond.rs @@ -45,7 +45,13 @@ impl Cond { pub fn wait_inner_typedmutex<'lock, T>(&self, guard: crate::sync::MutexGuard<'lock, T>) -> crate::sync::MutexGuard<'lock, T> { let mut newguard = None; let lock = guard.mutex; - self.wait_inner_generic(|| Ok(drop(guard)), || Ok(newguard = Some(lock.lock())), |_| unreachable!(), None).unwrap(); + self.wait_inner_generic(move || { + drop(guard); + Ok(()) + }, || { + newguard = Some(lock.lock()); + Ok(()) + }, |_| unreachable!(), None).unwrap(); newguard.unwrap() } // TODO: FUTEX_REQUEUE -- GitLab