ringkernel_procint/models/
event.rs1use rkyv::{Archive, Deserialize, Serialize};
6
7#[derive(
11 Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Archive, Serialize, Deserialize,
12)]
13#[repr(C)]
14pub struct HybridTimestamp {
15 pub physical_ms: u64,
17 pub logical: u64,
19}
20
21impl HybridTimestamp {
22 pub fn new(physical_ms: u64, logical: u64) -> Self {
24 Self {
25 physical_ms,
26 logical,
27 }
28 }
29
30 pub fn now() -> Self {
32 use std::time::{SystemTime, UNIX_EPOCH};
33 let physical_ms = SystemTime::now()
34 .duration_since(UNIX_EPOCH)
35 .unwrap()
36 .as_millis() as u64;
37 Self {
38 physical_ms,
39 logical: 0,
40 }
41 }
42
43 pub fn zero() -> Self {
45 Self::default()
46 }
47
48 pub fn tick(&mut self) {
50 self.logical += 1;
51 }
52
53 pub fn update(&mut self, remote: &HybridTimestamp) {
55 if remote.physical_ms > self.physical_ms {
56 self.physical_ms = remote.physical_ms;
57 self.logical = remote.logical + 1;
58 } else if remote.physical_ms == self.physical_ms {
59 self.logical = self.logical.max(remote.logical) + 1;
60 } else {
61 self.logical += 1;
62 }
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Archive, Serialize, Deserialize)]
68#[repr(u8)]
69pub enum EventType {
70 Start = 0,
72 #[default]
74 Complete = 1,
75 Schedule = 2,
77 Assign = 3,
79 Suspend = 4,
81 Resume = 5,
83 Abort = 6,
85}
86
87#[derive(Debug, Clone, Copy, Archive, Serialize, Deserialize)]
91#[repr(C, align(128))]
92pub struct GpuObjectEvent {
93 pub event_id: u64,
95 pub object_id: u64,
97 pub activity_id: u32,
99 pub event_type: u8,
101 pub _padding1: [u8; 3],
103 pub timestamp: HybridTimestamp,
105 pub resource_id: u32,
107 pub cost: f32,
109 pub duration_ms: u32,
111 pub flags: u32,
113 pub attributes: [u32; 4],
115 pub object_type_id: u32,
117 pub related_object_id: u64,
119 pub _reserved: [u8; 36],
121}
122
123impl Default for GpuObjectEvent {
124 fn default() -> Self {
125 Self {
126 event_id: 0,
127 object_id: 0,
128 activity_id: 0,
129 event_type: EventType::Complete as u8,
130 _padding1: [0; 3],
131 timestamp: HybridTimestamp::default(),
132 resource_id: 0,
133 cost: 0.0,
134 duration_ms: 0,
135 flags: 0,
136 attributes: [0; 4],
137 object_type_id: 0,
138 related_object_id: 0,
139 _reserved: [0; 36],
140 }
141 }
142}
143
144impl GpuObjectEvent {
145 pub fn new(
147 event_id: u64,
148 object_id: u64,
149 activity_id: u32,
150 event_type: EventType,
151 timestamp: HybridTimestamp,
152 ) -> Self {
153 Self {
154 event_id,
155 object_id,
156 activity_id,
157 event_type: event_type as u8,
158 timestamp,
159 ..Default::default()
160 }
161 }
162
163 pub fn get_event_type(&self) -> EventType {
165 match self.event_type {
166 0 => EventType::Start,
167 1 => EventType::Complete,
168 2 => EventType::Schedule,
169 3 => EventType::Assign,
170 4 => EventType::Suspend,
171 5 => EventType::Resume,
172 6 => EventType::Abort,
173 _ => EventType::Complete,
174 }
175 }
176
177 pub fn is_start(&self) -> bool {
179 self.event_type == EventType::Start as u8
180 }
181
182 pub fn is_complete(&self) -> bool {
184 self.event_type == EventType::Complete as u8
185 }
186}
187
188const _: () = assert!(std::mem::size_of::<GpuObjectEvent>() == 128);
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn test_event_size() {
197 assert_eq!(std::mem::size_of::<GpuObjectEvent>(), 128);
198 }
199
200 #[test]
201 fn test_timestamp_ordering() {
202 let t1 = HybridTimestamp::new(1000, 0);
203 let t2 = HybridTimestamp::new(1000, 1);
204 let t3 = HybridTimestamp::new(1001, 0);
205
206 assert!(t1 < t2);
207 assert!(t2 < t3);
208 }
209
210 #[test]
211 fn test_hlc_update() {
212 let mut local = HybridTimestamp::new(1000, 5);
213 let remote = HybridTimestamp::new(1000, 10);
214 local.update(&remote);
215 assert_eq!(local.logical, 11);
216 }
217}