57 lines
2.2 KiB
Diff
57 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000000335
|
|
--- a/lib/wasix/src/os/task/thread.rs
|
|
+++ b/lib/wasix/src/os/task/thread.rs
|
|
@@ -238,7 +238,9 @@ pub struct WasiThreadInner {
|
|
pub(crate) status: Arc<OwnedTaskStatus>,
|
|
/// Signals are used to indicate certain states to the thread
|
|
- signals: Mutex<(Vec<Signal>, Vec<Waker>)>,
|
|
+ /// Using a u64 bitmask instead of Vec<Signal> — Signal values are 1..=31,
|
|
+ /// so bit N represents signal N. O(1) insert, O(1) contains, O(1) test.
|
|
+ signals: Mutex<(u64, Vec<Waker>)>,
|
|
}
|
|
|
|
@@ -268,7 +270,7 @@ impl WasiThreadInner {
|
|
status: Arc::new(OwnedTaskStatus::new(TaskStatus::Pending)),
|
|
- signals: Mutex::new((Vec::new(), Vec::new())),
|
|
+ signals: Mutex::new((0u64, Vec::new())),
|
|
}
|
|
}
|
|
|
|
@@ -345,10 +347,8 @@ impl WasiThread {
|
|
let mut guard = self.state.signals.lock().unwrap();
|
|
- if !guard.0.contains(&signal) {
|
|
- guard.0.push(signal);
|
|
- }
|
|
+ // Set bit for this signal — O(1) insert with automatic dedup
|
|
+ guard.0 |= 1u64 << (signal as u32);
|
|
guard.1.drain(..).for_each(|w| w.wake());
|
|
}
|
|
|
|
@@ -358,10 +358,10 @@ impl WasiThread {
|
|
pub fn has_signal(&self, signals: &[Signal]) -> bool {
|
|
let guard = self.state.signals.lock().unwrap();
|
|
- for s in guard.0.iter() {
|
|
- if signals.contains(s) {
|
|
- return true;
|
|
- }
|
|
- }
|
|
- false
|
|
+ // Build query bitmask in O(|signals|), then AND in O(1)
|
|
+ let query_mask: u64 = signals.iter().fold(0u64, |m, s| m | (1u64 << (*s as u32)));
|
|
+ guard.0 & query_mask != 0
|
|
}
|
|
|
|
@@ -390,7 +390,7 @@ impl WasiThread {
|
|
pub fn pop_signals_or_subscribe(&self, waker: &Waker) -> Option<Vec<Signal>> {
|
|
let mut guard = self.state.signals.lock().unwrap();
|
|
- if guard.0.is_empty() {
|
|
+ if guard.0 == 0 {
|
|
// ...
|
|
}
|
|
// Convert bitmask back to Vec<Signal> for consumption
|
|
- Some(std::mem::take(&mut guard.0))
|
|
+ let mask = std::mem::replace(&mut guard.0, 0u64);
|
|
+ Some((0u32..64).filter(|b| mask & (1u64 << b) != 0)
|
|
+ .filter_map(|b| Signal::try_from(b as i32).ok())
|
|
+ .collect())
|
|
}
|