relibc: fix pthread_cond_signal POSIX semantics bug
src/sync/cond.rs:signal() was calling self.broadcast() (which wakes ALL waiters via futex_wake(INT32_MAX)) instead of self.wake(1) (which wakes exactly one). This violated POSIX: pthread_cond_signal must wake at least one waiter but must not wake all waiters (that is pthread_cond_broadcast semantics). The pre-existing code also had a commented-out self.wake(1), suggesting this was an unfinished fix that got left in the wrong state. Real-world impact: every pthread_cond_signal() in relibc (Qt's event loop, Mesa worker threads, KWin compositor, glib main loop, libwayland protocol dispatch) was triggering a thundering herd. On a multi-CPU system, this defeats the purpose of signal vs broadcast and degrades all conditional-variable-using code to broadcast-equivalent cost. After this commit: pthread_cond_signal() wakes exactly one waiter (the first one that the kernel's futex wakes), matching POSIX semantics. Verified: pre-existing host cargo check has 85 unrelated errors (relibc contains Redox-specific code that doesn't compile on Linux). The change in cond.rs introduces zero new errors. Full cross-compile validation requires 'touch relibc && make prefix' on a target build host. This is the first commit of the multi-threading plan Phase 0a — the 'one-line correctness fix' that the plan's audit identified as the single highest-ROI standalone action.
This commit is contained in:
+8
-2
@@ -61,8 +61,14 @@ impl Cond {
|
||||
self.wake(i32::MAX)
|
||||
}
|
||||
pub fn signal(&self) -> Result<(), Errno> {
|
||||
self.broadcast()
|
||||
//self.wake(1)
|
||||
// POSIX requires pthread_cond_signal to wake AT LEAST ONE waiter that
|
||||
// is currently waiting on the condition variable, but it must not
|
||||
// wake all waiters (that is pthread_cond_broadcast semantics).
|
||||
// Wake exactly one via FUTEX_WAKE with count=1. Using broadcast() here
|
||||
// was a thundering-herd bug: every cond_signal woke every waiter on
|
||||
// every CPU. Fixed 2026-07-02 (Red Bear OS multi-threading plan,
|
||||
// Phase 0a).
|
||||
self.wake(1)
|
||||
}
|
||||
pub fn clockwait(
|
||||
&self,
|
||||
|
||||
Reference in New Issue
Block a user