nproc: Expose processor count and use it to pick between yielding and non-yielding spin locks
This commit is contained in:
parent
0d71c98cc2
commit
98bcb40671
15
apps/nproc.c
Normal file
15
apps/nproc.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user