Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 56 additions & 56 deletions rust/ittapi/src/domain.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@
use crate::util::access_sys_fn;
use std::ffi::CString;
/// A domain enables tagging trace data for different modules or libraries in a program. See the
/// [Domain API] documentation for more information.
///
/// [Domain API]:
/// https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/current/domain-api.html
pub struct Domain(*mut ittapi_sys::__itt_domain);
impl Domain {
/// Create a new domain. Note that, if the `ittnotify` library is not initialized, this call
/// will succeed but the domain will be invalid; see discussion TODO.
///
/// ```
/// # use ittapi::Domain;
/// let domain = Domain::new("test-domain");
/// ```
///
/// # Panics
///
/// Panics if the domain name contains a `0` byte.
#[must_use]
pub fn new(name: &str) -> Self {
#[cfg(unix)]
let create_fn = access_sys_fn!(__itt_domain_create_ptr__3_0);
#[cfg(windows)]
let create_fn = access_sys_fn!(__itt_domain_createA_ptr__3_0);
let c_string =
CString::new(name).expect("unable to create a CString; does it contain a 0 byte?");
let domain = unsafe { create_fn(c_string.as_ptr()) };
Self(domain)
}
/// Use the `__itt_domain` pointer internally.
pub(crate) fn as_ptr(&self) -> *const ittapi_sys::__itt_domain {
self.0.cast_const()
}
}
/// As discussed in the [ITT documentation], the `__itt_domain` structure is accessible by any
/// thread in the process.
///
/// [ITT documentation]:
/// https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/current/domain-api.html
unsafe impl Sync for Domain {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic(expected = "unable to create a CString; does it contain a 0 byte?")]
fn zero_byte() {
let _domain = Domain::new("zero\0byte\0name");
}
}
use crate::util::access_sys_fn;
use std::ffi::CString;

/// A domain enables tagging trace data for different modules or libraries in a program. See the
/// [Domain API] documentation for more information.
///
/// [Domain API]:
/// https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/current/domain-api.html
pub struct Domain(*mut ittapi_sys::__itt_domain);
impl Domain {
/// Create a new domain. Note that, if the `ittnotify` library is not initialized, this call
/// will succeed but the domain will be invalid; see discussion TODO.
///
/// ```
/// # use ittapi::Domain;
/// let domain = Domain::new("test-domain");
/// ```
///
/// # Panics
///
/// Panics if the domain name contains a `0` byte.
#[must_use]
pub fn new(name: &str) -> Self {
#[cfg(unix)]
let create_fn = access_sys_fn!(__itt_domain_create_ptr__3_0);
#[cfg(windows)]
let create_fn = access_sys_fn!(__itt_domain_createA_ptr__3_0);
let c_string =
CString::new(name).expect("unable to create a CString; does it contain a 0 byte?");
let domain = unsafe { create_fn(c_string.as_ptr()) };
Self(domain)
}

/// Use the `__itt_domain` pointer internally.
pub(crate) fn as_ptr(&self) -> *const ittapi_sys::__itt_domain {
self.0.cast_const()
}
}

/// As discussed in the [ITT documentation], the `__itt_domain` structure is accessible by any
/// thread in the process.
///
/// [ITT documentation]:
/// https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/current/domain-api.html
unsafe impl Sync for Domain {}

#[cfg(test)]
mod tests {
use super::*;

#[test]
#[should_panic(expected = "unable to create a CString; does it contain a 0 byte?")]
fn zero_byte() {
let _domain = Domain::new("zero\0byte\0name");
}
}
188 changes: 94 additions & 94 deletions rust/ittapi/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,94 +1,94 @@
use std::{ffi::CString, marker::PhantomData};

