1
0
Fork 0
forked from wry/wry

vulkan: create high-priority queues if possible

This commit is contained in:
Julian Orth 2025-05-10 22:44:00 +02:00
parent 7a623006e2
commit 68713b2e39
9 changed files with 253 additions and 44 deletions

View file

@ -6,6 +6,13 @@ use {
},
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, oserror::OsError},
},
opera::PhantomNotSend,
parking_lot::{Condvar, Mutex},
std::{
mem,
sync::Arc,
thread::{self, JoinHandle},
},
uapi::{
c::{SYS_capget, SYS_capset, syscall},
map_err,
@ -22,6 +29,24 @@ pub struct PrCompCaps {
caps: PrCaps,
}
pub struct PrCapsThread {
thread: Option<JoinHandle<()>>,
data: Arc<ThreadData>,
_no_send: PhantomNotSend,
}
#[derive(Default)]
struct ThreadData {
cond: Condvar,
mutex: Mutex<MutData>,
}
#[derive(Default)]
struct MutData {
exit: bool,
fun: Option<Box<dyn FnOnce() + Send>>,
}
pub fn pr_caps() -> PrCaps {
let mut hdr = cap_user_header_t {
version: _LINUX_CAPABILITY_VERSION_3,
@ -103,6 +128,70 @@ impl PrCompCaps {
pub fn has_nice(&self) -> bool {
self.caps.effective.contains(1 << CAP_SYS_NICE)
}
pub fn into_thread(self) -> PrCapsThread {
let data = Arc::new(ThreadData::default());
let data2 = data.clone();
let jh = thread::Builder::new()
.name("SYS_nice thread".to_string())
.spawn(move || {
let data2 = data2;
let mut lock = data2.mutex.lock();
loop {
if lock.exit {
return;
}
if let Some(f) = lock.fun.take() {
f();
}
data2.cond.wait(&mut lock);
}
})
.expect("Could not spawn SYS_nice thread");
PrCapsThread {
thread: Some(jh),
data,
_no_send: Default::default(),
}
}
}
impl PrCapsThread {
pub unsafe fn run<T, F>(&self, f: F) -> T
where
F: FnOnce() -> T,
{
struct AssertSend<T>(T);
unsafe impl<T> Send for AssertSend<T> {}
struct Data<T> {
cond: Condvar,
mutex: Mutex<Option<AssertSend<T>>>,
}
let data = Arc::new(Data {
cond: Default::default(),
mutex: Default::default(),
});
let data2 = data.clone();
let f = AssertSend(f);
let fun = Box::new(move || {
let f = f;
let t = f.0();
*data2.mutex.lock() = Some(AssertSend(t));
data2.cond.notify_all();
});
let fun = unsafe {
mem::transmute::<Box<dyn FnOnce() + Send + '_>, Box<dyn FnOnce() + Send>>(fun)
};
self.data.mutex.lock().fun = Some(fun);
self.data.cond.notify_all();
let mut lock = data.mutex.lock();
loop {
if let Some(t) = lock.take() {
return t.0;
}
data.cond.wait(&mut lock);
}
}
}
impl Drop for PrCaps {
@ -111,6 +200,14 @@ impl Drop for PrCaps {
}
}
impl Drop for PrCapsThread {
fn drop(&mut self) {
self.data.mutex.lock().exit = true;
self.data.cond.notify_all();
let _ = self.thread.take().unwrap().join();
}
}
mod sys {
#![allow(dead_code)]