1818╚─────────────────────────────────────────────────────────────────────────────*/
1919#include "libc/assert.h"
2020#include "libc/calls/calls.h"
21+ #include "libc/calls/struct/cpuset.h"
2122#include "libc/calls/struct/rlimit.h"
2223#include "libc/calls/struct/sigaction.h"
2324#include "libc/calls/struct/siginfo.h"
3132#include "libc/intrin/strace.h"
3233#include "libc/intrin/ubsan.h"
3334#include "libc/intrin/weaken.h"
35+ #include "libc/limits.h"
3436#include "libc/log/log.h"
3537#include "libc/macros.h"
3638#include "libc/mem/leaks.h"
5254#include "libc/thread/tls.h"
5355#include "third_party/getopt/getopt.internal.h"
5456
57+ #pragma weak main
58+
5559#define USAGE \
5660 " [FLAGS]\n\
5761\n\
@@ -88,7 +92,41 @@ static void GetOpts(int argc, char *argv[]) {
8892 }
8993}
9094
91- #pragma weak main
95+ static int rando (void ) {
96+ return _rand64 () & INT_MAX ;
97+ }
98+
99+ static void limit_process_to_single_cpu (void ) {
100+ extern int disable_limit_process_to_single_cpu ;
101+ if (_weaken (disable_limit_process_to_single_cpu ))
102+ return ;
103+ if (!(IsLinux () || IsFreebsd () || IsNetbsd () || IsWindows ()))
104+ return ;
105+ if (IsFreebsd () && getuid ())
106+ return ;
107+ cpu_set_t legal ;
108+ if (sched_getaffinity (0 , sizeof (cpu_set_t ), & legal ) == -1 ) {
109+ perror ("sched_setaffinity failed" );
110+ exit (1 );
111+ }
112+ int count = CPU_COUNT (& legal );
113+ cpu_set_t newset ;
114+ CPU_ZERO (& newset );
115+ bool done = false;
116+ while (!done ) {
117+ for (int i = 0 ; i < CPU_SETSIZE ; ++ i ) {
118+ if (CPU_ISSET (i , & legal ) && !(rando () % count )) {
119+ CPU_SET (rando () % count , & newset );
120+ done = true;
121+ break ;
122+ }
123+ }
124+ }
125+ if (sched_setaffinity (0 , sizeof (cpu_set_t ), & newset ) == -1 ) {
126+ perror ("sched_setaffinity failed" );
127+ exit (1 );
128+ }
129+ }
92130
93131/**
94132 * Generic test program main function.
@@ -108,8 +146,11 @@ int main(int argc, char *argv[]) {
108146 return 1 ;
109147 }
110148
149+ // // this sometimes helps tease out mt bugs
150+ // limit_process_to_single_cpu();
151+
111152 // test huge pointers by enabling pml5t
112- if (_rand64 () % 2 ) {
153+ if (rando () % 2 ) {
113154 errno_t e = errno ;
114155 mmap ((char * )0x80000000000000 , 1 , PROT_NONE , //
115156 MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0 );
0 commit comments