delay syscall ok
This commit is contained in:
parent
6c1c2e05ad
commit
9c17cfaecf
@ -46,6 +46,7 @@ typedef struct s_proc {
|
|||||||
phyaddr_t cr3;
|
phyaddr_t cr3;
|
||||||
int priority;
|
int priority;
|
||||||
int ticks;
|
int ticks;
|
||||||
|
int target_tick;
|
||||||
}PROCESS_0;
|
}PROCESS_0;
|
||||||
|
|
||||||
#define KERN_STACKSIZE (8 * KB)
|
#define KERN_STACKSIZE (8 * KB)
|
||||||
@ -59,7 +60,7 @@ typedef union u_proc {
|
|||||||
// kern/main.c
|
// kern/main.c
|
||||||
extern PROCESS *p_proc_ready;
|
extern PROCESS *p_proc_ready;
|
||||||
/* pcb表 */
|
/* pcb表 */
|
||||||
#define PCB_SIZE 2
|
#define PCB_SIZE 3
|
||||||
// kern/main.c
|
// kern/main.c
|
||||||
extern PROCESS proc_table[];
|
extern PROCESS proc_table[];
|
||||||
|
|
||||||
@ -72,4 +73,7 @@ void switch_kern_context(
|
|||||||
// 处理函数
|
// 处理函数
|
||||||
void schedule(void);
|
void schedule(void);
|
||||||
u32 kern_get_pid(PROCESS *p_proc);
|
u32 kern_get_pid(PROCESS *p_proc);
|
||||||
|
void kern_delay_tick(PROCESS*, u32);
|
||||||
|
|
||||||
|
extern bool has_runnable;
|
||||||
#endif /* MINIOS_KERN_PROCESS_H */
|
#endif /* MINIOS_KERN_PROCESS_H */
|
||||||
@ -21,5 +21,5 @@ ssize_t do_get_pid(void);
|
|||||||
// kern/fs.c
|
// kern/fs.c
|
||||||
ssize_t do_read(int fd, void *buf, size_t count);
|
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_write(int fd, const void *buf, size_t count);
|
||||||
|
ssize_t do_delay_ticks(u32 ticks);
|
||||||
#endif /* MINIOS_KERN_SYSCALL_H */
|
#endif /* MINIOS_KERN_SYSCALL_H */
|
||||||
@ -6,5 +6,6 @@
|
|||||||
#define _NR_get_pid 1
|
#define _NR_get_pid 1
|
||||||
#define _NR_read 2
|
#define _NR_read 2
|
||||||
#define _NR_write 3
|
#define _NR_write 3
|
||||||
|
#define _NR_delay_ticks 4
|
||||||
|
|
||||||
#endif /* MINIOS_SYSCALL_H */
|
#endif /* MINIOS_SYSCALL_H */
|
||||||
|
|||||||
@ -15,5 +15,5 @@ ssize_t get_ticks();
|
|||||||
ssize_t get_pid();
|
ssize_t get_pid();
|
||||||
ssize_t read(int fd, void *buf, size_t count);
|
ssize_t read(int fd, void *buf, size_t count);
|
||||||
ssize_t write(int fd, const void *buf, size_t count);
|
ssize_t write(int fd, const void *buf, size_t count);
|
||||||
|
ssize_t delay_ticks(u32 ticks);
|
||||||
#endif
|
#endif
|
||||||
10
kern/main.c
10
kern/main.c
@ -79,8 +79,11 @@ void kernel_main(void)
|
|||||||
// lcr3(p_proc->pcb.cr3);
|
// lcr3(p_proc->pcb.cr3);
|
||||||
|
|
||||||
static char filename[PCB_SIZE][12] = {
|
static char filename[PCB_SIZE][12] = {
|
||||||
"TESTPID BIN",
|
// "TESTPID BIN",
|
||||||
"TESTKEY BIN",
|
// "TESTKEY BIN",
|
||||||
|
"DELAY BIN",
|
||||||
|
"DELAY BIN",
|
||||||
|
"DELAY BIN",
|
||||||
};
|
};
|
||||||
// 从磁盘中将文件读出,需要注意的是要满足短目录项的文件名长度11,
|
// 从磁盘中将文件读出,需要注意的是要满足短目录项的文件名长度11,
|
||||||
// 前八个为文件名,后三个为后缀名,跟BootLoader做法一致
|
// 前八个为文件名,后三个为后缀名,跟BootLoader做法一致
|
||||||
@ -147,10 +150,11 @@ void kernel_main(void)
|
|||||||
|
|
||||||
// 初始化其余量
|
// 初始化其余量
|
||||||
p_proc->pcb.pid = i;
|
p_proc->pcb.pid = i;
|
||||||
static int priority_table[PCB_SIZE] = {1, 2};
|
static int priority_table[PCB_SIZE] = {1, 1, 1};
|
||||||
// priority 预计给每个进程分配的时间片
|
// priority 预计给每个进程分配的时间片
|
||||||
// ticks 进程剩余的进程片
|
// ticks 进程剩余的进程片
|
||||||
p_proc->pcb.priority = p_proc->pcb.ticks = priority_table[i];
|
p_proc->pcb.priority = p_proc->pcb.ticks = priority_table[i];
|
||||||
|
p_proc->pcb.target_tick = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_proc_ready = proc_table;
|
p_proc_ready = proc_table;
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include <kern/process.h>
|
#include <kern/process.h>
|
||||||
#include <kern/protect.h>
|
#include <kern/protect.h>
|
||||||
#include <kern/syscall.h>
|
#include <kern/syscall.h>
|
||||||
|
#include <kern/time.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 这个函数是写给汇编函数用,
|
* 这个函数是写给汇编函数用,
|
||||||
@ -36,6 +37,7 @@ to_kern_stack(u32 ret_esp)
|
|||||||
/*
|
/*
|
||||||
* 调度函数
|
* 调度函数
|
||||||
*/
|
*/
|
||||||
|
bool has_runnable = true;
|
||||||
void
|
void
|
||||||
schedule(void)
|
schedule(void)
|
||||||
{
|
{
|
||||||
@ -44,13 +46,29 @@ schedule(void)
|
|||||||
// 如果中断没关,一定!一定!一定!要关中断保证当前执行流操作的原子性
|
// 如果中断没关,一定!一定!一定!要关中断保证当前执行流操作的原子性
|
||||||
if (IF_BIT != 0)
|
if (IF_BIT != 0)
|
||||||
disable_int();
|
disable_int();
|
||||||
|
// kprintf("sched\n");
|
||||||
PROCESS *p_cur_proc = p_proc_ready;
|
PROCESS *p_cur_proc = p_proc_ready;
|
||||||
PROCESS *p_next_proc = p_proc_ready + 1;
|
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) {
|
if (p_next_proc >= proc_table + PCB_SIZE) {
|
||||||
p_next_proc = proc_table;
|
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;
|
p_proc_ready = p_next_proc;
|
||||||
// 切换进程页表和tss
|
// 切换进程页表和tss
|
||||||
lcr3(p_proc_ready->pcb.cr3);
|
lcr3(p_proc_ready->pcb.cr3);
|
||||||
@ -102,3 +120,14 @@ do_get_pid(void)
|
|||||||
{
|
{
|
||||||
return (ssize_t)kern_get_pid(p_proc_ready);
|
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;
|
||||||
|
}
|
||||||
@ -9,12 +9,14 @@ static ssize_t sys_get_ticks(void);
|
|||||||
static ssize_t sys_get_pid(void);
|
static ssize_t sys_get_pid(void);
|
||||||
static ssize_t sys_read(void);
|
static ssize_t sys_read(void);
|
||||||
static ssize_t sys_write(void);
|
static ssize_t sys_write(void);
|
||||||
|
static ssize_t sys_delay_ticks(void);
|
||||||
|
|
||||||
ssize_t (*syscall_table[])(void) = {
|
ssize_t (*syscall_table[])(void) = {
|
||||||
[_NR_get_ticks] sys_get_ticks,
|
[_NR_get_ticks] sys_get_ticks,
|
||||||
[_NR_get_pid] sys_get_pid,
|
[_NR_get_pid] sys_get_pid,
|
||||||
[_NR_read] sys_read,
|
[_NR_read] sys_read,
|
||||||
[_NR_write] sys_write,
|
[_NR_write] sys_write,
|
||||||
|
[_NR_delay_ticks] sys_delay_ticks,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -84,3 +86,8 @@ sys_write(void)
|
|||||||
{
|
{
|
||||||
return do_write(get_arg(0), (const void *)get_arg(1), get_arg(2));
|
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));
|
||||||
|
}
|
||||||
@ -150,6 +150,11 @@ void
|
|||||||
clock_interrupt_handler(int irq)
|
clock_interrupt_handler(int irq)
|
||||||
{
|
{
|
||||||
timecounter_inc();
|
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) {
|
if (--p_proc_ready->pcb.ticks == 0) {
|
||||||
p_proc_ready->pcb.ticks = p_proc_ready->pcb.priority;
|
p_proc_ready->pcb.ticks = p_proc_ready->pcb.priority;
|
||||||
|
|||||||
@ -114,3 +114,9 @@ write(int fd, const void *buf, size_t count)
|
|||||||
{
|
{
|
||||||
return syscall3(_NR_write, fd, (size_t)buf, count);
|
return syscall3(_NR_write, fd, (size_t)buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
delay_ticks(u32 ticks)
|
||||||
|
{
|
||||||
|
return syscall1(_NR_delay_ticks, ticks);
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ int main()
|
|||||||
printf("\x1b[%dmI'm %d!\x1b[0m", 90 + pid + 1, pid);
|
printf("\x1b[%dmI'm %d!\x1b[0m", 90 + pid + 1, pid);
|
||||||
fflush();
|
fflush();
|
||||||
int before_ticks = get_ticks();
|
int before_ticks = get_ticks();
|
||||||
//delay_ticks(target_ticks);
|
delay_ticks(target_ticks);
|
||||||
int after_ticks = get_ticks();
|
int after_ticks = get_ticks();
|
||||||
|
|
||||||
int real_ticks = after_ticks - before_ticks;
|
int real_ticks = after_ticks - before_ticks;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user