no spinning when waiting, just exit; repr(c) job

This commit is contained in:
Janis 2025-06-20 22:31:03 +02:00
parent 3eec242097
commit 8b3ecb1455

View file

@ -600,6 +600,7 @@ mod job {
error: ManuallyDrop<Option<Box<dyn Any + Send + 'static>>>, error: ManuallyDrop<Option<Box<dyn Any + Send + 'static>>>,
} }
#[repr(C)]
pub struct Job<T = ()> { pub struct Job<T = ()> {
/// tagged pointer, 8-aligned /// tagged pointer, 8-aligned
harness_and_state: TaggedAtomicPtr<usize, 3>, harness_and_state: TaggedAtomicPtr<usize, 3>,
@ -763,8 +764,7 @@ mod job {
// after sleeping, state should be `Finished` // after sleeping, state should be `Finished`
} }
Err(state) => { 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 { if state == JobState::Finished as usize {
let err = unsafe { (&mut *self.err_or_link.get()).error.take() }; let err = unsafe { (&mut *self.err_or_link.get()).error.take() };
@ -1070,7 +1070,8 @@ impl JobCounter {
/// must only be called once /// must only be called once
pub unsafe fn wait(&self) { 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); let count = self.jobs_pending.load(Ordering::SeqCst);
if count > 0 { if count > 0 {
@ -1364,20 +1365,22 @@ impl WorkerThread {
continue 'outer; continue 'outer;
} }
None => { None => {
// TODO: spin2win
tracing::trace!("waiting for shared job, thread id: {:?}", self.index); tracing::trace!("waiting for shared job, thread id: {:?}", self.index);
// TODO: wait on latch? if we have something that can // TODO: wait on latch? if we have something that can
// signal being done, e.g. can be waited on instead of // signal being done, e.g. can be waited on instead of
// shared jobs, we should wait on it instead, but we // shared jobs, we should wait on it instead, but we
// would also want to receive shared jobs still? // would also want to receive shared jobs still?
// Spin? probably just wastes CPU time.
// self.context.shared_job.wait(&mut guard); // self.context.shared_job.wait(&mut guard);
// if spin.spin() { // if spin.spin() {
// // wait for more shared jobs. // // wait for more shared jobs.
// // self.context.shared_job.wait(&mut guard); // // self.context.shared_job.wait(&mut guard);
// return; // return;
// } // }
std::thread::yield_now(); // Yield? same as spinning, really, so just exit and let the upstream use wait
// std::thread::yield_now();
return;
} }
} }
} }