event: break long dependency chains on drop

This prevents stack overflows on drop without making it expensive to read
from dependencies (e.g. my attempt to use Weak instead).

Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29190>
This commit is contained in:
Karol Herbst 2024-05-14 12:38:14 +02:00 committed by Marge Bot
parent 2f1f98e846
commit 48c752d3e0
1 changed files with 22 additions and 0 deletions

View File

@ -10,6 +10,7 @@ use mesa_rust_util::static_assert;
use rusticl_opencl_gen::*;
use std::collections::HashSet;
use std::mem;
use std::sync::Arc;
use std::sync::Condvar;
use std::sync::Mutex;
@ -262,6 +263,27 @@ impl Event {
}
}
impl Drop for Event {
// implement drop in order to prevent stack overflows of long dependency chains.
//
// This abuses the fact that `Arc::into_inner` only succeeds when there is one strong reference
// so we turn a recursive drop chain into a drop list for events having no other references.
fn drop(&mut self) {
if self.deps.is_empty() {
return;
}
let mut deps_list = vec![mem::take(&mut self.deps)];
while let Some(deps) = deps_list.pop() {
for dep in deps {
if let Some(mut dep) = Arc::into_inner(dep) {
deps_list.push(mem::take(&mut dep.deps));
}
}
}
}
}
// TODO worker thread per device
// Condvar to wait on new events to work on
// notify condvar when flushing queue events to worker