feat(nexshell): implement Visual Causal Graph Viewer
- Added 'stl graph' command to NexShell for ASCII causal visualization - Integrated Causal Graph Audit into kernel boot summary - Optimized STL list command to show absolute event IDs - Fixed Nim kernel crashes by avoiding dynamic string allocations in STL summary - Hardened HAL-to-NexShell interface with proper extern declarations
This commit is contained in:
parent
2da8463fb7
commit
ae667db013
|
|
@ -37,6 +37,7 @@ type
|
||||||
proc stl_query_by_fiber*(fiber_id: uint64, result: var QueryResult) {.importc, cdecl.}
|
proc stl_query_by_fiber*(fiber_id: uint64, result: var QueryResult) {.importc, cdecl.}
|
||||||
proc stl_query_by_kind*(kind: uint16, result: var QueryResult) {.importc, cdecl.}
|
proc stl_query_by_kind*(kind: uint16, result: var QueryResult) {.importc, cdecl.}
|
||||||
proc stl_get_recent*(max_count: uint32, result: var QueryResult) {.importc, cdecl.}
|
proc stl_get_recent*(max_count: uint32, result: var QueryResult) {.importc, cdecl.}
|
||||||
|
proc stl_query_by_time_range*(start_ns: uint64, end_ns: uint64, result: var QueryResult) {.importc, cdecl.}
|
||||||
|
|
||||||
type
|
type
|
||||||
LineageResult* = object
|
LineageResult* = object
|
||||||
|
|
@ -45,6 +46,20 @@ type
|
||||||
|
|
||||||
proc stl_trace_lineage*(event_id: uint64, result: var LineageResult) {.importc, cdecl.}
|
proc stl_trace_lineage*(event_id: uint64, result: var LineageResult) {.importc, cdecl.}
|
||||||
|
|
||||||
|
type
|
||||||
|
SystemStats* = object
|
||||||
|
total_events*: uint32
|
||||||
|
boot_events*: uint32
|
||||||
|
fiber_events*: uint32
|
||||||
|
cap_events*: uint32
|
||||||
|
io_events*: uint32
|
||||||
|
mem_events*: uint32
|
||||||
|
net_events*: uint32
|
||||||
|
security_events*: uint32
|
||||||
|
|
||||||
|
proc stl_get_stats*(stats: var SystemStats) {.importc, cdecl.}
|
||||||
|
proc stl_export_binary*(dest: pointer, max_size: uint64): uint64 {.importc, cdecl.}
|
||||||
|
|
||||||
## Event Types (Mirror from ontology.zig)
|
## Event Types (Mirror from ontology.zig)
|
||||||
type
|
type
|
||||||
EventKind* = enum
|
EventKind* = enum
|
||||||
|
|
@ -153,42 +168,50 @@ proc init_stl_subsystem*() =
|
||||||
kprintln("[STL] System Truth Ledger initialized")
|
kprintln("[STL] System Truth Ledger initialized")
|
||||||
|
|
||||||
## Query API
|
## Query API
|
||||||
proc stl_print_summary*() =
|
proc stl_print_summary*() {.exportc, cdecl.} =
|
||||||
## Print a summary of the STL ledger to the console
|
## Print a summary of the STL ledger to the console
|
||||||
kprintln("\n[STL] Event Summary:")
|
var stats: SystemStats
|
||||||
let total = stl_count()
|
stl_get_stats(stats)
|
||||||
kprint("[STL] Total Events: "); kprint_hex(uint64(total)); kprintln("")
|
|
||||||
|
kprintln("\n[STL] System Truth Ledger Summary:")
|
||||||
|
kprint("[STL] Total Events: "); kprint_hex(uint64(stats.total_events)); kprintln("")
|
||||||
|
kprint("[STL] Lifecycle: "); kprint_hex(uint64(stats.boot_events + stats.fiber_events)); kprintln("")
|
||||||
|
kprint("[STL] Capabilities: "); kprint_hex(uint64(stats.cap_events)); kprintln("")
|
||||||
|
kprint("[STL] I/O & Channels: "); kprint_hex(uint64(stats.io_events)); kprintln("")
|
||||||
|
kprint("[STL] Memory: "); kprint_hex(uint64(stats.mem_events)); kprintln("")
|
||||||
|
kprint("[STL] Security/Policy: "); kprint_hex(uint64(stats.security_events)); kprintln("")
|
||||||
|
|
||||||
var res: QueryResult
|
# Demonstrate Causal Graph for the last event
|
||||||
|
if stats.total_events > 0:
|
||||||
# Boot Events
|
let last_id = uint64(stats.total_events - 1)
|
||||||
stl_query_by_kind(uint16(EvSystemBoot), res)
|
|
||||||
kprint("[STL] SystemBoot: "); kprint_hex(uint64(res.count)); kprintln("")
|
|
||||||
|
|
||||||
# Fiber Spawn
|
|
||||||
stl_query_by_kind(uint16(EvFiberSpawn), res)
|
|
||||||
kprint("[STL] FiberSpawn: "); kprint_hex(uint64(res.count)); kprintln("")
|
|
||||||
|
|
||||||
# Cap Grants
|
|
||||||
stl_query_by_kind(uint16(EvCapabilityGrant), res)
|
|
||||||
kprint("[STL] CapGrant: "); kprint_hex(uint64(res.count)); kprintln("")
|
|
||||||
|
|
||||||
# Demonstrate Lineage Tracing for the last event
|
|
||||||
if total > 0:
|
|
||||||
let last_id = uint64(total - 1)
|
|
||||||
var lineage: LineageResult
|
var lineage: LineageResult
|
||||||
stl_trace_lineage(last_id, lineage)
|
stl_trace_lineage(last_id, lineage)
|
||||||
|
|
||||||
kprint("[STL] Lineage Trace for Event "); kprint_hex(last_id); kprintln(":")
|
kprintln("\n[STL] Causal Graph Audit:");
|
||||||
|
kprint("[STL] Target: "); kprint_hex(last_id); kprintln("")
|
||||||
|
|
||||||
for i in 0..<lineage.count:
|
for i in 0..<lineage.count:
|
||||||
let eid = lineage.event_ids[i]
|
let eid = lineage.event_ids[i]
|
||||||
let ev_ptr = stl_lookup(eid)
|
let ev_ptr = stl_lookup(eid)
|
||||||
|
|
||||||
|
if i > 0: kprintln(" |")
|
||||||
|
|
||||||
|
kprint(" +-- ["); kprint_hex(eid); kprint("] ")
|
||||||
|
|
||||||
if ev_ptr != nil:
|
if ev_ptr != nil:
|
||||||
# We can't easily access fields of Event struct from Nim if it's packed in Zig
|
# Kind is at offset 0 (2 bytes)
|
||||||
# but we know kind is at offset 0 (2 bytes)
|
let kind_val = cast[ptr uint16](ev_ptr)[]
|
||||||
let kind = cast[ptr uint16](ev_ptr)[]
|
if kind_val == uint16(EvSystemBoot): kprintln("SystemBoot")
|
||||||
kprint(" <- ["); kprint_hex(eid); kprint("] Kind="); kprint_hex(uint64(kind)); kprintln("")
|
elif kind_val == uint16(EvFiberSpawn): kprintln("FiberSpawn")
|
||||||
|
elif kind_val == uint16(EvCapabilityGrant): kprintln("CapGrant")
|
||||||
|
elif kind_val == uint16(EvAccessDenied): kprintln("AccessDenied")
|
||||||
|
else:
|
||||||
|
kprint("Kind="); kprint_hex(uint64(kind_val)); kprintln("")
|
||||||
else:
|
else:
|
||||||
kprint(" <- ["); kprint_hex(eid); kprintln("] (Lookup Failed)")
|
kprintln("Unknown")
|
||||||
|
|
||||||
kprintln("[STL] Summary complete.")
|
kprintln("\n[STL] Summary complete.")
|
||||||
|
|
||||||
|
proc export_stl_binary*(dest: pointer, max_size: uint64): uint64 =
|
||||||
|
## Export STL events to a binary buffer
|
||||||
|
return stl_export_binary(dest, max_size)
|
||||||
|
|
|
||||||
161
hal/ontology.zig
161
hal/ontology.zig
|
|
@ -178,11 +178,8 @@ pub const SystemTruthLedger = struct {
|
||||||
|
|
||||||
/// Get current event count
|
/// Get current event count
|
||||||
pub fn count(self: *const SystemTruthLedger) u32 {
|
pub fn count(self: *const SystemTruthLedger) u32 {
|
||||||
if (self.head >= self.tail) {
|
if (self.epoch > 0) return STL_SIZE;
|
||||||
return self.head - self.tail;
|
return self.head;
|
||||||
} else {
|
|
||||||
return (STL_SIZE - self.tail) + self.head;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -350,6 +347,127 @@ pub export fn stl_trace_lineage(event_id: u64, result: *LineageResult) void {
|
||||||
result.count = count;
|
result.count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Query events by time range (C ABI)
|
||||||
|
pub export fn stl_query_by_time_range(start_ns: u64, end_ns: u64, result: *QueryResult) void {
|
||||||
|
if (!stl_initialized) {
|
||||||
|
result.count = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var count: u32 = 0;
|
||||||
|
var idx = global_stl.tail;
|
||||||
|
|
||||||
|
while (idx != global_stl.head and count < 64) : (idx = (idx + 1) % STL_SIZE) {
|
||||||
|
const event = &global_stl.events[idx];
|
||||||
|
if (!event.is_null() and event.timestamp_ns >= start_ns and event.timestamp_ns <= end_ns) {
|
||||||
|
result.events[count] = event;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// System statistics structure
|
||||||
|
pub const SystemStats = extern struct {
|
||||||
|
total_events: u32,
|
||||||
|
boot_events: u32,
|
||||||
|
fiber_events: u32,
|
||||||
|
cap_events: u32,
|
||||||
|
io_events: u32,
|
||||||
|
mem_events: u32,
|
||||||
|
net_events: u32,
|
||||||
|
security_events: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Get system statistics from STL (C ABI)
|
||||||
|
pub export fn stl_get_stats(stats: *SystemStats) void {
|
||||||
|
if (!stl_initialized) {
|
||||||
|
stats.* = .{
|
||||||
|
.total_events = 0,
|
||||||
|
.boot_events = 0,
|
||||||
|
.fiber_events = 0,
|
||||||
|
.cap_events = 0,
|
||||||
|
.io_events = 0,
|
||||||
|
.mem_events = 0,
|
||||||
|
.net_events = 0,
|
||||||
|
.security_events = 0,
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var s = SystemStats{
|
||||||
|
.total_events = global_stl.count(),
|
||||||
|
.boot_events = 0,
|
||||||
|
.fiber_events = 0,
|
||||||
|
.cap_events = 0,
|
||||||
|
.io_events = 0,
|
||||||
|
.mem_events = 0,
|
||||||
|
.net_events = 0,
|
||||||
|
.security_events = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
var idx = global_stl.tail;
|
||||||
|
while (idx != global_stl.head) : (idx = (idx + 1) % STL_SIZE) {
|
||||||
|
const event = &global_stl.events[idx];
|
||||||
|
if (event.is_null()) continue;
|
||||||
|
|
||||||
|
switch (event.kind) {
|
||||||
|
.SystemBoot, .SystemShutdown => s.boot_events += 1,
|
||||||
|
.FiberSpawn, .FiberTerminate => s.fiber_events += 1,
|
||||||
|
.CapabilityGrant, .CapabilityRevoke, .CapabilityDelegate => s.cap_events += 1,
|
||||||
|
.ChannelOpen, .ChannelClose, .ChannelRead, .ChannelWrite => s.io_events += 1,
|
||||||
|
.MemoryAllocate, .MemoryFree, .MemoryMap => s.mem_events += 1,
|
||||||
|
.NetworkPacketRx, .NetworkPacketTx => s.net_events += 1,
|
||||||
|
.AccessDenied, .PolicyViolation => s.security_events += 1,
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.* = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Binary Header for STL Export
|
||||||
|
pub const STLHeader = extern struct {
|
||||||
|
magic: u32 = 0x53544C21, // "STL!"
|
||||||
|
version: u16 = 1,
|
||||||
|
event_count: u16,
|
||||||
|
event_size: u8 = @sizeOf(Event),
|
||||||
|
_reserved: [23]u8 = [_]u8{0} ** 23, // Pad to 32 bytes for alignment
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Export all events as a contiguous binary blob (C ABI)
|
||||||
|
/// Returns number of bytes written
|
||||||
|
pub export fn stl_export_binary(dest: [*]u8, max_size: usize) usize {
|
||||||
|
if (!stl_initialized) return 0;
|
||||||
|
|
||||||
|
const count = global_stl.count();
|
||||||
|
const required_size = @sizeOf(STLHeader) + (count * @sizeOf(Event));
|
||||||
|
|
||||||
|
if (max_size < required_size) return 0;
|
||||||
|
|
||||||
|
var ptr = dest;
|
||||||
|
|
||||||
|
// Write Header
|
||||||
|
const header = STLHeader{
|
||||||
|
.event_count = @as(u16, @intCast(count)),
|
||||||
|
};
|
||||||
|
@memcpy(ptr, @as([*]const u8, @ptrCast(&header))[0..@sizeOf(STLHeader)]);
|
||||||
|
ptr += @sizeOf(STLHeader);
|
||||||
|
|
||||||
|
// Write Events (in chronological order from tail to head)
|
||||||
|
var idx = global_stl.tail;
|
||||||
|
while (idx != global_stl.head) : (idx = (idx + 1) % STL_SIZE) {
|
||||||
|
const event = &global_stl.events[idx];
|
||||||
|
if (event.is_null()) continue;
|
||||||
|
|
||||||
|
@memcpy(ptr, @as([*]const u8, @ptrCast(event))[0..@sizeOf(Event)]);
|
||||||
|
ptr += @sizeOf(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return required_size;
|
||||||
|
}
|
||||||
|
|
||||||
// Unit tests
|
// Unit tests
|
||||||
test "Event creation and validation" {
|
test "Event creation and validation" {
|
||||||
const event = Event{
|
const event = Event{
|
||||||
|
|
@ -418,3 +536,36 @@ test "STL wraparound" {
|
||||||
try std.testing.expect(stl.epoch > 0);
|
try std.testing.expect(stl.epoch > 0);
|
||||||
try std.testing.expect(stl.count() == STL_SIZE);
|
try std.testing.expect(stl.count() == STL_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "STL binary export" {
|
||||||
|
var stl = SystemTruthLedger.init();
|
||||||
|
|
||||||
|
_ = stl.append(Event{
|
||||||
|
.kind = .SystemBoot,
|
||||||
|
._reserved = 0,
|
||||||
|
.timestamp_ns = 100,
|
||||||
|
.fiber_id = 0,
|
||||||
|
.entity_id = 0,
|
||||||
|
.cause_id = 0,
|
||||||
|
.data0 = 1,
|
||||||
|
.data1 = 2,
|
||||||
|
.data2 = 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mock global STL for export test (since export uses global_stl)
|
||||||
|
global_stl = stl;
|
||||||
|
stl_initialized = true;
|
||||||
|
|
||||||
|
var buf: [512]u8 align(16) = undefined;
|
||||||
|
const written = stl_export_binary(&buf, buf.len);
|
||||||
|
|
||||||
|
try std.testing.expect(written > @sizeOf(STLHeader));
|
||||||
|
|
||||||
|
const header = @as(*const STLHeader, @ptrCast(@alignCast(&buf))).*;
|
||||||
|
try std.testing.expect(header.magic == 0x53544C21);
|
||||||
|
try std.testing.expect(header.event_count == 1);
|
||||||
|
|
||||||
|
const first_ev = @as(*const Event, @ptrCast(@alignCast(&buf[@sizeOf(STLHeader)])));
|
||||||
|
try std.testing.expect(first_ev.kind == .SystemBoot);
|
||||||
|
try std.testing.expect(first_ev.data0 == 1);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,85 @@ fn process_command(cmd_text: []const u8, cmd_ring: *RingBuffer(CmdPacket)) void
|
||||||
print(" - NetSwitch (Traffic Engine)\n");
|
print(" - NetSwitch (Traffic Engine)\n");
|
||||||
print(" - Subject (Userland Loader)\n");
|
print(" - Subject (Userland Loader)\n");
|
||||||
print(" - Kernel (Main)\n");
|
print(" - Kernel (Main)\n");
|
||||||
|
} else if (std.mem.eql(u8, cmd_text, "stl summary")) {
|
||||||
|
stl_print_summary();
|
||||||
|
} else if (std.mem.eql(u8, cmd_text, "stl list")) {
|
||||||
|
print("[NexShell] Recent Events:\n");
|
||||||
|
const total = stl_count();
|
||||||
|
const start = if (total > 10) total - 10 else 0;
|
||||||
|
var id = total - 1;
|
||||||
|
while (id >= start) {
|
||||||
|
const ev = stl_lookup(id);
|
||||||
|
if (ev) |e| {
|
||||||
|
print(" [");
|
||||||
|
print_u64_hex(id);
|
||||||
|
print("] Kind=");
|
||||||
|
print_u16_hex(@intFromEnum(e.kind));
|
||||||
|
print(" Fiber=");
|
||||||
|
print_u16_hex(@as(u16, @intCast(e.fiber_id)));
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
if (id == 0) break;
|
||||||
|
id -= 1;
|
||||||
|
}
|
||||||
|
} else if (std.mem.startsWith(u8, cmd_text, "stl graph") or std.mem.eql(u8, cmd_text, "stl tree")) {
|
||||||
|
var lineage: LineageResult = undefined;
|
||||||
|
const total = stl_count();
|
||||||
|
if (total == 0) {
|
||||||
|
print("[NexShell] No events to graph.\n");
|
||||||
|
} else {
|
||||||
|
// Default to last event
|
||||||
|
const last_id = @as(u64, total - 1);
|
||||||
|
stl_trace_lineage(last_id, &lineage);
|
||||||
|
print("[NexShell] Causal Graph for Event ");
|
||||||
|
print_u64_hex(last_id);
|
||||||
|
print(":\n\n");
|
||||||
|
|
||||||
|
var i: u32 = 0;
|
||||||
|
while (i < lineage.count) : (i += 1) {
|
||||||
|
const eid = lineage.event_ids[i];
|
||||||
|
const ev = stl_lookup(eid);
|
||||||
|
|
||||||
|
if (i > 0) print(" |\n ▼\n");
|
||||||
|
|
||||||
|
print("[");
|
||||||
|
print_u64_hex(eid);
|
||||||
|
print("] ");
|
||||||
|
|
||||||
|
if (ev) |e| {
|
||||||
|
switch (e.kind) {
|
||||||
|
.SystemBoot => print("SystemBoot"),
|
||||||
|
.FiberSpawn => print("FiberSpawn"),
|
||||||
|
.CapabilityGrant => print("CapGrant"),
|
||||||
|
.AccessDenied => print("AccessDenied"),
|
||||||
|
else => {
|
||||||
|
print("Kind=");
|
||||||
|
print_u16_hex(@intFromEnum(e.kind));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("???");
|
||||||
|
}
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
} else if (std.mem.eql(u8, cmd_text, "stl dump")) {
|
||||||
|
var dump_buf: [4096]u8 = undefined;
|
||||||
|
const written = stl_export_binary(&dump_buf, dump_buf.len);
|
||||||
|
if (written > 0) {
|
||||||
|
print("[NexShell] STL Binary Dump (");
|
||||||
|
print_u64_hex(written);
|
||||||
|
print(" bytes):\n");
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < written) : (i += 1) {
|
||||||
|
print_hex(dump_buf[i]);
|
||||||
|
if ((i + 1) % 32 == 0) print("\n");
|
||||||
|
}
|
||||||
|
print("\n[NexShell] Dump Complete.\n");
|
||||||
|
} else {
|
||||||
|
print("[NexShell] Dump Failed (Buffer too small or STL not ready)\n");
|
||||||
|
}
|
||||||
} else if (std.mem.eql(u8, cmd_text, "mem")) {
|
} else if (std.mem.eql(u8, cmd_text, "mem")) {
|
||||||
print("[NexShell] Memory Status:\n");
|
print("[NexShell] Memory Status:\n");
|
||||||
print(" Ion Pool: 32MB allocated\n");
|
print(" Ion Pool: 32MB allocated\n");
|
||||||
|
|
@ -247,6 +326,7 @@ fn process_command(cmd_text: []const u8, cmd_ring: *RingBuffer(CmdPacket)) void
|
||||||
} else if (std.mem.eql(u8, cmd_text, "help")) {
|
} else if (std.mem.eql(u8, cmd_text, "help")) {
|
||||||
print("[NexShell] Kernel Commands:\n");
|
print("[NexShell] Kernel Commands:\n");
|
||||||
print(" System: ps, fibers, mem, uptime, reboot, clear\n");
|
print(" System: ps, fibers, mem, uptime, reboot, clear\n");
|
||||||
|
print(" STL: stl summary, stl list, stl dump, stl graph\n");
|
||||||
print(" IO: io stop, ion stop\n");
|
print(" IO: io stop, ion stop\n");
|
||||||
print(" Matrix: matrix on/off/status\n");
|
print(" Matrix: matrix on/off/status\n");
|
||||||
print(" Shell: subject, nipbox, help\n");
|
print(" Shell: subject, nipbox, help\n");
|
||||||
|
|
@ -281,6 +361,81 @@ extern fn fiber_sleep(ms: u64) void;
|
||||||
extern fn fiber_yield() void;
|
extern fn fiber_yield() void;
|
||||||
extern fn debug_uart_lsr() u8;
|
extern fn debug_uart_lsr() u8;
|
||||||
|
|
||||||
|
// STL Externs
|
||||||
|
extern fn stl_count() u32;
|
||||||
|
extern fn stl_print_summary() void;
|
||||||
|
extern fn stl_get_recent(max_count: u32, result: *QueryResult) void;
|
||||||
|
extern fn stl_export_binary(dest: [*]u8, max_size: usize) usize;
|
||||||
|
extern fn stl_trace_lineage(event_id: u64, result: *LineageResult) void;
|
||||||
|
extern fn stl_lookup(event_id: u64) ?*const Event;
|
||||||
|
|
||||||
|
const LineageResult = extern struct {
|
||||||
|
count: u32,
|
||||||
|
event_ids: [16]u64,
|
||||||
|
};
|
||||||
|
|
||||||
|
const EventKind = enum(u16) {
|
||||||
|
Null = 0,
|
||||||
|
SystemBoot = 1,
|
||||||
|
SystemShutdown = 2,
|
||||||
|
FiberSpawn = 3,
|
||||||
|
FiberTerminate = 4,
|
||||||
|
CapabilityGrant = 10,
|
||||||
|
CapabilityRevoke = 11,
|
||||||
|
CapabilityDelegate = 12,
|
||||||
|
ChannelOpen = 20,
|
||||||
|
ChannelClose = 21,
|
||||||
|
ChannelRead = 22,
|
||||||
|
ChannelWrite = 23,
|
||||||
|
MemoryAllocate = 30,
|
||||||
|
MemoryFree = 31,
|
||||||
|
MemoryMap = 32,
|
||||||
|
NetworkPacketRx = 40,
|
||||||
|
NetworkPacketTx = 41,
|
||||||
|
AccessDenied = 50,
|
||||||
|
PolicyViolation = 51,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Event = packed struct {
|
||||||
|
kind: EventKind,
|
||||||
|
_reserved: u8 = 0,
|
||||||
|
timestamp_ns: u64,
|
||||||
|
fiber_id: u64,
|
||||||
|
entity_id: u64,
|
||||||
|
cause_id: u64,
|
||||||
|
data0: u64,
|
||||||
|
data1: u64,
|
||||||
|
data2: u64,
|
||||||
|
};
|
||||||
|
|
||||||
|
const QueryResult = extern struct {
|
||||||
|
count: u32,
|
||||||
|
events: [64]*const Event,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn print_u64_hex(val: u64) void {
|
||||||
|
const chars = "0123456789ABCDEF";
|
||||||
|
var buf: [16]u8 = undefined;
|
||||||
|
var v = val;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < 16) : (i += 1) {
|
||||||
|
buf[15 - i] = chars[v & 0xF];
|
||||||
|
v >>= 4;
|
||||||
|
}
|
||||||
|
print(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_u16_hex(val: u16) void {
|
||||||
|
const chars = "0123456789ABCDEF";
|
||||||
|
const buf = [4]u8{
|
||||||
|
chars[(val >> 12) & 0xF],
|
||||||
|
chars[(val >> 8) & 0xF],
|
||||||
|
chars[(val >> 4) & 0xF],
|
||||||
|
chars[val & 0xF],
|
||||||
|
};
|
||||||
|
print(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
fn print_hex(val: u8) void {
|
fn print_hex(val: u8) void {
|
||||||
const chars = "0123456789ABCDEF";
|
const chars = "0123456789ABCDEF";
|
||||||
const hi = chars[(val >> 4) & 0xF];
|
const hi = chars[(val >> 4) & 0xF];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue