#![doc(hidden)]
use core::mem;
use core::ptr;
use core::time::Duration;
use eventheader_types::ExtensionKind;
pub use eventheader_types::EventHeader;
pub use eventheader_types::EventHeaderExtension;
pub use eventheader_types::HeaderFlags;
pub use tracepoint::EventDataDescriptor;
pub use tracepoint::TracepointState;
pub use crate::provider::provider_new;
pub use crate::provider::CommandString;
pub use crate::provider::EventHeaderTracepoint;
pub const EVENTHEADER_COMMAND_TYPES: &str =
"u8 eventheader_flags; u8 version; u16 id; u16 tag; u8 opcode; u8 level";
pub const EVENTHEADER_NAME_MAX: usize = 256;
pub const EVENTHEADER_COMMAND_MAX: usize =
EVENTHEADER_NAME_MAX + 1 + EVENTHEADER_COMMAND_TYPES.len();
pub const fn tag_byte0(tag: u16) -> u8 {
return tag.to_ne_bytes()[0];
}
pub const fn tag_byte1(tag: u16) -> u8 {
return tag.to_ne_bytes()[1];
}
pub fn slice_count<T>(value: &[T]) -> u16 {
let len = value.len();
return if 65535 < len { 65535 } else { len as u16 };
}
pub const fn time_from_duration_after_1970(duration: Duration) -> i64 {
const I64_MAX: u64 = i64::MAX as u64;
let duration_secs = duration.as_secs();
if duration_secs > I64_MAX {
i64::MAX
} else {
duration_secs as i64
}
}
pub const fn time_from_duration_before_1970(duration: Duration) -> i64 {
const I64_MAX: u64 = i64::MAX as u64;
let duration_secs = duration.as_secs();
if duration_secs > I64_MAX {
i64::MIN
} else {
-(duration_secs as i64) - ((duration.subsec_nanos() != 0) as i64)
}
}
unsafe fn append_bytes<T: Sized>(dst: *mut u8, src: &T) -> *mut u8 {
let size = mem::size_of::<T>();
unsafe {
ptr::copy_nonoverlapping(src as *const T as *const u8, dst, size);
return dst.add(size);
}
}
pub fn write_eventheader(
state: &TracepointState,
event_header: &EventHeader,
activity_id: Option<&[u8; 16]>,
related_id: Option<&[u8; 16]>,
meta_len: u16,
data: &mut [EventDataDescriptor],
) -> i32 {
debug_assert!(data[0].is_empty());
debug_assert!(related_id.is_none() || activity_id.is_some());
debug_assert!(
(activity_id.is_none() && meta_len == 0)
|| event_header.flags == HeaderFlags::DefaultWithExtension
);
let mut extension_count = (activity_id.is_some() as u8) + ((meta_len != 0) as u8);
const HEADERS_SIZE_MAX: usize = mem::size_of::<u32>() + mem::size_of::<EventHeader>() + mem::size_of::<EventHeaderExtension>() + 16 + 16 + mem::size_of::<EventHeaderExtension>(); let mut headers: [u8; HEADERS_SIZE_MAX] = [0; HEADERS_SIZE_MAX];
let headers_len;
unsafe {
let mut headers_ptr = headers.as_mut_ptr().add(mem::size_of::<u32>()); headers_ptr = append_bytes(headers_ptr, event_header);
match activity_id {
None => debug_assert!(related_id.is_none()),
Some(aid) => match related_id {
None => {
extension_count -= 1;
headers_ptr = append_bytes(
headers_ptr,
&EventHeaderExtension::from_parts(
16,
ExtensionKind::ActivityId,
extension_count > 0,
),
);
headers_ptr = append_bytes(headers_ptr, aid);
}
Some(rid) => {
extension_count -= 1;
headers_ptr = append_bytes(
headers_ptr,
&EventHeaderExtension::from_parts(
32,
ExtensionKind::ActivityId,
extension_count > 0,
),
);
headers_ptr = append_bytes(headers_ptr, aid);
headers_ptr = append_bytes(headers_ptr, rid);
}
},
}
if meta_len != 0 {
extension_count -= 1;
headers_ptr = append_bytes(
headers_ptr,
&EventHeaderExtension::from_parts(
meta_len,
ExtensionKind::Metadata,
extension_count > 0,
),
);
}
headers_len = headers_ptr.offset_from(headers.as_mut_ptr()) as usize;
}
debug_assert!(headers_len <= headers.len());
debug_assert!(extension_count == 0);
let writev_result = state.write_with_headers(data, &mut headers[0..headers_len]);
return writev_result;
}