Repository: intel/ittapi (language: python)

Issue:
Rust ittapi-sys bindings out of date, bindgen-up-to-date.rs possibly broken.
I recently discovered Intel Vtune https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/2024-0/anomaly-detection-analysis.html
It required the following functions to be integrated with the application:
```C
__itt_mark_pt_region_begin(region);
__itt_mark_pt_region_end(region);
```
But they're not available in the rust ittapi(-sys) bindings.
I tried regenerating with `BLESS=1` but the functions didn't show up.
Any chance `bindgen-up-to-date.rs` is broken?

Off note:
Most functions in the public API have a `ITTAPI` which seem to be missing here for both of these functions. Not sure if this is relevant or problematic.
Rust ittapi-sys bindings out of date, bindgen-up-to-date.rs possibly broken.
I recently discovered Intel Vtune https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/2024-0/anomaly-detection-analysis.html
It required the following functions to be integrated with the application:
```C
__itt_mark_pt_region_begin(region);
__itt_mark_pt_region_end(region);
```
But they're not available in the rust ittapi(-sys) bindings.
I tried regenerating with `BLESS=1` but the functions didn't show up.
Any chance `bindgen-up-to-date.rs` is broken?

Off note:
Most functions in the public API have a `ITTAPI` which seem to be missing here for both of these functions. Not sure if this is relevant or problematic.
Rust ittapi-sys bindings out of date, bindgen-up-to-date.rs possibly broken.
I recently discovered Intel Vtune https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/2024-0/anomaly-detection-analysis.html
It required the following functions to be integrated with the application:
```C
__itt_mark_pt_region_begin(region);
__itt_mark_pt_region_end(region);
```
But they're not available in the rust ittapi(-sys) bindings.
I tried regenerating with `BLESS=1` but the functions didn't show up.
Any chance `bindgen-up-to-date.rs` is broken?

Off note:
Most functions in the public API have a `ITTAPI` which seem to be missing here for both of these functions. Not sure if this is relevant or problematic.
Rust ittapi-sys bindings out of date, bindgen-up-to-date.rs possibly broken.
I recently discovered Intel Vtune https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/2024-0/anomaly-detection-analysis.html
It required the following functions to be integrated with the application:
```C
__itt_mark_pt_region_begin(region);
__itt_mark_pt_region_end(region);
```
But they're not available in the rust ittapi(-sys) bindings.
I tried regenerating with `BLESS=1` but the functions didn't show up.
Any chance `bindgen-up-to-date.rs` is broken?

Off note:
Most functions in the public API have a `ITTAPI` which seem to be missing here for both of these functions. Not sure if this is relevant or problematic.


Discussion / hints:
I think this is a good find. If you notice in the binding-generation code, it doesn't have an `allowlist_function` entry:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/rust/ittapi-sys/tests/bindgen-up-to-date.rs#L33-L35

When I add `.allowlist_function("__itt.*")` in there, I see many more functions now present in the bindings, including the ones you mention. But now I'm wondering why I didn't add that in the first place (@ekovanova, were we supposed to use the pointer versions like `__itt_*_ptr__3_0` instead?).

@codecnotsupported, a couple more questions:
- this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?
- are you using `ittapi-sys` directly? Or do you want to get these `mark` functions in to the high-level bindings?
- this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

Thanks again for the report!

>this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?

The latter.

>are you using ittapi-sys directly? Or do you want to get these mark functions in to the high-level bindings?

I was using ittapi-sys directly because there wasn't a high-level API binding. High-level bindings would be preferred.
 
>this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

In `ittnotify.h`, most public API functions are prefixed with `ITTAPI` and `__itt_mark_pt_region_begin/end` seems to be a exception to this rule.
I have no clue what the  `ITTAPI` prefix does. I am merely denoting this anomaly just in case it means something to you.

Example:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L452

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L529
I think this is a good find. If you notice in the binding-generation code, it doesn't have an `allowlist_function` entry:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/rust/ittapi-sys/tests/bindgen-up-to-date.rs#L33-L35

