Skip to main content

ringkernel_procint/models/
event.rs

1//! Process event types for GPU processing.
2//!
3//! GPU-aligned structures for efficient kernel execution.
4
5use rkyv::{Archive, Deserialize, Serialize};
6
7/// Hybrid timestamp combining physical and logical clocks.
8///
9/// Provides causal ordering across distributed systems.
10#[derive(
11    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Archive, Serialize, Deserialize,
12)]
13#[repr(C)]
14pub struct HybridTimestamp {
15    /// Physical time in milliseconds since epoch.
16    pub physical_ms: u64,
17    /// Logical counter for ordering events at same physical time.
18    pub logical: u64,
19}
20
21impl HybridTimestamp {
22    /// Create a new timestamp.
23    pub fn new(physical_ms: u64, logical: u64) -> Self {
24        Self {
25            physical_ms,
26            logical,
27        }
28    }
29
30    /// Create a timestamp from current time.
31    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    /// Create a zero timestamp.
44    pub fn zero() -> Self {
45        Self::default()
46    }
47
48    /// Tick the logical counter.
49    pub fn tick(&mut self) {
50        self.logical += 1;
51    }
52
53    /// Update from a remote timestamp (for HLC sync).
54    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/// Event type classification.
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Archive, Serialize, Deserialize)]
68#[repr(u8)]
69pub enum EventType {
70    /// Activity started.
71    Start = 0,
72    /// Activity completed.
73    #[default]
74    Complete = 1,
75    /// Activity scheduled.
76    Schedule = 2,
77    /// Activity assigned to resource.
78    Assign = 3,
79    /// Activity suspended.
80    Suspend = 4,
81    /// Activity resumed.
82    Resume = 5,
83    /// Activity aborted.
84    Abort = 6,
85}
86
87/// GPU-compatible process event (128 bytes, cache-line aligned).
88///
89/// Represents a single event in an event log, optimized for GPU processing.
90#[derive(Debug, Clone, Copy, Archive, Serialize, Deserialize)]
91#[repr(C, align(128))]
92pub struct GpuObjectEvent {
93    /// Unique event identifier.
94    pub event_id: u64,
95    /// Case/trace identifier (object ID in OCPM terms).
96    pub object_id: u64,
97    /// Activity identifier.
98    pub activity_id: u32,
99    /// Event type (start, complete, etc.).
100    pub event_type: u8,
101    /// Padding for alignment.
102    pub _padding1: [u8; 3],
103    /// Event timestamp with HLC.
104    pub timestamp: HybridTimestamp,
105    /// Resource that performed the activity.
106    pub resource_id: u32,
107    /// Cost associated with the event.
108    pub cost: f32,
109    /// Duration in milliseconds (for interval events).
110    pub duration_ms: u32,
111    /// Event flags (custom attributes).
112    pub flags: u32,
113    /// Custom attribute values.
114    pub attributes: [u32; 4],
115    /// Object type identifier (for OCPM).
116    pub object_type_id: u32,
117    /// Related object ID (for object relationships).
118    pub related_object_id: u64,
119    /// Reserved for future use.
120    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    /// Create a new event.
146    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    /// Get the event type.
164    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    /// Check if this is a start event.
178    pub fn is_start(&self) -> bool {
179        self.event_type == EventType::Start as u8
180    }
181
182    /// Check if this is a complete event.
183    pub fn is_complete(&self) -> bool {
184        self.event_type == EventType::Complete as u8
185    }
186}
187
188// Verify size at compile time
189const _: () = 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}