5851974b20
Release fork infrastructure: - REDBEAR_RELEASE=0.1.1 with offline enforcement (fetch/distclean/unfetch blocked) - 195 BLAKE3-verified source archives in standard format - Atomic provisioning via provision-release.sh (staging + .complete sentry) - 5-phase improvement plan: restore format auto-detection, source tree validation (validate-source-trees.py), archive-map.json, REPO_BINARY fallback Archive normalization: - Removed 87 duplicate/unversioned archives from shared pool - Regenerated all archives in consistent format with source/ + recipe.toml - BLAKE3SUMS and manifest.json generated from stable tarball set Patch management: - verify-patches.sh: pre-sync dry-run report (OK/REVERSED/CONFLICT) - 121 upstream-absorbed patches moved to absorbed/ directories - 43 active patches verified clean against rebased sources - Stress test: base updated to upstream HEAD, relibc reset and patched Compilation fixes: - relibc: Vec imports in redox-rt (proc.rs, lib.rs, sys.rs) - relibc: unsafe from_raw_parts in mod.rs (2024 edition) - fetch.rs: rev comparison handles short/full hash prefixes - kibi recipe: corrected rev mismatch New scripts: restore-sources.sh, provision-release.sh, verify-sources-archived.sh, check-upstream-releases.sh, validate-source-trees.py, verify-patches.sh, repair-archive-format.sh, generate-manifest.py Documentation: AGENTS.md, README.md, local/AGENTS.md updated for release fork model
126 lines
3.7 KiB
Diff
126 lines
3.7 KiB
Diff
diff --git a/src/sync/barrier.rs b/src/sync/barrier.rs
|
|
index 6204a23..b5847b5 100644
|
|
--- a/src/sync/barrier.rs
|
|
+++ b/src/sync/barrier.rs
|
|
@@ -1,18 +1,34 @@
|
|
-use core::num::NonZeroU32;
|
|
+use core::{
|
|
+ num::NonZeroU32,
|
|
+ sync::atomic::{AtomicU32, Ordering},
|
|
+};
|
|
|
|
pub struct Barrier {
|
|
original_count: NonZeroU32,
|
|
// 4
|
|
lock: crate::sync::Mutex<Inner>,
|
|
// 16
|
|
- cvar: crate::header::pthread::RlctCond,
|
|
+ cvar: FutexState,
|
|
// 24
|
|
}
|
|
#[derive(Debug)]
|
|
struct Inner {
|
|
- count: u32,
|
|
- // TODO: Overflows might be problematic... 64-bit?
|
|
- gen_id: u32,
|
|
+ _unused0: u32,
|
|
+ _unused1: u32,
|
|
+}
|
|
+
|
|
+struct FutexState {
|
|
+ count: AtomicU32,
|
|
+ sense: AtomicU32,
|
|
+}
|
|
+
|
|
+impl FutexState {
|
|
+ const fn new(count: u32) -> Self {
|
|
+ Self {
|
|
+ count: AtomicU32::new(count),
|
|
+ sense: AtomicU32::new(0),
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
pub enum WaitResult {
|
|
@@ -25,61 +41,36 @@ impl Barrier {
|
|
Self {
|
|
original_count: count,
|
|
lock: crate::sync::Mutex::new(Inner {
|
|
- count: 0,
|
|
- gen_id: 0,
|
|
+ _unused0: 0,
|
|
+ _unused1: 0,
|
|
}),
|
|
- cvar: crate::header::pthread::RlctCond::new(),
|
|
+ cvar: FutexState::new(count.get()),
|
|
}
|
|
}
|
|
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;
|
|
- if let Ok(()) = self.cvar.broadcast() {}; // TODO handle error
|
|
+ let _ = &self.lock;
|
|
+ let sense = self.cvar.sense.load(Ordering::Acquire);
|
|
|
|
- drop(guard);
|
|
+ if self.cvar.count.fetch_sub(1, Ordering::AcqRel) == 1 {
|
|
+ self.cvar
|
|
+ .count
|
|
+ .store(self.original_count.get(), Ordering::Relaxed);
|
|
+ self.cvar
|
|
+ .sense
|
|
+ .store(sense.wrapping_add(1), Ordering::Release);
|
|
+ crate::sync::futex_wake(&self.cvar.sense, i32::MAX);
|
|
|
|
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
|
|
- } else {
|
|
- 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);
|
|
+ // SMP fix: wait directly on the barrier generation word instead of routing through the
|
|
+ // condvar unlock->futex_wait path. If the last thread flips `sense` after we load it
|
|
+ // but before our futex wait starts, the futex observes a stale value and returns
|
|
+ // immediately instead of sleeping forever after a missed broadcast wakeup.
|
|
+ while self.cvar.sense.load(Ordering::Acquire) == sense {
|
|
+ let _ = crate::sync::futex_wait(&self.cvar.sense, sense, None);
|
|
}
|
|
|
|
WaitResult::Waited
|
|
}
|
|
- */
|
|
}
|
|
}
|
|
-static LOCK: crate::sync::Mutex<()> = crate::sync::Mutex::new(());
|