gtauri: distance-from-viewport drop policy for ALL jobs
The backlog must never delay on-screen work. Urgent jobs (real Chromium requests) are now stale-dropped too, not just prefetch: a fast fling queues urgent work for every band it crosses, and all of it except the final band is dead — it filled the queue cap and made fresh on-screen requests wait for the JS retry timer. Safe because the anchor now settles at the final scroll position (trailing send), and on-screen cells have idx >= VPORT so they can never be dropped. A pure LIFO would not fix this: stale jobs sit at the stack bottom, never popped, still blocking the cap. Emulator fling test: 309 stale urgent jobs purged, queue peak 28, all 850 decodable images loaded.
This commit is contained in:
parent
02d1f097ac
commit
d990627200
|
|
@ -228,11 +228,13 @@ fn set_prefetch_window(lo: usize, hi: usize) {
|
||||||
VPORT.store(lo as u32, Ordering::Relaxed);
|
VPORT.store(lo as u32, Ordering::Relaxed);
|
||||||
let mut q = Q.lock().unwrap();
|
let mut q = Q.lock().unwrap();
|
||||||
let mut inq = INFLIGHT.lock().unwrap();
|
let mut inq = INFLIGHT.lock().unwrap();
|
||||||
// Stale PREFETCH work (far behind the new viewport) is worthless — drop
|
// The anchor just moved to `lo`: everything more than STALE_ROWS
|
||||||
// it. URGENT jobs (real pending requests) are never dropped here.
|
// behind it is dead work (urgent included — a fling leaves urgent
|
||||||
|
// jobs for every band it crossed). Drop it instantly so it can never
|
||||||
|
// delay the new viewport or eat queue capacity.
|
||||||
let kept = q.len();
|
let kept = q.len();
|
||||||
q.retain(|j| {
|
q.retain(|j| {
|
||||||
if j.urgent || j.idx + STALE_ROWS >= lo as u32 {
|
if j.idx + STALE_ROWS >= lo as u32 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inq.remove(&j.id);
|
inq.remove(&j.id);
|
||||||
|
|
@ -269,14 +271,21 @@ fn pop_next() -> Job {
|
||||||
g = Q_CV.wait(g).unwrap();
|
g = Q_CV.wait(g).unwrap();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Only PREFETCH work is droppable. URGENT jobs are real pending
|
// Distance-from-viewport policy: any job more than STALE_ROWS
|
||||||
// requests (JS/Chromium is waiting on them) — even if the viewport
|
// behind the viewport is dead work — the user flung past it, and
|
||||||
// anchor went stale, they must run.
|
// decoding it would only delay what is actually on screen. This
|
||||||
|
// applies to URGENT jobs too (a fling queues urgent work for every
|
||||||
|
// band it crosses; all of it except the final band is stale). Safe
|
||||||
|
// because the anchor now always settles at the final scroll
|
||||||
|
// position (trailing send), and on-screen cells have idx >= VPORT
|
||||||
|
// so they can never be dropped. (A pure LIFO would not solve this:
|
||||||
|
// the stale pile sits at the stack bottom, never popped, still
|
||||||
|
// blocking the queue cap.)
|
||||||
if let Some(j) = g.front() {
|
if let Some(j) = g.front() {
|
||||||
if !j.urgent && j.idx + STALE_ROWS < VPORT.load(Ordering::Relaxed) {
|
if j.idx + STALE_ROWS < VPORT.load(Ordering::Relaxed) {
|
||||||
let j = g.pop_front().unwrap();
|
let j = g.pop_front().unwrap();
|
||||||
INFLIGHT.lock().unwrap().remove(&j.id);
|
INFLIGHT.lock().unwrap().remove(&j.id);
|
||||||
tr(&format!("drop stale id={} idx={}", j.id, j.idx));
|
tr(&format!("drop stale id={} idx={} urgent={}", j.id, j.idx, j.urgent));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user