it: wait for async engine and cpu worker to become idle
This commit is contained in:
parent
58f82d889b
commit
a9aad0c613
5 changed files with 59 additions and 3 deletions
|
|
@ -35,6 +35,8 @@ pub struct AsyncEngine {
|
||||||
yield_stash: RefCell<VecDeque<Waker>>,
|
yield_stash: RefCell<VecDeque<Waker>>,
|
||||||
stopped: Cell<bool>,
|
stopped: Cell<bool>,
|
||||||
now: Cell<Option<Time>>,
|
now: Cell<Option<Time>>,
|
||||||
|
#[cfg(feature = "it")]
|
||||||
|
idle: Cell<Option<Waker>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncEngine {
|
impl AsyncEngine {
|
||||||
|
|
@ -48,6 +50,8 @@ impl AsyncEngine {
|
||||||
yield_stash: Default::default(),
|
yield_stash: Default::default(),
|
||||||
stopped: Cell::new(false),
|
stopped: Cell::new(false),
|
||||||
now: Default::default(),
|
now: Default::default(),
|
||||||
|
#[cfg(feature = "it")]
|
||||||
|
idle: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +95,15 @@ impl AsyncEngine {
|
||||||
pub fn dispatch(&self) {
|
pub fn dispatch(&self) {
|
||||||
let mut stash = self.stash.borrow_mut();
|
let mut stash = self.stash.borrow_mut();
|
||||||
let mut yield_stash = self.yield_stash.borrow_mut();
|
let mut yield_stash = self.yield_stash.borrow_mut();
|
||||||
while self.num_queued.get() > 0 {
|
loop {
|
||||||
|
if self.num_queued.get() == 0 {
|
||||||
|
#[cfg(feature = "it")]
|
||||||
|
if let Some(idle) = self.idle.take() {
|
||||||
|
idle.wake();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
self.now.take();
|
self.now.take();
|
||||||
self.iteration.fetch_add(1);
|
self.iteration.fetch_add(1);
|
||||||
let mut phase = 0;
|
let mut phase = 0;
|
||||||
|
|
@ -116,6 +128,22 @@ impl AsyncEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "it")]
|
||||||
|
pub async fn idle(&self) {
|
||||||
|
use std::{future::poll_fn, task::Poll};
|
||||||
|
let mut register = true;
|
||||||
|
poll_fn(|ctx| {
|
||||||
|
if register {
|
||||||
|
self.idle.set(Some(ctx.waker().clone()));
|
||||||
|
register = false;
|
||||||
|
Poll::Pending
|
||||||
|
} else {
|
||||||
|
Poll::Ready(())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
fn push(&self, runnable: Runnable, phase: Phase) {
|
fn push(&self, runnable: Runnable, phase: Phase) {
|
||||||
self.queues[phase as usize].push(runnable);
|
self.queues[phase as usize].push(runnable);
|
||||||
self.num_queued.fetch_add(1);
|
self.num_queued.fetch_add(1);
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,23 @@ impl CpuWorker {
|
||||||
job_data,
|
job_data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "it")]
|
||||||
|
pub fn wait_idle(&self) -> bool {
|
||||||
|
let was_idle = self.data.pending_jobs.is_empty();
|
||||||
|
loop {
|
||||||
|
self.data.dispatch_completions();
|
||||||
|
if self.data.pending_jobs.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut remote = self.data.completed_jobs_remote.lock();
|
||||||
|
while remote.queue.is_empty() {
|
||||||
|
remote.condvar = Some(self.data.sync_wake_condvar.clone());
|
||||||
|
self.data.sync_wake_condvar.wait(&mut remote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
was_idle
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn work(
|
fn work(
|
||||||
|
|
|
||||||
|
|
@ -85,10 +85,9 @@ impl TestClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sync(&self) {
|
pub async fn sync(&self) {
|
||||||
self.run.state.eng.yield_now().await;
|
|
||||||
self.run.sync().await;
|
self.run.sync().await;
|
||||||
self.tran.sync().await;
|
self.tran.sync().await;
|
||||||
self.run.state.eng.yield_now().await;
|
self.run.state.idle().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn take_screenshot(&self, include_cursor: bool) -> Result<Vec<u8>, TestError> {
|
pub async fn take_screenshot(&self, include_cursor: bool) -> Result<Vec<u8>, TestError> {
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ impl TestJayCompositor {
|
||||||
&self,
|
&self,
|
||||||
include_cursor: bool,
|
include_cursor: bool,
|
||||||
) -> Result<(DmaBuf, Option<Rc<OwnedFd>>), TestError> {
|
) -> Result<(DmaBuf, Option<Rc<OwnedFd>>), TestError> {
|
||||||
|
self.tran.sync().await;
|
||||||
|
self.tran.run.state.idle().await;
|
||||||
let js = Rc::new(TestJayScreenshot {
|
let js = Rc::new(TestJayScreenshot {
|
||||||
id: self.tran.id(),
|
id: self.tran.id(),
|
||||||
state: self.tran.run.state.clone(),
|
state: self.tran.run.state.clone(),
|
||||||
|
|
|
||||||
10
src/state.rs
10
src/state.rs
|
|
@ -1218,6 +1218,16 @@ impl State {
|
||||||
output.vblank();
|
output.vblank();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "it")]
|
||||||
|
pub async fn idle(&self) {
|
||||||
|
loop {
|
||||||
|
self.eng.idle().await;
|
||||||
|
if self.cpu_worker.wait_idle() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue