From 98bcb406715c4da860752c39662d68ba29f4180d Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Thu, 2 Sep 2021 17:27:21 +0900 Subject: [PATCH] nproc: Expose processor count and use it to pick between yielding and non-yielding spin locks --- apps/nproc.c | 15 +++++++++++++++ base/usr/include/sys/sysfunc.h | 1 + kernel/sys/syscall.c | 3 +++ libc/main.c | 3 +++ libc/pthread/pthread.c | 7 ++++++- libc/pthread/pthread_rwlock.c | 11 ++++++++--- libc/stdlib/malloc.c | 8 +++++++- 7 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 apps/nproc.c diff --git a/apps/nproc.c b/apps/nproc.c new file mode 100644 index 00000000..53fbd637 --- /dev/null +++ b/apps/nproc.c @@ -0,0 +1,15 @@ +/** + * @brief Print the number of available processors. + * + * @copyright + * This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2018 K. Lange + */ +#include +#include + +int main(int argc, char * argv[]) { + printf("%d\n", sysfunc(TOARU_SYS_FUNC_NPROC, NULL)); + return 0; +} diff --git a/base/usr/include/sys/sysfunc.h b/base/usr/include/sys/sysfunc.h index 30d37475..71e5f9a2 100644 --- a/base/usr/include/sys/sysfunc.h +++ b/base/usr/include/sys/sysfunc.h @@ -21,6 +21,7 @@ #define TOARU_SYS_FUNC_THREADNAME 11 #define TOARU_SYS_FUNC_SETVGACURSOR 13 #define TOARU_SYS_FUNC_SETGSBASE 14 +#define TOARU_SYS_FUNC_NPROC 15 _Begin_C_Header extern int sysfunc(int command, char ** args); diff --git a/kernel/sys/syscall.c b/kernel/sys/syscall.c index 7a8807e6..ef51787e 100644 --- a/kernel/sys/syscall.c +++ b/kernel/sys/syscall.c @@ -149,6 +149,9 @@ static long sys_sysfunc(long fn, char ** args) { arch_set_tls_base(this_core->current_process->thread.context.tls_base); return 0; + case TOARU_SYS_FUNC_NPROC: + return processor_count; + default: printf("Bad system function: %ld\n", fn); return -EINVAL; diff --git a/libc/main.c b/libc/main.c index 091ed813..5a655e6b 100644 --- a/libc/main.c +++ b/libc/main.c @@ -4,6 +4,7 @@ #include #include +#include DEFN_SYSCALL1(exit, SYS_EXT, int); DEFN_SYSCALL2(sleepabs, SYS_SLEEPABS, unsigned long, unsigned long); @@ -33,6 +34,7 @@ void _exit(int val){ extern void __make_tls(void); +int __libc_is_multicore = 0; static int __libc_init_called = 0; __attribute__((constructor)) @@ -40,6 +42,7 @@ static void _libc_init(void) { __libc_init_called = 1; __make_tls(); __stdio_init_buffers(); + __libc_is_multicore = sysfunc(TOARU_SYS_FUNC_NPROC, NULL) > 1; unsigned int x = 0; unsigned int nulls = 0; diff --git a/libc/pthread/pthread.c b/libc/pthread/pthread.c index a03227c5..591eca1d 100644 --- a/libc/pthread/pthread.c +++ b/libc/pthread/pthread.c @@ -17,6 +17,11 @@ DEFN_SYSCALL3(clone, SYS_CLONE, uintptr_t, uintptr_t, void *); DEFN_SYSCALL0(gettid, SYS_GETTID); +extern int __libc_is_multicore; +static inline void _yield(void) { + if (!__libc_is_multicore) syscall_yield(); +} + #define PTHREAD_STACK_SIZE 0x100000 int clone(uintptr_t a,uintptr_t b,void* c) { @@ -89,7 +94,7 @@ void pthread_cleanup_pop(int execute) { int pthread_mutex_lock(pthread_mutex_t *mutex) { while (__sync_lock_test_and_set(mutex, 0x01)) { - syscall_yield(); + _yield(); } return 0; } diff --git a/libc/pthread/pthread_rwlock.c b/libc/pthread/pthread_rwlock.c index a6f9460c..2b7cd315 100644 --- a/libc/pthread/pthread_rwlock.c +++ b/libc/pthread/pthread_rwlock.c @@ -9,7 +9,12 @@ #include -#define ACQUIRE_LOCK() do { while (__sync_lock_test_and_set(&lock->atomic_lock, 0x01)) { syscall_yield(); } } while (0) +extern int __libc_is_multicore; +static inline void _yield(void) { + if (!__libc_is_multicore) syscall_yield(); +} + +#define ACQUIRE_LOCK() do { while (__sync_lock_test_and_set(&lock->atomic_lock, 0x01)) { _yield(); } } while (0) #define RELEASE_LOCK() do { __sync_lock_release(&lock->atomic_lock); } while (0) int pthread_rwlock_init(pthread_rwlock_t * lock, void * args) { @@ -31,7 +36,7 @@ int pthread_rwlock_wrlock(pthread_rwlock_t * lock) { RELEASE_LOCK(); return 0; } - syscall_yield(); + _yield(); } } @@ -43,7 +48,7 @@ int pthread_rwlock_rdlock(pthread_rwlock_t * lock) { RELEASE_LOCK(); return 0; } - syscall_yield(); + _yield(); } } diff --git a/libc/stdlib/malloc.c b/libc/stdlib/malloc.c index f690ccd3..7437a598 100644 --- a/libc/stdlib/malloc.c +++ b/libc/stdlib/malloc.c @@ -164,9 +164,15 @@ static void _malloc_assert(const char * file, int line, const char * func, const exit(1); } +extern int __libc_is_multicore; + +static inline void _yield(void) { + if (!__libc_is_multicore) syscall_yield(); +} + static void spin_lock(int volatile * lock, const char * caller) { while(__sync_lock_test_and_set(lock, 0x01)) { - syscall_yield(); + _yield(); } _lock_holder = caller; }