From dcda6f7d8db4a9d29b8761093cb867bea9f996f6 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 7 Sep 2023 05:39:58 -0700 Subject: [PATCH] Simplify the rusage.com command --- examples/rusage.c | 166 ++++++++++++------------------ examples/unbourne.c | 11 +- third_party/python/freeze.c | 3 + third_party/python/launch.c | 3 + third_party/python/pyobj.c | 3 + third_party/python/pythontester.c | 3 + third_party/python/repl.c | 3 + 7 files changed, 86 insertions(+), 106 deletions(-) diff --git a/examples/rusage.c b/examples/rusage.c index e28b6b467..7a965a162 100644 --- a/examples/rusage.c +++ b/examples/rusage.c @@ -7,121 +7,83 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/calls/struct/rusage.h" #include "libc/calls/calls.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction.h" -#include "libc/errno.h" -#include "libc/log/check.h" -#include "libc/log/log.h" -#include "libc/math.h" -#include "libc/runtime/clktck.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/struct/timespec.h" +#include "libc/fmt/itoa.h" +#include "libc/log/appendresourcereport.internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdio/append.h" #include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/sig.h" -#include "libc/time/time.h" - -#define PREFIX "\e[1mRL\e[0m: " - -static void PrintResourceReport(struct rusage *ru) { - long utime, stime; - long double ticks; - if (ru->ru_maxrss) { - fprintf(stderr, "%sballooned to %,ldkb in size\n", PREFIX, ru->ru_maxrss); - } - if ((utime = ru->ru_utime.tv_sec * 1000000 + ru->ru_utime.tv_usec) | - (stime = ru->ru_stime.tv_sec * 1000000 + ru->ru_stime.tv_usec)) { - ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK)); - fprintf(stderr, "%sneeded %,ldµs cpu (%d%% kernel)\n", PREFIX, - utime + stime, (int)((long double)stime / (utime + stime) * 100)); - if (ru->ru_idrss) { - fprintf(stderr, "%sneeded %,ldkb memory on average\n", PREFIX, - lroundl(ru->ru_idrss / ticks)); - } - if (ru->ru_isrss) { - fprintf(stderr, "%sneeded %,ldkb stack on average\n", PREFIX, - lroundl(ru->ru_isrss / ticks)); - } - if (ru->ru_ixrss) { - fprintf(stderr, "%smapped %,ldkb shared on average\n", PREFIX, - lroundl(ru->ru_ixrss / ticks)); - } - } - if (ru->ru_minflt || ru->ru_majflt) { - fprintf(stderr, "%scaused %,ld page faults (%d%% memcpy)\n", PREFIX, - ru->ru_minflt + ru->ru_majflt, - (int)((long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) * - 100)); - } - if (ru->ru_nvcsw + ru->ru_nivcsw > 1) { - fprintf(stderr, "%s%,ld context switches (%d%% consensual)\n", PREFIX, - ru->ru_nvcsw + ru->ru_nivcsw, - (int)((long double)ru->ru_nvcsw / (ru->ru_nvcsw + ru->ru_nivcsw) * - 100)); - } - if (ru->ru_msgrcv || ru->ru_msgsnd) { - fprintf(stderr, "%sreceived %,ld message%s and sent %,ld\n", PREFIX, - ru->ru_msgrcv, ru->ru_msgrcv == 1 ? "" : "s", ru->ru_msgsnd); - } - if (ru->ru_inblock || ru->ru_oublock) { - fprintf(stderr, "%sperformed %,ld read%s and %,ld write i/o operations\n", - PREFIX, ru->ru_inblock, ru->ru_inblock == 1 ? "" : "s", - ru->ru_oublock); - } - if (ru->ru_nsignals) { - fprintf(stderr, "%sreceived %,ld signals\n", PREFIX, ru->ru_nsignals); - } - if (ru->ru_nswap) { - fprintf(stderr, "%sgot swapped %,ld times\n", PREFIX, ru->ru_nswap); - } -} - -struct rusage rusage; int main(int argc, char *argv[]) { - int pid, wstatus; - long double ts1, ts2; - sigset_t chldmask, savemask; - struct sigaction dflt, ignore, saveint, savequit; + + const char *prog = argv[0]; + if (!prog) prog = "rusage"; + if (argc < 2) { - fprintf(stderr, "Usage: %s PROG [ARGS...]\n", argv[0]); - return 1; + tinyprint(2, prog, ": missing command\n", NULL); + exit(1); } - dflt.sa_flags = 0; - dflt.sa_handler = SIG_DFL; - sigemptyset(&dflt.sa_mask); + + // block process management signals + sigset_t mask, orig; + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGQUIT); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &mask, &orig); + + struct timespec started = timespec_real(); + + // launch subprocess + int child = fork(); + if (child == -1) { + perror(prog); + exit(1); + } + if (!child) { + sigprocmask(SIG_SETMASK, &orig, 0); + execvp(argv[1], argv + 1); + _Exit(127); + } + + // wait for subprocess + int ws; + struct rusage ru; + struct sigaction ignore; ignore.sa_flags = 0; ignore.sa_handler = SIG_IGN; sigemptyset(&ignore.sa_mask); - sigaction(SIGINT, &ignore, &saveint); - sigaction(SIGQUIT, &ignore, &savequit); - sigemptyset(&chldmask); - sigaddset(&chldmask, SIGCHLD); - sigprocmask(SIG_BLOCK, &chldmask, &savemask); - ts1 = nowl(); - CHECK_NE(-1, (pid = fork())); - if (!pid) { - sigaction(SIGINT, &dflt, 0); - sigaction(SIGQUIT, &dflt, 0); - sigprocmask(SIG_SETMASK, &savemask, 0); - execvp(argv[1], argv + 1); - fprintf(stderr, "exec failed %d\n", errno); - _Exit(127); + sigaction(SIGINT, &ignore, 0); + sigaction(SIGQUIT, &ignore, 0); + if (wait4(child, &ws, 0, &ru) == -1) { + perror(prog); + exit(1); } - while (wait4(pid, &wstatus, 0, &rusage) == -1) { - CHECK_EQ(EINTR, errno); - } - ts2 = nowl(); - sigaction(SIGINT, &saveint, 0); - sigaction(SIGQUIT, &savequit, 0); - sigprocmask(SIG_SETMASK, &savemask, 0); - fprintf(stderr, "%stook %,ldµs wall time\n", PREFIX, - (int64_t)((ts2 - ts1) * 1e6)); - PrintResourceReport(&rusage); - if (WIFEXITED(wstatus)) { - return WEXITSTATUS(wstatus); - } else { - return 128 + WTERMSIG(wstatus); + + // compute wall time + char strmicros[27]; + struct timespec ended = timespec_real(); + struct timespec elapsed = timespec_sub(ended, started); + FormatInt64Thousands(strmicros, timespec_tomicros(elapsed)); + + // show report + char *b = 0; + appends(&b, "took "); + appends(&b, strmicros); + appends(&b, "µs wall time\n"); + AppendResourceReport(&b, &ru, "\n"); + write(2, b, appendz(b).i); + + // propagate status + if (WIFSIGNALED(ws)) { + signal(WTERMSIG(ws), SIG_DFL); + raise(WTERMSIG(ws)); } + return WEXITSTATUS(ws); } diff --git a/examples/unbourne.c b/examples/unbourne.c index f85709c00..a643f3c68 100644 --- a/examples/unbourne.c +++ b/examples/unbourne.c @@ -129,6 +129,7 @@ #include "libc/macros.internal.h" #include "libc/mem/alg.h" #include "libc/mem/alloca.h" +#include "libc/mem/gc.internal.h" #include "libc/mem/mem.h" #include "libc/paths.h" #include "libc/runtime/runtime.h" @@ -1787,7 +1788,7 @@ static int xvsnprintf(char *outbuf, unsigned length, const char *fmt, return ret; } -static int xvasprintf(char **sp, unsigned size, const char *f, va_list ap) { +static int Xvasprintf(char **sp, unsigned size, const char *f, va_list ap) { char *s; int len; va_list ap2; @@ -1858,7 +1859,7 @@ printfesque(2) static int Xasprintf(char **sp, const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); - ret = xvasprintf(sp, 0, fmt, ap); + ret = Xvasprintf(sp, 0, fmt, ap); va_end(ap); return ret; } @@ -1871,7 +1872,7 @@ static void doformat(struct output *dest, const char *f, va_list ap) { setstackmark(&smark); s = dest->nextc; olen = dest->end - dest->nextc; - len = xvasprintf(&s, olen, f, ap); + len = Xvasprintf(&s, olen, f, ap); if (likely(olen > len)) { dest->nextc += len; goto out; @@ -5821,7 +5822,9 @@ retry: linenoiseSetHintsCallback(ShellHint); linenoiseSetCompletionCallback(ShellCompletion); } - if ((p = linenoiseWithHistory(">: ", "unbourne"))) { + char ps1[256]; + snprintf(ps1, sizeof(ps1), "%d >: ", exitstatus); + if ((p = linenoiseWithHistory(ps1, "unbourne"))) { nr = min(strlen(p), IBUFSIZ - 2); memcpy(buf, p, nr); buf[nr++] = '\n'; diff --git a/third_party/python/freeze.c b/third_party/python/freeze.c index bf01f43d0..a77a76326 100644 --- a/third_party/python/freeze.c +++ b/third_party/python/freeze.c @@ -7,6 +7,7 @@ #include "libc/assert.h" #include "libc/log/log.h" #include "libc/mem/mem.h" +#include "libc/runtime/stack.h" #include "third_party/python/Include/bytesobject.h" #include "third_party/python/Include/compile.h" #include "third_party/python/Include/fileutils.h" @@ -18,6 +19,8 @@ #include "third_party/python/Include/pythonrun.h" /* clang-format off */ +STATIC_STACK_ALIGN(GetStackSize()); + #define HEADER "\ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│\n\ │vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│\n\ diff --git a/third_party/python/launch.c b/third_party/python/launch.c index 89c4a6e60..b9c0512e9 100644 --- a/third_party/python/launch.c +++ b/third_party/python/launch.c @@ -13,6 +13,7 @@ #include "libc/log/log.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/stack.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" #include "third_party/python/Include/abstract.h" @@ -39,6 +40,8 @@ #include "third_party/python/Include/yoink.h" /* clang-format off */ +STATIC_STACK_ALIGN(GetStackSize()); + #define USE_COSMO_CRASH MODE_DBG + 0 __static_yoink("zipos"); diff --git a/third_party/python/pyobj.c b/third_party/python/pyobj.c index 75c37d088..1084ace26 100644 --- a/third_party/python/pyobj.c +++ b/third_party/python/pyobj.c @@ -29,6 +29,7 @@ #include "libc/mem/gc.internal.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/stack.h" #include "libc/stdio/append.h" #include "libc/stdio/stdio.h" #include "libc/sysv/consts/clock.h" @@ -64,6 +65,8 @@ #include "tool/build/lib/stripcomponents.h" /* clang-format off */ +STATIC_STACK_ALIGN(GetStackSize()); + __static_yoink("_PyUnicode_GetCode"); #define MANUAL "\ diff --git a/third_party/python/pythontester.c b/third_party/python/pythontester.c index 206a84def..f5f4cfbba 100644 --- a/third_party/python/pythontester.c +++ b/third_party/python/pythontester.c @@ -6,11 +6,14 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/log/log.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/stack.h" #include "third_party/python/Include/yoink.h" #include "third_party/python/runpythonmodule.h" #include "tool/args/args.h" // clang-format off +STATIC_STACK_ALIGN(GetStackSize()); + int main(int argc, char **argv) { diff --git a/third_party/python/repl.c b/third_party/python/repl.c index 412790e79..8741cb007 100644 --- a/third_party/python/repl.c +++ b/third_party/python/repl.c @@ -4,11 +4,14 @@ │ Python 3 │ │ https://docs.python.org/3/license.html │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/stack.h" #include "third_party/python/Include/yoink.h" #include "third_party/python/runpythonmodule.h" #include "tool/args/args.h" // clang-format off +STATIC_STACK_ALIGN(GetStackSize()); + int main(int argc, char **argv) {