59 lines
2.3 KiB
Markdown
59 lines
2.3 KiB
Markdown
# wasmtime-0001: WorkQueue high_priority Vec<WorkItem> 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:4874` — `high_priority: Vec<WorkItem>`
|
|
- `crates/wasmtime/src/runtime/component/concurrent.rs:5093` — `self.high_priority.iter().any(&mut predicate)`
|
|
- `crates/wasmtime/src/runtime/component/concurrent.rs:5098` — `self.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
|
|
```
|