Skip to documentation
SLOP

tiny.trace.Session

Reference tiny.trace Session

Defined in session.

API (26)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callssessionSession
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/trace/src/session.zig:17

zig
pub const Session = struct {    allocator: Allocator,    mode: event.Mode,    sink: ?event.Sink = null,    source: ?event.Source = null,    epoch: u64 = 0,    next_seq: u64 = 1,    sequence_exhausted: bool = false,    replay_cursor: u64 = 0,    last_checkpoint: ?event.Event = null,    pub fn initOff(allocator: Allocator) Session {        return .{ .allocator = allocator, .mode = .off };    }    pub fn initRecord(allocator: Allocator, sink: event.Sink) Session {        return .{ .allocator = allocator, .mode = .record, .sink = sink };    }    pub fn initReplay(allocator: Allocator, source: event.Source) Session {        return .{ .allocator = allocator, .mode = .replay, .source = source };    }    pub fn deinit(self: *Session) void {        if (self.last_checkpoint) |*item| item.deinit(self.allocator);        self.* = undefined;    }    pub fn replayProgress(self: *const Session) ReplayProgress {        const event_count = if (self.source) |source| source.count() else 0;        std.debug.assert(self.replay_cursor <= event_count);        return .{            .cursor = self.replay_cursor,            .event_count = event_count,            .remaining_count = event_count - self.replay_cursor,        };    }    pub fn sessionStart(        self: *Session,        thread_id: event.ThreadId,        label: []const u8,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.sessionStart(timepoint, label));    }    pub fn sessionEnd(        self: *Session,        thread_id: event.ThreadId,        status: i64,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.sessionEnd(timepoint, status));    }    pub fn functionEnter(        self: *Session,        thread_id: event.ThreadId,        site: event.Safepoint,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.functionEnter(timepoint, site));    }    pub fn functionExit(        self: *Session,        thread_id: event.ThreadId,        site: event.Safepoint,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.functionExit(timepoint, site));    }    pub fn safepoint(        self: *Session,        thread_id: event.ThreadId,        site: event.Safepoint,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.safepointReached(timepoint, site));    }    pub fn allocation(        self: *Session,        thread_id: event.ThreadId,        object_id: u64,        size: u64,        alignment: u32,        label: ?[]const u8,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.allocation(            timepoint,            object_id,            size,            alignment,            label,        ));    }    pub fn free(        self: *Session,        thread_id: event.ThreadId,        object_id: u64,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.free(timepoint, object_id));    }    pub fn boundaryBytesAlloc(        self: *Session,        thread_id: event.ThreadId,        operation: []const u8,        recorded_value: ?[]const u8,    ) ![]u8 {        const timepoint = try self.prepareTimepoint(thread_id);        switch (self.mode) {            .off => {                const source_value = recorded_value orelse return error.MissingBoundaryValue;                const value = try self.allocator.dupe(u8, source_value);                self.commitTimepoint(timepoint);                return value;            },            .record => {                const value = recorded_value orelse return error.MissingBoundaryValue;                const owned = try self.allocator.dupe(u8, value);                errdefer self.allocator.free(owned);                try self.sink.?.append(event.Event.boundaryBytes(timepoint, operation, value));                self.commitTimepoint(timepoint);                return owned;            },            .replay => {                const source = self.source.?;                const actual = (try source.peek()) orelse return error.MissingReplayEvent;                const recorded = actual.data orelse return error.ReplayEventMismatch;                const expected = event.Event.boundaryBytes(timepoint, operation, recorded);                if (!expected.eqlForReplay(actual.*)) return error.ReplayEventMismatch;                const next_replay_cursor = try self.prepareReplayCursor();                const value = try self.allocator.dupe(u8, recorded);                source.advance();                self.replay_cursor = next_replay_cursor;                self.commitTimepoint(timepoint);                return value;            },        }    }    pub fn checkpointCapture(        self: *Session,        thread_id: event.ThreadId,        label: []const u8,        provider: checkpoint.Provider,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        const bytes = try provider.captureAlloc(self.allocator);        defer self.allocator.free(bytes);        return try self.handleEvent(event.Event.checkpoint(timepoint, label, bytes));    }    pub fn checkpointRestore(        self: *Session,        thread_id: event.ThreadId,        label: []const u8,        provider: checkpoint.Provider,    ) !event.Timepoint {        const checkpoint_event = self.last_checkpoint orelse return error.MissingCheckpoint;        const checkpoint_bytes = checkpoint_event.data orelse return error.MissingCheckpoint;        const timepoint = try self.prepareTimepoint(thread_id);        const expected = event.Event.checkpointRestore(timepoint, label);        const prepared_replay = if (self.mode == .replay)            try self.prepareReplay(expected)        else            null;        const replay_timepoint = if (prepared_replay) |prepared|            prepared.actual.timepoint        else            timepoint;        provider.prepareRestoreBytes(checkpoint_bytes) catch |err| {            provider.cancelRestore();            return err;        };        errdefer provider.cancelRestore();        if (self.mode == .record) try self.sink.?.append(expected);        provider.commitRestore();        if (prepared_replay) |prepared| self.commitReplay(prepared);        self.commitTimepoint(timepoint);        return replay_timepoint;    }    pub fn userEvent(        self: *Session,        thread_id: event.ThreadId,        label: []const u8,        bytes: []const u8,    ) !event.Timepoint {        const timepoint = try self.prepareTimepoint(thread_id);        return try self.handleEvent(event.Event.user(timepoint, label, bytes));    }    pub fn verifyReplayComplete(self: *Session) !void {        if (self.mode != .replay) return;        const source = self.source.?;        if (self.replay_cursor != source.count()) return error.ReplayNotComplete;        if (try source.peek() != null) return error.ReplayNotComplete;    }    fn prepareTimepoint(self: *const Session, thread_id: event.ThreadId) !event.Timepoint {        if (self.sequence_exhausted) return error.SequenceExhausted;        return event.Timepoint{            .epoch = self.epoch,            .thread_id = thread_id,            .seq = self.next_seq,        };    }    fn commitTimepoint(self: *Session, timepoint: event.Timepoint) void {        std.debug.assert(!self.sequence_exhausted);        std.debug.assert(timepoint.epoch == self.epoch);        std.debug.assert(timepoint.seq == self.next_seq);        if (self.next_seq == std.math.maxInt(u64)) {            self.sequence_exhausted = true;        } else {            self.next_seq += 1;        }    }    fn handleEvent(self: *Session, expected: event.Event) !event.Timepoint {        var owned_checkpoint: ?event.Event = null;        errdefer if (owned_checkpoint) |*owned| owned.deinit(self.allocator);        var replay_timepoint: ?event.Timepoint = null;        switch (self.mode) {            .off => {                if (expected.kind == .checkpoint) {                    owned_checkpoint = try expected.cloneAlloc(self.allocator);                }            },            .record => {                if (expected.kind == .checkpoint) {                    owned_checkpoint = try expected.cloneAlloc(self.allocator);                }                try self.sink.?.append(expected);            },            .replay => {                const prepared = try self.prepareReplay(expected);                replay_timepoint = prepared.actual.timepoint;                if (prepared.actual.kind == .checkpoint) {                    owned_checkpoint = try prepared.actual.cloneAlloc(self.allocator);                }                self.commitReplay(prepared);            },        }        self.commitTimepoint(expected.timepoint);        if (owned_checkpoint) |owned| {            self.replaceCheckpoint(owned);            owned_checkpoint = null;        }        return replay_timepoint orelse expected.timepoint;    }    const PreparedReplay = struct {        source: event.Source,        actual: *const event.Event,        next_cursor: u64,    };    fn prepareReplay(self: *Session, expected: event.Event) !PreparedReplay {        const source = self.source.?;        const actual = (try source.peek()) orelse return error.MissingReplayEvent;        if (!expected.eqlForReplay(actual.*)) return error.ReplayEventMismatch;        return .{            .source = source,            .actual = actual,            .next_cursor = try self.prepareReplayCursor(),        };    }    fn prepareReplayCursor(self: *const Session) !u64 {        return std.math.add(u64, self.replay_cursor, 1) catch            return error.ReplayCursorExhausted;    }    fn commitReplay(self: *Session, prepared: PreparedReplay) void {        prepared.source.advance();        self.replay_cursor = prepared.next_cursor;    }    fn replaceCheckpoint(self: *Session, owned: event.Event) void {        if (self.last_checkpoint) |*previous| previous.deinit(self.allocator);        self.last_checkpoint = owned;    }};

