all: use tracy for tracing
This commit is contained in:
parent
50186e764e
commit
ccad3cf0fb
56 changed files with 647 additions and 171 deletions
|
|
@ -146,16 +146,14 @@ impl Acceptor {
|
|||
}
|
||||
let acc = Rc::new(Acceptor { socket });
|
||||
let futures = vec![
|
||||
state.eng.spawn(accept(
|
||||
acc.socket.secure.clone(),
|
||||
state.clone(),
|
||||
ClientCaps::all(),
|
||||
)),
|
||||
state.eng.spawn(accept(
|
||||
acc.socket.insecure.clone(),
|
||||
state.clone(),
|
||||
CAPS_DEFAULT,
|
||||
)),
|
||||
state.eng.spawn(
|
||||
"secure acceptor",
|
||||
accept(acc.socket.secure.clone(), state.clone(), ClientCaps::all()),
|
||||
),
|
||||
state.eng.spawn(
|
||||
"insecure acceptor",
|
||||
accept(acc.socket.insecure.clone(), state.clone(), CAPS_DEFAULT),
|
||||
),
|
||||
];
|
||||
state.acceptor.set(Some(acc.clone()));
|
||||
Ok((acc, futures))
|
||||
|
|
|
|||
|
|
@ -64,16 +64,21 @@ impl AsyncEngine {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn spawn<T, F: Future<Output = T> + 'static>(self: &Rc<Self>, f: F) -> SpawnedFuture<T> {
|
||||
self.spawn_(Phase::EventHandling, f)
|
||||
pub fn spawn<T, F: Future<Output = T> + 'static>(
|
||||
self: &Rc<Self>,
|
||||
name: &str,
|
||||
f: F,
|
||||
) -> SpawnedFuture<T> {
|
||||
self.spawn_(name, Phase::EventHandling, f)
|
||||
}
|
||||
|
||||
pub fn spawn2<T, F: Future<Output = T> + 'static>(
|
||||
self: &Rc<Self>,
|
||||
name: &str,
|
||||
phase: Phase,
|
||||
f: F,
|
||||
) -> SpawnedFuture<T> {
|
||||
self.spawn_(phase, f)
|
||||
self.spawn_(name, phase, f)
|
||||
}
|
||||
|
||||
pub fn yield_now(self: &Rc<Self>) -> Yield {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
async_engine::{AsyncEngine, Phase},
|
||||
tracy::ZoneName,
|
||||
utils::{
|
||||
numcell::NumCell,
|
||||
ptr_ext::{MutPtrExt, PtrExt},
|
||||
|
|
@ -95,6 +96,8 @@ struct Task<T, F: Future<Output = T>> {
|
|||
data: UnsafeCell<TaskData<T, F>>,
|
||||
waker: Cell<Option<Waker>>,
|
||||
queue: Rc<AsyncEngine>,
|
||||
#[cfg_attr(not(feature = "tracy"), expect(dead_code))]
|
||||
zone: ZoneName,
|
||||
}
|
||||
|
||||
pub(super) struct Runnable {
|
||||
|
|
@ -122,6 +125,7 @@ impl Drop for Runnable {
|
|||
impl AsyncEngine {
|
||||
pub(super) fn spawn_<T, F: Future<Output = T>>(
|
||||
self: &Rc<Self>,
|
||||
#[cfg_attr(not(feature = "tracy"), expect(unused_variables))] name: &str,
|
||||
phase: Phase,
|
||||
f: F,
|
||||
) -> SpawnedFuture<T> {
|
||||
|
|
@ -134,6 +138,7 @@ impl AsyncEngine {
|
|||
}),
|
||||
waker: Cell::new(None),
|
||||
queue: self.clone(),
|
||||
zone: create_zone_name!("task:{}", name),
|
||||
});
|
||||
unsafe {
|
||||
f.schedule_run();
|
||||
|
|
@ -229,7 +234,11 @@ impl<T, F: Future<Output = T>> Task<T, F> {
|
|||
let waker = Waker::from_raw(raw_waker);
|
||||
|
||||
let mut ctx = Context::from_waker(&waker);
|
||||
if let Poll::Ready(d) = Pin::new_unchecked(&mut *data.future).poll(&mut ctx) {
|
||||
let poll = {
|
||||
dynamic_zone!(self.zone);
|
||||
Pin::new_unchecked(&mut *data.future).poll(&mut ctx)
|
||||
};
|
||||
if let Poll::Ready(d) = poll {
|
||||
ManuallyDrop::drop(&mut data.future);
|
||||
ptr::write(&mut data.result, ManuallyDrop::new(d));
|
||||
self.state.or_assign(COMPLETED);
|
||||
|
|
|
|||
|
|
@ -163,8 +163,14 @@ impl Debug for MetalBackend {
|
|||
|
||||
impl MetalBackend {
|
||||
async fn run(self: Rc<Self>) -> Result<(), MetalError> {
|
||||
let _monitor = self.state.eng.spawn(self.clone().monitor_devices());
|
||||
let _events = self.state.eng.spawn(self.clone().handle_libinput_events());
|
||||
let _monitor = self
|
||||
.state
|
||||
.eng
|
||||
.spawn("monitor devices", self.clone().monitor_devices());
|
||||
let _events = self.state.eng.spawn(
|
||||
"handle libinput events",
|
||||
self.clone().handle_libinput_events(),
|
||||
);
|
||||
if let Err(e) = self.enumerate_devices() {
|
||||
return Err(MetalError::Enumerate(Box::new(e)));
|
||||
}
|
||||
|
|
@ -175,7 +181,7 @@ impl MetalBackend {
|
|||
impl Backend for MetalBackend {
|
||||
fn run(self: Rc<Self>) -> SpawnedFuture<Result<(), Box<dyn Error>>> {
|
||||
let slf = self.clone();
|
||||
self.state.eng.spawn(async move {
|
||||
self.state.eng.spawn("metal backend", async move {
|
||||
slf.run().await?;
|
||||
Ok(())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use {
|
|||
},
|
||||
theme::Color,
|
||||
time::Time,
|
||||
tracy::FrameName,
|
||||
tree::OutputNode,
|
||||
utils::{errorfmt::ErrorFmt, oserror::OsError, transform_ext::TransformExt},
|
||||
video::{
|
||||
|
|
@ -90,6 +91,8 @@ impl MetalConnector {
|
|||
}
|
||||
|
||||
pub async fn present_loop(self: Rc<Self>) {
|
||||
#[cfg_attr(not(feature = "tracy"), expect(unused_variables))]
|
||||
let frame_name = FrameName::get(&self.kernel_id().to_string());
|
||||
let mut cur_sec = 0;
|
||||
let mut max = 0;
|
||||
loop {
|
||||
|
|
@ -113,6 +116,7 @@ impl MetalConnector {
|
|||
expected_sequence += 1;
|
||||
}
|
||||
}
|
||||
frame!(frame_name);
|
||||
if let Err(e) = self.present_once().await {
|
||||
log::error!("Could not present: {}", ErrorFmt(e));
|
||||
continue;
|
||||
|
|
@ -293,6 +297,7 @@ impl MetalConnector {
|
|||
cursor: Option<&CursorProgramming>,
|
||||
new_fb: Option<&PresentFb>,
|
||||
) -> Result<(), MetalError> {
|
||||
zone!("program_connector");
|
||||
let mut changes = self.master.change();
|
||||
let mut try_async_flip = self.try_async_flip();
|
||||
macro_rules! change {
|
||||
|
|
|
|||
|
|
@ -1089,10 +1089,11 @@ fn create_connector(
|
|||
presentation_is_zero_copy: Cell::new(false),
|
||||
});
|
||||
let futures = ConnectorFutures {
|
||||
_present: backend
|
||||
.state
|
||||
.eng
|
||||
.spawn2(Phase::Present, slf.clone().present_loop()),
|
||||
_present: backend.state.eng.spawn2(
|
||||
"present loop",
|
||||
Phase::Present,
|
||||
slf.clone().present_loop(),
|
||||
),
|
||||
};
|
||||
Ok((slf, futures))
|
||||
}
|
||||
|
|
@ -1791,10 +1792,10 @@ impl MetalBackend {
|
|||
}
|
||||
}
|
||||
|
||||
let drm_handler = self
|
||||
.state
|
||||
.eng
|
||||
.spawn(self.clone().handle_drm_events(slf.clone()));
|
||||
let drm_handler = self.state.eng.spawn(
|
||||
"handle drm events",
|
||||
self.clone().handle_drm_events(slf.clone()),
|
||||
);
|
||||
slf.dev.handle_events.handle_events.set(Some(drm_handler));
|
||||
|
||||
Ok(slf)
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> {
|
|||
impl Backend for XBackend {
|
||||
fn run(self: Rc<Self>) -> SpawnedFuture<Result<(), Box<dyn Error>>> {
|
||||
let slf = self.clone();
|
||||
self.state.eng.spawn(async move {
|
||||
self.state.eng.spawn("x backend", async move {
|
||||
slf.run().await?;
|
||||
Ok(())
|
||||
})
|
||||
|
|
@ -280,12 +280,19 @@ impl XBackend {
|
|||
async fn run(self: Rc<Self>) -> Result<(), XBackendError> {
|
||||
self.query_devices(INPUT_DEVICE_ALL_MASTER).await?;
|
||||
|
||||
let _events = self.state.eng.spawn(self.clone().event_handler());
|
||||
let _grab = self.state.eng.spawn(self.clone().grab_handler());
|
||||
let _present = self
|
||||
let _events = self
|
||||
.state
|
||||
.eng
|
||||
.spawn2(Phase::Present, self.clone().present_handler());
|
||||
.spawn("x event handler", self.clone().event_handler());
|
||||
let _grab = self
|
||||
.state
|
||||
.eng
|
||||
.spawn("grab handler", self.clone().grab_handler());
|
||||
let _present = self.state.eng.spawn2(
|
||||
"present handler",
|
||||
Phase::Present,
|
||||
self.clone().present_handler(),
|
||||
);
|
||||
|
||||
self.state.set_render_ctx(Some(self.ctx.clone()));
|
||||
self.state
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ impl Clients {
|
|||
data.objects.display.set(Some(display.clone()));
|
||||
data.objects.add_client_object(display).expect("");
|
||||
let client = ClientHolder {
|
||||
_handler: global.eng.spawn(tasks::client(data.clone())),
|
||||
_handler: global.eng.spawn("client", tasks::client(data.clone())),
|
||||
data: data.clone(),
|
||||
};
|
||||
log::info!(
|
||||
|
|
|
|||
|
|
@ -14,9 +14,16 @@ use {
|
|||
};
|
||||
|
||||
pub async fn client(data: Rc<Client>) {
|
||||
let mut recv = data.state.eng.spawn(receive(data.clone())).fuse();
|
||||
let mut recv = data
|
||||
.state
|
||||
.eng
|
||||
.spawn("client receive", receive(data.clone()))
|
||||
.fuse();
|
||||
let mut shutdown = data.shutdown.triggered().fuse();
|
||||
let _send = data.state.eng.spawn2(Phase::PostLayout, send(data.clone()));
|
||||
let _send = data
|
||||
.state
|
||||
.eng
|
||||
.spawn2("client send", Phase::PostLayout, send(data.clone()));
|
||||
select! {
|
||||
_ = recv => { },
|
||||
_ = shutdown => { },
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ impl CpuJob for CloseMemWork {
|
|||
|
||||
impl CpuWork for CloseMemWork {
|
||||
fn run(&mut self) -> Option<Box<dyn AsyncCpuWork>> {
|
||||
zone!("CloseMemWork");
|
||||
self.fd.take();
|
||||
unsafe {
|
||||
c::munmap(self.data as _, self.data.len());
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use {
|
|||
sighand::{self, SighandError},
|
||||
state::{ConnectorData, IdleState, ScreenlockState, State, XWaylandState},
|
||||
tasks::{self, idle},
|
||||
tracy::enable_profiler,
|
||||
tree::{
|
||||
container_layout, container_render_data, float_layout, float_titles,
|
||||
output_render_data, DisplayNode, NodeIds, OutputNode, TearingMode, VrrMode,
|
||||
|
|
@ -62,6 +63,7 @@ pub const MAX_EXTENTS: i32 = (1 << 22) - 1;
|
|||
pub fn start_compositor(global: GlobalArgs, args: RunArgs) {
|
||||
let forker = create_forker();
|
||||
let portal = portal::run_from_compositor(global.log_level.into());
|
||||
enable_profiler();
|
||||
let logger = Logger::install_compositor(global.log_level.into());
|
||||
let portal = match portal {
|
||||
Ok(p) => Some(p),
|
||||
|
|
@ -279,9 +281,12 @@ fn start_compositor2(
|
|||
}
|
||||
let mut _portal = None;
|
||||
if let (Some(portal), Some(logger)) = (portal, &logger) {
|
||||
_portal = Some(engine.spawn(portal.spawn(engine.clone(), ring.clone(), logger.clone())));
|
||||
_portal = Some(engine.spawn(
|
||||
"portal",
|
||||
portal.spawn(engine.clone(), ring.clone(), logger.clone()),
|
||||
));
|
||||
}
|
||||
let _compositor = engine.spawn(start_compositor3(state.clone(), test_future));
|
||||
let _compositor = engine.spawn("compositor", start_compositor3(state.clone(), test_future));
|
||||
ring.run()?;
|
||||
state.clear();
|
||||
Ok(())
|
||||
|
|
@ -354,20 +359,65 @@ fn start_global_event_handlers(
|
|||
let eng = &state.eng;
|
||||
|
||||
vec![
|
||||
eng.spawn(tasks::handle_backend_events(state.clone())),
|
||||
eng.spawn(tasks::handle_slow_clients(state.clone())),
|
||||
eng.spawn(tasks::handle_hardware_cursor_tick(state.clone())),
|
||||
eng.spawn2(Phase::Layout, container_layout(state.clone())),
|
||||
eng.spawn2(Phase::PostLayout, container_render_data(state.clone())),
|
||||
eng.spawn2(Phase::PostLayout, output_render_data(state.clone())),
|
||||
eng.spawn2(Phase::Layout, float_layout(state.clone())),
|
||||
eng.spawn2(Phase::PostLayout, float_titles(state.clone())),
|
||||
eng.spawn2(Phase::PostLayout, idle(state.clone(), backend.clone())),
|
||||
eng.spawn2(Phase::PostLayout, input_popup_positioning(state.clone())),
|
||||
eng.spawn2(Phase::Present, perform_toplevel_screencasts(state.clone())),
|
||||
eng.spawn2(Phase::PostLayout, perform_screencast_realloc(state.clone())),
|
||||
eng.spawn2(Phase::PostLayout, visualize_damage(state.clone())),
|
||||
eng.spawn(tasks::handle_slow_ei_clients(state.clone())),
|
||||
eng.spawn(
|
||||
"backend events",
|
||||
tasks::handle_backend_events(state.clone()),
|
||||
),
|
||||
eng.spawn("slow client", tasks::handle_slow_clients(state.clone())),
|
||||
eng.spawn(
|
||||
"handware cursor tick",
|
||||
tasks::handle_hardware_cursor_tick(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"container layout",
|
||||
Phase::Layout,
|
||||
container_layout(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"container render",
|
||||
Phase::PostLayout,
|
||||
container_render_data(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"output render",
|
||||
Phase::PostLayout,
|
||||
output_render_data(state.clone()),
|
||||
),
|
||||
eng.spawn2("float layout", Phase::Layout, float_layout(state.clone())),
|
||||
eng.spawn2(
|
||||
"float titles",
|
||||
Phase::PostLayout,
|
||||
float_titles(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"idle",
|
||||
Phase::PostLayout,
|
||||
idle(state.clone(), backend.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"input, popup positioning",
|
||||
Phase::PostLayout,
|
||||
input_popup_positioning(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"toplevel screencast present",
|
||||
Phase::Present,
|
||||
perform_toplevel_screencasts(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"screencast realloc",
|
||||
Phase::PostLayout,
|
||||
perform_screencast_realloc(state.clone()),
|
||||
),
|
||||
eng.spawn2(
|
||||
"visualize damage",
|
||||
Phase::PostLayout,
|
||||
visualize_damage(state.clone()),
|
||||
),
|
||||
eng.spawn(
|
||||
"slow ei clients",
|
||||
tasks::handle_slow_ei_clients(state.clone()),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ impl ConfigProxyHandler {
|
|||
let handler = {
|
||||
let timer = timer.clone();
|
||||
let slf = self.clone();
|
||||
self.state.eng.spawn(async move {
|
||||
self.state.eng.spawn("config timer", async move {
|
||||
loop {
|
||||
match timer.expired(&slf.state.ring).await {
|
||||
Ok(_) => slf.send(&ServerMessage::TimerExpired {
|
||||
|
|
@ -1400,7 +1400,7 @@ impl ConfigProxyHandler {
|
|||
let slf = self.clone();
|
||||
let trigger = event.clone();
|
||||
let fd = fd.clone();
|
||||
let future = self.state.eng.spawn(async move {
|
||||
let future = self.state.eng.spawn("config fd poller", async move {
|
||||
loop {
|
||||
trigger.triggered().await;
|
||||
let res = slf.state.ring.poll(&fd, events).await.merge();
|
||||
|
|
|
|||
|
|
@ -283,8 +283,11 @@ impl CpuWorker {
|
|||
pending_job_data_cache: Default::default(),
|
||||
});
|
||||
Ok(Self {
|
||||
_completions_listener: eng.spawn(data.clone().wait_for_completions()),
|
||||
_job_enqueuer: eng.spawn(data.clone().equeue_jobs()),
|
||||
_completions_listener: eng.spawn(
|
||||
"cpu worker completions",
|
||||
data.clone().wait_for_completions(),
|
||||
),
|
||||
_job_enqueuer: eng.spawn("cpu worker enqueue", data.clone().equeue_jobs()),
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
|
@ -325,10 +328,13 @@ fn work(
|
|||
async_jobs: Default::default(),
|
||||
stopped: Cell::new(false),
|
||||
});
|
||||
let _stop_listener = worker.eng.spawn(worker.clone().handle_stop(stop));
|
||||
let _new_job_listener = worker
|
||||
let _stop_listener = worker
|
||||
.eng
|
||||
.spawn(worker.clone().handle_new_jobs(new_jobs, have_new_jobs));
|
||||
.spawn("stop listener", worker.clone().handle_stop(stop));
|
||||
let _new_job_listener = worker.eng.spawn(
|
||||
"new job listener",
|
||||
worker.clone().handle_new_jobs(new_jobs, have_new_jobs),
|
||||
);
|
||||
if let Err(e) = worker.ring.run() {
|
||||
panic!("io_uring failed: {}", ErrorFmt(e));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ impl ImgCopyWork {
|
|||
|
||||
impl CpuWork for ImgCopyWork {
|
||||
fn run(&mut self) -> Option<Box<dyn AsyncCpuWork>> {
|
||||
zone!("ImgCopyWork");
|
||||
for rect in &self.rects {
|
||||
let mut offset = rect.y1() * self.stride + rect.x1() * self.bpp;
|
||||
if rect.width() == self.width {
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ impl AsyncCpuWork for ReadWriteWorkConfig {
|
|||
completion: WorkCompletion,
|
||||
) -> SpawnedFuture<CompletedWork> {
|
||||
let ring = ring.clone();
|
||||
eng.spawn(async move {
|
||||
eng.spawn("shm read/write", async move {
|
||||
let res = loop {
|
||||
if self.cancel.cancelled.load(Relaxed) {
|
||||
break Err(ReadWriteJobError::Cancelled);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ impl AsyncCpuWork for AsyncWork {
|
|||
completion: WorkCompletion,
|
||||
) -> SpawnedFuture<CompletedWork> {
|
||||
let ring = ring.clone();
|
||||
eng.spawn(async move {
|
||||
eng.spawn("", async move {
|
||||
let mut buf = [0; 8];
|
||||
let res = ring
|
||||
.read_no_cancel(self.0.borrow(), 0, &mut buf, |_| ())
|
||||
|
|
@ -90,7 +90,7 @@ fn run(cancel: bool) {
|
|||
work: Work(eventfd.clone()),
|
||||
cancel,
|
||||
}));
|
||||
let _fut1 = eng.spawn(async move {
|
||||
let _fut1 = eng.spawn("", async move {
|
||||
wheel.timeout(1).await.unwrap();
|
||||
if cancel {
|
||||
drop(pending_job);
|
||||
|
|
@ -99,7 +99,7 @@ fn run(cancel: bool) {
|
|||
pending::<()>().await;
|
||||
}
|
||||
});
|
||||
let _fut2 = eng.spawn(async move {
|
||||
let _fut2 = eng.spawn("", async move {
|
||||
ae.triggered().await;
|
||||
ring2.stop();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -39,10 +39,14 @@ impl Auth {
|
|||
}
|
||||
log::info!("{}: Authenticated", self.socket.bus_name);
|
||||
self.socket.incoming.set(Some(
|
||||
self.socket.eng.spawn(handle_incoming(self.socket.clone())),
|
||||
self.socket
|
||||
.eng
|
||||
.spawn("dbus incoming", handle_incoming(self.socket.clone())),
|
||||
));
|
||||
self.socket.outgoing_.set(Some(
|
||||
self.socket.eng.spawn(handle_outgoing(self.socket.clone())),
|
||||
self.socket
|
||||
.eng
|
||||
.spawn("dbus outgoing", handle_outgoing(self.socket.clone())),
|
||||
));
|
||||
self.socket.auth.take();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ async fn connect(
|
|||
}
|
||||
},
|
||||
);
|
||||
let future = eng.spawn(handle_auth(socket.clone()));
|
||||
let future = eng.spawn("dbus auth", handle_auth(socket.clone()));
|
||||
socket.auth.set(Some(future));
|
||||
Ok(socket)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,9 +126,10 @@ impl EiAcceptor {
|
|||
return Err(EiAcceptorError::ListenFailed(e.into()));
|
||||
}
|
||||
let acc = Rc::new(EiAcceptor { socket });
|
||||
let future = state
|
||||
.eng
|
||||
.spawn(accept(acc.socket.insecure.clone(), state.clone()));
|
||||
let future = state.eng.spawn(
|
||||
"ei accept",
|
||||
accept(acc.socket.insecure.clone(), state.clone()),
|
||||
);
|
||||
Ok((acc, future))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,9 @@ impl EiClients {
|
|||
handshake.send_handshake_version();
|
||||
data.objects.add_handshake(&handshake);
|
||||
let client = EiClientHolder {
|
||||
_handler: global.eng.spawn(ei_tasks::ei_client(data.clone())),
|
||||
_handler: global
|
||||
.eng
|
||||
.spawn("ei client", ei_tasks::ei_client(data.clone())),
|
||||
data: data.clone(),
|
||||
};
|
||||
log::info!(
|
||||
|
|
|
|||
|
|
@ -16,9 +16,16 @@ use {
|
|||
};
|
||||
|
||||
pub async fn ei_client(data: Rc<EiClient>) {
|
||||
let mut recv = data.state.eng.spawn(receive(data.clone())).fuse();
|
||||
let mut recv = data
|
||||
.state
|
||||
.eng
|
||||
.spawn("ei receive", receive(data.clone()))
|
||||
.fuse();
|
||||
let mut shutdown = data.shutdown.triggered().fuse();
|
||||
let _send = data.state.eng.spawn2(Phase::PostLayout, send(data.clone()));
|
||||
let _send = data
|
||||
.state
|
||||
.eng
|
||||
.spawn2("ei send", Phase::PostLayout, send(data.clone()));
|
||||
select! {
|
||||
_ = recv => { },
|
||||
_ = shutdown => { },
|
||||
|
|
|
|||
|
|
@ -109,13 +109,20 @@ impl ForkerProxy {
|
|||
|
||||
pub fn install(self: &Rc<Self>, state: &Rc<State>) {
|
||||
state.forker.set(Some(self.clone()));
|
||||
self.task_proc.set(Some(
|
||||
state.eng.spawn(self.clone().check_process(state.clone())),
|
||||
self.task_proc.set(Some(state.eng.spawn(
|
||||
"forker check process",
|
||||
self.clone().check_process(state.clone()),
|
||||
)));
|
||||
self.task_in.set(Some(
|
||||
state
|
||||
.eng
|
||||
.spawn("forker incoming", self.clone().incoming(state.clone())),
|
||||
));
|
||||
self.task_out.set(Some(
|
||||
state
|
||||
.eng
|
||||
.spawn("forker outgoing", self.clone().outgoing(state.clone())),
|
||||
));
|
||||
self.task_in
|
||||
.set(Some(state.eng.spawn(self.clone().incoming(state.clone()))));
|
||||
self.task_out
|
||||
.set(Some(state.eng.spawn(self.clone().outgoing(state.clone()))));
|
||||
}
|
||||
|
||||
pub fn setenv(&self, key: &[u8], val: &[u8]) {
|
||||
|
|
@ -353,8 +360,8 @@ impl Forker {
|
|||
outgoing: Default::default(),
|
||||
pending_spawns: Default::default(),
|
||||
});
|
||||
let _f1 = ae.spawn(forker.clone().incoming());
|
||||
let _f2 = ae.spawn(forker.clone().outgoing());
|
||||
let _f1 = ae.spawn("forker incoming", forker.clone().incoming());
|
||||
let _f2 = ae.spawn("forker outgoing", forker.clone().outgoing());
|
||||
let _ = ring.run();
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
|
@ -462,7 +469,7 @@ impl Forker {
|
|||
}
|
||||
drop(write);
|
||||
let slf = self.clone();
|
||||
let spawn = self.ae.spawn(async move {
|
||||
let spawn = self.ae.spawn("await spawn", async move {
|
||||
let read = Rc::new(read);
|
||||
if let Err(e) = slf.ring.readable(&read).await {
|
||||
log::error!(
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ struct AllocWork {
|
|||
|
||||
impl CpuWork for AllocWork {
|
||||
fn run(&mut self) -> Option<Box<dyn AsyncCpuWork>> {
|
||||
zone!("AllocWork");
|
||||
let r = do_alloc(
|
||||
&mut self.allocator.lock(),
|
||||
&self.device,
|
||||
|
|
@ -303,6 +304,7 @@ struct FreeWork {
|
|||
|
||||
impl CpuWork for FreeWork {
|
||||
fn run(&mut self) -> Option<Box<dyn AsyncCpuWork>> {
|
||||
zone!("FreeWork");
|
||||
let ua = self.allocation.take().unwrap();
|
||||
unsafe {
|
||||
do_free(&mut self.allocator.lock(), &self.device, ua.block, ua.ptr);
|
||||
|
|
|
|||
|
|
@ -274,6 +274,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn collect_memory(&self, opts: &[GfxApiOpt]) {
|
||||
zone!("collect_memory");
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
memory.sample.clear();
|
||||
for cmd in opts {
|
||||
|
|
@ -296,6 +297,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn begin_command_buffer(&self, buf: CommandBuffer) -> Result<(), VulkanError> {
|
||||
zone!("begin_command_buffer");
|
||||
let begin_info =
|
||||
CommandBufferBeginInfo::default().flags(CommandBufferUsageFlags::ONE_TIME_SUBMIT);
|
||||
unsafe {
|
||||
|
|
@ -307,6 +309,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn initial_barriers(&self, buf: CommandBuffer, fb: &VulkanImage) {
|
||||
zone!("initial_barriers");
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
let memory = &mut *memory;
|
||||
memory.image_barriers.clear();
|
||||
|
|
@ -355,6 +358,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn begin_rendering(&self, buf: CommandBuffer, fb: &VulkanImage, clear: Option<&Color>) {
|
||||
zone!("begin_rendering");
|
||||
let rendering_attachment_info = {
|
||||
let mut rai = RenderingAttachmentInfo::default()
|
||||
.image_view(fb.render_view.unwrap_or(fb.texture_view))
|
||||
|
|
@ -388,6 +392,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn set_viewport(&self, buf: CommandBuffer, fb: &VulkanImage) {
|
||||
zone!("set_viewport");
|
||||
let viewport = Viewport {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
|
|
@ -419,6 +424,7 @@ impl VulkanRenderer {
|
|||
fb: &VulkanImage,
|
||||
opts: &[GfxApiOpt],
|
||||
) -> Result<(), VulkanError> {
|
||||
zone!("record_draws");
|
||||
let pipelines = self.get_or_create_pipelines(fb.format.vk_format)?;
|
||||
let dev = &self.device.device;
|
||||
let mut current_pipeline = None;
|
||||
|
|
@ -519,12 +525,14 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn end_rendering(&self, buf: CommandBuffer) {
|
||||
zone!("end_rendering");
|
||||
unsafe {
|
||||
self.device.device.cmd_end_rendering(buf);
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_bridge_to_dmabuf(&self, buf: CommandBuffer, fb: &VulkanImage) {
|
||||
zone!("copy_bridge_to_dmabuf");
|
||||
let Some(bridge) = &fb.bridge else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -584,6 +592,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn final_barriers(&self, buf: CommandBuffer, fb: &VulkanImage) {
|
||||
zone!("final_barriers");
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
let memory = &mut *memory;
|
||||
memory.image_barriers.clear();
|
||||
|
|
@ -625,6 +634,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn end_command_buffer(&self, buf: CommandBuffer) -> Result<(), VulkanError> {
|
||||
zone!("end_command_buffer");
|
||||
unsafe {
|
||||
self.device
|
||||
.device
|
||||
|
|
@ -634,6 +644,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn create_wait_semaphores(&self, fb: &VulkanImage) -> Result<(), VulkanError> {
|
||||
zone!("create_wait_semaphores");
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
let memory = &mut *memory;
|
||||
memory.wait_semaphore_infos.clear();
|
||||
|
|
@ -658,6 +669,7 @@ impl VulkanRenderer {
|
|||
match sync {
|
||||
AcquireSync::None => {}
|
||||
AcquireSync::Implicit { .. } => {
|
||||
zone!("import implicit");
|
||||
for plane in &buf.template.dmabuf.planes {
|
||||
let fd = dma_buf_export_sync_file(&plane.fd, flag)
|
||||
.map_err(VulkanError::IoctlExportSyncFile)?;
|
||||
|
|
@ -694,6 +706,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn import_release_semaphore(&self, fb: &VulkanImage) {
|
||||
zone!("import_release_semaphore");
|
||||
let memory = &mut *self.memory.borrow_mut();
|
||||
let sync_file = match memory.release_sync_file.as_ref() {
|
||||
Some(sync_file) => sync_file,
|
||||
|
|
@ -727,6 +740,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn submit(&self, buf: CommandBuffer) -> Result<(), VulkanError> {
|
||||
zone!("submit");
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
let release_fence = self.device.create_fence()?;
|
||||
let command_buffer_info = CommandBufferSubmitInfo::default().command_buffer(buf);
|
||||
|
|
@ -743,6 +757,7 @@ impl VulkanRenderer {
|
|||
)
|
||||
.map_err(VulkanError::Submit)?;
|
||||
}
|
||||
zone!("export_sync_file");
|
||||
let release_sync_file = match release_fence.export_sync_file() {
|
||||
Ok(s) => Some(s),
|
||||
Err(e) => {
|
||||
|
|
@ -761,6 +776,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn create_pending_frame(self: &Rc<Self>, buf: Rc<VulkanCommandBuffer>) {
|
||||
zone!("create_pending_frame");
|
||||
let point = self.allocate_point();
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
let frame = Rc::new(PendingFrame {
|
||||
|
|
@ -773,12 +789,15 @@ impl VulkanRenderer {
|
|||
_release_fence: memory.release_fence.take(),
|
||||
});
|
||||
self.pending_frames.set(frame.point, frame.clone());
|
||||
let future = self.eng.spawn(await_release(
|
||||
memory.release_sync_file.clone(),
|
||||
self.ring.clone(),
|
||||
frame.clone(),
|
||||
self.clone(),
|
||||
));
|
||||
let future = self.eng.spawn(
|
||||
"await release",
|
||||
await_release(
|
||||
memory.release_sync_file.clone(),
|
||||
self.ring.clone(),
|
||||
frame.clone(),
|
||||
self.clone(),
|
||||
),
|
||||
);
|
||||
frame.waiter.set(Some(future));
|
||||
}
|
||||
|
||||
|
|
@ -976,6 +995,7 @@ impl VulkanRenderer {
|
|||
opts: &[GfxApiOpt],
|
||||
clear: Option<&Color>,
|
||||
) -> Result<Option<SyncFile>, VulkanError> {
|
||||
zone!("execute");
|
||||
let res = self.try_execute(fb, opts, clear);
|
||||
let sync_file = {
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
|
|
@ -989,6 +1009,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
pub(super) fn allocate_command_buffer(&self) -> Result<Rc<VulkanCommandBuffer>, VulkanError> {
|
||||
zone!("allocate_command_buffer");
|
||||
let buf = match self.command_buffers.pop() {
|
||||
Some(b) => b,
|
||||
_ => {
|
||||
|
|
@ -1000,6 +1021,7 @@ impl VulkanRenderer {
|
|||
}
|
||||
|
||||
fn allocate_semaphore(&self) -> Result<Rc<VulkanSemaphore>, VulkanError> {
|
||||
zone!("allocate_semaphore");
|
||||
let semaphore = match self.wait_semaphores.pop() {
|
||||
Some(s) => s,
|
||||
_ => self.device.create_semaphore()?,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ impl VulkanDevice {
|
|||
|
||||
impl VulkanSemaphore {
|
||||
pub fn import_sync_file(&self, sync_file: OwnedFd) -> Result<(), VulkanError> {
|
||||
zone!("import_sync_file");
|
||||
let fd_info = ImportSemaphoreFdInfoKHR::default()
|
||||
.fd(sync_file.raw())
|
||||
.flags(SemaphoreImportFlags::TEMPORARY)
|
||||
|
|
|
|||
|
|
@ -164,14 +164,10 @@ impl VulkanShmImage {
|
|||
else {
|
||||
return Ok(());
|
||||
};
|
||||
let future = img.renderer.eng.spawn(await_upload(
|
||||
point,
|
||||
img.clone(),
|
||||
cmd,
|
||||
sync_file,
|
||||
fence,
|
||||
staging,
|
||||
));
|
||||
let future = img.renderer.eng.spawn(
|
||||
"await upload",
|
||||
await_upload(point, img.clone(), cmd, sync_file, fence, staging),
|
||||
);
|
||||
img.renderer.pending_uploads.set(point, future);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -519,13 +515,10 @@ impl VulkanShmImage {
|
|||
else {
|
||||
return Ok(());
|
||||
};
|
||||
let future = img.renderer.eng.spawn(await_async_upload(
|
||||
point,
|
||||
img.clone(),
|
||||
cmd,
|
||||
fence,
|
||||
sync_file,
|
||||
));
|
||||
let future = img.renderer.eng.spawn(
|
||||
"await async upload",
|
||||
await_async_upload(point, img.clone(), cmd, fence, sync_file),
|
||||
);
|
||||
img.renderer.pending_uploads.set(point, future);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,11 @@ impl ExtIdleNotifierV1RequestHandler for ExtIdleNotifierV1 {
|
|||
});
|
||||
track!(self.client, notification);
|
||||
self.client.add_client_obj(¬ification)?;
|
||||
let future = self.client.state.eng.spawn(run(notification.clone()));
|
||||
let future = self
|
||||
.client
|
||||
.state
|
||||
.eng
|
||||
.spawn("idle notifier", run(notification.clone()));
|
||||
notification.task.set(Some(future));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ impl WlSeatGlobal {
|
|||
});
|
||||
slf.pointer_cursor.set_owner(slf.clone());
|
||||
let seat = slf.clone();
|
||||
let future = state.eng.spawn(async move {
|
||||
let future = state.eng.spawn("seat handler", async move {
|
||||
loop {
|
||||
seat.tree_changed.triggered().await;
|
||||
seat.state.tree_changed_sent.set(false);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ fn cancel(timeout: bool) {
|
|||
let wheel = Wheel::new(&eng, &ring).unwrap();
|
||||
let queue = Rc::new(AsyncQueue::new());
|
||||
let queue2 = queue.clone();
|
||||
let _fut1 = eng.spawn(async move {
|
||||
let _fut1 = eng.spawn("", async move {
|
||||
let (read, _write) = uapi::pipe().unwrap();
|
||||
let mut buf = [10];
|
||||
let res = ring
|
||||
|
|
@ -29,7 +29,7 @@ fn cancel(timeout: bool) {
|
|||
));
|
||||
ring.stop();
|
||||
});
|
||||
let _fut2 = eng.spawn(async move {
|
||||
let _fut2 = eng.spawn("", async move {
|
||||
let id = queue2.pop().await;
|
||||
if timeout {
|
||||
wheel.timeout(1).await.unwrap();
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ fn run_test(it_run: &ItRun, test: &'static dyn TestCase, cfg: Rc<TestConfig>) {
|
|||
let errors = errors2.clone();
|
||||
Box::new(async move {
|
||||
let future: Pin<_> = test.run(testrun.clone()).into();
|
||||
let future = state.eng.spawn2(Phase::Present, future);
|
||||
let future = state.eng.spawn2("testrun", Phase::Present, future);
|
||||
let timeout = state.wheel.timeout(500000);
|
||||
match future::select(future, timeout).await {
|
||||
Either::Left((Ok(..), _)) => {}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ where
|
|||
impl Backend for TestBackend {
|
||||
fn run(self: Rc<Self>) -> SpawnedFuture<Result<(), Box<dyn std::error::Error>>> {
|
||||
let future = (self.test_future)(&self.state);
|
||||
self.state.eng.spawn(async move {
|
||||
self.state.eng.spawn("", async move {
|
||||
let future: Pin<_> = future.into();
|
||||
future.await;
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ impl TestTransport {
|
|||
pub fn init(self: &Rc<Self>) {
|
||||
self.incoming.set(Some(
|
||||
self.run.state.eng.spawn(
|
||||
"",
|
||||
Incoming {
|
||||
tc: self.clone(),
|
||||
buf: BufFdIn::new(&self.socket, &self.run.state.ring),
|
||||
|
|
@ -156,6 +157,7 @@ impl TestTransport {
|
|||
));
|
||||
self.outgoing.set(Some(
|
||||
self.run.state.eng.spawn(
|
||||
"",
|
||||
Outgoing {
|
||||
tc: self.clone(),
|
||||
buf: BufFdOut::new(&self.socket, &self.run.state.ring),
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
mod macros;
|
||||
#[macro_use]
|
||||
mod leaks;
|
||||
#[macro_use]
|
||||
mod tracy;
|
||||
mod acceptor;
|
||||
mod allocator;
|
||||
mod async_engine;
|
||||
|
|
|
|||
|
|
@ -347,8 +347,12 @@ impl PwConHolder {
|
|||
data.send_hello();
|
||||
data.send_properties();
|
||||
let con = Rc::new(PwConHolder {
|
||||
outgoing: Cell::new(Some(eng.spawn(data.clone().handle_outgoing()))),
|
||||
incoming: Cell::new(Some(eng.spawn(data.clone().handle_incoming()))),
|
||||
outgoing: Cell::new(Some(
|
||||
eng.spawn("pw outgoing", data.clone().handle_outgoing()),
|
||||
)),
|
||||
incoming: Cell::new(Some(
|
||||
eng.spawn("pw incoming", data.clone().handle_incoming()),
|
||||
)),
|
||||
con: data,
|
||||
});
|
||||
con.con.holder.set(Rc::downgrade(&con));
|
||||
|
|
|
|||
|
|
@ -745,7 +745,9 @@ impl PwClientNode {
|
|||
let typed = map.typed::<pw_node_activation>();
|
||||
self.activation.set(Some(typed.clone()));
|
||||
self.transport_in.set(Some(
|
||||
self.con.eng.spawn(self.clone().transport_in(typed, readfd)),
|
||||
self.con
|
||||
.eng
|
||||
.spawn("pw transport in", self.clone().transport_in(typed, readfd)),
|
||||
));
|
||||
self.transport_out.set(Some(writefd));
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ pub struct PortalStartup {
|
|||
|
||||
impl PortalStartup {
|
||||
pub async fn spawn(self, eng: Rc<AsyncEngine>, ring: Rc<IoUring>, logger: Arc<Logger>) {
|
||||
let f1 = eng.spawn({
|
||||
let f1 = eng.spawn("check portal exit code", {
|
||||
let ring = ring.clone();
|
||||
async move {
|
||||
if let Err(e) = ring.readable(&self.pidfd).await {
|
||||
|
|
@ -103,7 +103,7 @@ impl PortalStartup {
|
|||
}
|
||||
}
|
||||
});
|
||||
let f2 = eng.spawn({
|
||||
let f2 = eng.spawn("portal logger", {
|
||||
let ring = ring.clone();
|
||||
let logger = logger.clone();
|
||||
async move {
|
||||
|
|
@ -155,7 +155,10 @@ fn run(logger: Arc<Logger>, freestanding: bool) {
|
|||
fatal!("Could not create an IO-uring: {}", ErrorFmt(e));
|
||||
}
|
||||
};
|
||||
let _f = eng.spawn(run_async(eng.clone(), ring.clone(), logger, freestanding));
|
||||
let _f = eng.spawn(
|
||||
"portal",
|
||||
run_async(eng.clone(), ring.clone(), logger, freestanding),
|
||||
);
|
||||
if let Err(e) = ring.run() {
|
||||
fatal!("The IO-uring returned an error: {}", ErrorFmt(e));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -579,11 +579,11 @@ impl WindowData {
|
|||
fractional_scale,
|
||||
seats: Default::default(),
|
||||
});
|
||||
data.render_task.set(Some(
|
||||
dpy.state
|
||||
.eng
|
||||
.spawn2(Phase::Present, data.clone().render_task()),
|
||||
));
|
||||
data.render_task.set(Some(dpy.state.eng.spawn2(
|
||||
"render",
|
||||
Phase::Present,
|
||||
data.clone().render_task(),
|
||||
)));
|
||||
data.fractional_scale.owner.set(Some(data.clone()));
|
||||
data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,12 +64,16 @@ impl SecurityContextAcceptors {
|
|||
close_future: Cell::new(None),
|
||||
});
|
||||
log::info!("Creating security acceptor {acceptor}");
|
||||
acceptor
|
||||
.listen_future
|
||||
.set(Some(state.eng.spawn(acceptor.clone().accept())));
|
||||
acceptor
|
||||
.close_future
|
||||
.set(Some(state.eng.spawn(acceptor.clone().close())));
|
||||
acceptor.listen_future.set(Some(
|
||||
state
|
||||
.eng
|
||||
.spawn("security accept", acceptor.clone().accept()),
|
||||
));
|
||||
acceptor.close_future.set(Some(
|
||||
state
|
||||
.eng
|
||||
.spawn("security await close", acceptor.clone().close()),
|
||||
));
|
||||
self.acceptors.set(acceptor.id, acceptor);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub fn install(
|
|||
Ok(fd) => Rc::new(fd),
|
||||
Err(e) => return Err(SighandError::CreateFailed(e.into())),
|
||||
};
|
||||
Ok(eng.spawn(handle_signals(fd, ring.clone())))
|
||||
Ok(eng.spawn("signal handler", handle_signals(fd, ring.clone())))
|
||||
}
|
||||
|
||||
async fn handle_signals(fd: Rc<OwnedFd>, ring: Rc<IoUring>) {
|
||||
|
|
|
|||
|
|
@ -729,7 +729,7 @@ impl State {
|
|||
}
|
||||
let mut handler = self.xwayland.handler.borrow_mut();
|
||||
if handler.is_none() {
|
||||
*handler = Some(self.eng.spawn(xwayland::manage(self.clone())));
|
||||
*handler = Some(self.eng.spawn("xwayland", xwayland::manage(self.clone())));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ pub fn handle(state: &Rc<State>, connector: &Rc<dyn Connector>) {
|
|||
state: state.clone(),
|
||||
data: data.clone(),
|
||||
};
|
||||
let future = state.eng.spawn(oh.handle());
|
||||
let future = state.eng.spawn("connector handler", oh.handle());
|
||||
data.handler.set(Some(future));
|
||||
if state.connectors.set(id, data).is_some() {
|
||||
panic!("Connector id has been reused");
|
||||
|
|
@ -141,7 +141,10 @@ impl ConnectorHandler {
|
|||
&self.data,
|
||||
&desired_state,
|
||||
));
|
||||
let _schedule = self.state.eng.spawn(schedule.clone().drive());
|
||||
let _schedule = self
|
||||
.state
|
||||
.eng
|
||||
.spawn("output schedule", schedule.clone().drive());
|
||||
let on = Rc::new(OutputNode {
|
||||
id: self.state.node_ids.next(),
|
||||
workspaces: Default::default(),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ pub fn handle(state: &Rc<State>, dev: Rc<dyn BackendDrmDevice>) {
|
|||
state: state.clone(),
|
||||
data: data.clone(),
|
||||
};
|
||||
let future = state.eng.spawn(oh.handle());
|
||||
let future = state.eng.spawn("drmdev handler", oh.handle());
|
||||
data.handler.set(Some(future));
|
||||
if state.drm_devs.set(id, data).is_some() {
|
||||
panic!("Drm device id has been reused");
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
|
|||
data: data.clone(),
|
||||
ae: ae.clone(),
|
||||
};
|
||||
let handler = state.eng.spawn(oh.handle());
|
||||
let handler = state.eng.spawn("input dev handler", oh.handle());
|
||||
state.input_device_handlers.borrow_mut().insert(
|
||||
dev.id(),
|
||||
InputDeviceData {
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ where
|
|||
};
|
||||
let eng2 = eng.clone();
|
||||
let ring2 = ring.clone();
|
||||
let _f = eng.spawn(async move {
|
||||
let _f = eng.spawn("tool client", async move {
|
||||
let tc = match ToolClient::try_new(logger, eng2, ring2).await {
|
||||
Ok(tc) => tc,
|
||||
Err(e) => handle_error(e),
|
||||
|
|
@ -199,6 +199,7 @@ impl ToolClient {
|
|||
});
|
||||
slf.incoming.set(Some(
|
||||
slf.eng.spawn(
|
||||
"tool client incoming",
|
||||
Incoming {
|
||||
tc: slf.clone(),
|
||||
buf: BufFdIn::new(&socket, &slf.ring),
|
||||
|
|
@ -208,6 +209,7 @@ impl ToolClient {
|
|||
));
|
||||
slf.outgoing.set(Some(
|
||||
slf.eng.spawn(
|
||||
"tool client outgoing",
|
||||
Outgoing {
|
||||
tc: slf.clone(),
|
||||
buf: BufFdOut::new(&socket, &slf.ring),
|
||||
|
|
@ -239,7 +241,7 @@ impl ToolClient {
|
|||
if let Some(res) = res {
|
||||
let id = slf.next_id.fetch_add(1);
|
||||
let slf2 = slf.clone();
|
||||
let future = slf.eng.spawn(async move {
|
||||
let future = slf.eng.spawn("tool client handler", async move {
|
||||
res.await;
|
||||
slf2.pending_futures.borrow_mut().remove(&id);
|
||||
});
|
||||
|
|
|
|||
15
src/tracy.rs
Normal file
15
src/tracy.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#[cfg(feature = "tracy")]
|
||||
#[macro_use]
|
||||
mod tracy_impl;
|
||||
|
||||
#[cfg(feature = "tracy")]
|
||||
use tracy_impl as imp;
|
||||
|
||||
#[cfg(not(feature = "tracy"))]
|
||||
#[macro_use]
|
||||
mod tracy_noop;
|
||||
|
||||
#[cfg(not(feature = "tracy"))]
|
||||
use tracy_noop as imp;
|
||||
|
||||
pub use imp::{enable_profiler, FrameName, ZoneName};
|
||||
212
src/tracy/tracy_impl.rs
Normal file
212
src/tracy/tracy_impl.rs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
use {
|
||||
ahash::AHashMap,
|
||||
parking_lot::Mutex,
|
||||
std::{
|
||||
ffi::{CStr, CString},
|
||||
ptr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering::Relaxed},
|
||||
LazyLock,
|
||||
},
|
||||
},
|
||||
tracy_client_sys::{
|
||||
___tracy_c_zone_context, ___tracy_emit_frame_mark_end, ___tracy_emit_frame_mark_start,
|
||||
___tracy_emit_zone_end, ___tracy_source_location_data, ___tracy_startup_profiler,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ZoneName {
|
||||
data: &'static ZoneNameData,
|
||||
}
|
||||
|
||||
struct ZoneNameData {
|
||||
_name: CString,
|
||||
loc: ___tracy_source_location_data,
|
||||
}
|
||||
|
||||
unsafe impl Sync for ZoneNameData {}
|
||||
unsafe impl Send for ZoneNameData {}
|
||||
|
||||
static CACHE: LazyLock<Mutex<AHashMap<String, ZoneName>>> = LazyLock::new(|| Default::default());
|
||||
|
||||
impl ZoneName {
|
||||
pub fn __get(name: &str) -> Self {
|
||||
let mut cache = CACHE.lock();
|
||||
if let Some(span) = cache.get(name) {
|
||||
return *span;
|
||||
}
|
||||
let cname = CString::new(name).unwrap();
|
||||
let span = ZoneName {
|
||||
data: Box::leak(Box::new(ZoneNameData {
|
||||
loc: ___tracy_source_location_data {
|
||||
name: cname.as_ptr(),
|
||||
function: ptr::null(),
|
||||
file: ptr::null(),
|
||||
line: 0,
|
||||
color: 0,
|
||||
},
|
||||
_name: cname,
|
||||
})),
|
||||
};
|
||||
cache.insert(name.to_string(), span);
|
||||
span
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn __enter(self) -> RunningZone {
|
||||
if enabled() {
|
||||
unsafe {
|
||||
let zone = tracy_client_sys::___tracy_emit_zone_begin(&self.data.loc, 1);
|
||||
RunningZone(Some(zone))
|
||||
}
|
||||
} else {
|
||||
RunningZone(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! create_zone_name {
|
||||
($($tt:tt)*) => {
|
||||
crate::tracy::ZoneName::__get(&format!($($tt)*))
|
||||
};
|
||||
}
|
||||
|
||||
pub struct RunningZone(Option<___tracy_c_zone_context>);
|
||||
|
||||
impl Drop for RunningZone {
|
||||
#[inline(always)]
|
||||
fn drop(&mut self) {
|
||||
if let Some(zone) = self.0 {
|
||||
unsafe {
|
||||
___tracy_emit_zone_end(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! dynamic_raii_zone {
|
||||
($name:expr) => {{
|
||||
let name: ZoneName = $name;
|
||||
name.__enter()
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! dynamic_zone {
|
||||
($name:expr) => {
|
||||
let _zone = dynamic_raii_zone!($name);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! raii_zone {
|
||||
($($tt:tt)*) => {
|
||||
{
|
||||
static CACHE: std::sync::LazyLock<crate::tracy::ZoneName> = std::sync::LazyLock::new(|| {
|
||||
create_zone_name!($($tt)*)
|
||||
});
|
||||
CACHE.__enter()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! zone {
|
||||
($($tt:tt)*) => {
|
||||
let _zone = raii_zone!($($tt)*);
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct FrameName {
|
||||
name: &'static CString,
|
||||
}
|
||||
|
||||
static FRAME_CACHE: LazyLock<Mutex<AHashMap<String, FrameName>>> =
|
||||
LazyLock::new(|| Default::default());
|
||||
|
||||
impl FrameName {
|
||||
pub fn get(name: &str) -> Self {
|
||||
let mut cache = FRAME_CACHE.lock();
|
||||
if let Some(frame_name) = cache.get(name) {
|
||||
return *frame_name;
|
||||
}
|
||||
let cname = CString::new(name).unwrap();
|
||||
let span = Self {
|
||||
name: Box::leak(Box::new(cname)),
|
||||
};
|
||||
cache.insert(name.to_string(), span);
|
||||
span
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn __start(self) -> RenderingFrame {
|
||||
if enabled() {
|
||||
unsafe {
|
||||
___tracy_emit_frame_mark_start(self.name.as_ptr());
|
||||
}
|
||||
}
|
||||
RenderingFrame { name: self.name }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! raii_frame {
|
||||
($name:expr) => {{
|
||||
let name: FrameName = $name;
|
||||
name.__start()
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! frame {
|
||||
($name:expr) => {
|
||||
let _frame = raii_frame!($name);
|
||||
};
|
||||
}
|
||||
|
||||
pub struct RenderingFrame {
|
||||
name: &'static CString,
|
||||
}
|
||||
|
||||
impl Drop for RenderingFrame {
|
||||
#[inline(always)]
|
||||
fn drop(&mut self) {
|
||||
if enabled() {
|
||||
unsafe {
|
||||
___tracy_emit_frame_mark_end(self.name.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(static_mut_refs)]
|
||||
unsafe extern "C" fn ___tracy_demangle(
|
||||
mangled: *const std::ffi::c_char,
|
||||
) -> *const std::ffi::c_char {
|
||||
use std::io::Write;
|
||||
if mangled.is_null() {
|
||||
return ptr::null();
|
||||
}
|
||||
let Ok(mangled) = CStr::from_ptr(mangled).to_str() else {
|
||||
return ptr::null();
|
||||
};
|
||||
let demangled = rustc_demangle::demangle(mangled);
|
||||
static mut BUF: Vec<u8> = Vec::new();
|
||||
BUF.clear();
|
||||
if let Err(_) = write!(BUF, "{demangled:#}\0") {
|
||||
return ptr::null();
|
||||
}
|
||||
BUF.as_ptr().cast()
|
||||
}
|
||||
|
||||
static ENABLED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[inline(always)]
|
||||
fn enabled() -> bool {
|
||||
ENABLED.load(Relaxed)
|
||||
}
|
||||
|
||||
pub fn enable_profiler() {
|
||||
unsafe {
|
||||
___tracy_startup_profiler();
|
||||
}
|
||||
ENABLED.store(true, Relaxed);
|
||||
}
|
||||
51
src/tracy/tracy_noop.rs
Normal file
51
src/tracy/tracy_noop.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#![allow(unused_macros)]
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ZoneName;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct FrameName;
|
||||
|
||||
impl FrameName {
|
||||
pub fn get(_name: &str) -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! create_zone_name {
|
||||
($($tt:tt)*) => {
|
||||
crate::tracy::ZoneName
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! dynamic_raii_zone {
|
||||
($name:expr) => {};
|
||||
}
|
||||
|
||||
macro_rules! dynamic_zone {
|
||||
($name:expr) => {};
|
||||
}
|
||||
|
||||
macro_rules! raii_zone {
|
||||
($($tt:tt)*) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! zone {
|
||||
($($tt:tt)*) => {};
|
||||
}
|
||||
|
||||
macro_rules! raii_frame {
|
||||
($name:expr) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! frame {
|
||||
($name:expr) => {};
|
||||
}
|
||||
|
||||
pub fn enable_profiler() {
|
||||
// nothing
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ impl RunToplevel {
|
|||
let slf = Rc::new(RunToplevel {
|
||||
queue: Default::default(),
|
||||
});
|
||||
let future = eng.spawn({
|
||||
let future = eng.spawn("run toplevel", {
|
||||
let slf = slf.clone();
|
||||
async move {
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ impl WaitForSyncObj {
|
|||
trigger: Default::default(),
|
||||
});
|
||||
Waiter {
|
||||
_task: self.eng.spawn(waiter.clone().run()),
|
||||
_task: self.eng.spawn("wait for sync obj", waiter.clone().run()),
|
||||
inner: waiter,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ impl Wheel {
|
|||
cached_futures: Default::default(),
|
||||
});
|
||||
data.dispatcher
|
||||
.set(Some(eng.spawn(data.clone().dispatch())));
|
||||
.set(Some(eng.spawn("wheel", data.clone().dispatch())));
|
||||
Ok(Rc::new(Wheel { data }))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ impl UsrCon {
|
|||
);
|
||||
slf.incoming.set(Some(
|
||||
slf.eng.spawn(
|
||||
"wl_usr incoming",
|
||||
Incoming {
|
||||
con: slf.clone(),
|
||||
buf: BufFdIn::new(&socket, &slf.ring),
|
||||
|
|
@ -156,6 +157,7 @@ impl UsrCon {
|
|||
));
|
||||
slf.outgoing.set(Some(
|
||||
slf.eng.spawn(
|
||||
"wl_usr outgoing",
|
||||
Outgoing {
|
||||
con: slf.clone(),
|
||||
buf: BufFdOut::new(&socket, &slf.ring),
|
||||
|
|
|
|||
12
src/xcon.rs
12
src/xcon.rs
|
|
@ -453,9 +453,11 @@ impl Xcon {
|
|||
xorg: CloneCell::new(Weak::new()),
|
||||
events: Default::default(),
|
||||
});
|
||||
let outgoing = state
|
||||
.eng
|
||||
.spawn2(Phase::PostLayout, handle_outgoing(data.clone()));
|
||||
let outgoing = state.eng.spawn2(
|
||||
"xcon send",
|
||||
Phase::PostLayout,
|
||||
handle_outgoing(data.clone()),
|
||||
);
|
||||
let mut buf = data.bufio.buf();
|
||||
let mut fds = vec![];
|
||||
{
|
||||
|
|
@ -502,7 +504,9 @@ impl Xcon {
|
|||
return Err(XconError::Authenticate(reason.to_owned()));
|
||||
}
|
||||
let setup = Setup::deserialize(&mut parser)?;
|
||||
let incoming = state.eng.spawn(handle_incoming(data.clone(), incoming));
|
||||
let incoming = state
|
||||
.eng
|
||||
.spawn("X incoming", handle_incoming(data.clone(), incoming));
|
||||
let slf = Rc::new(Self {
|
||||
extensions: data.fetch_extension_data().await?,
|
||||
outgoing: Cell::new(Some(outgoing)),
|
||||
|
|
|
|||
|
|
@ -150,7 +150,9 @@ async fn run(
|
|||
Ok(w) => w,
|
||||
Err(e) => return Err(XWaylandError::Socketpair(e.into())),
|
||||
};
|
||||
let stderr_read = state.eng.spawn(log_xwayland(state.clone(), stderr_read));
|
||||
let stderr_read = state
|
||||
.eng
|
||||
.spawn("log Xwayland", log_xwayland(state.clone(), stderr_read));
|
||||
let pidfd = forker
|
||||
.xwayland(
|
||||
&state,
|
||||
|
|
@ -188,7 +190,7 @@ async fn run(
|
|||
Ok(w) => w,
|
||||
Err(e) => return Err(XWaylandError::CreateWm(Box::new(e))),
|
||||
};
|
||||
let _wm = state.eng.spawn(wm.run());
|
||||
let _wm = state.eng.spawn("XWM", wm.run());
|
||||
state.ring.readable(&pidfd).await?;
|
||||
}
|
||||
state.xwayland.queue.clear();
|
||||
|
|
|
|||
|
|
@ -1678,7 +1678,7 @@ impl Wm {
|
|||
};
|
||||
self.shared
|
||||
.transfers
|
||||
.set(id, self.state.eng.spawn(wtx.run()));
|
||||
.set(id, self.state.eng.spawn("wayland to X transfer", wtx.run()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1781,9 +1781,12 @@ impl Wm {
|
|||
state: self.state.clone(),
|
||||
shared: self.shared.clone(),
|
||||
};
|
||||
self.shared
|
||||
.transfers
|
||||
.set(id, self.state.eng.spawn(transfer.run()));
|
||||
self.shared.transfers.set(
|
||||
id,
|
||||
self.state
|
||||
.eng
|
||||
.spawn("X to wayland transfer", transfer.run()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue