1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
| diff --git a/Makefile b/Makefile index 1fa367e..a74296b 100644
@@ -175,6 +175,7 @@ UPROGS=\ $U/_grind\ $U/_wc\ $U/_zombie\ + $U/_alarmtest\ diff --git a/kernel/defs.h b/kernel/defs.h index 4b9bbc0..9148b4c 100644
@@ -80,6 +80,7 @@ int pipewrite(struct pipe*, uint64, int); void printf(char*, ...); void panic(char*) __attribute__((noreturn)); void printfinit(void); +void backtrace(void); // add for lab traps // proc.c int cpuid(void); diff --git a/kernel/printf.c b/kernel/printf.c index e1347de..057faba 100644
@@ -121,6 +121,7 @@ panic(char *s) printf("panic: "); printf(s); printf("\n"); + backtrace(); panicked = 1; // freeze uart output from other CPUs for(;;) ; @@ -132,3 +133,13 @@ printfinit(void) initlock(&pr.lock, "pr"); pr.locking = 1; } +void +backtrace() +{ + printf("backtrace:\n"); + uint64 fp = r_fp(); + while(PGROUNDDOWN(fp) < PGROUNDUP(fp)){ + printf("%p\n", *((uint64*)(fp - 8))); + fp = *(uint64*)(fp - 16); + } +} diff --git a/kernel/proc.h b/kernel/proc.h index 9c16ea7..8f8ad3e 100644
@@ -103,4 +103,9 @@ struct proc { struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) + + int ticks; // alarm interval + int count; // how many ticks have passed since the last call + uint64 handler; // the pointer to the handler function + struct trapframe traps; }; diff --git a/kernel/riscv.h b/kernel/riscv.h index 0aec003..d193d59 100644
@@ -352,3 +352,10 @@ sfence_vma() typedef uint64 pte_t; typedef uint64 *pagetable_t; // 512 PTEs +static inline uint64 +r_fp() +{ + uint64 x; + asm volatile("mv %0, s0" : "=r" (x) ); + return x; +} \ No newline at end of file diff --git a/kernel/syscall.c b/kernel/syscall.c index c1b3670..24bfccd 100644
@@ -104,6 +104,8 @@ extern uint64 sys_unlink(void); extern uint64 sys_wait(void); extern uint64 sys_write(void); extern uint64 sys_uptime(void); +extern uint64 sys_sigalarm(void); +extern uint64 sys_sigreturn(void); static uint64 (*syscalls[])(void) = { [SYS_fork] sys_fork, @@ -127,6 +129,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
@@ -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 e8bcda9..50d8cf4 100644
@@ -57,6 +57,7 @@ sys_sleep(void) { int n; uint ticks0; + backtrace(); if(argint(0, &n) < 0) return -1; @@ -95,3 +96,31 @@ sys_uptime(void) release(&tickslock); return xticks; } +// sys_sigalarm() should store the alarm interval +// and the pointer to the handler function +int +sys_sigalarm(void) +{ + struct proc *p = myproc(); + int ticks; + uint64 handler; + + if(argint(0, &ticks) < 0) + return -1; + if(argaddr(1, &handler) < 0) + return -1; + + p->ticks = ticks; + p->handler = handler; + + return 0; +} +int +sys_sigreturn() +{ + struct proc *p = myproc(); + p->count = 0; // reset p->count + // restore p->trapframe from p->traps + memmove(p->trapframe, &(p->traps), sizeof(struct trapframe)); + return 0; +} \ No newline at end of file diff --git a/kernel/trap.c b/kernel/trap.c index a63249e..f1d4022 100644
@@ -77,8 +77,14 @@ usertrap(void) exit(-1); // give up the CPU if this is a timer interrupt. - if(which_dev == 2) + if(which_dev == 2){ + if(++p->count == p->ticks){ // need call handler function + // save p->trapframe to p->traps + memmove(&(p->traps), p->trapframe, sizeof(struct trapframe)); + p->trapframe->epc = p->handler; + } yield(); + } usertrapret(); } diff --git a/user/user.h b/user/user.h index b71ecda..57404e0 100644
@@ -23,6 +23,8 @@ int getpid(void); char* sbrk(int); int sleep(int); int uptime(void); +int sigalarm(int ticks, void (*handler)()); +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
@@ -36,3 +36,5 @@ entry("getpid"); entry("sbrk"); entry("sleep"); entry("uptime"); +entry("sigalarm"); +entry("sigreturn");
|