summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--trap.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/trap.c b/trap.c
index e17f8fe..5f5d4a0 100644
--- a/trap.c
+++ b/trap.c
@@ -36,6 +36,8 @@ trapinit(void)
void
usertrap(void)
{
+ int which_dev = 0;
+
if((r_sstatus() & SSTATUS_SPP) != 0)
panic("usertrap: not from user mode");
@@ -62,7 +64,7 @@ usertrap(void)
p->tf->epc += 4;
syscall();
- } else if(devintr()){
+ } else if((which_dev = devintr()) != 0){
// ok
} else {
printf("usertrap(): unexpected scause 0x%p pid=%d\n", r_scause(), p->pid);
@@ -73,6 +75,10 @@ usertrap(void)
if(p->killed)
exit();
+ // give up the CPU if this is a timer interrupt.
+ if(which_dev == 2)
+ yield();
+
usertrapret();
}
@@ -146,7 +152,9 @@ kerneltrap()
// check if it's an external interrupt or software interrupt,
// and handle it.
-// returns 1 if handled, 0 if not recognized.
+// returns 2 if timer interrupt,
+// 1 if other device,
+// 0 if not recognized.
int
devintr()
{
@@ -176,7 +184,7 @@ devintr()
// acknowledge.
w_sip(r_sip() & ~2);
- return 1;
+ return 2;
} else {
return 0;
}