From dbebef0e0359827c8a55fa893066b815d6d86f31 Mon Sep 17 00:00:00 2001 From: Matheus Date: Thu, 21 Aug 2025 20:46:06 -0300 Subject: [PATCH] scheduler: implement nice --- kernel-src/arch/x86-64/syscall.asm | 4 +- kernel-src/arch/x86-64/syscalllog.c | 10 +++-- kernel-src/include/kernel/auth.h | 1 + kernel-src/include/kernel/proc.h | 1 + kernel-src/include/kernel/scheduler.h | 2 + kernel-src/include/kernel/thread.h | 4 +- kernel-src/sys/defaultauth.c | 7 ++++ kernel-src/sys/scheduler/metrics.c | 7 ++-- kernel-src/sys/scheduler/scheduler.c | 9 +---- kernel-src/sys/syscalls/nice.c | 17 ++++++++ kernel-src/sys/thread.c | 4 +- patches/mlibc/jinx-working-patch.patch | 55 ++++++++++++++++++++------ 12 files changed, 89 insertions(+), 32 deletions(-) create mode 100644 kernel-src/sys/syscalls/nice.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 7418b416..dd44f043 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -92,6 +92,7 @@ extern syscall_sigtimedwait extern syscall_sigpending extern syscall_killthread extern syscall_shutdown +extern syscall_nice syscalltab: dq syscall_print dq syscall_mmap @@ -186,7 +187,8 @@ dq syscall_sigtimedwait dq syscall_sigpending dq syscall_killthread dq syscall_shutdown -syscallcount equ 93 +dq syscall_nice +syscallcount equ 94 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/arch/x86-64/syscalllog.c b/kernel-src/arch/x86-64/syscalllog.c index 20ffc9ac..b997b190 100644 --- a/kernel-src/arch/x86-64/syscalllog.c +++ b/kernel-src/arch/x86-64/syscalllog.c @@ -5,7 +5,7 @@ #ifdef SYSCALL_LOGGING -#define SYSCALL_COUNT 93 +#define SYSCALL_COUNT 94 #define LOGSTR(x) arch_e9_puts(x) static char *name[] = { @@ -101,7 +101,8 @@ static char *name[] = { "sigtimedwait", "sigpending", "killthread", - "shutdown" + "shutdown", + "nice" }; static char *args[] = { @@ -195,9 +196,10 @@ static char *args[] = { "egid %d", // setegid "sigset %p", // sigsuspend "sigset %p info %p, timespec %p", // sigtimedwait - "sigset %p\n", // sigpending + "sigset %p", // sigpending "pid %d tid %d signal %d", // killthread - "how %d" // shutdown + "how %d", // shutdown + "off %d" // nice }; #endif diff --git a/kernel-src/include/kernel/auth.h b/kernel-src/include/kernel/auth.h index 6cd81692..305c9a97 100644 --- a/kernel-src/include/kernel/auth.h +++ b/kernel-src/include/kernel/auth.h @@ -38,6 +38,7 @@ #define AUTH_ACTIONS_CRED_SETEGID 32 #define AUTH_ACTIONS_PROCESS_SIGNAL 1 +#define AUTH_ACTIONS_PROCESS_NICE 2 #define AUTH_ACTIONS_NETWORK_CONFIGURE 1 #define AUTH_ACTIONS_NETWORK_BINDRESERVED 2 diff --git a/kernel-src/include/kernel/proc.h b/kernel-src/include/kernel/proc.h index b9df6768..ac487fc7 100644 --- a/kernel-src/include/kernel/proc.h +++ b/kernel-src/include/kernel/proc.h @@ -41,6 +41,7 @@ typedef struct proc_t { spinlock_t nodeslock; semaphore_t waitsem; spinlock_t exiting; + int nice; spinlock_t jobctllock; struct { diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 20167500..1785e3f0 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -13,6 +13,8 @@ #define SCHED_RUN_QUEUE_SIZE 32 #define SCHED_MAX_INTERACTIVITY 100 +#define SCHED_NICE_MAX 19 +#define SCHED_NICE_MIN -20 typedef struct { struct { diff --git a/kernel-src/include/kernel/thread.h b/kernel-src/include/kernel/thread.h index 131596a4..ae3a551e 100644 --- a/kernel-src/include/kernel/thread.h +++ b/kernel-src/include/kernel/thread.h @@ -37,7 +37,6 @@ typedef struct thread_t { vmmcontext_t *vmmctx; tid_t tid; int flags; - long priority; bool sleepintstatus; spinlock_t sleeplock; int wakeupreason; @@ -45,6 +44,7 @@ typedef struct thread_t { void *kernelarg; context_t *usercopyctx; int class; + int nice; struct { spinlock_t lock; eventheader_t waitpendingevent; @@ -67,7 +67,7 @@ typedef struct thread_t { } thread_t; __attribute__((noreturn)) void sched_threadexit(); -thread_t *sched_newthread(void *ip, size_t kstacksize, int priority, struct proc_t *proc, void *ustack); +thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, struct proc_t *proc, void *ustack); void sched_destroythread(thread_t *); #endif diff --git a/kernel-src/sys/defaultauth.c b/kernel-src/sys/defaultauth.c index 33f1650f..c9664610 100644 --- a/kernel-src/sys/defaultauth.c +++ b/kernel-src/sys/defaultauth.c @@ -264,6 +264,13 @@ static int process(cred_t *cred, int actions, void *arg0, void *arg1, void *arg2 DONE_CHECK(actions); } + if (actions & AUTH_ACTIONS_PROCESS_NICE) { + if (CRED_IS_ESU(cred)) + weight += 1; + + DONE_CHECK(actions); + } + done: return weight ? AUTH_DECISION_ALLOW : AUTH_DECISION_DEFER; } diff --git a/kernel-src/sys/scheduler/metrics.c b/kernel-src/sys/scheduler/metrics.c index 11434b92..b9406481 100644 --- a/kernel-src/sys/scheduler/metrics.c +++ b/kernel-src/sys/scheduler/metrics.c @@ -11,11 +11,12 @@ static void update_interactivity(thread_t *thread) { time_t run_time = thread->metrics.run_time_avg_us; if (sleep_time > run_time) - thread->metrics.interactivity_score = min((SCALING_FACTOR * run_time) / sleep_time, SCHED_MAX_INTERACTIVITY); + thread->metrics.interactivity_score = (SCALING_FACTOR * run_time) / sleep_time; else - thread->metrics.interactivity_score = min((SCALING_FACTOR * sleep_time) / run_time + SCALING_FACTOR, SCHED_MAX_INTERACTIVITY); + thread->metrics.interactivity_score = (SCALING_FACTOR * sleep_time) / run_time + SCALING_FACTOR; - // TODO nice value impacting this + thread->metrics.interactivity_score += thread->nice + (thread->proc ? thread->proc->nice : 0); + thread->metrics.interactivity_score = min(thread->metrics.interactivity_score, SCHED_MAX_INTERACTIVITY); } static void offset_times(thread_t *thread, time_t run_us, time_t sleep_us) { diff --git a/kernel-src/sys/scheduler/scheduler.c b/kernel-src/sys/scheduler/scheduler.c index c78e06a1..01834107 100644 --- a/kernel-src/sys/scheduler/scheduler.c +++ b/kernel-src/sys/scheduler/scheduler.c @@ -310,15 +310,10 @@ void sched_reschedule_on_cpu(cpu_t *cpu, bool target) { if (cpu == current_cpu()) goto leave; - long old_priority = current_thread()->priority; - current_thread()->priority = 0; - sched_thread_stopping_callback(current_thread(), false); arch_context_saveandcall(reschedule_yield, current_cpu()->schedulerstack, cpu); - current_thread()->priority = old_priority; - leave: interrupt_set(status); if (target == false) @@ -354,7 +349,7 @@ void sched_ap_entry() { __assert(current_cpu()->schedulerstack); current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE); - current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL); + current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 100, NULL, NULL); __assert(current_cpu()->idlethread); current_cpu()->idlethread->class = THREAD_CLASS_IDLE; sched_queue(current_cpu()->idlethread); @@ -382,7 +377,7 @@ void sched_init() { __assert(current_cpu()->schedulerstack); current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE); - current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL); + current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 100, NULL, NULL); __assert(current_cpu()->idlethread); current_cpu()->idlethread->class = THREAD_CLASS_IDLE; current_cpu()->thread = sched_newthread(NULL, PAGE_SIZE * 32, 0, NULL, NULL); diff --git a/kernel-src/sys/syscalls/nice.c b/kernel-src/sys/syscalls/nice.c new file mode 100644 index 00000000..d59e383b --- /dev/null +++ b/kernel-src/sys/syscalls/nice.c @@ -0,0 +1,17 @@ +#include +#include +#include + +syscallret_t syscall_nice(context_t *, int nice) { + syscallret_t ret; + + + if (nice < 0) { + + } + + current_thread()->proc->nice = max(min(current_thread()->proc->nice + nice, SCHED_NICE_MAX), SCHED_NICE_MIN); + + ret.ret = current_thread()->proc->nice; + return ret; +} diff --git a/kernel-src/sys/thread.c b/kernel-src/sys/thread.c index b091529c..ca11b9a2 100644 --- a/kernel-src/sys/thread.c +++ b/kernel-src/sys/thread.c @@ -5,7 +5,7 @@ static scache_t *thread_cache; -thread_t *sched_newthread(void *ip, size_t kstacksize, int priority, proc_t *proc, void *ustack) { +thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, void *ustack) { if (thread_cache == NULL) { thread_cache = slab_newcache(sizeof(thread_t), 0, NULL, NULL); __assert(thread_cache); @@ -28,8 +28,8 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int priority, proc_t *pro // non kernel thread vmm contexts are handled by the caller thread->vmmctx = proc ? NULL : &vmm_kernelctx; thread->proc = proc; - thread->priority = priority; thread->kernelstacksize = kstacksize; + thread->nice = nice; if (proc) { // each thread holds one reference to proc PROC_HOLD(proc); diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index 995be358..f40421b6 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -95,21 +95,42 @@ index fc34a3b..b1a95a9 100644 #include diff --git mlibc-clean/options/posix/generic/unistd.cpp mlibc-workdir/options/posix/generic/unistd.cpp -index 444ad22..d1ca86e 100644 +index 444ad22..44205bd 100644 --- mlibc-clean/options/posix/generic/unistd.cpp +++ mlibc-workdir/options/posix/generic/unistd.cpp -@@ -484,8 +484,9 @@ int lockf(int fd, int op, off_t size) { +@@ -483,9 +483,16 @@ int lockf(int fd, int op, off_t size) { + return -1; } - int nice(int) { +-int nice(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -+ return EPERM; -+ //__ensure(!"Not implemented"); -+ //__builtin_unreachable(); ++int nice(int nice) { ++ int new_nice; ++ ++ MLIBC_CHECK_OR_ENOSYS(mlibc::sys_nice, -1); ++ if(int e = mlibc::sys_nice(nice, &new_nice); e) { ++ errno = e; ++ return -1; ++ } ++ ++ return new_nice; } long pathconf(const char *, int name) { +diff --git mlibc-clean/options/posix/include/mlibc/posix-sysdeps.hpp mlibc-workdir/options/posix/include/mlibc/posix-sysdeps.hpp +index a224474..21a1046 100644 +--- mlibc-clean/options/posix/include/mlibc/posix-sysdeps.hpp ++++ mlibc-workdir/options/posix/include/mlibc/posix-sysdeps.hpp +@@ -236,6 +236,8 @@ int sys_vm_unmap(void *pointer, size_t size); + + [[gnu::weak]] int sys_waitid(idtype_t idtype, id_t id, siginfo_t *info, int options); + ++[[gnu::weak]] int sys_nice(int nice, int *ret); ++ + } //namespace mlibc + + #endif // MLIBC_POSIX_SYSDEPS diff --git mlibc-clean/options/rtld/generic/main.cpp mlibc-workdir/options/rtld/generic/main.cpp index 9219ef0..1ff679c 100644 --- mlibc-clean/options/rtld/generic/main.cpp @@ -137,7 +158,7 @@ index d5ba7b2..a86353f 100644 long error = syscall(SYSCALL_ARCHCTL, &ret, func, (uint64_t)arg); if(error) diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp -index 2a504ab..3c46318 100644 +index 2a504ab..6a7c882 100644 --- mlibc-clean/sysdeps/astral/generic/generic.cpp +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp @@ -31,6 +31,12 @@ namespace mlibc { @@ -153,10 +174,17 @@ index 2a504ab..3c46318 100644 int sys_getsockopt(int fd, int layer, int number, void *__restrict buffer, socklen_t *__restrict size) { (void)size; -@@ -40,6 +46,11 @@ namespace mlibc { +@@ -40,6 +46,18 @@ namespace mlibc { return 0; } ++ int sys_nice(int nice, int *ret) { ++ long r = -1; ++ long e = syscall(SYSCALL_NICE, &r, nice); ++ *ret = r; ++ return e; ++ } ++ + int sys_shutdown(int sockfd, int how) { + long ret; + return syscall(SYSCALL_SHUTDOWN, &ret, sockfd, how); @@ -165,7 +193,7 @@ index 2a504ab..3c46318 100644 int sys_tgkill(int pid, int tid, int sig) { long ret; return syscall(SYSCALL_KILLTHREAD, &ret, pid, tid, sig); -@@ -161,7 +172,18 @@ namespace mlibc { +@@ -161,7 +179,18 @@ namespace mlibc { *bytes_written = writec; return error; } @@ -185,7 +213,7 @@ index 2a504ab..3c46318 100644 #ifndef MLIBC_BUILDING_RTLD typedef struct { -@@ -487,6 +509,12 @@ namespace mlibc { +@@ -487,6 +516,12 @@ namespace mlibc { return ret; } @@ -198,7 +226,7 @@ index 2a504ab..3c46318 100644 #ifndef MLIBC_BUILDING_RTLD [[noreturn]] void sys_thread_exit() { -@@ -882,7 +910,7 @@ namespace mlibc { +@@ -882,7 +917,7 @@ namespace mlibc { int sys_tcb_set(void *pointer) { long r; @@ -225,14 +253,15 @@ index d738e02..7e4f2a1 100644 #ifdef __cplusplus extern "C" { diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h -index 5f42d62..852f9ff 100644 +index 5f42d62..09a5d5f 100644 --- mlibc-clean/sysdeps/astral/include/astral/syscall.h +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -96,6 +96,7 @@ +@@ -96,6 +96,8 @@ #define SYSCALL_SIGTIMEDWAIT 89 #define SYSCALL_SIGPENDING 90 #define SYSCALL_KILLTHREAD 91 +#define SYSCALL_SHUTDOWN 92 ++#define SYSCALL_NICE 93 #ifndef __MLIBC_ABI_ONLY