/// See the [Event API] documentation.
///
/// [Event API]: https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/current/event-api.html
///
/// ```
/// let event = ittapi::Event::new("foo");
/// {
/// let span = event.start();
/// // do some work...
/// // ...the event is stopped when `span` is dropped
/// }
/// ```
pub struct Event(ittapi_sys::__itt_event);
impl Event {
/// Create the event.
///
/// # Panics
///
/// Panics if the name contains a `0` byte or if its size will not fit in a 32-bit
/// representation.
#[must_use]
pub fn new(name: &str) -> Self {
#[cfg(unix)]
let create_fn = unsafe { ittapi_sys::__itt_event_create_ptr__3_0 };
#[cfg(windows)]
let create_fn = unsafe { ittapi_sys::__itt_event_createA_ptr__3_0 };
if let Some(create_fn) = create_fn {
let c_string =
CString::new(name).expect("unable to create a CString; does it contain a 0 byte?");
let size = name
.len()
.try_into()
.expect("unable to fit the name length into an i32");
let event = unsafe { create_fn(c_string.as_ptr(), size) };
Self(event)
} else {
Self(-1)
}
}

/// Start the event.
///
/// # Panics
///
/// This will panic if the ITT library cannot start the event.
#[must_use]
pub fn start(&self) -> StartedEvent {
if let Some(start_fn) = unsafe { ittapi_sys::__itt_event_start_ptr__3_0 } {
let result = unsafe { start_fn(self.0) };
assert!(result == 0, "unable to start event");
}
StartedEvent {
event: self.0,
phantom: PhantomData,
}
}
}

pub struct StartedEvent<'a> {
event: ittapi_sys::__itt_event,
phantom: PhantomData<&'a mut ()>,
}

impl StartedEvent<'_> {
/// End the event.
#[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 Drop for StartedEvent<'_> {
fn drop(&mut self) {
if let Some(end_fn) = unsafe { ittapi_sys::__itt_event_end_ptr__3_0 } {
let result = unsafe { end_fn(self.event) };
assert!(result == 0, "unable to stop event");
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn sanity() {
let event = Event::new("test");
let _started_event = event.start();
// Dropping `started_event` ends the event.
}
}
use std::{ffi::CString, marker::PhantomData};

/// See the [Event API] documentation.
///
/// [Event API]: https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/current/event-api.html
///
/// ```
/// let event = ittapi::Event::new("foo");
/// {
/// let span = event.start();
/// // do some work...
/// // ...the event is stopped when `span` is dropped
/// }
/// ```
pub struct Event(ittapi_sys::__itt_event);
impl Event {
/// Create the event.
///
/// # Panics
///
/// Panics if the name contains a `0` byte or if its size will not fit in a 32-bit
/// representation.
#[must_use]
pub fn new(name: &str) -> Self {
#[cfg(unix)]
let create_fn = unsafe { ittapi_sys::__itt_event_create_ptr__3_0 };
#[cfg(windows)]
let create_fn = unsafe { ittapi_sys::__itt_event_createA_ptr__3_0 };
if let Some(create_fn) = create_fn {
let c_string =
CString::new(name).expect("unable to create a CString; does it contain a 0 byte?");
let size = name
.len()
.try_into()
.expect("unable to fit the name length into an i32");
let event = unsafe { create_fn(c_string.as_ptr(), size) };
Self(event)
} else {
Self(-1)
}
}

/// Start the event.
///
/// # Panics
///
/// This will panic if the ITT library cannot start the event.
#[must_use]
pub fn start(&self) -> StartedEvent {

Check warning

Code scanning / clippy

hiding a lifetime that's elided elsewhere is confusing Warning

hiding a lifetime that's elided elsewhere is confusing

Check warning

Code scanning / clippy

hiding a lifetime that's elided elsewhere is confusing Warning

hiding a lifetime that's elided elsewhere is confusing
if let Some(start_fn) = unsafe { ittapi_sys::__itt_event_start_ptr__3_0 } {
let result = unsafe { start_fn(self.0) };
assert!(result == 0, "unable to start event");
}
StartedEvent {
event: self.0,
phantom: PhantomData,
}
}
}

pub struct StartedEvent<'a> {
event: ittapi_sys::__itt_event,
phantom: PhantomData<&'a mut ()>,
}

impl StartedEvent<'_> {
/// End the event.
#[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 Drop for StartedEvent<'_> {
fn drop(&mut self) {
if let Some(end_fn) = unsafe { ittapi_sys::__itt_event_end_ptr__3_0 } {
let result = unsafe { end_fn(self.event) };
assert!(result == 0, "unable to stop event");
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn sanity() {
let event = Event::new("test");
let _started_event = event.start();
// Dropping `started_event` ends the event.
}
}
Loading