From c7c962ffefdb5be9aa1e5b327d594ae8d972e447 Mon Sep 17 00:00:00 2001 From: CGH0S7 <776459475@qq.com> Date: Wed, 18 Jun 2025 16:02:24 +0800 Subject: [PATCH] alarm task finished --- Makefile | 3 ++- kernel/proc.c | 9 +++++++++ kernel/proc.h | 4 ++++ kernel/syscall.c | 4 ++++ kernel/syscall.h | 2 ++ kernel/sysproc.c | 25 +++++++++++++++++++++++++ kernel/trap.c | 11 +++++++++-- time.txt | 1 + user/user.h | 2 ++ user/usys.pl | 2 ++ 10 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 time.txt diff --git a/Makefile b/Makefile index af4c4ca..7bed292 100644 --- a/Makefile +++ b/Makefile @@ -213,7 +213,8 @@ endif ifeq ($(LAB),traps) UPROGS += \ $U/_call\ - $U/_bttest + $U/_bttest\ + $U/_alarmtest endif ifeq ($(LAB),lazy) diff --git a/kernel/proc.c b/kernel/proc.c index 130d9ce..1d41012 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -132,6 +132,12 @@ found: return 0; } + if((p->pre_trapframe = (struct trapframe *)kalloc()) == 0){ + freeproc(p); + release(&p->lock); + return 0; + } + // An empty user page table. p->pagetable = proc_pagetable(p); if(p->pagetable == 0){ @@ -160,6 +166,9 @@ freeproc(struct proc *p) p->trapframe = 0; if(p->pagetable) proc_freepagetable(p->pagetable, p->sz); + if(p->pre_trapframe) + kfree((void*)p->pre_trapframe); + p->pre_trapframe = 0; p->pagetable = 0; p->sz = 0; p->pid = 0; diff --git a/kernel/proc.h b/kernel/proc.h index d021857..f7fc14c 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -104,4 +104,8 @@ struct proc { struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) + int alarm_cnt; // Alarm count + int inter_cnt; // interrupts count + uint64 handler; // alarm func address + struct trapframe *pre_trapframe; }; diff --git a/kernel/syscall.c b/kernel/syscall.c index ed65409..c34b372 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -101,6 +101,8 @@ extern uint64 sys_unlink(void); extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); +extern uint64 sys_sigalarm(void); +extern uint64 sys_sigreturn(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -126,6 +128,8 @@ static uint64 (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, +[SYS_sigalarm] sys_sigalarm, +[SYS_sigreturn] sys_sigreturn, }; void diff --git a/kernel/syscall.h b/kernel/syscall.h index bc5f356..67ca3a4 100644 --- a/kernel/syscall.h +++ b/kernel/syscall.h @@ -20,3 +20,5 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 +#define SYS_sigalarm 22 +#define SYS_sigreturn 23 diff --git a/kernel/sysproc.c b/kernel/sysproc.c index 651a697..0d9e9a3 100644 --- a/kernel/sysproc.c +++ b/kernel/sysproc.c @@ -93,3 +93,28 @@ sys_uptime(void) release(&tickslock); return xticks; } + +uint64 +sys_sigalarm(void) +{ + int alarm_cnt; + uint64 addr; + struct proc *p = myproc(); + argint(0, &alarm_cnt); + argaddr(1, &addr); + + p->inter_cnt = 0; + p->handler = addr; + p->alarm_cnt = alarm_cnt; + + return 0; +} + +uint64 +sys_sigreturn(void) +{ + struct proc* p = myproc(); + *p->trapframe = *p->pre_trapframe; + p->inter_cnt = 0; + return p->pre_trapframe->a0; +} diff --git a/kernel/trap.c b/kernel/trap.c index d454a7d..64d87aa 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -77,8 +77,15 @@ usertrap(void) exit(-1); // give up the CPU if this is a timer interrupt. - if(which_dev == 2) - yield(); + if(which_dev == 2){ + p->inter_cnt++; + if (p->inter_cnt == p->alarm_cnt && 0 < p->alarm_cnt) { + *p->pre_trapframe = *p->trapframe; + p->trapframe->epc = p->handler; + } else { + yield(); + } + } usertrapret(); } diff --git a/time.txt b/time.txt new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/time.txt @@ -0,0 +1 @@ +8 diff --git a/user/user.h b/user/user.h index f16fe27..81a2910 100644 --- a/user/user.h +++ b/user/user.h @@ -22,6 +22,8 @@ int getpid(void); char* sbrk(int); int sleep(int); int uptime(void); +int sigalarm(int, void(*)()); +int sigreturn(void); // ulib.c int stat(const char*, struct stat*); diff --git a/user/usys.pl b/user/usys.pl index 01e426e..fa548b0 100755 --- a/user/usys.pl +++ b/user/usys.pl @@ -36,3 +36,5 @@ entry("getpid"); entry("sbrk"); entry("sleep"); entry("uptime"); +entry("sigalarm"); +entry("sigreturn");