From 9c17cfaecfcd7987c6e68775a10a44bb1495e489 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Sun, 30 Oct 2022 01:53:43 +0800 Subject: [PATCH] delay syscall ok --- inc/kern/process.h | 6 +++++- inc/kern/syscall.h | 2 +- inc/syscall.h | 1 + inc/user/syscall.h | 2 +- kern/main.c | 10 +++++++--- kern/process.c | 39 ++++++++++++++++++++++++++++++++++----- kern/syscall.c | 7 +++++++ kern/trap.c | 5 +++++ lib/user/syscall.c | 6 ++++++ user/delay.c | 2 +- 10 files changed, 68 insertions(+), 12 deletions(-) diff --git a/inc/kern/process.h b/inc/kern/process.h index 97c2207..cfab044 100644 --- a/inc/kern/process.h +++ b/inc/kern/process.h @@ -46,6 +46,7 @@ typedef struct s_proc { phyaddr_t cr3; int priority; int ticks; + int target_tick; }PROCESS_0; #define KERN_STACKSIZE (8 * KB) @@ -59,7 +60,7 @@ typedef union u_proc { // kern/main.c extern PROCESS *p_proc_ready; /* pcb表 */ -#define PCB_SIZE 2 +#define PCB_SIZE 3 // kern/main.c extern PROCESS proc_table[]; @@ -72,4 +73,7 @@ void switch_kern_context( // 处理函数 void schedule(void); u32 kern_get_pid(PROCESS *p_proc); +void kern_delay_tick(PROCESS*, u32); + +extern bool has_runnable; #endif /* MINIOS_KERN_PROCESS_H */ \ No newline at end of file diff --git a/inc/kern/syscall.h b/inc/kern/syscall.h index 31ded36..2668e21 100644 --- a/inc/kern/syscall.h +++ b/inc/kern/syscall.h @@ -21,5 +21,5 @@ ssize_t do_get_pid(void); // kern/fs.c ssize_t do_read(int fd, void *buf, size_t count); ssize_t do_write(int fd, const void *buf, size_t count); - +ssize_t do_delay_ticks(u32 ticks); #endif /* MINIOS_KERN_SYSCALL_H */ \ No newline at end of file diff --git a/inc/syscall.h b/inc/syscall.h index ca6230a..cf67177 100644 --- a/inc/syscall.h +++ b/inc/syscall.h @@ -6,5 +6,6 @@ #define _NR_get_pid 1 #define _NR_read 2 #define _NR_write 3 +#define _NR_delay_ticks 4 #endif /* MINIOS_SYSCALL_H */ diff --git a/inc/user/syscall.h b/inc/user/syscall.h index ee37810..e5e4169 100644 --- a/inc/user/syscall.h +++ b/inc/user/syscall.h @@ -15,5 +15,5 @@ ssize_t get_ticks(); ssize_t get_pid(); ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); - +ssize_t delay_ticks(u32 ticks); #endif \ No newline at end of file diff --git a/kern/main.c b/kern/main.c index 4762e8a..8189df6 100644 --- a/kern/main.c +++ b/kern/main.c @@ -79,8 +79,11 @@ void kernel_main(void) // lcr3(p_proc->pcb.cr3); static char filename[PCB_SIZE][12] = { - "TESTPID BIN", - "TESTKEY BIN", + // "TESTPID BIN", + // "TESTKEY BIN", + "DELAY BIN", + "DELAY BIN", + "DELAY BIN", }; // 从磁盘中将文件读出,需要注意的是要满足短目录项的文件名长度11, // 前八个为文件名,后三个为后缀名,跟BootLoader做法一致 @@ -147,10 +150,11 @@ void kernel_main(void) // 初始化其余量 p_proc->pcb.pid = i; - static int priority_table[PCB_SIZE] = {1, 2}; + static int priority_table[PCB_SIZE] = {1, 1, 1}; // priority 预计给每个进程分配的时间片 // ticks 进程剩余的进程片 p_proc->pcb.priority = p_proc->pcb.ticks = priority_table[i]; + p_proc->pcb.target_tick = 0; } p_proc_ready = proc_table; diff --git a/kern/process.c b/kern/process.c index eeb116e..d3ad1d1 100644 --- a/kern/process.c +++ b/kern/process.c @@ -8,6 +8,7 @@ #include #include #include +#include /* * 这个函数是写给汇编函数用, @@ -36,6 +37,7 @@ to_kern_stack(u32 ret_esp) /* * 调度函数 */ +bool has_runnable = true; void schedule(void) { @@ -44,13 +46,29 @@ schedule(void) // 如果中断没关,一定!一定!一定!要关中断保证当前执行流操作的原子性 if (IF_BIT != 0) disable_int(); - +// kprintf("sched\n"); PROCESS *p_cur_proc = p_proc_ready; - PROCESS *p_next_proc = p_proc_ready + 1; - if (p_next_proc >= proc_table + PCB_SIZE) { - p_next_proc = proc_table; + PROCESS *p_next_proc = p_proc_ready; + has_runnable = false; +_again: + do { + p_next_proc = p_next_proc + 1; + if (p_next_proc >= proc_table + PCB_SIZE) { + p_next_proc = proc_table; + } + if (p_next_proc->pcb.target_tick == 0 || p_next_proc->pcb.target_tick <= kern_get_ticks()) { + p_next_proc->pcb.target_tick = 0; + has_runnable = true; + break; + } + } while(p_next_proc != p_proc_ready); + if (!has_runnable) { + enable_int(); // remember to enable int, or it'll die here + asm volatile("hlt"); // hlt will wake up when int comes + IF_BIT = read_eflags() & FL_IF; + if (IF_BIT != 0) disable_int(); // retry with int disabled + goto _again; } - p_proc_ready = p_next_proc; // 切换进程页表和tss lcr3(p_proc_ready->pcb.cr3); @@ -101,4 +119,15 @@ ssize_t do_get_pid(void) { return (ssize_t)kern_get_pid(p_proc_ready); +} + +void kern_delay_ticks(PROCESS *p_proc, u32 target_tick) { + p_proc->pcb.target_tick = target_tick; +} + +ssize_t +do_delay_ticks(u32 ticks) { + kern_delay_ticks(p_proc_ready, kern_get_ticks() + ticks); + schedule(); + return 0; } \ No newline at end of file diff --git a/kern/syscall.c b/kern/syscall.c index 891cc4a..92bba56 100644 --- a/kern/syscall.c +++ b/kern/syscall.c @@ -9,12 +9,14 @@ static ssize_t sys_get_ticks(void); static ssize_t sys_get_pid(void); static ssize_t sys_read(void); static ssize_t sys_write(void); +static ssize_t sys_delay_ticks(void); ssize_t (*syscall_table[])(void) = { [_NR_get_ticks] sys_get_ticks, [_NR_get_pid] sys_get_pid, [_NR_read] sys_read, [_NR_write] sys_write, +[_NR_delay_ticks] sys_delay_ticks, }; /* @@ -83,4 +85,9 @@ static ssize_t sys_write(void) { return do_write(get_arg(0), (const void *)get_arg(1), get_arg(2)); +} + +static ssize_t +sys_delay_ticks(void) { + return do_delay_ticks(get_arg(0)); } \ No newline at end of file diff --git a/kern/trap.c b/kern/trap.c index d2c373b..ee3c6ed 100644 --- a/kern/trap.c +++ b/kern/trap.c @@ -150,6 +150,11 @@ void clock_interrupt_handler(int irq) { timecounter_inc(); + if (!has_runnable) return; + // maybe do nothing would be better, try to avoid recursive call to schedule + // because we must be in a schedule when runnable is false + // we just need a clock int to wake up it + // 当一个函数的时间片全用完时 if (--p_proc_ready->pcb.ticks == 0) { p_proc_ready->pcb.ticks = p_proc_ready->pcb.priority; diff --git a/lib/user/syscall.c b/lib/user/syscall.c index 6162b13..ad5f5f7 100644 --- a/lib/user/syscall.c +++ b/lib/user/syscall.c @@ -113,4 +113,10 @@ ssize_t write(int fd, const void *buf, size_t count) { return syscall3(_NR_write, fd, (size_t)buf, count); +} + +ssize_t +delay_ticks(u32 ticks) +{ + return syscall1(_NR_delay_ticks, ticks); } \ No newline at end of file diff --git a/user/delay.c b/user/delay.c index c177b72..ec34cef 100644 --- a/user/delay.c +++ b/user/delay.c @@ -12,7 +12,7 @@ int main() printf("\x1b[%dmI'm %d!\x1b[0m", 90 + pid + 1, pid); fflush(); int before_ticks = get_ticks(); - //delay_ticks(target_ticks); + delay_ticks(target_ticks); int after_ticks = get_ticks(); int real_ticks = after_ticks - before_ticks;