delay syscall ok

This commit is contained in:
ridethepig 2022-10-30 01:53:43 +08:00
parent 6c1c2e05ad
commit 9c17cfaecf
10 changed files with 68 additions and 12 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -8,6 +8,7 @@
#include <kern/process.h>
#include <kern/protect.h>
#include <kern/syscall.h>
#include <kern/time.h>
/*
*
@ -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;
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;