summaryrefslogtreecommitdiff
path: root/trap.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-04 14:25:48 -0400
committerRobert Morris <[email protected]>2019-06-04 14:25:48 -0400
commitec3d3a1fceee437c640f9c5c05fc517edfb1899e (patch)
tree574b281c392d58913236ec495e7df091bc6c1972 /trap.c
parenta82772594e1807632b3650bff111108f250de3b7 (diff)
downloadxv6-labs-ec3d3a1fceee437c640f9c5c05fc517edfb1899e.tar.gz
xv6-labs-ec3d3a1fceee437c640f9c5c05fc517edfb1899e.tar.bz2
xv6-labs-ec3d3a1fceee437c640f9c5c05fc517edfb1899e.zip
yield if timer interrupt
all user tests passed
Diffstat (limited to 'trap.c')
-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;
}