diff --git a/libc/testlib/BUILD.mk b/libc/testlib/BUILD.mk index 5de84b1d2..a81790c86 100644 --- a/libc/testlib/BUILD.mk +++ b/libc/testlib/BUILD.mk @@ -215,6 +215,7 @@ LIBC_TESTMAIN_DIRECTDEPS = \ LIBC_LOG \ LIBC_MEM \ LIBC_NEXGEN32E \ + LIBC_PROC \ LIBC_RUNTIME \ LIBC_STDIO \ LIBC_SYSV \ @@ -222,7 +223,7 @@ LIBC_TESTMAIN_DIRECTDEPS = \ LIBC_TESTLIB \ LIBC_TESTLIB_RUNNER \ THIRD_PARTY_DLMALLOC \ - THIRD_PARTY_GETOPT + THIRD_PARTY_GETOPT \ LIBC_TESTMAIN_DEPS := \ $(call uniq,$(foreach x,$(LIBC_TESTMAIN_DIRECTDEPS),$($(x)))) diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c index 923f02608..538ca3ec5 100644 --- a/libc/testlib/testmain.c +++ b/libc/testlib/testmain.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/struct/cpuset.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/siginfo.h" @@ -31,6 +32,7 @@ #include "libc/intrin/strace.h" #include "libc/intrin/ubsan.h" #include "libc/intrin/weaken.h" +#include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.h" #include "libc/mem/leaks.h" @@ -52,6 +54,8 @@ #include "libc/thread/tls.h" #include "third_party/getopt/getopt.internal.h" +#pragma weak main + #define USAGE \ " [FLAGS]\n\ \n\ @@ -88,7 +92,41 @@ static void GetOpts(int argc, char *argv[]) { } } -#pragma weak main +static int rando(void) { + return _rand64() & INT_MAX; +} + +static void limit_process_to_single_cpu(void) { + extern int disable_limit_process_to_single_cpu; + if (_weaken(disable_limit_process_to_single_cpu)) + return; + if (!(IsLinux() || IsFreebsd() || IsNetbsd() || IsWindows())) + return; + if (IsFreebsd() && getuid()) + return; + cpu_set_t legal; + if (sched_getaffinity(0, sizeof(cpu_set_t), &legal) == -1) { + perror("sched_setaffinity failed"); + exit(1); + } + int count = CPU_COUNT(&legal); + cpu_set_t newset; + CPU_ZERO(&newset); + bool done = false; + while (!done) { + for (int i = 0; i < CPU_SETSIZE; ++i) { + if (CPU_ISSET(i, &legal) && !(rando() % count)) { + CPU_SET(rando() % count, &newset); + done = true; + break; + } + } + } + if (sched_setaffinity(0, sizeof(cpu_set_t), &newset) == -1) { + perror("sched_setaffinity failed"); + exit(1); + } +} /** * Generic test program main function. @@ -108,8 +146,11 @@ int main(int argc, char *argv[]) { return 1; } + // // this sometimes helps tease out mt bugs + // limit_process_to_single_cpu(); + // test huge pointers by enabling pml5t - if (_rand64() % 2) { + if (rando() % 2) { errno_t e = errno; mmap((char *)0x80000000000000, 1, PROT_NONE, // MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); diff --git a/test/libc/proc/sched_getaffinity_test.c b/test/libc/proc/sched_getaffinity_test.c index 33d3c16e5..dad9c1b26 100644 --- a/test/libc/proc/sched_getaffinity_test.c +++ b/test/libc/proc/sched_getaffinity_test.c @@ -30,6 +30,8 @@ #include "libc/thread/thread.h" #include "libc/thread/thread2.h" +int disable_limit_process_to_single_cpu; + void SetUp(void) { if (!IsLinux() && !IsFreebsd() && !IsWindows()) { exit(0);