When I add `.allowlist_function("__itt.*")` in there, I see many more functions now present in the bindings, including the ones you mention. But now I'm wondering why I didn't add that in the first place (@ekovanova, were we supposed to use the pointer versions like `__itt_*_ptr__3_0` instead?).

@codecnotsupported, a couple more questions:
- this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?
- are you using `ittapi-sys` directly? Or do you want to get these `mark` functions in to the high-level bindings?
- this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

Thanks again for the report!

>this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?

The latter.

>are you using ittapi-sys directly? Or do you want to get these mark functions in to the high-level bindings?

I was using ittapi-sys directly because there wasn't a high-level API binding. High-level bindings would be preferred.
 
>this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

In `ittnotify.h`, most public API functions are prefixed with `ITTAPI` and `__itt_mark_pt_region_begin/end` seems to be a exception to this rule.
I have no clue what the  `ITTAPI` prefix does. I am merely denoting this anomaly just in case it means something to you.

Example:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L452

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L529
I think this is a good find. If you notice in the binding-generation code, it doesn't have an `allowlist_function` entry:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/rust/ittapi-sys/tests/bindgen-up-to-date.rs#L33-L35

When I add `.allowlist_function("__itt.*")` in there, I see many more functions now present in the bindings, including the ones you mention. But now I'm wondering why I didn't add that in the first place (@ekovanova, were we supposed to use the pointer versions like `__itt_*_ptr__3_0` instead?).

@codecnotsupported, a couple more questions:
- this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?
- are you using `ittapi-sys` directly? Or do you want to get these `mark` functions in to the high-level bindings?
- this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

Thanks again for the report!

>this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?

The latter.

>are you using ittapi-sys directly? Or do you want to get these mark functions in to the high-level bindings?

I was using ittapi-sys directly because there wasn't a high-level API binding. High-level bindings would be preferred.
 
>this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

In `ittnotify.h`, most public API functions are prefixed with `ITTAPI` and `__itt_mark_pt_region_begin/end` seems to be a exception to this rule.
I have no clue what the  `ITTAPI` prefix does. I am merely denoting this anomaly just in case it means something to you.

Example:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L452

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L529
I think this is a good find. If you notice in the binding-generation code, it doesn't have an `allowlist_function` entry:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/rust/ittapi-sys/tests/bindgen-up-to-date.rs#L33-L35

When I add `.allowlist_function("__itt.*")` in there, I see many more functions now present in the bindings, including the ones you mention. But now I'm wondering why I didn't add that in the first place (@ekovanova, were we supposed to use the pointer versions like `__itt_*_ptr__3_0` instead?).

@codecnotsupported, a couple more questions:
- this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?
- are you using `ittapi-sys` directly? Or do you want to get these `mark` functions in to the high-level bindings?
- this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

Thanks again for the report!

>this statement is unclear to me: "It required the following functions to be integrated with the application." Do you mean that your application failed to compile or it failed to run inside VTune? Or just that you were not able to in fact mark the regions because the API is not yet available in the Rust bindings?

The latter.

>are you using ittapi-sys directly? Or do you want to get these mark functions in to the high-level bindings?

I was using ittapi-sys directly because there wasn't a high-level API binding. High-level bindings would be preferred.
 
>this statement is also confusing me: "Most functions in the public API have a ITTAPI which seem to be missing here for both of these functions." What do you mean by that?

In `ittnotify.h`, most public API functions are prefixed with `ITTAPI` and `__itt_mark_pt_region_begin/end` seems to be a exception to this rule.
I have no clue what the  `ITTAPI` prefix does. I am merely denoting this anomaly just in case it means something to you.

Example:

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L452

https://github.com/intel/ittapi/blob/9fdc83031a22d66ad23dab8865bc0d9331ee6189/include/ittnotify.h#L529

Fix patch:
diff --git a/rust/ittapi-sys/Cargo.toml b/rust/ittapi-sys/Cargo.toml
index 1df3944..520f63e 100644
--- a/rust/ittapi-sys/Cargo.toml
+++ b/rust/ittapi-sys/Cargo.toml
@@ -28,5 +28,5 @@ exclude = [
 cc = "1.0.73"
 
 [dev-dependencies]
-bindgen = "0.68"
+bindgen = "0.69.4"
 diff = "0.1"
diff --git a/rust/ittapi-sys/README.md b/rust/ittapi-sys/README.md
index 3e5f44e..15dccf1 100644
--- a/rust/ittapi-sys/README.md
+++ b/rust/ittapi-sys/README.md
@@ -26,9 +26,16 @@ Linux](https://docs.wasmtime.dev/examples-profiling-vtune.html)
 
 ```toml
 [dependencies]
-ittapi-sys = "0.3"
+ittapi-sys = "*"
 ```
 
+Using the symbols in this crate can be tricky: `ittapi` consists of a static part (e.g.,
+`libittnotify.a`) linked in this crate _and_ a dynamic part (e.g., `libittnotify_collector.so`,
+VTune Profiler). The static part provides the ITT data symbols that may be subsequently resolved to
+actual implementations in the dynamic part--the data collector. This crate only provides symbols
+like `__itt_task_begin_ptr__3_0`, not `__itt_task_begin`, to avoid link errors; programs using
+`ittapi` should compile even if the dynamic part is not present. Using the [high-level Rust crate]
+avoids this complexity.
 
 ### Build
 
diff --git a/rust/ittapi-sys/src/freebsd/ittnotify_bindings.rs b/rust/ittapi-sys/src/freebsd/ittnotify_bindings.rs
index 1ff21d3..0ce95b3 100644
--- a/rust/ittapi-sys/src/freebsd/ittnotify_bindings.rs
+++ b/rust/ittapi-sys/src/freebsd/ittnotify_bindings.rs
@@ -69,6 +69,14 @@ pub type __itt_pt_region_create_ptr__3_0_t = ::std::option::Option<
 extern "C" {
     pub static mut __itt_pt_region_create_ptr__3_0: __itt_pt_region_create_ptr__3_0_t;
 }
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the beginning of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_begin(region: __itt_pt_region);
+}
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the end of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_end(region: __itt_pt_region);
+}
 pub type __itt_thread_set_name_ptr__3_0_t =
     ::std::option::Option<unsafe extern "C" fn(name: *const ::std::os::raw::c_char)>;
 extern "C" {
diff --git a/rust/ittapi-sys/src/lib.rs b/rust/ittapi-sys/src/lib.rs
index ac7b2fd..24a9006 100644
--- a/rust/ittapi-sys/src/lib.rs
+++ b/rust/ittapi-sys/src/lib.rs
@@ -1,4 +1,5 @@
 //! This library contains OS-specific bindings to the C `ittapi` library.
+
 #![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
 #![allow(unused)]
 #![deny(clippy::all)]
@@ -32,11 +33,3 @@ include!("windows/jitprofiling_bindings.rs");
 include!("freebsd/jitprofiling_bindings.rs");
 #[cfg(target_os = "openbsd")]
 include!("openbsd/jitprofiling_bindings.rs");
-
-// #[link(name = "ittnotify", kind = "static")]
-// extern "C" {
-//     #[link_name = "__itt_domain_create_init_3_0"]
-//     pub fn __itt_domain_create_init_3_0(name: *const std::os::raw::c_char) -> *mut __itt_domain;
-//     // #[link_name = "__itt_domain_create_init_3_0"]
-//     // pub fn __itt_domain_create(name: *const std::os::raw::c_char) -> *mut __itt_domain;
-// }
diff --git a/rust/ittapi-sys/src/linux/ittnotify_bindings.rs b/rust/ittapi-sys/src/linux/ittnotify_bindings.rs
index e3270a0..cd069fd 100644
--- a/rust/ittapi-sys/src/linux/ittnotify_bindings.rs
+++ b/rust/ittapi-sys/src/linux/ittnotify_bindings.rs
@@ -1,4 +1,4 @@
-/* automatically generated by rust-bindgen 0.68.1 */
+/* automatically generated by rust-bindgen 0.69.4 */
 
 pub const ITT_OS_WIN: u32 = 1;
 pub const ITT_OS_LINUX: u32 = 2;
@@ -59,6 +59,14 @@ pub type __itt_pt_region_create_ptr__3_0_t = ::std::option::Option<
 extern "C" {
     pub static mut __itt_pt_region_create_ptr__3_0: __itt_pt_region_create_ptr__3_0_t;
 }
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the beginning of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_begin(region: __itt_pt_region);
+}
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the end of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_end(region: __itt_pt_region);
+}
 pub type __itt_thread_set_name_ptr__3_0_t =
     ::std::option::Option<unsafe extern "C" fn(name: *const ::std::os::raw::c_char)>;
 extern "C" {
diff --git a/rust/ittapi-sys/src/linux/jitprofiling_bindings.rs b/rust/ittapi-sys/src/linux/jitprofiling_bindings.rs
index 29927bd..1e9d976 100644
--- a/rust/ittapi-sys/src/linux/jitprofiling_bindings.rs
+++ b/rust/ittapi-sys/src/linux/jitprofiling_bindings.rs
@@ -1,4 +1,4 @@
-/* automatically generated by rust-bindgen 0.68.1 */
+/* automatically generated by rust-bindgen 0.69.4 */
 
 #[doc = "<\\brief Send this to shutdown the agent.\n Use NULL for event data."]
 pub const iJIT_jvm_event_iJVM_EVENT_TYPE_SHUTDOWN: iJIT_jvm_event = 2;
diff --git a/rust/ittapi-sys/src/macos/ittnotify_bindings.rs b/rust/ittapi-sys/src/macos/ittnotify_bindings.rs
index bc065b2..9c1e40c 100644
--- a/rust/ittapi-sys/src/macos/ittnotify_bindings.rs
+++ b/rust/ittapi-sys/src/macos/ittnotify_bindings.rs
@@ -1,4 +1,4 @@
-/* automatically generated by rust-bindgen 0.68.1 */
+/* automatically generated by rust-bindgen 0.69.4 */
 
 pub const ITT_OS_WIN: u32 = 1;
 pub const ITT_OS_LINUX: u32 = 2;
@@ -59,6 +59,14 @@ pub type __itt_pt_region_create_ptr__3_0_t = ::std::option::Option<
 extern "C" {
     pub static mut __itt_pt_region_create_ptr__3_0: __itt_pt_region_create_ptr__3_0_t;
 }
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the beginning of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_begin(region: __itt_pt_region);
+}
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the end of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_end(region: __itt_pt_region);
+}
 pub type __itt_thread_set_name_ptr__3_0_t =
     ::std::option::Option<unsafe extern "C" fn(name: *const ::std::os::raw::c_char)>;
 extern "C" {
diff --git a/rust/ittapi-sys/src/macos/jitprofiling_bindings.rs b/rust/ittapi-sys/src/macos/jitprofiling_bindings.rs
index 29927bd..1e9d976 100644
--- a/rust/ittapi-sys/src/macos/jitprofiling_bindings.rs
+++ b/rust/ittapi-sys/src/macos/jitprofiling_bindings.rs
@@ -1,4 +1,4 @@
-/* automatically generated by rust-bindgen 0.68.1 */
+/* automatically generated by rust-bindgen 0.69.4 */
 
 #[doc = "<\\brief Send this to shutdown the agent.\n Use NULL for event data."]
 pub const iJIT_jvm_event_iJVM_EVENT_TYPE_SHUTDOWN: iJIT_jvm_event = 2;
diff --git a/rust/ittapi-sys/src/openbsd/ittnotify_bindings.rs b/rust/ittapi-sys/src/openbsd/ittnotify_bindings.rs
index 2a0ad9f..82e3cc5 100644
--- a/rust/ittapi-sys/src/openbsd/ittnotify_bindings.rs
+++ b/rust/ittapi-sys/src/openbsd/ittnotify_bindings.rs
@@ -52,6 +52,14 @@ pub type __itt_pt_region_create_ptr__3_0_t = ::std::option::Option<
 extern "C" {
     pub static mut __itt_pt_region_create_ptr__3_0: __itt_pt_region_create_ptr__3_0_t;
 }
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the beginning of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_begin(region: __itt_pt_region);
+}
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the end of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_end(region: __itt_pt_region);
+}
 pub type __itt_thread_set_name_ptr__3_0_t =
     ::std::option::Option<unsafe extern "C" fn(name: *const ::std::os::raw::c_char)>;
 extern "C" {
diff --git a/rust/ittapi-sys/src/windows/ittnotify_bindings.rs b/rust/ittapi-sys/src/windows/ittnotify_bindings.rs
index be4c19f..39458a7 100644
--- a/rust/ittapi-sys/src/windows/ittnotify_bindings.rs
+++ b/rust/ittapi-sys/src/windows/ittnotify_bindings.rs
@@ -1,4 +1,4 @@
-/* automatically generated by rust-bindgen 0.68.1 */
+/* automatically generated by rust-bindgen 0.69.4 */
 
 pub const ITT_OS_WIN: u32 = 1;
 pub const ITT_OS_LINUX: u32 = 2;
@@ -65,6 +65,14 @@ pub type __itt_pt_region_createW_ptr__3_0_t =
 extern "C" {
     pub static mut __itt_pt_region_createW_ptr__3_0: __itt_pt_region_createW_ptr__3_0_t;
 }
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the beginning of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_begin(region: __itt_pt_region);
+}
+extern "C" {
+    #[doc = " @brief function contains a special code pattern identified on the post-processing stage and\n marks the end of a code region targeted for Intel PT analysis\n @param[in] region - region id, 0 <= region < 8"]
+    pub fn __itt_mark_pt_region_end(region: __itt_pt_region);
+}
 pub type __itt_thread_set_nameA_ptr__3_0_t =
     ::std::option::Option<unsafe extern "C" fn(name: *const ::std::os::raw::c_char)>;
 extern "C" {
diff --git a/rust/ittapi-sys/src/windows/jitprofiling_bindings.rs b/rust/ittapi-sys/src/windows/jitprofiling_bindings.rs
index 17ce844..ad67453 100644
--- a/rust/ittapi-sys/src/windows/jitprofiling_bindings.rs
+++ b/rust/ittapi-sys/src/windows/jitprofiling_bindings.rs
@@ -1,4 +1,4 @@
-/* automatically generated by rust-bindgen 0.68.1 */
+/* automatically generated by rust-bindgen 0.69.4 */
 
 #[doc = "<\\brief Send this to shutdown the agent.\n Use NULL for event data."]
 pub const iJIT_jvm_event_iJVM_EVENT_TYPE_SHUTDOWN: iJIT_jvm_event = 2;
diff --git a/rust/ittapi/src/domain.rs b/rust/ittapi/src/domain.rs
index 5c779a8..f77b08e 100644
--- a/rust/ittapi/src/domain.rs
+++ b/rust/ittapi/src/domain.rs
@@ -43,3 +43,14 @@ impl Domain {
 /// [ITT documentation]:
 ///     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/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");
+    }
+}
diff --git a/rust/ittapi/src/lib.rs b/rust/ittapi/src/lib.rs
index ad3ef9e..32e841e 100644
--- a/rust/ittapi/src/lib.rs
+++ b/rust/ittapi/src/lib.rs
@@ -13,6 +13,7 @@ mod collection_control;
 mod domain;
 mod event;
 pub mod jit;
