diff --git a/src/gallium/frontends/rusticl/core/event.rs b/src/gallium/frontends/rusticl/core/event.rs index 2ee27630715..23bfbbb8242 100644 --- a/src/gallium/frontends/rusticl/core/event.rs +++ b/src/gallium/frontends/rusticl/core/event.rs @@ -212,6 +212,14 @@ impl Event { .wait_timeout(lock, Duration::from_secs(1)) .unwrap() .0; + + if let Some(queue) = &self.queue { + // in case the queue worker thread exited abnormally we'll need to stop spinning on + // the cv here, because otherwise we'll end up spinning endlessly. + if queue.is_dead() { + return CL_OUT_OF_HOST_MEMORY; + } + } } lock.status } diff --git a/src/gallium/frontends/rusticl/core/queue.rs b/src/gallium/frontends/rusticl/core/queue.rs index ed239aa90e5..7059886fab5 100644 --- a/src/gallium/frontends/rusticl/core/queue.rs +++ b/src/gallium/frontends/rusticl/core/queue.rs @@ -88,7 +88,7 @@ pub struct Queue { pub props: cl_command_queue_properties, pub props_v2: Properties, state: Mutex, - _thrd: JoinHandle<()>, + thrd: JoinHandle<()>, } impl_cl_type_trait!(cl_command_queue, Queue, CL_INVALID_COMMAND_QUEUE); @@ -122,7 +122,7 @@ impl Queue { last: Weak::new(), chan_in: tx_q, }), - _thrd: thread::Builder::new() + thrd: thread::Builder::new() .name("rusticl queue thread".into()) .spawn(move || { // Track the error of all executed events. This is only needed for in-order @@ -250,6 +250,10 @@ impl Queue { Ok(()) } + pub fn is_dead(&self) -> bool { + self.thrd.is_finished() + } + pub fn is_profiling_enabled(&self) -> bool { (self.props & (CL_QUEUE_PROFILING_ENABLE as u64)) != 0 }