diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-05-24 08:22:47 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-05-27 20:56:48 -0700 |
| commit | f97c2f28fdc3061bc7e30ccfcafaccbee77993b6 (patch) | |
| tree | a2c4165829d84b35df23346b1808a43e0cccec41 | |
| parent | f6873c6b00544923d5699737651f2bc4fe29fd06 (diff) | |
| download | zig-f97c2f28fdc3061bc7e30ccfcafaccbee77993b6.tar.gz zig-f97c2f28fdc3061bc7e30ccfcafaccbee77993b6.zip | |
update the codebase for the new std.Progress API
49 files changed, 226 insertions, 355 deletions
diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index f894403648..8f80e4393d 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -528,7 +528,7 @@ const MsgWriter = struct { config: std.io.tty.Config, fn init(config: std.io.tty.Config) MsgWriter { - std.debug.getStderrMutex().lock(); + std.debug.lockStdErr(); return .{ .w = std.io.bufferedWriter(std.io.getStdErr().writer()), .config = config, @@ -537,7 +537,7 @@ const MsgWriter = struct { pub fn deinit(m: *MsgWriter) void { m.w.flush() catch {}; - std.debug.getStderrMutex().unlock(); + std.debug.unlockStdErr(); } pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void { diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 35dcbb882b..d4c96fe08b 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -289,8 +289,7 @@ pub fn main() !void { .windows_api => {}, } - var progress: std.Progress = .{ .dont_print_on_dumb = true }; - const main_progress_node = progress.start("", 0); + const main_progress_node = std.Progress.start(.{}); builder.debug_log_scopes = debug_log_scopes.items; builder.resolveInstallPrefix(install_prefix, dir_list); @@ -385,7 +384,7 @@ fn runStepNames( arena: std.mem.Allocator, b: *std.Build, step_names: []const []const u8, - parent_prog_node: *std.Progress.Node, + parent_prog_node: std.Progress.Node, thread_pool_options: std.Thread.Pool.Options, run: *Run, seed: u32, @@ -452,7 +451,7 @@ fn runStepNames( { defer parent_prog_node.end(); - var step_prog = parent_prog_node.start("steps", step_stack.count()); + const step_prog = parent_prog_node.start("steps", step_stack.count()); defer step_prog.end(); var wait_group: std.Thread.WaitGroup = .{}; @@ -467,7 +466,7 @@ fn runStepNames( if (step.state == .skipped_oom) continue; thread_pool.spawnWg(&wait_group, workerMakeOneStep, .{ - &wait_group, &thread_pool, b, step, &step_prog, run, + &wait_group, &thread_pool, b, step, step_prog, run, }); } } @@ -891,7 +890,7 @@ fn workerMakeOneStep( thread_pool: *std.Thread.Pool, b: *std.Build, s: *Step, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, run: *Run, ) void { // First, check the conditions for running this step. If they are not met, @@ -941,11 +940,10 @@ fn workerMakeOneStep( } } - var sub_prog_node = prog_node.start(s.name, 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start(s.name, 0); defer sub_prog_node.end(); - const make_result = s.make(&sub_prog_node); + const make_result = s.make(sub_prog_node); // No matter the result, we want to display error/warning messages. const show_compile_errors = !run.prominent_compile_errors and @@ -954,8 +952,8 @@ fn workerMakeOneStep( const show_stderr = s.result_stderr.len > 0; if (show_error_msgs or show_compile_errors or show_stderr) { - sub_prog_node.context.lock_stderr(); - defer sub_prog_node.context.unlock_stderr(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); printErrorMessages(b, s, run) catch {}; } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index a2e8a7c564..4443fa404c 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1059,7 +1059,7 @@ pub fn getUninstallStep(b: *Build) *Step { return &b.uninstall_tls.step; } -fn makeUninstall(uninstall_step: *Step, prog_node: *std.Progress.Node) anyerror!void { +fn makeUninstall(uninstall_step: *Step, prog_node: std.Progress.Node) anyerror!void { _ = prog_node; const uninstall_tls: *TopLevelStep = @fieldParentPtr("step", uninstall_step); const b: *Build = @fieldParentPtr("uninstall_tls", uninstall_tls); @@ -2281,10 +2281,10 @@ pub const LazyPath = union(enum) { .cwd_relative => |p| return src_builder.pathFromCwd(p), .generated => |gen| { var file_path: []const u8 = gen.file.step.owner.pathFromRoot(gen.file.path orelse { - std.debug.getStderrMutex().lock(); + std.debug.lockStdErr(); const stderr = std.io.getStdErr(); dumpBadGetPathHelp(gen.file.step, stderr, src_builder, asking_step) catch {}; - std.debug.getStderrMutex().unlock(); + std.debug.unlockStdErr(); @panic("misconfigured build script"); }); @@ -2351,8 +2351,8 @@ fn dumpBadDirnameHelp( comptime msg: []const u8, args: anytype, ) anyerror!void { - debug.getStderrMutex().lock(); - defer debug.getStderrMutex().unlock(); + debug.lockStdErr(); + defer debug.unlockStdErr(); const stderr = io.getStdErr(); const w = stderr.writer(); diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 01bea6c0ce..a965735843 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -58,7 +58,7 @@ pub const TestResults = struct { } }; -pub const MakeFn = *const fn (step: *Step, prog_node: *std.Progress.Node) anyerror!void; +pub const MakeFn = *const fn (step: *Step, prog_node: std.Progress.Node) anyerror!void; pub const State = enum { precheck_unstarted, @@ -176,7 +176,7 @@ pub fn init(options: StepOptions) Step { /// If the Step's `make` function reports `error.MakeFailed`, it indicates they /// have already reported the error. Otherwise, we add a simple error report /// here. -pub fn make(s: *Step, prog_node: *std.Progress.Node) error{ MakeFailed, MakeSkipped }!void { +pub fn make(s: *Step, prog_node: std.Progress.Node) error{ MakeFailed, MakeSkipped }!void { const arena = s.owner.allocator; s.makeFn(s, prog_node) catch |err| switch (err) { @@ -217,7 +217,7 @@ pub fn getStackTrace(s: *Step) ?std.builtin.StackTrace { }; } -fn makeNoOp(step: *Step, prog_node: *std.Progress.Node) anyerror!void { +fn makeNoOp(step: *Step, prog_node: std.Progress.Node) anyerror!void { _ = prog_node; var all_cached = true; @@ -303,7 +303,7 @@ pub fn addError(step: *Step, comptime fmt: []const u8, args: anytype) error{OutO pub fn evalZigProcess( s: *Step, argv: []const []const u8, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !?[]const u8 { assert(argv.len != 0); const b = s.owner; @@ -313,12 +313,16 @@ pub fn evalZigProcess( try handleChildProcUnsupported(s, null, argv); try handleVerbose(s.owner, null, argv); + const sub_prog_node = prog_node.start("", 0); + defer sub_prog_node.end(); + var child = std.process.Child.init(argv, arena); child.env_map = &b.graph.env_map; child.stdin_behavior = .Pipe; child.stdout_behavior = .Pipe; child.stderr_behavior = .Pipe; child.request_resource_usage_statistics = true; + child.progress_node = sub_prog_node; child.spawn() catch |err| return s.fail("unable to spawn {s}: {s}", .{ argv[0], @errorName(err), @@ -337,11 +341,6 @@ pub fn evalZigProcess( const Header = std.zig.Server.Message.Header; var result: ?[]const u8 = null; - var node_name: std.ArrayListUnmanaged(u8) = .{}; - defer node_name.deinit(gpa); - var sub_prog_node = prog_node.start("", 0); - defer sub_prog_node.end(); - const stdout = poller.fifo(.stdout); poll: while (true) { @@ -379,11 +378,6 @@ pub fn evalZigProcess( .extra = extra_array, }; }, - .progress => { - node_name.clearRetainingCapacity(); - try node_name.appendSlice(gpa, body); - sub_prog_node.setName(node_name.items); - }, .emit_bin_path => { const EbpHdr = std.zig.Server.Message.EmitBinPath; const ebp_hdr = @as(*align(1) const EbpHdr, @ptrCast(body)); diff --git a/lib/std/Build/Step/CheckFile.zig b/lib/std/Build/Step/CheckFile.zig index b3323f9e98..b7ce2ded61 100644 --- a/lib/std/Build/Step/CheckFile.zig +++ b/lib/std/Build/Step/CheckFile.zig @@ -46,7 +46,7 @@ pub fn setName(check_file: *CheckFile, name: []const u8) void { check_file.step.name = name; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const check_file: *CheckFile = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index fa0ccc339d..84c9c62abb 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -550,7 +550,7 @@ pub fn checkComputeCompare( check_object.checks.append(check) catch @panic("OOM"); } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const gpa = b.allocator; diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index f660ef64a6..e27dd65619 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -967,7 +967,7 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking const maybe_path: ?*GeneratedFile = @field(compile, tag_name); const generated_file = maybe_path orelse { - std.debug.getStderrMutex().lock(); + std.debug.lockStdErr(); const stderr = std.io.getStdErr(); std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {}; @@ -976,7 +976,7 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking }; const path = generated_file.path orelse { - std.debug.getStderrMutex().lock(); + std.debug.lockStdErr(); const stderr = std.io.getStdErr(); std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {}; @@ -987,7 +987,7 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking return path; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const arena = b.allocator; const compile: *Compile = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 4a0e64e8d0..212ea605ed 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -164,7 +164,7 @@ fn putValue(config_header: *ConfigHeader, field_name: []const u8, comptime T: ty } } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const config_header: *ConfigHeader = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/Fmt.zig b/lib/std/Build/Step/Fmt.zig index 3010d701b1..f346c6cc39 100644 --- a/lib/std/Build/Step/Fmt.zig +++ b/lib/std/Build/Step/Fmt.zig @@ -36,7 +36,7 @@ pub fn create(owner: *std.Build, options: Options) *Fmt { return fmt; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { // zig fmt is fast enough that no progress is needed. _ = prog_node; diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig index c56bafcfb5..bd1d5db4a9 100644 --- a/lib/std/Build/Step/InstallArtifact.zig +++ b/lib/std/Build/Step/InstallArtifact.zig @@ -115,7 +115,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins return install_artifact; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const install_artifact: *InstallArtifact = @fieldParentPtr("step", step); const b = step.owner; diff --git a/lib/std/Build/Step/InstallDir.zig b/lib/std/Build/Step/InstallDir.zig index 1722b975f7..0a6edafb33 100644 --- a/lib/std/Build/Step/InstallDir.zig +++ b/lib/std/Build/Step/InstallDir.zig @@ -56,7 +56,7 @@ pub fn create(owner: *std.Build, options: Options) *InstallDir { return install_dir; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const install_dir: *InstallDir = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/InstallFile.zig b/lib/std/Build/Step/InstallFile.zig index 6fa6d6bc99..8202a9d796 100644 --- a/lib/std/Build/Step/InstallFile.zig +++ b/lib/std/Build/Step/InstallFile.zig @@ -36,7 +36,7 @@ pub fn create( return install_file; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const install_file: *InstallFile = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index 515736dbc1..966764adcc 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -90,7 +90,7 @@ pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath { return if (objcopy.output_file_debug) |*file| .{ .generated = .{ .file = file } } else null; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const objcopy: *ObjCopy = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index c4daed73ff..2937cf70e1 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -410,7 +410,7 @@ pub fn getOutput(options: *Options) LazyPath { return .{ .generated = .{ .file = &options.generated_file } }; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { // This step completes so quickly that no progress is necessary. _ = prog_node; diff --git a/lib/std/Build/Step/RemoveDir.zig b/lib/std/Build/Step/RemoveDir.zig index 64a3c72668..6483a684aa 100644 --- a/lib/std/Build/Step/RemoveDir.zig +++ b/lib/std/Build/Step/RemoveDir.zig @@ -22,7 +22,7 @@ pub fn create(owner: *std.Build, dir_path: []const u8) *RemoveDir { return remove_dir; } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { // TODO update progress node while walking file system. // Should the standard library support this use case?? _ = prog_node; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index fec5b5ab67..d49d0b3ce2 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -574,7 +574,7 @@ const IndexedOutput = struct { tag: @typeInfo(Arg).Union.tag_type.?, output: *Output, }; -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const arena = b.allocator; const run: *Run = @fieldParentPtr("step", step); @@ -878,7 +878,7 @@ fn runCommand( argv: []const []const u8, has_side_effects: bool, output_dir_path: []const u8, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !void { const step = &run.step; const b = step.owner; @@ -1195,7 +1195,7 @@ fn spawnChildAndCollect( run: *Run, argv: []const []const u8, has_side_effects: bool, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !ChildProcResult { const b = run.step.owner; const arena = b.allocator; @@ -1235,6 +1235,10 @@ fn spawnChildAndCollect( child.stdin_behavior = .Pipe; } + if (run.stdio != .zig_test) { + child.progress_node = prog_node.start("", 0); + } + try child.spawn(); var timer = try std.time.Timer.start(); @@ -1264,7 +1268,7 @@ const StdIoResult = struct { fn evalZigTest( run: *Run, child: *std.process.Child, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !StdIoResult { const gpa = run.step.owner.allocator; const arena = run.step.owner.allocator; @@ -1291,7 +1295,7 @@ fn evalZigTest( var metadata: ?TestMetadata = null; var sub_prog_node: ?std.Progress.Node = null; - defer if (sub_prog_node) |*n| n.end(); + defer if (sub_prog_node) |n| n.end(); poll: while (true) { while (stdout.readableLength() < @sizeOf(Header)) { @@ -1406,7 +1410,7 @@ const TestMetadata = struct { expected_panic_msgs: []const u32, string_bytes: []const u8, next_index: u32, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, fn testName(tm: TestMetadata, index: u32) []const u8 { return std.mem.sliceTo(tm.string_bytes[tm.names[index]..], 0); @@ -1421,7 +1425,7 @@ fn requestNextTest(in: fs.File, metadata: *TestMetadata, sub_prog_node: *?std.Pr if (metadata.expected_panic_msgs[i] != 0) continue; const name = metadata.testName(i); - if (sub_prog_node.*) |*n| n.end(); + if (sub_prog_node.*) |n| n.end(); sub_prog_node.* = metadata.prog_node.start(name, 0); try sendRunTestMessage(in, i); diff --git a/lib/std/Build/Step/TranslateC.zig b/lib/std/Build/Step/TranslateC.zig index cb1b48e3c0..e07744c2da 100644 --- a/lib/std/Build/Step/TranslateC.zig +++ b/lib/std/Build/Step/TranslateC.zig @@ -116,7 +116,7 @@ pub fn defineCMacroRaw(translate_c: *TranslateC, name_and_value: []const u8) voi translate_c.c_macros.append(translate_c.step.owner.dupe(name_and_value)) catch @panic("OOM"); } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { const b = step.owner; const translate_c: *TranslateC = @fieldParentPtr("step", step); diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 401c5b78ec..0639573b8f 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -198,7 +198,7 @@ fn maybeUpdateName(write_file: *WriteFile) void { } } -fn make(step: *Step, prog_node: *std.Progress.Node) !void { +fn make(step: *Step, prog_node: std.Progress.Node) !void { _ = prog_node; const b = step.owner; const write_file: *WriteFile = @fieldParentPtr("step", step); diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index b7ac1fa328..c5c1d17b93 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -58,7 +58,7 @@ pub const Options = struct { /// cannot fit into this buffer which will look bad but not cause any malfunctions. /// /// Must be at least 200 bytes. - draw_buffer: []u8, + draw_buffer: []u8 = &default_draw_buffer, /// How many nanoseconds between writing updates to the terminal. refresh_rate_ns: u64 = 60 * std.time.ns_per_ms, /// How many nanoseconds to keep the output hidden @@ -67,6 +67,7 @@ pub const Options = struct { /// 0 means unknown. estimated_total_items: usize = 0, root_name: []const u8 = "", + disable_printing: bool = false, }; /// Represents one unit of progress. Each node can have children nodes, or @@ -203,6 +204,13 @@ pub const Node = struct { @atomicStore(u32, &storage.estimated_total_count, std.math.lossyCast(u32, count), .monotonic); } + /// Thread-safe. + pub fn increaseEstimatedTotalItems(n: Node, count: usize) void { + const index = n.index.unwrap() orelse return; + const storage = storageByIndex(index); + _ = @atomicRmw(u32, &storage.estimated_total_count, .Add, std.math.lossyCast(u32, count), .monotonic); + } + /// Finish a started `Node`. Thread-safe. pub fn end(n: Node) void { const index = n.index.unwrap() orelse return; @@ -290,6 +298,8 @@ var node_parents_buffer: [default_node_storage_buffer_len]Node.Parent = undefine var node_storage_buffer: [default_node_storage_buffer_len]Node.Storage = undefined; var node_freelist_buffer: [default_node_storage_buffer_len]Node.OptionalIndex = undefined; +var default_draw_buffer: [2000]u8 = undefined; + /// Initializes a global Progress instance. /// /// Asserts there is only one global Progress instance. @@ -318,6 +328,9 @@ pub fn start(options: Options) Node { } } else |env_err| switch (env_err) { error.EnvironmentVariableNotFound => { + if (options.disable_printing) { + return .{ .index = .none }; + } const stderr = std.io.getStdErr(); if (stderr.supportsAnsiEscapeCodes()) { global_progress.terminal = stderr; @@ -330,7 +343,7 @@ pub fn start(options: Options) Node { global_progress.terminal = stderr; } - if (global_progress.terminal == null) { + if (global_progress.terminal == null or !global_progress.supports_ansi_escape_codes) { return .{ .index = .none }; } @@ -379,7 +392,10 @@ fn updateThreadRun() void { return clearTerminal(); const buffer = computeRedraw(); - write(buffer); + if (stderr_mutex.tryLock()) { + defer stderr_mutex.unlock(); + write(buffer); + } } while (true) { @@ -390,10 +406,25 @@ fn updateThreadRun() void { return clearTerminal(); const buffer = computeRedraw(); - write(buffer); + if (stderr_mutex.tryLock()) { + defer stderr_mutex.unlock(); + write(buffer); + } } } +/// Allows the caller to freely write to stderr until `unlockStdErr` is called. +/// +/// During the lock, any `std.Progress` information is cleared from the terminal. +pub fn lockStdErr() void { + stderr_mutex.lock(); + clearTerminal(); +} + +pub fn unlockStdErr() void { + stderr_mutex.unlock(); +} + fn ipcThreadRun(fd: posix.fd_t) anyerror!void { { _ = wait(global_progress.initial_delay_ns); @@ -432,6 +463,8 @@ const tree_line = "\x1B\x28\x30\x78\x1B\x28\x42 "; // │ const tree_langle = "\x1B\x28\x30\x6d\x71\x1B\x28\x42 "; // └─ fn clearTerminal() void { + if (global_progress.newline_count == 0) return; + var i: usize = 0; const buf = global_progress.draw_buffer; @@ -876,3 +909,5 @@ fn handleSigWinch(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) assert(sig == posix.SIG.WINCH); global_progress.redraw_event.set(); } + +var stderr_mutex: std.Thread.Mutex = .{}; diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 980b027f0a..41439df5e6 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -77,19 +77,28 @@ const PdbOrDwarf = union(enum) { } }; -var stderr_mutex = std.Thread.Mutex{}; +/// Allows the caller to freely write to stderr until `unlockStdErr` is called. +/// +/// During the lock, any `std.Progress` information is cleared from the terminal. +pub fn lockStdErr() void { + std.Progress.lockStdErr(); +} + +pub fn unlockStdErr() void { + std.Progress.unlockStdErr(); +} /// Print to stderr, unbuffered, and silently returning on failure. Intended /// for use in "printf debugging." Use `std.log` functions for proper logging. pub fn print(comptime fmt: []const u8, args: anytype) void { - stderr_mutex.lock(); - defer stderr_mutex.unlock(); + lockStdErr(); + defer unlockStdErr(); const stderr = io.getStdErr().writer(); nosuspend stderr.print(fmt, args) catch return; } pub fn getStderrMutex() *std.Thread.Mutex { - return &stderr_mutex; + @compileError("deprecated. call std.debug.lockStdErr() and std.debug.unlockStdErr() instead which will integrate properly with std.Progress"); } /// TODO multithreaded awareness @@ -107,8 +116,8 @@ pub fn getSelfDebugInfo() !*DebugInfo { /// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned. /// Obtains the stderr mutex while dumping. pub fn dump_hex(bytes: []const u8) void { - stderr_mutex.lock(); - defer stderr_mutex.unlock(); + lockStdErr(); + defer unlockStdErr(); dump_hex_fallible(bytes) catch {}; } diff --git a/lib/std/json/dynamic.zig b/lib/std/json/dynamic.zig index a56d37bf0b..a1849b0fed 100644 --- a/lib/std/json/dynamic.zig +++ b/lib/std/json/dynamic.zig @@ -52,8 +52,8 @@ pub const Value = union(enum) { } pub fn dump(self: Value) void { - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); const stderr = std.io.getStdErr().writer(); stringify(self, .{}, stderr) catch return; diff --git a/lib/std/log.zig b/lib/std/log.zig index 0562d09c51..b2c05112b0 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -45,8 +45,8 @@ //! const prefix = "[" ++ comptime level.asText() ++ "] " ++ scope_prefix; //! //! // Print the message to stderr, silently ignoring any errors -//! std.debug.getStderrMutex().lock(); -//! defer std.debug.getStderrMutex().unlock(); +//! std.debug.lockStdErr(); +//! defer std.debug.unlockStdErr(); //! const stderr = std.io.getStdErr().writer(); //! nosuspend stderr.print(prefix ++ format ++ "\n", args) catch return; //! } @@ -152,8 +152,8 @@ pub fn defaultLog( var bw = std.io.bufferedWriter(stderr); const writer = bw.writer(); - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); nosuspend { writer.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return; bw.flush() catch return; diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index 5a6651b248..2d69ff901d 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -155,8 +155,8 @@ pub const RenderOptions = struct { }; pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void { - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); const stderr = std.io.getStdErr(); return renderToWriter(eb, options, stderr.writer()) catch return; } diff --git a/lib/std/zig/Server.zig b/lib/std/zig/Server.zig index 10e14a55fc..7f8de00b4a 100644 --- a/lib/std/zig/Server.zig +++ b/lib/std/zig/Server.zig @@ -14,8 +14,6 @@ pub const Message = struct { zig_version, /// Body is an ErrorBundle. error_bundle, - /// Body is a UTF-8 string. - progress, /// Body is a EmitBinPath. emit_bin_path, /// Body is a TestMetadata diff --git a/src/Compilation.zig b/src/Compilation.zig index 03b981812e..512ceeabbd 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1273,8 +1273,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil if (options.verbose_llvm_cpu_features) { if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { const target = options.root_mod.resolved_target.result; - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); const stderr = std.io.getStdErr().writer(); nosuspend { stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print; @@ -1934,7 +1934,7 @@ pub fn getTarget(self: Compilation) Target { /// Only legal to call when cache mode is incremental and a link file is present. pub fn hotCodeSwap( comp: *Compilation, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, pid: std.process.Child.Id, ) !void { const lf = comp.bin_file.?; @@ -1966,7 +1966,7 @@ fn cleanupAfterUpdate(comp: *Compilation) void { } /// Detect changes to source files, perform semantic analysis, and update the output files. -pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void { +pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { const tracy_trace = trace(@src()); defer tracy_trace.end(); @@ -2256,7 +2256,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void } } -fn flush(comp: *Compilation, arena: Allocator, prog_node: *std.Progress.Node) !void { +fn flush(comp: *Compilation, arena: Allocator, prog_node: std.Progress.Node) !void { if (comp.bin_file) |lf| { // This is needed before reading the error flags. lf.flush(arena, prog_node) catch |err| switch (err) { @@ -2566,13 +2566,11 @@ pub fn emitLlvmObject( default_emit: Emit, bin_emit_loc: ?EmitLoc, llvm_object: *LlvmObject, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !void { if (build_options.only_c) @compileError("unreachable"); - var sub_prog_node = prog_node.start("LLVM Emit Object", 0); - sub_prog_node.activate(); - sub_prog_node.context.refresh(); + const sub_prog_node = prog_node.start("LLVM Emit Object", 0); defer sub_prog_node.end(); try llvm_object.emit(.{ @@ -3249,23 +3247,23 @@ pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Module.File) !void { pub fn performAllTheWork( comp: *Compilation, - main_progress_node: *std.Progress.Node, + main_progress_node: std.Progress.Node, ) error{ TimerUnsupported, OutOfMemory }!void { // Here we queue up all the AstGen tasks first, followed by C object compilation. // We wait until the AstGen tasks are all completed before proceeding to the // (at least for now) single-threaded main work queue. However, C object compilation // only needs to be finished by the end of this function. - var zir_prog_node = main_progress_node.start("AST Lowering", 0); + const zir_prog_node = main_progress_node.start("AST Lowering", 0); defer zir_prog_node.end(); - var wasm_prog_node = main_progress_node.start("Compile Autodocs", 0); + const wasm_prog_node = main_progress_node.start("Compile Autodocs", 0); defer wasm_prog_node.end(); - var c_obj_prog_node = main_progress_node.start("Compile C Objects", comp.c_source_files.len); + const c_obj_prog_node = main_progress_node.start("Compile C Objects", comp.c_source_files.len); defer c_obj_prog_node.end(); - var win32_resource_prog_node = main_progress_node.start("Compile Win32 Resources", comp.rc_source_files.len); + const win32_resource_prog_node = main_progress_node.start("Compile Win32 Resources", comp.rc_source_files.len); defer win32_resource_prog_node.end(); comp.work_queue_wait_group.reset(); @@ -3274,7 +3272,7 @@ pub fn performAllTheWork( if (!build_options.only_c and !build_options.only_core_functionality) { if (comp.docs_emit != null) { comp.thread_pool.spawnWg(&comp.work_queue_wait_group, workerDocsCopy, .{comp}); - comp.work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, &wasm_prog_node }); + comp.work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, wasm_prog_node }); } } @@ -3313,7 +3311,7 @@ pub fn performAllTheWork( while (comp.astgen_work_queue.readItem()) |file| { comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerAstGenFile, .{ - comp, file, &zir_prog_node, &comp.astgen_wait_group, .root, + comp, file, zir_prog_node, &comp.astgen_wait_group, .root, }); } @@ -3325,14 +3323,14 @@ pub fn performAllTheWork( while (comp.c_object_work_queue.readItem()) |c_object| { comp.thread_pool.spawnWg(&comp.work_queue_wait_group, workerUpdateCObject, .{ - comp, c_object, &c_obj_prog_node, + comp, c_object, c_obj_prog_node, }); } if (!build_options.only_core_functionality) { while (comp.win32_resource_work_queue.readItem()) |win32_resource| { comp.thread_pool.spawnWg(&comp.work_queue_wait_group, workerUpdateWin32Resource, .{ - comp, win32_resource, &win32_resource_prog_node, + comp, win32_resource, win32_resource_prog_node, }); } } @@ -3342,7 +3340,6 @@ pub fn performAllTheWork( try reportMultiModuleErrors(mod); try mod.flushRetryableFailures(); mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); - mod.sema_prog_node.activate(); } defer if (comp.module) |mod| { mod.sema_prog_node.end(); @@ -3379,7 +3376,7 @@ pub fn performAllTheWork( } } -fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !void { +fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void { switch (job) { .codegen_decl => |decl_index| { const module = comp.module.?; @@ -3803,7 +3800,7 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, } } -fn workerDocsWasm(comp: *Compilation, prog_node: *std.Progress.Node) void { +fn workerDocsWasm(comp: *Compilation, prog_node: std.Progress.Node) void { workerDocsWasmFallible(comp, prog_node) catch |err| { comp.lockAndSetMiscFailure(.docs_wasm, "unable to build autodocs: {s}", .{ @errorName(err), @@ -3811,7 +3808,7 @@ fn workerDocsWasm(comp: *Compilation, prog_node: *std.Progress.Node) void { }; } -fn workerDocsWasmFallible(comp: *Compilation, prog_node: *std.Progress.Node) anyerror!void { +fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void { const gpa = comp.gpa; var arena_allocator = std.heap.ArenaAllocator.init(gpa); @@ -3952,12 +3949,11 @@ const AstGenSrc = union(enum) { fn workerAstGenFile( comp: *Compilation, file: *Module.File, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, wg: *WaitGroup, src: AstGenSrc, ) void { - var child_prog_node = prog_node.start(file.sub_file_path, 0); - child_prog_node.activate(); + const child_prog_node = prog_node.start(file.sub_file_path, 0); defer child_prog_node.end(); const mod = comp.module.?; @@ -4265,7 +4261,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module fn workerUpdateCObject( comp: *Compilation, c_object: *CObject, - progress_node: *std.Progress.Node, + progress_node: std.Progress.Node, ) void { comp.updateCObject(c_object, progress_node) catch |err| switch (err) { error.AnalysisFail => return, @@ -4282,7 +4278,7 @@ fn workerUpdateCObject( fn workerUpdateWin32Resource( comp: *Compilation, win32_resource: *Win32Resource, - progress_node: *std.Progress.Node, + progress_node: std.Progress.Node, ) void { comp.updateWin32Resource(win32_resource, progress_node) catch |err| switch (err) { error.AnalysisFail => return, @@ -4300,7 +4296,7 @@ fn buildCompilerRtOneShot( comp: *Compilation, output_mode: std.builtin.OutputMode, out: *?CRTFile, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) void { comp.buildOutputFromZig( "compiler_rt.zig", @@ -4427,7 +4423,7 @@ fn reportRetryableEmbedFileError( } } -fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.Progress.Node) !void { +fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Progress.Node) !void { if (comp.config.c_frontend == .aro) { return comp.failCObj(c_object, "aro does not support compiling C objects yet", .{}); } @@ -4467,9 +4463,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P const c_source_basename = std.fs.path.basename(c_object.src.src_path); - c_obj_prog_node.activate(); - var child_progress_node = c_obj_prog_node.start(c_source_basename, 0); - child_progress_node.activate(); + const child_progress_node = c_obj_prog_node.start(c_source_basename, 0); defer child_progress_node.end(); // Special case when doing build-obj for just one C file. When there are more than one object @@ -4731,7 +4725,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P }; } -fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32_resource_prog_node: *std.Progress.Node) !void { +fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32_resource_prog_node: std.Progress.Node) !void { if (!std.process.can_spawn) { return comp.failWin32Resource(win32_resource, "{s} does not support spawning a child process", .{@tagName(builtin.os.tag)}); } @@ -4763,9 +4757,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 _ = comp.failed_win32_resources.swapRemove(win32_resource); } - win32_resource_prog_node.activate(); - var child_progress_node = win32_resource_prog_node.start(src_basename, 0); - child_progress_node.activate(); + const child_progress_node = win32_resource_prog_node.start(src_basename, 0); defer child_progress_node.end(); var man = comp.obtainWin32ResourceCacheManifest(); @@ -4833,7 +4825,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 }); try argv.appendSlice(&.{ "--", in_rc_path, out_res_path }); - try spawnZigRc(comp, win32_resource, src_basename, arena, argv.items, &child_progress_node); + try spawnZigRc(comp, win32_resource, arena, argv.items, child_progress_node); break :blk digest; }; @@ -4901,7 +4893,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 try argv.appendSlice(rc_src.extra_flags); try argv.appendSlice(&.{ "--", rc_src.src_path, out_res_path }); - try spawnZigRc(comp, win32_resource, src_basename, arena, argv.items, &child_progress_node); + try spawnZigRc(comp, win32_resource, arena, argv.items, child_progress_node); // Read depfile and update cache manifest { @@ -4966,10 +4958,9 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 fn spawnZigRc( comp: *Compilation, win32_resource: *Win32Resource, - src_basename: []const u8, arena: Allocator, argv: []const []const u8, - child_progress_node: *std.Progress.Node, + child_progress_node: std.Progress.Node, ) !void { var node_name: std.ArrayListUnmanaged(u8) = .{}; defer node_name.deinit(arena); @@ -4978,6 +4969,7 @@ fn spawnZigRc( child.stdin_behavior = .Ignore; child.stdout_behavior = .Pipe; child.stderr_behavior = .Pipe; + child.progress_node = child_progress_node; child.spawn() catch |err| { return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {s}", .{ argv[0], @errorName(err) }); @@ -5019,22 +5011,6 @@ fn spawnZigRc( }; return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle); }, - .progress => { - node_name.clearRetainingCapacity(); - // <resinator> is a special string that indicates that the child - // process has reached resinator's main function - if (std.mem.eql(u8, body, "<resinator>")) { - child_progress_node.setName(src_basename); - } - // Ignore 0-length strings since if multiple zig rc commands - // are executed at the same time, only one will send progress strings - // while the other(s) will send empty strings. - else if (body.len > 0) { - try node_name.appendSlice(arena, "build 'zig rc'... "); - try node_name.appendSlice(arena, body); - child_progress_node.setName(node_name.items); - } - }, else => {}, // ignore other messages } @@ -5937,8 +5913,8 @@ pub fn lockAndParseLldStderr(comp: *Compilation, prefix: []const u8, stderr: []c } pub fn dump_argv(argv: []const []const u8) void { - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); const stderr = std.io.getStdErr().writer(); for (argv[0 .. argv.len - 1]) |arg| { nosuspend stderr.print("{s} ", .{arg}) catch return; @@ -5989,11 +5965,10 @@ pub fn updateSubCompilation( parent_comp: *Compilation, sub_comp: *Compilation, misc_task: MiscTask, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !void { { - var sub_node = prog_node.start(@tagName(misc_task), 0); - sub_node.activate(); + const sub_node = prog_node.start(@tagName(misc_task), 0); defer sub_node.end(); try sub_comp.update(prog_node); @@ -6024,7 +5999,7 @@ fn buildOutputFromZig( output_mode: std.builtin.OutputMode, out: *?CRTFile, misc_task_tag: MiscTask, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !void { const tracy_trace = trace(@src()); defer tracy_trace.end(); @@ -6131,7 +6106,7 @@ pub fn build_crt_file( root_name: []const u8, output_mode: std.builtin.OutputMode, misc_task_tag: MiscTask, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, /// These elements have to get mutated to add the owner module after it is /// created within this function. c_source_files: []CSourceFile, diff --git a/src/Module.zig b/src/Module.zig index c571c851fe..55b08701dc 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2991,8 +2991,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { try mod.deleteDeclExports(decl_index); } - var decl_prog_node = mod.sema_prog_node.start("", 0); - decl_prog_node.activate(); + const decl_prog_node = mod.sema_prog_node.start("", 0); defer decl_prog_node.end(); const sema_result: SemaDeclResult = blk: { @@ -5316,7 +5315,7 @@ fn handleUpdateExports( pub fn populateTestFunctions( mod: *Module, - main_progress_node: *std.Progress.Node, + main_progress_node: std.Progress.Node, ) !void { const gpa = mod.gpa; const ip = &mod.intern_pool; @@ -5333,7 +5332,6 @@ pub fn populateTestFunctions( // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions` // was not referenced by start code. mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); - mod.sema_prog_node.activate(); defer { mod.sema_prog_node.end(); mod.sema_prog_node = undefined; diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 97cbd36bd0..6528c2a53f 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -35,7 +35,7 @@ name_tok: std.zig.Ast.TokenIndex, lazy_status: LazyStatus, parent_package_root: Cache.Path, parent_manifest_ast: ?*const std.zig.Ast, -prog_node: *std.Progress.Node, +prog_node: std.Progress.Node, job_queue: *JobQueue, /// If true, don't add an error for a missing hash. This flag is not passed /// down to recursive dependencies. It's intended to be used only be the CLI. @@ -720,8 +720,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void { }; } - // job_queue mutex is locked so this is OK. - f.prog_node.unprotected_estimated_total_items += new_fetch_index; + f.prog_node.increaseEstimatedTotalItems(new_fetch_index); break :nf .{ new_fetches[0..new_fetch_index], prog_names[0..new_fetch_index] }; }; @@ -751,9 +750,8 @@ pub fn relativePathDigest( } pub fn workerRun(f: *Fetch, prog_name: []const u8) void { - var prog_node = f.prog_node.start(prog_name, 0); + const prog_node = f.prog_node.start(prog_name, 0); defer prog_node.end(); - prog_node.activate(); run(f) catch |err| switch (err) { error.OutOfMemory => f.oom_flag = true, @@ -1311,9 +1309,8 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac var index_file = try pack_dir.createFile("pkg.idx", .{ .read = true }); defer index_file.close(); { - var index_prog_node = f.prog_node.start("Index pack", 0); + const index_prog_node = f.prog_node.start("Index pack", 0); defer index_prog_node.end(); - index_prog_node.activate(); var index_buffered_writer = std.io.bufferedWriter(index_file.writer()); try git.indexPack(gpa, pack_file, index_buffered_writer.writer()); try index_buffered_writer.flush(); @@ -1321,9 +1318,8 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac } { - var checkout_prog_node = f.prog_node.start("Checkout", 0); + const checkout_prog_node = f.prog_node.start("Checkout", 0); defer checkout_prog_node.end(); - checkout_prog_node.activate(); var repository = try git.Repository.init(gpa, pack_file, index_file); defer repository.deinit(); var diagnostics: git.Diagnostics = .{ .allocator = arena }; diff --git a/src/glibc.zig b/src/glibc.zig index 5ec0442d6a..6474a23dce 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -160,7 +160,7 @@ pub const CRTFile = enum { libc_nonshared_a, }; -pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void { +pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progress.Node) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } @@ -658,7 +658,7 @@ pub const BuiltSharedObjects = struct { const all_map_basename = "all.map"; -pub fn buildSharedObjects(comp: *Compilation, prog_node: *std.Progress.Node) !void { +pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !void { const tracy = trace(@src()); defer tracy.end(); @@ -1065,7 +1065,7 @@ fn buildSharedLib( bin_directory: Compilation.Directory, asm_file_basename: []const u8, lib: Lib, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !void { const tracy = trace(@src()); defer tracy.end(); diff --git a/src/libcxx.zig b/src/libcxx.zig index b1b2014cb5..1c48f77527 100644 --- a/src/libcxx.zig +++ b/src/libcxx.zig @@ -113,7 +113,7 @@ pub const BuildError = error{ ZigCompilerNotBuiltWithLLVMExtensions, }; -pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) BuildError!void { +pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } @@ -357,7 +357,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) BuildError comp.libcxx_static_lib = try sub_compilation.toCrtFile(); } -pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) BuildError!void { +pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } diff --git a/src/libtsan.zig b/src/libtsan.zig index 28dba65772..1aa32e6ff0 100644 --- a/src/libtsan.zig +++ b/src/libtsan.zig @@ -13,7 +13,7 @@ pub const BuildError = error{ TSANUnsupportedCPUArchitecture, }; -pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) BuildError!void { +pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } diff --git a/src/libunwind.zig b/src/libunwind.zig index 808ea298ab..7783876827 100644 --- a/src/libunwind.zig +++ b/src/libunwind.zig @@ -14,7 +14,7 @@ pub const BuildError = error{ ZigCompilerNotBuiltWithLLVMExtensions, }; -pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) BuildError!void { +pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } diff --git a/src/link.zig b/src/link.zig index c05b545a89..ef09639dcf 100644 --- a/src/link.zig +++ b/src/link.zig @@ -535,7 +535,7 @@ pub const File = struct { /// Commit pending changes and write headers. Takes into account final output mode /// and `use_lld`, not only `effectiveOutputMode`. /// `arena` has the lifetime of the call to `Compilation.update`. - pub fn flush(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void { + pub fn flush(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void { if (build_options.only_c) { assert(base.tag == .c); return @as(*C, @fieldParentPtr("base", base)).flush(arena, prog_node); @@ -572,7 +572,7 @@ pub const File = struct { /// Commit pending changes and write headers. Works based on `effectiveOutputMode` /// rather than final output mode. - pub fn flushModule(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void { + pub fn flushModule(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void { switch (base.tag) { inline else => |tag| { if (tag != .c and build_options.only_c) unreachable; @@ -688,7 +688,7 @@ pub const File = struct { } } - pub fn linkAsArchive(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void { + pub fn linkAsArchive(base: *File, arena: Allocator, prog_node: std.Progress.Node) FlushError!void { const tracy = trace(@src()); defer tracy.end(); @@ -966,7 +966,7 @@ pub const File = struct { base: File, arena: Allocator, llvm_object: *LlvmObject, - prog_node: *std.Progress.Node, + prog_node: std.Progress.Node, ) !void { return base.comp.emitLlvmObject(arena, base.emit, .{ .directory = null, diff --git a/src/link/C.zig b/src/link/C.zig index 07814c9e71..305af40156 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -370,7 +370,7 @@ pub fn updateDeclLineNumber(self: *C, zcu: *Zcu, decl_index: InternPool.DeclInde _ = decl_index; } -pub fn flush(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void { +pub fn flush(self: *C, arena: Allocator, prog_node: std.Progress.Node) !void { return self.flushModule(arena, prog_node); } @@ -389,14 +389,13 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { return defines; } -pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void { +pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !void { _ = arena; // Has the same lifetime as the call to Compilation.update. const tracy = trace(@src()); defer tracy.end(); - var sub_prog_node = prog_node.start("Flush Module", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("Flush Module", 0); defer sub_prog_node.end(); const comp = self.base.comp; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 31cfe1ca9d..d24d69d913 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1702,7 +1702,7 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { gop.value_ptr.* = current; } -pub fn flush(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const comp = self.base.comp; const use_lld = build_options.have_llvm and comp.config.use_lld; if (use_lld) { @@ -1714,7 +1714,7 @@ pub fn flush(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link. } } -pub fn flushModule(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1726,8 +1726,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) return; } - var sub_prog_node = prog_node.start("COFF Flush", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("COFF Flush", 0); defer sub_prog_node.end(); const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; diff --git a/src/link/Coff/lld.zig b/src/link/Coff/lld.zig index 47753cbf01..c2620c1fe9 100644 --- a/src/link/Coff/lld.zig +++ b/src/link/Coff/lld.zig @@ -16,7 +16,7 @@ const Allocator = mem.Allocator; const Coff = @import("../Coff.zig"); const Compilation = @import("../../Compilation.zig"); -pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) !void { +pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: std.Progress.Node) !void { const tracy = trace(@src()); defer tracy.end(); @@ -38,9 +38,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) } } else null; - var sub_prog_node = prog_node.start("LLD Link", 0); - sub_prog_node.activate(); - sub_prog_node.context.refresh(); + const sub_prog_node = prog_node.start("LLD Link", 0); defer sub_prog_node.end(); const is_lib = comp.config.output_mode == .Lib; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 8a3192f93e..eb27b4449e 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1064,7 +1064,7 @@ pub fn markDirty(self: *Elf, shdr_index: u32) void { } } -pub fn flush(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const use_lld = build_options.have_llvm and self.base.comp.config.use_lld; if (use_lld) { return self.linkWithLLD(arena, prog_node); @@ -1072,7 +1072,7 @@ pub fn flush(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.F try self.flushModule(arena, prog_node); } -pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1085,8 +1085,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) if (use_lld) return; } - var sub_prog_node = prog_node.start("ELF Flush", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("ELF Flush", 0); defer sub_prog_node.end(); const target = comp.root_mod.resolved_target.result; @@ -2147,7 +2146,7 @@ fn scanRelocs(self: *Elf) !void { } } -fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !void { +fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: std.Progress.Node) !void { const tracy = trace(@src()); defer tracy.end(); @@ -2169,9 +2168,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi } } else null; - var sub_prog_node = prog_node.start("LLD Link", 0); - sub_prog_node.activate(); - sub_prog_node.context.refresh(); + const sub_prog_node = prog_node.start("LLD Link", 0); defer sub_prog_node.end(); const output_mode = comp.config.output_mode; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 7bf195f5f9..947a2665de 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -360,11 +360,11 @@ pub fn deinit(self: *MachO) void { self.unwind_records.deinit(gpa); } -pub fn flush(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { try self.flushModule(arena, prog_node); } -pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const tracy = trace(@src()); defer tracy.end(); @@ -375,8 +375,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node try self.base.emitLlvmObject(arena, llvm_object, prog_node); } - var sub_prog_node = prog_node.start("MachO Flush", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("MachO Flush", 0); defer sub_prog_node.end(); const directory = self.base.emit.directory; diff --git a/src/link/NvPtx.zig b/src/link/NvPtx.zig index 111b59fc3b..8e1ebc9726 100644 --- a/src/link/NvPtx.zig +++ b/src/link/NvPtx.zig @@ -106,11 +106,11 @@ pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void { return self.llvm_object.freeDecl(decl_index); } -pub fn flush(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { return self.flushModule(arena, prog_node); } -pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { if (build_options.skip_non_native) @panic("Attempted to compile for architecture that was disabled by build configuration"); diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index a45142a12e..328d669b58 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -604,7 +604,7 @@ fn allocateGotIndex(self: *Plan9) usize { } } -pub fn flush(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const comp = self.base.comp; const use_lld = build_options.have_llvm and comp.config.use_lld; assert(!use_lld); @@ -663,7 +663,7 @@ fn atomCount(self: *Plan9) usize { return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count; } -pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { if (build_options.skip_non_native and builtin.object_format != .plan9) { @panic("Attempted to compile for object format that was disabled by build configuration"); } @@ -677,8 +677,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node const tracy = trace(@src()); defer tracy.end(); - var sub_prog_node = prog_node.start("Flush Module", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("Flush Module", 0); defer sub_prog_node.end(); log.debug("flushModule", .{}); diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index 27c905cc61..0cc238f140 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -193,11 +193,11 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void { _ = decl_index; } -pub fn flush(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { return self.flushModule(arena, prog_node); } -pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { if (build_options.skip_non_native) { @panic("Attempted to compile for architecture that was disabled by build configuration"); } @@ -205,8 +205,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node const tracy = trace(@src()); defer tracy.end(); - var sub_prog_node = prog_node.start("Flush Module", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("Flush Module", 0); defer sub_prog_node.end(); const spv = &self.object.spv; @@ -253,7 +252,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node const module = try spv.finalize(arena, target); errdefer arena.free(module); - const linked_module = self.linkModule(arena, module, &sub_prog_node) catch |err| switch (err) { + const linked_module = self.linkModule(arena, module, sub_prog_node) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, else => |other| { log.err("error while linking: {s}\n", .{@errorName(other)}); @@ -264,7 +263,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node try self.base.file.?.writeAll(std.mem.sliceAsBytes(linked_module)); } -fn linkModule(self: *SpirV, a: Allocator, module: []Word, progress: *std.Progress.Node) ![]Word { +fn linkModule(self: *SpirV, a: Allocator, module: []Word, progress: std.Progress.Node) ![]Word { _ = self; const lower_invocation_globals = @import("SpirV/lower_invocation_globals.zig"); diff --git a/src/link/SpirV/deduplicate.zig b/src/link/SpirV/deduplicate.zig index 4cf5ebf65a..292ff0e868 100644 --- a/src/link/SpirV/deduplicate.zig +++ b/src/link/SpirV/deduplicate.zig @@ -418,9 +418,8 @@ const EntityHashContext = struct { } }; -pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void { - var sub_node = progress.start("deduplicate", 0); - sub_node.activate(); +pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: std.Progress.Node) !void { + const sub_node = progress.start("deduplicate", 0); defer sub_node.end(); var arena = std.heap.ArenaAllocator.init(parser.a); diff --git a/src/link/SpirV/lower_invocation_globals.zig b/src/link/SpirV/lower_invocation_globals.zig index ee992112c8..edf16a7cd8 100644 --- a/src/link/SpirV/lower_invocation_globals.zig +++ b/src/link/SpirV/lower_invocation_globals.zig @@ -682,9 +682,8 @@ const ModuleBuilder = struct { } }; -pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void { - var sub_node = progress.start("Lower invocation globals", 6); - sub_node.activate(); +pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: std.Progress.Node) !void { + const sub_node = progress.start("Lower invocation globals", 6); defer sub_node.end(); var arena = std.heap.ArenaAllocator.init(parser.a); diff --git a/src/link/SpirV/prune_unused.zig b/src/link/SpirV/prune_unused.zig index cefdaddd93..a604d62349 100644 --- a/src/link/SpirV/prune_unused.zig +++ b/src/link/SpirV/prune_unused.zig @@ -255,9 +255,8 @@ fn removeIdsFromMap(a: Allocator, map: anytype, info: ModuleInfo, alive_marker: } } -pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: *std.Progress.Node) !void { - var sub_node = progress.start("Prune unused IDs", 0); - sub_node.activate(); +pub fn run(parser: *BinaryModule.Parser, binary: *BinaryModule, progress: std.Progress.Node) !void { + const sub_node = progress.start("Prune unused IDs", 0); defer sub_node.end(); var arena = std.heap.ArenaAllocator.init(parser.a); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index bf345813df..da6425326b 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2464,7 +2464,7 @@ fn appendDummySegment(wasm: *Wasm) !void { }); } -pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const comp = wasm.base.comp; const use_lld = build_options.have_llvm and comp.config.use_lld; @@ -2475,7 +2475,7 @@ pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link. } /// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary. -pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { +pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2486,8 +2486,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) if (use_lld) return; } - var sub_prog_node = prog_node.start("Wasm Flush", 0); - sub_prog_node.activate(); + const sub_prog_node = prog_node.start("Wasm Flush", 0); defer sub_prog_node.end(); const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type. @@ -3323,7 +3322,7 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void { } } -fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !void { +fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: std.Progress.Node) !void { const tracy = trace(@src()); defer tracy.end(); @@ -3350,9 +3349,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo } } else null; - var sub_prog_node = prog_node.start("LLD Link", 0); - sub_prog_node.activate(); - sub_prog_node.context.refresh(); + const sub_prog_node = prog_node.start("LLD Link", 0); defer sub_prog_node.end(); const is_obj = comp.config.output_mode == .Obj; diff --git a/src/main.zig b/src/main.zig index 099ceb27f9..20f9bfba54 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4028,22 +4028,7 @@ fn serve( var child_pid: ?std.process.Child.Id = null; - var progress: std.Progress = .{ - .terminal = null, - .root = .{ - .context = undefined, - .parent = null, - .name = "", - .unprotected_estimated_total_items = 0, - .unprotected_completed_items = 0, - }, - .columns_written = 0, - .prev_refresh_timestamp = 0, - .timer = null, - .done = false, - }; - const main_progress_node = &progress.root; - main_progress_node.context = &progress; + const main_progress_node = std.Progress.start(.{}); while (true) { const hdr = try server.receiveMessage(); @@ -4051,7 +4036,6 @@ fn serve( switch (hdr.tag) { .exit => return cleanExit(), .update => { - assert(main_progress_node.recently_updated_child == null); tracy.frameMark(); if (arg_mode == .translate_c) { @@ -4075,21 +4059,7 @@ fn serve( try comp.makeBinFileWritable(); } - if (builtin.single_threaded) { - try comp.update(main_progress_node); - } else { - var reset: std.Thread.ResetEvent = .{}; - - var progress_thread = try std.Thread.spawn(.{}, progressThread, .{ - &progress, &server, &reset, - }); - defer { - reset.set(); - progress_thread.join(); - } - - try comp.update(main_progress_node); - } + try comp.update(main_progress_node); try comp.makeBinFileExecutable(); try serveUpdateResults(&server, comp); @@ -4116,7 +4086,6 @@ fn serve( }, .hot_update => { tracy.frameMark(); - assert(main_progress_node.recently_updated_child == null); if (child_pid) |pid| { try comp.hotCodeSwap(main_progress_node, pid); try serveUpdateResults(&server, comp); @@ -4146,63 +4115,6 @@ fn serve( } } -fn progressThread(progress: *std.Progress, server: *const Server, reset: *std.Thread.ResetEvent) void { - while (true) { - if (reset.timedWait(500 * std.time.ns_per_ms)) |_| { - // The Compilation update has completed. - return; - } else |err| switch (err) { - error.Timeout => {}, - } - - var buf: std.BoundedArray(u8, 160) = .{}; - - { - progress.update_mutex.lock(); - defer progress.update_mutex.unlock(); - - var need_ellipse = false; - var maybe_node: ?*std.Progress.Node = &progress.root; - while (maybe_node) |node| { - if (need_ellipse) { - buf.appendSlice("... ") catch {}; - } - need_ellipse = false; - const eti = @atomicLoad(usize, &node.unprotected_estimated_total_items, .monotonic); - const completed_items = @atomicLoad(usize, &node.unprotected_completed_items, .monotonic); - const current_item = completed_items + 1; - if (node.name.len != 0 or eti > 0) { - if (node.name.len != 0) { - buf.appendSlice(node.name) catch {}; - need_ellipse = true; - } - if (eti > 0) { - if (need_ellipse) buf.appendSlice(" ") catch {}; - buf.writer().print("[{d}/{d}] ", .{ current_item, eti }) catch {}; - need_ellipse = false; - } else if (completed_items != 0) { - if (need_ellipse) buf.appendSlice(" ") catch {}; - buf.writer().print("[{d}] ", .{current_item}) catch {}; - need_ellipse = false; - } - } - maybe_node = @atomicLoad(?*std.Progress.Node, &node.recently_updated_child, .acquire); - } - } - - const progress_string = buf.slice(); - - server.serveMessage(.{ - .tag = .progress, - .bytes_len = @as(u32, @intCast(progress_string.len)), - }, &.{ - progress_string, - }) catch |err| { - fatal("unable to write to client: {s}", .{@errorName(err)}); - }; - } -} - fn serveUpdateResults(s: *Server, comp: *Compilation) !void { const gpa = comp.gpa; var error_bundle = try comp.getAllErrorsAlloc(); @@ -4472,19 +4384,10 @@ fn runOrTestHotSwap( fn updateModule(comp: *Compilation, color: Color) !void { { // If the terminal is dumb, we dont want to show the user all the output. - var progress: std.Progress = .{ .dont_print_on_dumb = true }; - const main_progress_node = progress.start("", 0); + const main_progress_node = std.Progress.start(.{ + .disable_printing = color == .off, + }); defer main_progress_node.end(); - switch (color) { - .off => { - progress.terminal = null; - }, - .on => { - progress.terminal = std.io.getStdErr(); - progress.supports_ansi_escape_codes = true; - }, - .auto => {}, - } try comp.update(main_progress_node); } @@ -4736,8 +4639,6 @@ const usage_build = ; fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { - var progress: std.Progress = .{ .dont_print_on_dumb = true }; - var build_file: ?[]const u8 = null; var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); @@ -5051,7 +4952,9 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { config, ); } else { - const root_prog_node = progress.start("Fetch Packages", 0); + const root_prog_node = std.Progress.start(.{ + .root_name = "Fetch Packages", + }); defer root_prog_node.end(); var job_queue: Package.Fetch.JobQueue = .{ @@ -5473,38 +5376,14 @@ fn jitCmd( }; defer comp.destroy(); - if (options.server and !builtin.single_threaded) { - var reset: std.Thread.ResetEvent = .{}; - var progress: std.Progress = .{ - .terminal = null, - .root = .{ - .context = undefined, - .parent = null, - .name = "", - .unprotected_estimated_total_items = 0, - .unprotected_completed_items = 0, - }, - .columns_written = 0, - .prev_refresh_timestamp = 0, - .timer = null, - .done = false, - }; - const main_progress_node = &progress.root; - main_progress_node.context = &progress; + if (options.server) { + const main_progress_node = std.Progress.start(.{}); var server = std.zig.Server{ .out = std.io.getStdOut(), .in = undefined, // won't be receiving messages .receive_fifo = undefined, // won't be receiving messages }; - var progress_thread = try std.Thread.spawn(.{}, progressThread, .{ - &progress, &server, &reset, - }); - defer { - reset.set(); - progress_thread.join(); - } - try comp.update(main_progress_node); var error_bundle = try comp.getAllErrorsAlloc(); @@ -6963,8 +6842,9 @@ fn cmdFetch( try http_client.initDefaultProxies(arena); - var progress: std.Progress = .{ .dont_print_on_dumb = true }; - const root_prog_node = progress.start("Fetch", 0); + var root_prog_node = std.Progress.start(.{ + .root_name = "Fetch", + }); defer root_prog_node.end(); var global_cache_directory: Compilation.Directory = l: { @@ -7028,8 +6908,8 @@ fn cmdFetch( const hex_digest = Package.Manifest.hexDigest(fetch.actual_hash); - progress.done = true; - progress.refresh(); + root_prog_node.end(); + root_prog_node = .{ .index = .none }; const name = switch (save) { .no => { diff --git a/src/mingw.zig b/src/mingw.zig index 803c0f9367..5aa79064ee 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -16,7 +16,7 @@ pub const CRTFile = enum { mingw32_lib, }; -pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void { +pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progress.Node) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } @@ -234,8 +234,8 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" }); if (comp.verbose_cc) print: { - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); const stderr = std.io.getStdErr().writer(); nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print; nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print; diff --git a/src/musl.zig b/src/musl.zig index 3228faf271..edeea9cca7 100644 --- a/src/musl.zig +++ b/src/musl.zig @@ -19,7 +19,7 @@ pub const CRTFile = enum { libc_so, }; -pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void { +pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progress.Node) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index 122d45230b..57d93b6f56 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -57,7 +57,7 @@ pub fn execModelCrtFileFullName(wasi_exec_model: std.builtin.WasiExecModel) []co }; } -pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progress.Node) !void { +pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progress.Node) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } diff --git a/test/standalone/cmakedefine/build.zig b/test/standalone/cmakedefine/build.zig index d90441360f..3c57523373 100644 --- a/test/standalone/cmakedefine/build.zig +++ b/test/standalone/cmakedefine/build.zig @@ -80,7 +80,7 @@ pub fn build(b: *std.Build) void { test_step.dependOn(&wrapper_header.step); } -fn compare_headers(step: *std.Build.Step, prog_node: *std.Progress.Node) !void { +fn compare_headers(step: *std.Build.Step, prog_node: std.Progress.Node) !void { _ = prog_node; const allocator = step.owner.allocator; const expected_fmt = "expected_{s}"; |