+mod region;
 mod string;
 mod task;
 mod util;
@@ -20,5 +21,6 @@ mod util;
 pub use collection_control::{detach, pause, resume};
 pub use domain::Domain;
 pub use event::Event;
+pub use region::{MarkedRegion, Region};
 pub use string::StringHandle;
 pub use task::Task;
diff --git a/rust/ittapi/src/region.rs b/rust/ittapi/src/region.rs
new file mode 100644
index 0000000..df20f90
--- /dev/null
+++ b/rust/ittapi/src/region.rs
@@ -0,0 +1,94 @@
+use std::ffi::CString;
+
+/// An Intel® Processor Trace region.
+pub struct Region(ittapi_sys::__itt_pt_region);
+impl Region {
+    /// Create a new Intel PT region.
+    ///
+    /// ```
+    /// # use ittapi::Region;
+    /// let region = Region::new("test-region");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if the domain name contains a `0` byte.
+    #[must_use]
+    pub fn new(name: &str) -> Self {
+        let c_string =
+            CString::new(name).expect("unable to create a CString; does it contain a 0 byte?");
+        #[cfg(unix)]
+        let create_fn = unsafe { ittapi_sys::__itt_pt_region_create_ptr__3_0 };
+        #[cfg(windows)]
+        let create_fn = unsafe { ittapi_sys::__itt_pt_region_createA_ptr__3_0 };
+        let region = if let Some(create_fn) = create_fn {
+            unsafe { create_fn(c_string.as_ptr()) }
+        } else {
+            // Use this value as a sentinel to indicate that the region was not created.
+            u8::MAX
+        };
+        Self(region)
+    }
+
+    /// Mark a section of code as an Intel PT region using `__itt_mark_pt_region_begin`. This can be
+    /// used for fine-grained profiling, such as [anomaly detection] (a preview feature of VTune).
+    ///
+    /// [anomaly detection]:
+    ///     https://www.intel.com/content/www/us/en/docs/vtune-profiler/user-guide/2024-1/anomaly-detection-analysis.html
+    ///
+    /// ```
+    /// # use ittapi::Region;
+    /// let region = Region::new("test-region");
+    /// // Mark a region for fine-grained measurement, such as a tight loop.
+    /// for _ in 0..10 {
+    ///     let _marked = region.mark();
+    ///     let _ = 2 + 2;
+    ///     // Marked region ends here, when dropped; use `end()` to end it explicitly.
+    /// }
+    /// ```
+    #[inline]
+    #[must_use]
+    pub fn mark(&self) -> MarkedRegion {
+        unsafe { ittapi_sys::__itt_mark_pt_region_begin(self.0) };
+        MarkedRegion(self)
+    }
+}
+
+/// A [`MarkedRegion`] is a Rust helper structure for ergonomically ending a marked region using
+/// `__itt_mark_pt_region_end`. See [`Region::mark`] for more details.
+pub struct MarkedRegion<'a>(&'a Region);
+impl<'a> MarkedRegion<'a> {
+    /// End the marked region.
+    #[inline]
+    pub fn end(self) {
+        // Do nothing; the `Drop` implementation does the work. See discussion at
+        // https://stackoverflow.com/questions/53254645.
+    }
+}
+impl Drop for MarkedRegion<'_> {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe { ittapi_sys::__itt_mark_pt_region_end(self.0 .0) };
+    }
+}
+
+#[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 _region = Region::new("zero\0byte\0name");
+    }
+
+    #[test]
+    fn sanity() {
+        let region = Region::new("region");
+        for _ in 0..10 {
+            let _marked_region = region.mark();
+            // Do nothing.
+            _marked_region.end();
+        }
+    }
+}


Test patch:
diff --git a/rust/ittapi-sys/tests/bindgen-up-to-date.rs b/rust/ittapi-sys/tests/bindgen-up-to-date.rs
index f16680e..7db83f0 100644
--- a/rust/ittapi-sys/tests/bindgen-up-to-date.rs
+++ b/rust/ittapi-sys/tests/bindgen-up-to-date.rs
@@ -32,6 +32,11 @@ fn test_ittnotify_bindings_up_to_date() {
         .formatter(bindgen::Formatter::Rustfmt)
         .allowlist_var("ITT.*")
         .allowlist_var("__itt.*")
+        // Also, note how few functions we allow: if we generate bindings for all the declared
+        // functions, we run into linking errors. Only some functions are actually defined in
+        // `libittnotify.a` but most are provided dynamically by the dynamic collection library. See
+        // the `README.md` for more details.
+        .allowlist_function("__itt_mark_pt.*")
         .header(concat(INCLUDE_PATH, "/ittnotify.h"))
         .generate()
         .expect("Unable to generate ittnotify bindings.")