66 lines
2.8 KiB
Diff
66 lines
2.8 KiB
Diff
--- a/crates/wasmtime/src/runtime/component/concurrent.rs
|
|
+++ b/crates/wasmtime/src/runtime/component/concurrent.rs
|
|
@@ -4872,7 +4872,10 @@ struct WorkQueue {
|
|
/// High-priority work items to be handled before low-priority items.
|
|
/// These items are drained and re-queued at the top of each scheduling
|
|
/// loop iteration.
|
|
- high_priority: Vec<WorkItem>,
|
|
+ /// Keyed by (instance, thread) for O(1) promote_thread_work_item lookup.
|
|
+ high_priority_by_thread: HashMap<QualifiedThreadId, VecDeque<WorkItem>>,
|
|
+ /// High-priority items without a specific thread target (WorkerFunction etc.)
|
|
+ high_priority_general: Vec<WorkItem>,
|
|
/// Low-priority work items. These are only handled after all high-priority
|
|
/// items have been processed.
|
|
low_priority: VecDeque<WorkItem>,
|
|
@@ -4908,7 +4911,8 @@ impl WorkQueue {
|
|
fn new() -> Self {
|
|
Self {
|
|
- high_priority: Vec::new(),
|
|
+ high_priority_by_thread: HashMap::new(),
|
|
+ high_priority_general: Vec::new(),
|
|
low_priority: VecDeque::new(),
|
|
}
|
|
}
|
|
@@ -5044,7 +5050,15 @@ impl WorkQueue {
|
|
fn push_high_priority(&mut self, item: WorkItem) {
|
|
- self.high_priority.push(item);
|
|
+ match &item {
|
|
+ WorkItem::ResumeThread(_, t) | WorkItem::GuestCall(_, GuestCall { thread: t, .. }) => {
|
|
+ self.high_priority_by_thread
|
|
+ .entry(*t)
|
|
+ .or_default()
|
|
+ .push_back(item);
|
|
+ }
|
|
+ _ => self.high_priority_general.push(item),
|
|
+ }
|
|
}
|
|
|
|
@@ -5086,14 +5100,25 @@ impl WorkQueue {
|
|
fn promote_work_items_matching<F>(&mut self, mut predicate: F) -> bool
|
|
where
|
|
F: FnMut(&WorkItem) -> bool,
|
|
{
|
|
- // If there's a high-priority work item to resume the current guest thread,
|
|
- // we don't need to promote anything, but we return true to indicate that
|
|
- // work is pending for the current instance.
|
|
- if self.high_priority.iter().any(&mut predicate) {
|
|
+ // Check thread-keyed high-priority items (O(1) lookup by thread id).
|
|
+ let found_in_keyed = self.high_priority_by_thread
|
|
+ .values()
|
|
+ .any(|q| q.iter().any(&mut predicate));
|
|
+ let found_in_general = !found_in_keyed &&
|
|
+ self.high_priority_general.iter().any(&mut predicate);
|
|
+
|
|
+ if found_in_keyed || found_in_general {
|
|
true
|
|
}
|
|
// Otherwise, look for a low-priority work item that matches the current
|
|
// instance and promote it to high-priority.
|
|
else if let Some(idx) = self.low_priority.iter().position(&mut predicate) {
|
|
let item = self.low_priority.remove(idx).unwrap();
|
|
self.push_high_priority(item);
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|