use crate::error::{nvml_sym, nvml_try, NvmlError};
use crate::ffi::bindings::*;
use crate::Nvml;
use std::mem;
use crate::struct_wrappers::event::EventData;
#[derive(Debug)]
pub struct EventSet<'nvml> {
set: nvmlEventSet_t,
pub nvml: &'nvml Nvml,
}
unsafe impl<'nvml> Send for EventSet<'nvml> {}
impl<'nvml> EventSet<'nvml> {
#[allow(clippy::missing_safety_doc)]
pub unsafe fn new(set: nvmlEventSet_t, nvml: &'nvml Nvml) -> Self {
Self { set, nvml }
}
pub fn release_events(self) -> Result<(), NvmlError> {
let sym = nvml_sym(self.nvml.lib.nvmlEventSetFree.as_ref())?;
unsafe {
nvml_try(sym(self.set))?;
}
mem::forget(self);
Ok(())
}
pub fn wait(&self, timeout_ms: u32) -> Result<EventData<'nvml>, NvmlError> {
let sym = nvml_sym(self.nvml.lib.nvmlEventSetWait_v2.as_ref())?;
unsafe {
let mut data: nvmlEventData_t = mem::zeroed();
nvml_try(sym(self.set, &mut data, timeout_ms))?;
Ok(EventData::new(data, self.nvml))
}
}
pub unsafe fn handle(&self) -> nvmlEventSet_t {
self.set
}
}
impl<'nvml> Drop for EventSet<'nvml> {
fn drop(&mut self) {
unsafe {
self.nvml.lib.nvmlEventSetFree(self.set);
}
}
}
#[cfg(test)]
#[cfg(target_os = "linux")]
mod test {
use crate::bitmasks::event::*;
use crate::test_utils::*;
#[test]
fn release_events() {
let nvml = nvml();
test_with_device(3, &nvml, |device| {
let set = nvml.create_event_set()?;
let set = device
.register_events(
EventTypes::PSTATE_CHANGE
| EventTypes::CRITICAL_XID_ERROR
| EventTypes::CLOCK_CHANGE,
set,
)
.map_err(|e| e.error)?;
set.release_events()
})
}
#[cfg(feature = "test-local")]
#[test]
fn wait() {
use crate::error::NvmlError;
let nvml = nvml();
let device = device(&nvml);
let set = nvml.create_event_set().expect("event set");
let set = device
.register_events(
EventTypes::PSTATE_CHANGE
| EventTypes::CRITICAL_XID_ERROR
| EventTypes::CLOCK_CHANGE,
set,
)
.expect("registration");
let data = match set.wait(10_000) {
Err(NvmlError::Timeout) => return (),
Ok(d) => d,
_ => panic!("An error other than `Timeout` occurred"),
};
print!("{:?} ...", data);
}
}