1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use crate::{domain::Domain, string::StringHandle};
/// A task is a logical unit of work performed by a particular thread. See the [Task API]
/// documentation for more information.
///
/// [Task API]:
/// https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top/api-support/instrumentation-and-tracing-technology-apis/instrumentation-tracing-technology-api-reference/task-api.html
///
/// ```
/// # use ittapi::{Domain, StringHandle, Task};
/// let _env_path = scoped_env::ScopedEnv::set("INTEL_LIBITTNOTIFY64", "<some path>");
/// let domain = Domain::new("domain");
/// let name = StringHandle::new("task");
/// // Measure a task using a pre-initialized string handle (most efficient).
/// {
/// let task = Task::begin(&domain, name);
/// let _ = 2 + 2;
/// task.end(); // Task ended here.
/// let _ = 3 + 3;
/// }
/// // Measure a task using a string reference (most convenient).
/// {
/// let _task = Task::begin(&domain, "task");
/// let _ = 2 + 2;
/// // Task ended here, when dropped.
/// }
/// ```
pub struct Task<'a>(&'a Domain);
impl<'a> Task<'a> {
/// Start a task on the current thread.
pub fn begin(domain: &'a Domain, name: impl Into<StringHandle>) -> Self {
if let Some(create_fn) = unsafe { ittapi_sys::__itt_task_begin_ptr__3_0 } {
// Currently the `taskid` and `parentid` parameters are unimplemented (TODO).
unsafe { create_fn(domain.as_ptr(), ITT_NULL, ITT_NULL, name.into().as_ptr()) };
}
Self(domain)
}
/// Finish the task.
#[allow(clippy::unused_self)]
pub fn end(self) {
// Do nothing; the `Drop` implementation does the work. See discussion at
// https://stackoverflow.com/questions/53254645.
}
}
impl<'a> Drop for Task<'a> {
fn drop(&mut self) {
// If `ittnotify` has not been initialized, this function may not be wired up.
if let Some(end_fn) = unsafe { ittapi_sys::__itt_task_end_ptr__3_0 } {
unsafe { end_fn(self.0.as_ptr()) }
}
}
}
/// Using the `__itt_null` symbol results in errors so we redefine it here.
const ITT_NULL: ittapi_sys::__itt_id = ittapi_sys::__itt_id {
d1: 0,
d2: 0,
d3: 0,
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sanity() {
let domain = Domain::new("domain");
let name = StringHandle::new("task");
let _task = Task::begin(&domain, name);
}
}