From 8b3ecb1455d0fe0a19d9346664bf04868b2efa16 Mon Sep 17 00:00:00 2001 From: Janis Date: Fri, 20 Jun 2025 22:31:03 +0200 Subject: [PATCH] no spinning when waiting, just exit; repr(c) job --- src/praetor/mod.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/praetor/mod.rs b/src/praetor/mod.rs index 7d38efc..dd04590 100644 --- a/src/praetor/mod.rs +++ b/src/praetor/mod.rs @@ -600,6 +600,7 @@ mod job { error: ManuallyDrop>>, } + #[repr(C)] pub struct Job { /// tagged pointer, 8-aligned harness_and_state: TaggedAtomicPtr, @@ -763,8 +764,7 @@ mod job { // after sleeping, state should be `Finished` } Err(state) => { - // debug_assert_ne!(state, JobState::Pending as usize); - + // job finished under us, check if it was successful if state == JobState::Finished as usize { let err = unsafe { (&mut *self.err_or_link.get()).error.take() }; @@ -1070,7 +1070,8 @@ impl JobCounter { /// must only be called once pub unsafe fn wait(&self) { - _ = self.waker.lock().insert(std::thread::current()); + // SAFETY: this is only called once, so the waker is guaranteed to be None. + assert!(self.waker.lock().replace(std::thread::current()).is_none()); let count = self.jobs_pending.load(Ordering::SeqCst); if count > 0 { @@ -1364,20 +1365,22 @@ impl WorkerThread { continue 'outer; } None => { - // TODO: spin2win tracing::trace!("waiting for shared job, thread id: {:?}", self.index); // TODO: wait on latch? if we have something that can // signal being done, e.g. can be waited on instead of // shared jobs, we should wait on it instead, but we // would also want to receive shared jobs still? + // Spin? probably just wastes CPU time. // self.context.shared_job.wait(&mut guard); // if spin.spin() { // // wait for more shared jobs. // // self.context.shared_job.wait(&mut guard); // return; // } - std::thread::yield_now(); + // Yield? same as spinning, really, so just exit and let the upstream use wait + // std::thread::yield_now(); + return; } } }