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