Index: lib/libc/dlfcn/init.c =================================================================== RCS file: /cvs/src/lib/libc/dlfcn/init.c,v diff -u -p -r1.24 init.c --- lib/libc/dlfcn/init.c 22 Jul 2024 22:06:27 -0000 1.24 +++ lib/libc/dlfcn/init.c 2 Oct 2024 21:03:02 -0000 @@ -21,6 +21,7 @@ #include #include #include /* timekeep */ +#include /* ncpus */ #ifndef PIC #include @@ -51,6 +52,7 @@ int _pagesize = 0; struct timekeep *_timekeep; unsigned long _hwcap, _hwcap2; int _hwcap_avail, _hwcap2_avail; +int _ncpus; /* * In dynamically linked binaries environ and __progname are overridden by @@ -130,6 +132,9 @@ _libc_preinit(int argc, char **argv, cha if (issetugid() == 0 && getenv("LIBC_NOUSERTC")) _timekeep = NULL; break; + case AUX_openbsd_ncpus: + _ncpus = aux->au_v; + break; } } @@ -167,6 +172,14 @@ _libc_preinit(int argc, char **argv, cha } } #endif /* !PIC */ + + if (_ncpus == 0) { + int mib[] = { CTL_HW, HW_NCPU }; + size_t len = sizeof(_ncpus); + + (void)sysctl(mib, sizeof(mib) / sizeof(mib[0]), + &_ncpus, &len, NULL, 0); + } } /* ARM just had to be different... */ Index: lib/libc/gen/sysconf.c =================================================================== RCS file: /cvs/src/lib/libc/gen/sysconf.c,v diff -u -p -r1.28 sysconf.c --- lib/libc/gen/sysconf.c 19 Jul 2022 09:25:44 -0000 1.28 +++ lib/libc/gen/sysconf.c 2 Oct 2024 21:03:02 -0000 @@ -45,6 +45,8 @@ #include #include +extern int _ncpus; /* passed by the kernel as an aux vector value */ + /* * sysconf -- * get configurable system variables. @@ -461,6 +463,8 @@ sysconf(int name) } case _SC_NPROCESSORS_CONF: + if (_ncpus != 0) + return (_ncpus); mib[0] = CTL_HW; mib[1] = HW_NCPU; break; Index: lib/libc/include/thread_private.h =================================================================== RCS file: /cvs/src/lib/libc/include/thread_private.h,v diff -u -p -r1.37 thread_private.h --- lib/libc/include/thread_private.h 18 Aug 2024 02:25:51 -0000 1.37 +++ lib/libc/include/thread_private.h 2 Oct 2024 21:03:02 -0000 @@ -6,6 +6,7 @@ #define _THREAD_PRIVATE_H_ extern int __isthreaded; +extern int _ncpus; #define _MALLOC_MUTEXES 32 void _malloc_init(int); Index: lib/libc/thread/rthread.c =================================================================== RCS file: /cvs/src/lib/libc/thread/rthread.c,v diff -u -p -r1.9 rthread.c --- lib/libc/thread/rthread.c 12 Oct 2020 22:06:51 -0000 1.9 +++ lib/libc/thread/rthread.c 2 Oct 2024 21:03:02 -0000 @@ -43,11 +46,43 @@ struct pthread _initial_thread = { /* * internal support functions */ + +/* + * Wait for the spinlock to become unlocked. + * + * On uniprocessor systems it is pointless to spin waiting for + * another thread to release the lock because this thread occupies + * the only CPU, preventing the thread holding the lock from running + * and leaving the critical section. + * + * On multiprocessor systems we spin, but not forever in case there + * are more threads than CPUs still, and more progress might be made + * if we can get the other thread to run. + */ + +static inline void +_spinlock_wait(volatile _atomic_lock_t *lock) +{ + do { + if (_ncpus > 1) { + unsigned int spin; + + for (spin = 0; spin < SPIN_COUNT; spin++) { + SPIN_WAIT(); + if (*lock == _ATOMIC_LOCK_UNLOCKED) + return; + } + } + + sched_yield(); + } while (*lock != _ATOMIC_LOCK_UNLOCKED); +} + void _spinlock(volatile _atomic_lock_t *lock) { while (_atomic_lock(lock)) - sched_yield(); + _spinlock_wait(lock); membar_enter_after_atomic(); } DEF_STRONG(_spinlock); Index: sys/kern/exec_elf.c =================================================================== RCS file: /cvs/src/sys/kern/exec_elf.c,v diff -u -p -r1.191 exec_elf.c --- sys/kern/exec_elf.c 15 Sep 2024 23:13:19 -0000 1.191 +++ sys/kern/exec_elf.c 2 Oct 2024 21:03:02 -0000 @@ -1023,6 +1023,10 @@ exec_elf_fixup(struct proc *p, struct ex a->au_v = p->p_p->ps_timekeep; a++; + a->au_id = AUX_openbsd_ncpus; + a->au_v = ncpus; + a++; + a->au_id = AUX_null; a->au_v = 0; a++; Index: sys/sys/exec_elf.h =================================================================== RCS file: /cvs/src/sys/sys/exec_elf.h,v diff -u -p -r1.105 exec_elf.h --- sys/sys/exec_elf.h 14 Jul 2024 09:48:49 -0000 1.105 +++ sys/sys/exec_elf.h 2 Oct 2024 21:03:02 -0000 @@ -734,6 +734,7 @@ enum AuxID { AUX_sun_gid = 2002, /* egid */ AUX_sun_rgid = 2003, /* rgid */ AUX_openbsd_timekeep = 4000, /* userland clock_gettime */ + AUX_openbsd_ncpus = 4001, /* ncpus */ }; struct elf_args { @@ -822,7 +823,7 @@ extern Elf_Dyn _DYNAMIC[]; /* * How many entries are in the AuxInfo array we pass to the process? */ -#define ELF_AUX_ENTRIES 11 +#define ELF_AUX_ENTRIES 12 #define ELF_AUX_WORDS (sizeof(AuxInfo) * ELF_AUX_ENTRIES / sizeof(char *)) struct exec_package;