From 1b5701a659e177e9567c895dbe8c80f465c3795c Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Fri, 19 Sep 2025 23:38:08 +0200 Subject: [PATCH] schedrelease() syscall for more efficient spinning --- kernel/hal/x86_64/intr.c | 4 ++++ kernel/hal/x86_64/intr.h | 2 ++ kernel/syscall/sched.c | 17 +++++++++++++++++ kernel/syscall/sched.h | 9 +++++++++ kernel/syscall/syscall.c | 2 ++ share/sysdefs/sched.h | 6 ++++++ share/sysdefs/syscall.h | 1 + ulib/system/system.c | 4 ++++ ulib/system/system.h | 1 + user/init/main.c | 4 +++- 10 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 kernel/syscall/sched.c create mode 100644 kernel/syscall/sched.h create mode 100644 share/sysdefs/sched.h diff --git a/kernel/hal/x86_64/intr.c b/kernel/hal/x86_64/intr.c index 20e8a1e..9160c10 100644 --- a/kernel/hal/x86_64/intr.c +++ b/kernel/hal/x86_64/intr.c @@ -17,6 +17,8 @@ #include "proc/ps2kbproc/ps2kbproc.h" #include "rbuf/rbuf.h" +IntrStackFrame *INTR_CURRENT_FRAME; + typedef struct BackTraceFrame { struct BackTraceFrame *rbp; uint64_t rip; @@ -196,6 +198,8 @@ void intr_eoi(uint8_t irq) { } void intr_handleintr(IntrStackFrame *frame) { + INTR_CURRENT_FRAME = frame; + if (frame->trapnum <= 31) { kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); intr_dumpframe(frame); diff --git a/kernel/hal/x86_64/intr.h b/kernel/hal/x86_64/intr.h index 232f202..b578d28 100644 --- a/kernel/hal/x86_64/intr.h +++ b/kernel/hal/x86_64/intr.h @@ -35,4 +35,6 @@ typedef struct { void intr_init(void); +IntrStackFrame *INTR_CURRENT_FRAME; + #endif // HAL_INTR_H_ diff --git a/kernel/syscall/sched.c b/kernel/syscall/sched.c new file mode 100644 index 0000000..c6db1ab --- /dev/null +++ b/kernel/syscall/sched.c @@ -0,0 +1,17 @@ +#include +#include "syscall.h" +#include "sched.h" +#include "proc/proc.h" +#include "spinlock/spinlock.h" +#include "errors.h" +#include "hal/hal.h" + +int32_t SYSCALL0(sys_schedrelease) { + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + + proc_sched((void *)INTR_CURRENT_FRAME); + + return E_OK; +} diff --git a/kernel/syscall/sched.h b/kernel/syscall/sched.h new file mode 100644 index 0000000..71e5bbf --- /dev/null +++ b/kernel/syscall/sched.h @@ -0,0 +1,9 @@ +#ifndef SYSCALL_SCHED_H_ +#define SYSCALL_SCHED_H_ + +#include +#include "syscall.h" + +int32_t SYSCALL0(sys_schedrelease); + +#endif // SYSCALL_SCHED_H_ diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index c02eeaf..ee3d38a 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -7,6 +7,7 @@ #include "ioctl.h" #include "ipcpipe.h" #include "mman.h" +#include "sched.h" int32_t SYSCALL1(sys_debugprint, string) { char *p = (char *)string; @@ -21,4 +22,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = { [SYS_IPCPIPE] = &sys_ipcpipe, [SYS_MMAN_MAP] = &sys_mman_map, [SYS_MMAN_UNMAP] = &sys_mman_unmap, + [SYS_SCHEDRELEASE] = &sys_schedrelease, }; diff --git a/share/sysdefs/sched.h b/share/sysdefs/sched.h new file mode 100644 index 0000000..1f54ecc --- /dev/null +++ b/share/sysdefs/sched.h @@ -0,0 +1,6 @@ +#ifndef SHARE_SYSDEFS_SHED_H_ +#define SHARE_SYSDEFS_SHED_H_ + + + +#endif // SHARE_SYSDEFS_SHED_H_ diff --git a/share/sysdefs/syscall.h b/share/sysdefs/syscall.h index 8cac4e6..3f6e0b3 100644 --- a/share/sysdefs/syscall.h +++ b/share/sysdefs/syscall.h @@ -8,6 +8,7 @@ enum { SYS_IPCPIPE = 4, SYS_MMAN_MAP = 5, SYS_MMAN_UNMAP = 6, + SYS_SCHEDRELEASE = 7, }; #endif // SHARE_HDRS_SYSCALL_H_ diff --git a/ulib/system/system.c b/ulib/system/system.c index 843d61b..c301e40 100644 --- a/ulib/system/system.c +++ b/ulib/system/system.c @@ -30,3 +30,7 @@ int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint int32_t mman_unmap(uint8_t *addr) { return syscall(SYS_MMAN_UNMAP, (uint64_t)addr, 0, 0, 0, 0, 0); } + +int32_t schedrelease(void) { + return syscall(SYS_SCHEDRELEASE, 0, 0, 0, 0, 0, 0); +} diff --git a/ulib/system/system.h b/ulib/system/system.h index 98d6b0b..73a0685 100644 --- a/ulib/system/system.h +++ b/ulib/system/system.h @@ -10,5 +10,6 @@ int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1, uint64_t arg2, uin int32_t ipcpipe(uint64_t pid, uint64_t pipenum, uint64_t cmd, uint8_t *buffer, size_t len); int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out); int32_t mman_unmap(uint8_t *addr); +int32_t schedrelease(void); #endif // ULIB_SYSTEM_SYSTEM_H_ diff --git a/user/init/main.c b/user/init/main.c index c25ef3e..51b0f97 100644 --- a/user/init/main.c +++ b/user/init/main.c @@ -20,7 +20,9 @@ void tb_runinitscript(void) { processctl(tb, PCTL_RUN, 0, 0, 0); - while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 4); + while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 4) { + schedrelease(); + } } void main(void) {