zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 7e8ee985e20f34ba6afb815a7cded443aca297d3 (tree)
parent f2cbc1912b9c58c2a20b9f32fb60b7793f5e4820
Author: Jacob Young <jacobly0@users.noreply.github.com>
Date:   Tue, 13 Jan 2026 19:10:45 -0500

tracy: add fiber integration

Diffstat:
Mbuild.zig | 14++++++++++++--
Mlib/std/Io/IoUring.zig | 44++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.zig | 2+-
Msrc/tracy.zig | 12++++++++++++
4 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/build.zig b/build.zig @@ -370,10 +370,20 @@ pub fn build(b: *std.Build) !void { &[_][]const u8{ tracy_path, "public", "TracyClient.cpp" }, ); - const tracy_c_flags: []const []const u8 = &.{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" }; + const tracy_c_flags: []const []const u8 = &.{ + "-DTRACY_ENABLE=1", + "-fno-sanitize=undefined", + "-DTRACY_FIBERS", + }; exe.root_module.addIncludePath(.{ .cwd_relative = tracy_path }); - exe.root_module.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags }); + exe.root_module.addCSourceFile(.{ + .file = .{ .cwd_relative = client_cpp }, + .flags = tracy_c_flags[0..switch (io_mode) { + .threaded => 2, + .evented => 3, + }], + }); exe.root_module.link_libc = true; exe.root_module.link_libcpp = true; diff --git a/lib/std/Io/IoUring.zig b/lib/std/Io/IoUring.zig @@ -44,6 +44,14 @@ const timestampFromPosix = Io.Threaded.timestampFromPosix; const unexpectedErrno = std.posix.unexpectedErrno; const winsize = std.posix.winsize; +const tracy = if (@hasDecl(@import("root"), "tracy")) @import("root").tracy else struct { + const enable = false; + inline fn fiberEnter(fiber: [*:0]const u8) void { + _ = fiber; + } + inline fn fiberLeave() void {} +}; + backing_allocator_needs_mutex: bool, backing_allocator_mutex: Io.Mutex, /// Does not need to be thread-safe if not used elsewhere. @@ -90,6 +98,7 @@ const Thread = struct { io_uring: IoUring, idle_search_index: u32, steal_ready_search_index: u32, + name_arena: if (tracy.enable) std.heap.ArenaAllocator.State else struct {}, csprng: Csprng, threadlocal var self: ?*Thread = null; @@ -138,6 +147,9 @@ const Fiber = struct { }, cancel_status: CancelStatus, cancel_protection: CancelProtection, + name: if (tracy.enable) [*:0]const u8 else void, + + var next_name: u64 = 0; const CancelStatus = packed struct(u32) { requested: bool, @@ -772,6 +784,7 @@ pub fn init(ev: *Evented, backing_allocator: Allocator, options: InitOptions) !v .status = .{ .queue_next = null }, .cancel_status = .unrequested, .cancel_protection = .unblocked, + .name = if (tracy.enable) "main task", }; const main_thread = &ev.threads.allocated[0]; Thread.self = main_thread; @@ -802,11 +815,13 @@ pub fn init(ev: *Evented, backing_allocator: Allocator, options: InitOptions) !v ), .idle_search_index = 1, .steal_ready_search_index = 1, + .name_arena = .{}, .csprng = .uninitialized, }; errdefer main_thread.io_uring.deinit(); log.debug("created main idle {*}", .{&main_thread.idle_context}); log.debug("created main {*}", .{main_fiber}); + if (tracy.enable) tracy.fiberEnter(main_fiber.name); } pub fn deinit(ev: *Evented) void { @@ -958,6 +973,7 @@ fn schedule(ev: *Evented, thread: *Thread, ready_queue: Fiber.Queue) bool { }, .idle_search_index = 0, .steal_ready_search_index = 0, + .name_arena = .{}, .csprng = .uninitialized, }; new_thread.thread = std.Thread.spawn(.{ @@ -1160,6 +1176,12 @@ const SwitchMessage = struct { fn handle(message: *const SwitchMessage, ev: *Evented) void { const thread: *Thread = .current(); thread.current_context = message.contexts.ready; + if (tracy.enable) { + if (message.contexts.ready != &thread.idle_context) { + const fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.ready)); + tracy.fiberEnter(fiber.name); + } else tracy.fiberLeave(); + } switch (message.pending_task) { .nothing => {}, .reschedule => if (message.contexts.prev != &thread.idle_context) { @@ -1543,6 +1565,17 @@ fn concurrent( .status = .{ .queue_next = null }, .cancel_status = .unrequested, .cancel_protection = .unblocked, + .name = if (tracy.enable) name: { + const thread: *Thread = .current(); + var name_arena = thread.name_arena.promote(std.heap.page_allocator); + defer thread.name_arena = name_arena.state; + break :name std.fmt.allocPrintSentinel( + name_arena.allocator(), + "task {d}", + .{@atomicRmw(u64, &Fiber.next_name, .Add, 1, .monotonic)}, + 0, + ) catch return error.ConcurrencyUnavailable; + }, }; closure.* = .{ .ev = ev, @@ -1920,6 +1953,17 @@ fn groupConcurrent( .status = .{ .queue_next = null }, .cancel_status = .unrequested, .cancel_protection = .unblocked, + .name = if (tracy.enable) name: { + const thread: *Thread = .current(); + var name_arena = thread.name_arena.promote(std.heap.page_allocator); + defer thread.name_arena = name_arena.state; + break :name std.fmt.allocPrintSentinel( + name_arena.allocator(), + "group task {d}", + .{@atomicRmw(u64, &Fiber.next_name, .Add, 1, .monotonic)}, + 0, + ) catch return error.ConcurrencyUnavailable; + }, }; closure.* = .{ .ev = ev, diff --git a/src/main.zig b/src/main.zig @@ -21,7 +21,7 @@ const AstGen = std.zig.AstGen; const ZonGen = std.zig.ZonGen; const Server = std.zig.Server; -const tracy = @import("tracy.zig"); +pub const tracy = @import("tracy.zig"); const Compilation = @import("Compilation.zig"); const link = @import("link.zig"); const Package = @import("Package.zig"); diff --git a/src/tracy.zig b/src/tracy.zig @@ -98,6 +98,16 @@ pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name } } +pub inline fn fiberEnter(fiber: [*:0]const u8) void { + if (!enable) return; + ___tracy_fiber_enter(fiber); +} + +pub inline fn fiberLeave() void { + if (!enable) return; + ___tracy_fiber_leave(); +} + pub fn tracyAllocator(allocator: std.mem.Allocator) TracyAllocator(null) { return TracyAllocator(null).init(allocator); } @@ -318,6 +328,8 @@ extern fn ___tracy_emit_memory_free_callstack_named(ptr: *const anyopaque, depth extern fn ___tracy_emit_logString(severity: MessageSeverity, color: i32, callstack_depth: i32, size: usize, txt: [*]const u8) void; extern fn ___tracy_emit_logStringL(severity: MessageSeverity, color: i32, callstack_depth: i32, txt: [*:0]const u8) void; extern fn ___tracy_emit_frame_mark(name: ?[*:0]const u8) void; +extern fn ___tracy_fiber_enter(fiber: [*:0]const u8) void; +extern fn ___tracy_fiber_leave() void; const ___tracy_source_location_data = extern struct { name: ?[*:0]const u8,