nproc: Expose processor count and use it to pick between yielding and non-yielding spin locks

This commit is contained in:
K. Lange 2021-09-02 17:27:21 +09:00
parent 0d71c98cc2
commit 98bcb40671
7 changed files with 43 additions and 5 deletions

15
apps/nproc.c Normal file
View File

@ -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 <stdio.h>
#include <sys/sysfunc.h>
int main(int argc, char * argv[]) {
printf("%d\n", sysfunc(TOARU_SYS_FUNC_NPROC, NULL));
return 0;
}

View File

@ -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);

View File

@ -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;

View File

@ -4,6 +4,7 @@
#include <syscall.h>
#include <syscall_nums.h>
#include <sys/sysfunc.h>
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;

View File

@ -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;
}

View File

@ -9,7 +9,12 @@
#include <sys/wait.h>
#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();
}
}

View File

@ -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;
}