| ... | ... | @@ -44,6 +44,14 @@ const timestampFromPosix = Io.Threaded.timestampFromPosix; |
| 44 | 44 | const unexpectedErrno = std.posix.unexpectedErrno; |
| 45 | 45 | const winsize = std.posix.winsize; |
| 46 | 46 | |
| 47 | const tracy = if (@hasDecl(@import("root"), "tracy")) @import("root").tracy else struct { |
| 48 | const enable = false; |
| 49 | inline fn fiberEnter(fiber: [*:0]const u8) void { |
| 50 | _ = fiber; |
| 51 | } |
| 52 | inline fn fiberLeave() void {} |
| 53 | }; |
| 54 | |
| 47 | 55 | backing_allocator_needs_mutex: bool, |
| 48 | 56 | backing_allocator_mutex: Io.Mutex, |
| 49 | 57 | /// Does not need to be thread-safe if not used elsewhere. |
| ... | ... | @@ -90,6 +98,7 @@ const Thread = struct { |
| 90 | 98 | io_uring: IoUring, |
| 91 | 99 | idle_search_index: u32, |
| 92 | 100 | steal_ready_search_index: u32, |
| 101 | name_arena: if (tracy.enable) std.heap.ArenaAllocator.State else struct {}, |
| 93 | 102 | csprng: Csprng, |
| 94 | 103 | |
| 95 | 104 | threadlocal var self: ?*Thread = null; |
| ... | ... | @@ -138,6 +147,9 @@ const Fiber = struct { |
| 138 | 147 | }, |
| 139 | 148 | cancel_status: CancelStatus, |
| 140 | 149 | cancel_protection: CancelProtection, |
| 150 | name: if (tracy.enable) [*:0]const u8 else void, |
| 151 | |
| 152 | var next_name: u64 = 0; |
| 141 | 153 | |
| 142 | 154 | const CancelStatus = packed struct(u32) { |
| 143 | 155 | requested: bool, |
| ... | ... | @@ -772,6 +784,7 @@ pub fn init(ev: *Evented, backing_allocator: Allocator, options: InitOptions) !v |
| 772 | 784 | .status = .{ .queue_next = null }, |
| 773 | 785 | .cancel_status = .unrequested, |
| 774 | 786 | .cancel_protection = .unblocked, |
| 787 | .name = if (tracy.enable) "main task", |
| 775 | 788 | }; |
| 776 | 789 | const main_thread = &ev.threads.allocated[0]; |
| 777 | 790 | Thread.self = main_thread; |
| ... | ... | @@ -802,11 +815,13 @@ pub fn init(ev: *Evented, backing_allocator: Allocator, options: InitOptions) !v |
| 802 | 815 | ), |
| 803 | 816 | .idle_search_index = 1, |
| 804 | 817 | .steal_ready_search_index = 1, |
| 818 | .name_arena = .{}, |
| 805 | 819 | .csprng = .uninitialized, |
| 806 | 820 | }; |
| 807 | 821 | errdefer main_thread.io_uring.deinit(); |
| 808 | 822 | log.debug("created main idle {*}", .{&main_thread.idle_context}); |
| 809 | 823 | log.debug("created main {*}", .{main_fiber}); |
| 824 | if (tracy.enable) tracy.fiberEnter(main_fiber.name); |
| 810 | 825 | } |
| 811 | 826 | |
| 812 | 827 | pub fn deinit(ev: *Evented) void { |
| ... | ... | @@ -958,6 +973,7 @@ fn schedule(ev: *Evented, thread: *Thread, ready_queue: Fiber.Queue) bool { |
| 958 | 973 | }, |
| 959 | 974 | .idle_search_index = 0, |
| 960 | 975 | .steal_ready_search_index = 0, |
| 976 | .name_arena = .{}, |
| 961 | 977 | .csprng = .uninitialized, |
| 962 | 978 | }; |
| 963 | 979 | new_thread.thread = std.Thread.spawn(.{ |
| ... | ... | @@ -1160,6 +1176,12 @@ const SwitchMessage = struct { |
| 1160 | 1176 | fn handle(message: *const SwitchMessage, ev: *Evented) void { |
| 1161 | 1177 | const thread: *Thread = .current(); |
| 1162 | 1178 | thread.current_context = message.contexts.ready; |
| 1179 | if (tracy.enable) { |
| 1180 | if (message.contexts.ready != &thread.idle_context) { |
| 1181 | const fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.ready)); |
| 1182 | tracy.fiberEnter(fiber.name); |
| 1183 | } else tracy.fiberLeave(); |
| 1184 | } |
| 1163 | 1185 | switch (message.pending_task) { |
| 1164 | 1186 | .nothing => {}, |
| 1165 | 1187 | .reschedule => if (message.contexts.prev != &thread.idle_context) { |
| ... | ... | @@ -1543,6 +1565,17 @@ fn concurrent( |
| 1543 | 1565 | .status = .{ .queue_next = null }, |
| 1544 | 1566 | .cancel_status = .unrequested, |
| 1545 | 1567 | .cancel_protection = .unblocked, |
| 1568 | .name = if (tracy.enable) name: { |
| 1569 | const thread: *Thread = .current(); |
| 1570 | var name_arena = thread.name_arena.promote(std.heap.page_allocator); |
| 1571 | defer thread.name_arena = name_arena.state; |
| 1572 | break :name std.fmt.allocPrintSentinel( |
| 1573 | name_arena.allocator(), |
| 1574 | "task {d}", |
| 1575 | .{@atomicRmw(u64, &Fiber.next_name, .Add, 1, .monotonic)}, |
| 1576 | 0, |
| 1577 | ) catch return error.ConcurrencyUnavailable; |
| 1578 | }, |
| 1546 | 1579 | }; |
| 1547 | 1580 | closure.* = .{ |
| 1548 | 1581 | .ev = ev, |
| ... | ... | @@ -1920,6 +1953,17 @@ fn groupConcurrent( |
| 1920 | 1953 | .status = .{ .queue_next = null }, |
| 1921 | 1954 | .cancel_status = .unrequested, |
| 1922 | 1955 | .cancel_protection = .unblocked, |
| 1956 | .name = if (tracy.enable) name: { |
| 1957 | const thread: *Thread = .current(); |
| 1958 | var name_arena = thread.name_arena.promote(std.heap.page_allocator); |
| 1959 | defer thread.name_arena = name_arena.state; |
| 1960 | break :name std.fmt.allocPrintSentinel( |
| 1961 | name_arena.allocator(), |
| 1962 | "group task {d}", |
| 1963 | .{@atomicRmw(u64, &Fiber.next_name, .Add, 1, .monotonic)}, |
| 1964 | 0, |
| 1965 | ) catch return error.ConcurrencyUnavailable; |
| 1966 | }, |
| 1923 | 1967 | }; |
| 1924 | 1968 | closure.* = .{ |
| 1925 | 1969 | .ev = ev, |