tiny.tracy.FlightRecorder
Defined in flight.
API (22)
Actions
Public operations.
Fields and members
Public fields and members.
discarding_eventdropped_eventsevent_lenevent_storageheader_lenheader_seenobserved_eventsoversized_eventsoverwritten_eventspolicyring_eventsring_headring_lenstatestoragestored_eventswriter
Source
Source: lib/tracy/src/flight.zig:11
zig
pub const FlightRecorder = struct { writer: std.Io.Writer, storage: []u8, event_storage: []u8, policy: OverflowPolicy, state: State = .accepting, header_seen: bool = false, header_len: usize = 0, ring_head: usize = 0, ring_len: usize = 0, ring_events: usize = 0, event_len: usize = 0, discarding_event: bool = false, observed_events: u64 = 0, stored_events: u64 = 0, overwritten_events: u64 = 0, dropped_events: u64 = 0, oversized_events: u64 = 0, pub fn init( storage: []u8, event_storage: []u8, writer_storage: []u8, policy: OverflowPolicy, ) FlightRecorder { assert(storage.len > 0); assert(event_storage.len > 0); assert(writer_storage.len > 0); assert(disjoint(storage, event_storage)); assert(disjoint(storage, writer_storage)); assert(disjoint(event_storage, writer_storage)); var recorder: FlightRecorder = .{ .writer = .{ .vtable = &writer_vtable, .buffer = writer_storage }, .storage = storage, .event_storage = event_storage, .policy = policy, }; recorder.assertValid(); return recorder; } pub fn interface(self: *FlightRecorder) *std.Io.Writer { self.assertValid(); return &self.writer; } pub fn reset(self: *FlightRecorder) void { self.writer.flush() catch unreachable; self.state = .accepting; self.header_seen = false; self.header_len = 0; self.ring_head = 0; self.ring_len = 0; self.ring_events = 0; self.event_len = 0; self.discarding_event = false; self.observed_events = 0; self.stored_events = 0; self.overwritten_events = 0; self.dropped_events = 0; self.oversized_events = 0; self.assertValid(); } pub fn snapshot(self: *FlightRecorder, destination: *std.Io.Writer) !Report { if (destination == &self.writer) return error.InvalidSnapshotWriter; try self.writer.flush(); self.assertValid(); const result = self.report(); if (self.header_len > 0) { try destination.writeAll(self.storage[0..self.header_len]); } const ring = self.ringStorage(); if (self.ring_len > 0) { const first_len = @min(self.ring_len, ring.len - self.ring_head); try destination.writeAll(ring[self.ring_head..][0..first_len]); const second_len = self.ring_len - first_len; if (second_len > 0) try destination.writeAll(ring[0..second_len]); } try result.writeJsonl(destination); return result; } pub fn report(self: *FlightRecorder) Report { self.writer.flush() catch unreachable; self.assertValid(); const retained_header: usize = if (self.header_len > 0) 1 else 0; return .{ .policy = self.policy, .state = self.state, .capacity_bytes = self.storage.len, .retained_bytes = self.header_len + self.ring_len, .event_capacity_bytes = self.event_storage.len, .writer_capacity_bytes = self.writer.buffer.len, .observed_events = self.observed_events, .stored_events = self.stored_events, .retained_events = retained_header + self.ring_events, .overwritten_events = self.overwritten_events, .dropped_events = self.dropped_events, .oversized_events = self.oversized_events, .partial_event_bytes = self.event_len, .discarding_oversized_event = self.discarding_event, }; } fn accept(self: *FlightRecorder, bytes: []const u8) void { for (bytes) |byte| { if (self.discarding_event) { if (byte == '\n') { self.finishOversizedEvent(); } continue; } if (byte == '\n') { self.commitEvent(self.event_storage[0..self.event_len]); self.event_len = 0; } else if (self.event_len == self.event_storage.len) { self.event_len = 0; self.discarding_event = true; } else { self.event_storage[self.event_len] = byte; self.event_len += 1; } } self.assertValid(); } fn finishOversizedEvent(self: *FlightRecorder) void { self.observed_events +|= 1; self.oversized_events +|= 1; self.discarding_event = false; if (self.header_seen) return; self.header_seen = true; if (self.policy == .stop_when_full) self.state = .full; } fn commitEvent(self: *FlightRecorder, payload: []const u8) void { self.observed_events +|= 1; const required = std.math.add(usize, payload.len, 1) catch { self.oversized_events +|= 1; return; }; if (!self.header_seen) { self.header_seen = true; if (required > self.storage.len) { self.oversized_events +|= 1; if (self.policy == .stop_when_full) self.state = .full; return; } @memcpy(self.storage[0..payload.len], payload); self.storage[payload.len] = '\n'; self.header_len = required; self.stored_events +|= 1; return; } self.commitRingEvent(payload, required); } fn commitRingEvent(self: *FlightRecorder, payload: []const u8, required: usize) void { if (self.state == .full) { self.dropped_events +|= 1; return; } const ring = self.ringStorage(); if (required > ring.len) { self.oversized_events +|= 1; if (self.policy == .stop_when_full) self.state = .full; return; } if (self.policy == .stop_when_full and required > ring.len - self.ring_len) { self.state = .full; self.dropped_events +|= 1; return; } while (required > ring.len - self.ring_len) self.evictOldest(); self.appendRing(payload); self.stored_events +|= 1; self.ring_events += 1; } fn appendRing(self: *FlightRecorder, payload: []const u8) void { const ring = self.ringStorage(); assert(payload.len + 1 <= ring.len - self.ring_len); var tail = advance(self.ring_head, self.ring_len, ring.len); const first_len = @min(payload.len, ring.len - tail); @memcpy(ring[tail..][0..first_len], payload[0..first_len]); const second_len = payload.len - first_len; if (second_len > 0) @memcpy(ring[0..second_len], payload[first_len..]); self.ring_len += payload.len; tail = advance(self.ring_head, self.ring_len, ring.len); ring[tail] = '\n'; self.ring_len += 1; } fn evictOldest(self: *FlightRecorder) void { const ring = self.ringStorage(); assert(self.ring_len > 0); var event_bytes: usize = 1; while (event_bytes <= self.ring_len) : (event_bytes += 1) { const index = advance(self.ring_head, event_bytes - 1, ring.len); if (ring[index] == '\n') break; } assert(event_bytes <= self.ring_len); self.ring_head = advance(self.ring_head, event_bytes, ring.len); self.ring_len -= event_bytes; self.ring_events -= 1; self.overwritten_events +|= 1; if (self.ring_len == 0) self.ring_head = 0; } fn ringStorage(self: *FlightRecorder) []u8 { return self.storage[self.header_len..]; } fn assertValid(self: *FlightRecorder) void { assert(self.storage.len > 0); assert(self.event_storage.len > 0); assert(self.writer.buffer.len > 0); assert(self.header_len <= self.storage.len); assert(self.ring_len <= self.storage.len - self.header_len); assert(self.event_len <= self.event_storage.len); if (self.discarding_event) assert(self.event_len == 0); assert(self.ring_events <= self.ring_len); if (self.state == .full) assert(self.policy == .stop_when_full); if (self.ring_len == 0) { assert(self.ring_head == 0); } else { assert(self.ringStorage().len > 0); assert(self.ring_head < self.ringStorage().len); } const header_events: usize = if (self.header_len > 0) 1 else 0; if (std.math.cast(u64, header_events + self.ring_events)) |retained| { const accounted = std.math.add(u64, self.overwritten_events, retained) catch null; if (accounted) |count| { if (self.stored_events != std.math.maxInt(u64)) { assert(self.stored_events == count); } } } if (self.observed_events != std.math.maxInt(u64)) { const accepted = std.math.add(u64, self.stored_events, self.dropped_events) catch null; if (accepted) |count| { const accounted = std.math.add(u64, count, self.oversized_events) catch null; if (accounted) |total| assert(self.observed_events == total); } } } const writer_vtable: std.Io.Writer.VTable = .{ .drain = drain, .flush = std.Io.Writer.defaultFlush, .rebase = std.Io.Writer.defaultRebase, }; fn drain( writer: *std.Io.Writer, data: []const []const u8, splat: usize, ) std.Io.Writer.Error!usize { const self: *FlightRecorder = @alignCast(@fieldParentPtr("writer", writer)); assert(data.len > 0); self.accept(writer.buffer[0..writer.end]); writer.end = 0; var consumed: usize = 0; for (data[0 .. data.len - 1]) |bytes| { self.accept(bytes); consumed += bytes.len; } const last = data[data.len - 1]; for (0..splat) |_| { self.accept(last); consumed += last.len; } return consumed; }};Source: lib/tracy/src/root.zig:69
zig
pub const FlightRecorder = flight_mod.FlightRecorder;Complete caller list for FlightRecorder.init
8 direct callers.
lib.tracy.src.flight.test_enabled_tracy_runtime_records_through_the_flight_recorder[function] — test source atlib/tracy/src/flight.zig:460in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_drops_oversized_rows_without_corrupting_later_rows[function] — test source atlib/tracy/src/flight.zig:382in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_overwrite_is_visible_in_tracy_capture_integrity[function] — test source atlib/tracy/src/flight.zig:428in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_overwrite_window_matches_an_independent_suffix_model[function] — test source atlib/tracy/src/flight.zig:336in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_preserves_the_header_and_latest_complete_events[function] — test source atlib/tracy/src/flight.zig:320in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_report_is_machine_readable_and_resettable[function] — test source atlib/tracy/src/flight.zig:488in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_snapshots_analyzable_tracy_jsonl[function] — test source atlib/tracy/src/flight.zig:398in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_stop_policy_preserves_the_earliest_complete_window[function] — test source atlib/tracy/src/flight.zig:366in nearest public ownertiny.tracy.flight
Complete caller list for FlightRecorder.interface
8 direct callers.
lib.tracy.src.flight.test_enabled_tracy_runtime_records_through_the_flight_recorder[function] — test source atlib/tracy/src/flight.zig:460in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_drops_oversized_rows_without_corrupting_later_rows[function] — test source atlib/tracy/src/flight.zig:382in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_overwrite_is_visible_in_tracy_capture_integrity[function] — test source atlib/tracy/src/flight.zig:428in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_overwrite_window_matches_an_independent_suffix_model[function] — test source atlib/tracy/src/flight.zig:336in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_preserves_the_header_and_latest_complete_events[function] — test source atlib/tracy/src/flight.zig:320in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_report_is_machine_readable_and_resettable[function] — test source atlib/tracy/src/flight.zig:488in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_snapshots_analyzable_tracy_jsonl[function] — test source atlib/tracy/src/flight.zig:398in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_stop_policy_preserves_the_earliest_complete_window[function] — test source atlib/tracy/src/flight.zig:366in nearest public ownertiny.tracy.flight
Complete caller list for FlightRecorder.snapshot
7 direct callers.
lib.tracy.src.flight.test_enabled_tracy_runtime_records_through_the_flight_recorder[function] — test source atlib/tracy/src/flight.zig:460in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_drops_oversized_rows_without_corrupting_later_rows[function] — test source atlib/tracy/src/flight.zig:382in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_overwrite_is_visible_in_tracy_capture_integrity[function] — test source atlib/tracy/src/flight.zig:428in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_overwrite_window_matches_an_independent_suffix_model[function] — test source atlib/tracy/src/flight.zig:336in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_preserves_the_header_and_latest_complete_events[function] — test source atlib/tracy/src/flight.zig:320in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_snapshots_analyzable_tracy_jsonl[function] — test source atlib/tracy/src/flight.zig:398in nearest public ownertiny.tracy.flightlib.tracy.src.flight.test_flight_recorder_stop_policy_preserves_the_earliest_complete_window[function] — test source atlib/tracy/src/flight.zig:366in nearest public ownertiny.tracy.flight
Audit
| Definitions | 6 |
|---|---|
| Public names | 12 |
| Members | 17 |
| Version | 26.7.0 |
| Revision | daab053ee433 |