use super::defines::AfError;
use super::error::HANDLE_ERROR;
use super::util::af_event;
use libc::c_int;
use std::default::Default;
extern "C" {
fn af_create_event(out: *mut af_event) -> c_int;
fn af_delete_event(out: af_event) -> c_int;
fn af_mark_event(out: af_event) -> c_int;
fn af_enqueue_wait_event(out: af_event) -> c_int;
fn af_block_event(out: af_event) -> c_int;
}
pub struct Event {
event_handle: af_event,
}
unsafe impl Send for Event {}
impl Default for Event {
fn default() -> Self {
let mut temp: af_event = std::ptr::null_mut();
unsafe {
let err_val = af_create_event(&mut temp as *mut af_event);
HANDLE_ERROR(AfError::from(err_val));
}
Self { event_handle: temp }
}
}
impl Event {
pub fn mark(&self) {
unsafe {
let err_val = af_mark_event(self.event_handle as af_event);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn enqueue_wait(&self) {
unsafe {
let err_val = af_enqueue_wait_event(self.event_handle as af_event);
HANDLE_ERROR(AfError::from(err_val));
}
}
pub fn block(&self) {
unsafe {
let err_val = af_block_event(self.event_handle as af_event);
HANDLE_ERROR(AfError::from(err_val));
}
}
}
impl Drop for Event {
fn drop(&mut self) {
unsafe {
let ret_val = af_delete_event(self.event_handle as af_event);
match ret_val {
0 => (),
_ => panic!("Failed to delete event resources: {}", ret_val),
}
}
}
}
#[cfg(test)]
mod tests {
use super::super::arith::pow;
use super::super::device::{info, set_device};
use super::super::event::Event;
use crate::{af_print, randu};
use std::sync::mpsc;
use std::thread;
#[test]
fn event_block() {
set_device(0);
info();
let a = randu!(10, 10);
let b = randu!(10, 10);
let c = randu!(10, 10);
let d = randu!(10, 10);
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
set_device(0);
let add_event = Event::default();
let add_res = b + c;
add_event.mark();
tx.send((add_res, add_event)).unwrap();
thread::sleep(std::time::Duration::new(10, 0));
let sub_event = Event::default();
let sub_res = d - 2;
sub_event.mark();
tx.send((sub_res, sub_event)).unwrap();
});
let (add_res, add_event) = rx.recv().unwrap();
println!("Got first message, waiting for addition result ...");
thread::sleep(std::time::Duration::new(5, 0));
add_event.block();
println!("Got addition result, now scaling it ... ");
let scaled = a * add_res;
let (sub_res, sub_event) = rx.recv().unwrap();
println!("Got message, waiting for subtraction result ...");
thread::sleep(std::time::Duration::new(5, 0));
sub_event.block();
let fin_res = pow(&scaled, &sub_res, false);
af_print!(
"Final result of the expression: ((a * (b + c))^(d - 2))",
&fin_res
);
}
}