Uh oh!
There was an error while loading. Please reload this page.
std.process.Child: implement maxrss on Darwin - #15050
Conversation
Turns out iOS does not match the OSX implementation (related node GH issue, and libuv solution PR):
Will get a simulator up for .ios, .watchos, .tvos to verify the archived man paged still applies to those. |
tjog
commented
Mar 23, 2023
Turns out the archived page is wrong. Darwin is consistent across apple platforms for I verified this on iOS simulator (see code block below). One complication is that on iOS the first wait4 call is always interrupted leaving garbage values in rusage. However, the second time around it succeeds. Discovered through how Swift uses But, The fact fork works in iOS simulator is odd, maybe the sandbox is disabled for performance reasons. I still think the best option is to set these other Darwin targets as unable to spawn and generate compile errors. This will allow reverting back to switch cases for For completeness, here is the C code ran through Xcode that verifies iOS also returns maxrss in bytes. The same code was run on MacOS by compiling with clang (no Xcode project was created). Code and results from macOS and iOS simulator, `wait4` perror is logged once for iOS simulator but never for macOS.#include<assert.h>#include<sys/errno.h>#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/wait.h>#include<sys/resource.h>intmain(intargc, char*argv[]) {
pid_tpid=fork();
if (pid==0) {
// Child processsize_tmem_size= (20*1024*1024); // Allocate 20MB of memory// maxrss results:// (MB granularity to ensure underlying allocator always grabs// different amount of pages):// mem_size macOS iOS// 1MB 1417216 2273280// 4MB 4571136 5455872// 10MB 10862592 11714560// 20MB 21348352 22167552char*mem=malloc(mem_size);
if (mem==NULL) {
perror("malloc");
exit(1);
}
// Use the memory to ensure it's not optimized awayfor (size_ti=0; i<mem_size; i++) {
mem[i] =i % 256;
}
sleep(1); // simulate some workfree(mem);
printf("Child exiting\n");
exit(0);
} elseif (pid>0) {
// Parent process// From Swift example https://github.com/apple/swift/blob/dfcc4fce9883ac9989eef9893651a780bad88cb4/lib/Basic/Unix/TaskQueue.inc#L599-L619intStatus=0;
structrusageUsage;
for (;;) {
// NOTE: only succeeds second time for iOS, need for loopconstpid_tpidFromWait=wait4(pid, &Status, 0, &Usage);
if (pidFromWait==pid)
break;
assert(pidFromWait==-1&&"Did not pass WNOHANG, should only get pidToWaitFor or -1");
if (errno==ECHILD||errno==EINVAL)
exit(1);
else {
perror("wait4");
}
}
intexit_status=WEXITSTATUS(Status);
printf("Child process terminated with status %d\n", exit_status);
printf("User time used: %ld.%06d s\n", Usage.ru_utime.tv_sec, Usage.ru_utime.tv_usec);
printf("System time used: %ld.%06d s\n", Usage.ru_stime.tv_sec, Usage.ru_stime.tv_usec);
printf("Max RSS: %ld\n", Usage.ru_maxrss);
} else {
// Fork failedperror("fork");
exit(1);
}
} |
kubkon
commented
Mar 23, 2023
For the future, official Apple OSS distributions can be found here: https://github.com/apple-oss-distributions |
kubkon
left a comment
There was a problem hiding this comment.
Nice work! I've got a couple nits and then i think we can go ahead and merge it. When it comes to iOS and other Apple platforms, I don't think anyone would want to spawn a child process using this API for the reasons you mentioned. I believe that for those platforms Apple prescribes you use their frameworks more than anything else. Having said that even if you could spawn a child with this API and it didn't work, we can always revisit later for better iOS support (and other Apple platforms).
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
1f123be to
43c50f8Comparetjog
commented
Mar 23, 2023
Updated with your comments in mind! Did not split the switch cases since they share the same implementation. |
kubkon
commented
Mar 24, 2023
Can you resolve conflicts with the master branch please? |
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.
43c50f8 to
25a0896Comparetjog
commented
Mar 24, 2023
Rebased and resolved! @kubkon |
Notably the Darwin (XNU) kernel the maxrss field is number of bytes and not kilobytes (kibibytes) like other platforms (e.g. Linux, BSD).
This is my first PR, although very small in scope, feel welcome to give input.
Fixes#14957