java-topology/defects/wasmtime/wasmtime-0001-workqueue-linear-scan.md

2.3 KiB

wasmtime-0001: WorkQueue high_priority Vec O(n) scan in async task scheduler

Severity: MEDIUM CWE: CWE-407 (Algorithmic Complexity — linear membership test in hot loop) Speedup: >10x at N=500 concurrent tasks (per scheduling call) Target: wasmtime (bytecodealliance/wasmtime) Files:

  • crates/wasmtime/src/runtime/component/concurrent.rs:4874high_priority: Vec<WorkItem>
  • crates/wasmtime/src/runtime/component/concurrent.rs:5093self.high_priority.iter().any(&mut predicate)
  • crates/wasmtime/src/runtime/component/concurrent.rs:5098self.low_priority.iter().position(&mut predicate)

Description

The async component model task scheduler (WorkQueue) uses a Vec<WorkItem> for its high_priority queue. The promote_work_items_matching() function (called by promote_thread_work_item and promote_instance_local_thread_work_item) performs a linear scan through all high-priority items to find one matching a predicate.

promote_thread_work_item() is called:

  • On every resume_thread() call — concurrent.rs:3363
  • Each time a thread fiber is to be resumed

With T concurrent threads and N work items per thread:

  • Each scheduling step: O(T*N) to find the right work item
  • Total scheduling work: O(T² * N) across all threads

Root Cause

WorkItem is an enum with variants ResumeThread(instance, thread), GuestCall(instance, call), WorkerFunction, PushFuture, ResumeFiber. The predicate for promote_thread_work_item matches on the thread field of ResumeThread and GuestCall variants.

Fix: replace Vec<WorkItem> with a HashMap<QualifiedThreadId, VecDeque<WorkItem>> so that thread-targeted work items can be looked up in O(1).

Non-thread-specific items (WorkerFunction, PushFuture, ResumeFiber) remain in a general queue scanned only when thread-specific lookup fails.

Patch

See patch/wasmtime-0001.patch

Complexity Before

promote_thread_work_item() with N high-priority items: O(N) per call T threads each promoting: O(T * N) per scheduling cycle

Complexity After

Thread-specific lookup: O(1) amortized via HashMap General work items: unchanged (small set in practice)

Reproduction

cd defects/wasmtime/unit && javac -d . *.java && java -ea unit.WorkQueueLinearScanTest