scheduler: implement nice

This commit is contained in:
Matheus
2025-08-21 20:46:06 -03:00
parent 3cf396393a
commit dbebef0e03
12 changed files with 89 additions and 32 deletions
+3 -1
View File
@@ -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:
+6 -4
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -41,6 +41,7 @@ typedef struct proc_t {
spinlock_t nodeslock;
semaphore_t waitsem;
spinlock_t exiting;
int nice;
spinlock_t jobctllock;
struct {
+2
View File
@@ -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 {
+2 -2
View File
@@ -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
+7
View File
@@ -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;
}
+4 -3
View File
@@ -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) {
+2 -7
View File
@@ -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);
+17
View File
@@ -0,0 +1,17 @@
#include <kernel/syscalls.h>
#include <kernel/thread.h>
#include <arch/cpu.h>
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;
}
+2 -2
View File
@@ -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);