std.Build.RunStep: add maxrss, duration, and cached status

This commit is contained in:
Andrew Kelley 2023-03-03 16:39:08 -07:00
parent 80d1976db9
commit 2996eb5587
5 changed files with 58 additions and 11 deletions

View File

@ -113,7 +113,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
};
try argv.appendSlice(&.{ full_src_path, full_dest_path });
_ = try step.spawnZigProcess(argv.items, prog_node);
_ = try step.evalZigProcess(argv.items, prog_node);
self.output_file.path = full_dest_path;
try man.writeManifest();

View File

@ -234,10 +234,12 @@ pub fn evalZigProcess(
child.stdin_behavior = .Pipe;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Pipe;
child.request_resource_usage_statistics = true;
child.spawn() catch |err| return s.fail("unable to spawn {s}: {s}", .{
argv[0], @errorName(err),
});
var timer = try std.time.Timer.start();
var poller = std.io.poll(gpa, enum { stdout, stderr }, .{
.stdout = child.stdout.?,
@ -301,7 +303,10 @@ pub fn evalZigProcess(
sub_prog_node.?.activate();
},
.emit_bin_path => {
result = try arena.dupe(u8, body);
const EbpHdr = std.zig.Server.Message.EmitBinPath;
const ebp_hdr = @ptrCast(*align(1) const EbpHdr, body);
s.result_cached = ebp_hdr.flags.cache_hit;
result = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]);
},
_ => {
// Unrecognized message.
@ -323,6 +328,9 @@ pub fn evalZigProcess(
const term = child.wait() catch |err| {
return s.fail("unable to wait for {s}: {s}", .{ argv[0], @errorName(err) });
};
s.result_duration_ns = timer.read();
s.result_peak_rss = child.resource_usage_statistics.getMaxRss() orelse 0;
try handleChildProcessTerm(s, term, null, argv);
if (s.result_error_bundle.errorMessageCount() > 0) {

View File

@ -12,7 +12,7 @@ pub const Message = struct {
error_bundle,
/// Body is a UTF-8 string.
progress,
/// Body is a UTF-8 string.
/// Body is a EmitBinPath.
emit_bin_path,
_,
};
@ -25,4 +25,15 @@ pub const Message = struct {
extra_len: u32,
string_bytes_len: u32,
};
/// Trailing:
/// * the file system path the emitted binary can be found
pub const EmitBinPath = extern struct {
flags: Flags,
pub const Flags = packed struct(u8) {
cache_hit: bool,
reserved: u7 = 0,
};
};
};

View File

@ -100,6 +100,7 @@ job_queued_compiler_rt_lib: bool = false,
job_queued_compiler_rt_obj: bool = false,
alloc_failure_occurred: bool = false,
formatted_panics: bool = false,
last_update_was_cache_hit: bool = false,
c_source_files: []const CSourceFile,
clang_argv: []const []const u8,
@ -1860,6 +1861,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
defer tracy_trace.end();
comp.clearMiscFailures();
comp.last_update_was_cache_hit = false;
var man: Cache.Manifest = undefined;
defer if (comp.whole_cache_manifest != null) man.deinit();
@ -1887,6 +1889,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
return err;
};
if (is_hit) {
comp.last_update_was_cache_hit = true;
log.debug("CacheMode.whole cache hit for {s}", .{comp.bin_file.options.root_name});
const digest = man.final();

View File

@ -3578,9 +3578,11 @@ fn serve(
var arena_instance = std.heap.ArenaAllocator.init(gpa);
defer arena_instance.deinit();
const arena = arena_instance.allocator();
var output_path: []const u8 = undefined;
try cmdTranslateC(comp, arena, &output_path);
try serveStringMessage(out, .emit_bin_path, output_path);
var output: TranslateCOutput = undefined;
try cmdTranslateC(comp, arena, &output);
try serveEmitBinPath(out, output.path, .{
.flags = .{ .cache_hit = output.cache_hit },
});
continue;
}
@ -3760,10 +3762,26 @@ fn serveUpdateResults(out: fs.File, comp: *Compilation) !void {
} else if (comp.bin_file.options.emit) |emit| {
const full_path = try emit.directory.join(gpa, &.{emit.sub_path});
defer gpa.free(full_path);
try serveStringMessage(out, .emit_bin_path, full_path);
try serveEmitBinPath(out, full_path, .{
.flags = .{ .cache_hit = comp.last_update_was_cache_hit },
});
}
}
fn serveEmitBinPath(
out: fs.File,
fs_path: []const u8,
header: std.zig.Server.Message.EmitBinPath,
) !void {
try serveMessage(out, .{
.tag = .emit_bin_path,
.bytes_len = @intCast(u32, fs_path.len + @sizeOf(std.zig.Server.Message.EmitBinPath)),
}, &.{
std.mem.asBytes(&header),
fs_path,
});
}
fn serveStringMessage(out: fs.File, tag: std.zig.Server.Message.Tag, s: []const u8) !void {
try serveMessage(out, .{
.tag = tag,
@ -4115,7 +4133,12 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void
}
}
fn cmdTranslateC(comp: *Compilation, arena: Allocator, output_path: ?*[]const u8) !void {
const TranslateCOutput = struct {
path: []const u8,
cache_hit: bool,
};
fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*TranslateCOutput) !void {
if (!build_options.have_llvm)
fatal("cannot translate-c: compiler built without LLVM extensions", .{});
@ -4126,14 +4149,16 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, output_path: ?*[]const u8
var man: Cache.Manifest = comp.obtainCObjectCacheManifest();
man.want_shared_lock = false;
defer if (output_path != null) man.deinit();
defer man.deinit();
man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err| {
fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) });
};
if (fancy_output) |p| p.cache_hit = true;
const digest = if (try man.hit()) man.final() else digest: {
if (fancy_output) |p| p.cache_hit = false;
var argv = std.ArrayList([]const u8).init(arena);
try argv.append(""); // argv[0] is program name, actual args start at [1]
@ -4229,11 +4254,11 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, output_path: ?*[]const u8
break :digest digest;
};
if (output_path) |out_path| {
if (fancy_output) |p| {
const full_zig_path = try comp.local_cache_directory.join(arena, &[_][]const u8{
"o", &digest, translated_zig_basename,
});
out_path.* = full_zig_path;
p.path = full_zig_path;
} else {
const out_zig_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest, translated_zig_basename });
const zig_file = comp.local_cache_directory.handle.openFile(out_zig_path, .{}) catch |err| {