authorgravatar for 28024277+tjog@users.noreply.github.comtjog <28024277+tjog@users.noreply.github.com> 2023-03-23 02:21:15+08:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-25 03:20:50+01:00
logf6a2b72ba8b6ab8f8dbef223788c6458af3d4da0
tree0728917fa73f5a86d9428f8f2e59957dd9237425
parentf99b75360db55413f4accf43a6f4161b14a5de9f

std.process.Child: implement maxrss on Darwin

Notably the Darwin (XNU) kernel the maxrss field is number of bytes and not kilobytes (kibibytes) like other platforms (e.g. Linux, BSD). watchOS and tvOS are not supported because they do not have the ability to spawn a child process. iOS is enabled but due to OS sandboxing it should fail with a permission error.

2 files changed, 21 insertions(+), 9 deletions(-)

lib/std/child_process.zig+20-8
......@@ -17,7 +17,6 @@ const Os = std.builtin.Os;
1717const TailQueue = std.TailQueue;
1818const maxInt = std.math.maxInt;
1919const assert = std.debug.assert;
20const is_darwin = builtin.target.isDarwin();
2120
2221pub const ChildProcess = struct {
2322 pub const Id = switch (builtin.os.tag) {
......@@ -77,7 +76,7 @@ pub const ChildProcess = struct {
7776 /// requested statistics may or may not be available. If they are
7877 /// available, then the `resource_usage_statistics` field will be populated
7978 /// after calling `wait`.
80 /// On Linux, this obtains rusage statistics from wait4().
79 /// On Linux and Darwin, this obtains rusage statistics from wait4().
8180 request_resource_usage_statistics: bool = false,
8281
8382 /// This is available after calling wait if
......@@ -106,12 +105,20 @@ pub const ChildProcess = struct {
106105 return null;
107106 }
108107 },
108 .macos, .ios => {
109 if (rus.rusage) |ru| {
110 // Darwin oddly reports in bytes instead of kilobytes.
111 return @intCast(usize, ru.maxrss);
112 } else {
113 return null;
114 }
115 },
109116 else => return null,
110117 }
111118 }
112119
113120 const rusage_init = switch (builtin.os.tag) {
114 .linux => @as(?std.os.rusage, null),
121 .linux, .macos, .ios => @as(?std.os.rusage, null),
115122 .windows => @as(?windows.VM_COUNTERS, null),
116123 else => {},
117124 };
......@@ -385,11 +392,16 @@ pub const ChildProcess = struct {
385392
386393 fn waitUnwrapped(self: *ChildProcess) !void {
387394 const res: os.WaitPidResult = res: {
388 if (builtin.os.tag == .linux and self.request_resource_usage_statistics) {
389 var ru: std.os.rusage = undefined;
390 const res = os.wait4(self.id, 0, &ru);
391 self.resource_usage_statistics.rusage = ru;
392 break :res res;
395 if (self.request_resource_usage_statistics) {
396 switch (builtin.os.tag) {
397 .linux, .macos, .ios => {
398 var ru: std.os.rusage = undefined;
399 const res = os.wait4(self.id, 0, &ru);
400 self.resource_usage_statistics.rusage = ru;
401 break :res res;
402 },
403 else => {},
404 }
393405 }
394406
395407 break :res os.waitpid(self.id, 0);
lib/std/process.zig+1-1
......@@ -1093,7 +1093,7 @@ pub const can_execv = switch (builtin.os.tag) {
10931093
10941094/// Tells whether spawning child processes is supported (e.g. via ChildProcess)
10951095pub const can_spawn = switch (builtin.os.tag) {
1096 .wasi => false,
1096 .wasi, .watchos, .tvos => false,
10971097 else => true,
10981098};
10991099