Source: lib/trace/src/root.zig:52

zig
pub const Session = session.Session;
Called byCallsNo direct callersEventallocationprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionallocation
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventboundaryBytesprivate sourcelib.trace.src.session.SessioncommitTimepointprivate sourcelib.trace.src.session.SessionprepareReplayCursorprivate sourcelib.trace.src.session.SessionprepareTimepointSessionboundaryBytesAlloc
Static calls · unresolved targets: 2 · external targets: 3.
Called byCallsNo direct callersEventcheckpointprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessioncheckpointCapture
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callersEventcheckpointRestoreprivate sourcelib.trace.src.session.SessioncommitReplayprivate sourcelib.trace.src.session.SessioncommitTimepointprivate sourcelib.trace.src.session.SessionprepareReplayprivate sourcelib.trace.src.session.SessionprepareTimepointSessioncheckpointRestore
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersEventfreeprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionfree
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventfunctionEnterprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionfunctionEnter
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventfunctionExitprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionfunctionExit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.trace.src.sessiontest: checkpoint provider owns commit...test sourcelib.trace.src.sessiontest: session failure atomicity requi...test sourcelib.trace.src.sessiontest: session sequence capacity admit...SessioninitOff
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.trace.src.properties.session.RecordFailur...propertytest sourcelib.trace.src.sessiontest: recording streams events withou...test sourcelib.trace.src.sessiontest: session failure atomicity alloc...test sourcelib.trace.src.sessiontest: session failure atomicity cance...test sourcelib.trace.src.sessiontest: session failure atomicity retri...test sourcelib.trace.src.testtest: record and replay sessions stre...SessioninitRecord
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.trace.src.properties.session.ReplayFailur...propertytest sourcelib.trace.src.sessiontest: boundary replay copies borrowed...test sourcelib.trace.src.sessiontest: replay mismatch leaves the sess...test sourcelib.trace.src.sessiontest: replay validates a borrowed str...test sourcelib.trace.src.sessiontest: session failure atomicity prese...+5 moreSessioninitReplay
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventsafepointReachedprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionsafepoint
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventsessionEndprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionsessionEnd
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventsessionStartprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionsessionStart
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersEventuserprivate sourcelib.trace.src.session.SessionhandleEventprivate sourcelib.trace.src.session.SessionprepareTimepointSessionuserEvent
Static calls · unresolved targets: 0 · external targets: 0.

Complete caller list for Session.initReplay

10 direct callers.

Audit

Definitions18
Public names36
Members9
Version26.7.0
Revisiondaab053ee433