diff --git a/labs/syscall.html b/labs/syscall.html index 835e510..662641c 100644 --- a/labs/syscall.html +++ b/labs/syscall.html @@ -7,10 +7,10 @@
You should put the following test program in user/alarmtest.c: -XXX Insert the final program here; maybe just give the code in the repo
 #include "kernel/param.h"
 #include "kernel/types.h"
@@ -143,12 +142,12 @@ void test0()
 {
   int i;
   printf(1, "test0 start\n");
-  alarm(2, periodic);
+  sigalarm(2, periodic);
   for(i = 0; i < 1000*500000; i++){
     if((i % 250000) == 0)
       write(2, ".", 1);
   }
-  alarm(0, 0);
+  sigalarm(0, 0);
   printf(1, "test0 done\n");
 }
 
@@ -171,7 +170,7 @@ void test1() {
 
   printf(1, "test1 start\n");
   j = 0;
-  alarm(2, periodic);
+  sigalarm(2, periodic);
   for(i = 0; i < 1000*500000; i++){
     foo(i, &j);
   }
@@ -185,55 +184,53 @@ void test1() {
 
 The program calls sigalarm(2, periodic1) in test0 to
 ask the kernel to force a call to periodic() every 2 ticks,
-and then spins for a while.  After you have implemented
-the sigalarm() system call in the kernel,
-alarmtest should produce output like this for test0:
+and then spins for a while.
+You can see the assembly
+code for alarmtest in user/alarmtest.asm, which may be handy
+for debugging.
+When you've finished the lab,
+alarmtest should produce output like this:
 
-Update output for final usertests.c
 
 $ alarmtest
-alarmtest starting
-.....alarm!
-....alarm!
-.....alarm!
-......alarm!
-.....alarm!
-....alarm!
-....alarm!
-......alarm!
-.....alarm!
-...alarm!
-...$ 
+test0 start
+...................................................alarm!
+.............................................................alarm!
+(repeated many times)
+test0 done
+test1 start
+..alarm!
+..alarm!
+..alarm!
+(repeated many times)
+test1 done
+$
 
-
 
 
-(If you only see one "alarm!", try increasing the number of iterations in
-alarmtest.c by 10x.)
+At first, however, you'll see that alarmtest only prints periods,
+and doesn't print "alarm!".
+
 
 
The main challenge will be to arrange that the handler is invoked
   when the process's alarm interval expires.  You'll need to modify
   usertrap() in kernel/trap.c so that when a
   process's alarm interval expires, the process executes
-  the handler. How can you do that?  You will need to understand in
-  detail how system calls work (i.e., the code in kernel/trampoline.S
-  and kernel/trap.c). Which register contains the address where
-  system calls return to?
+  the handler. How can you do that?  You will need to understand 
+  how system calls work (i.e., the code in kernel/trampoline.S
+  and kernel/trap.c). Which register contains the address to which
+  system calls return?
 
-
Your solution will be few lines of code, but it will be tricky to
-  write the right lines of code.  The most common failure scenario is that the
-  user program crashes or doesn't terminate.  You can see the assembly
-  code for the alarmtest program in alarmtest.asm, which will be handy
-  for debugging.
+
Your solution will be only a few lines of code, but it may be tricky to
+  get it right.
 
-
Test0: invoke handler
+test0: invoke handler
 
-To get started, the best strategy is to first pass test0, which
-  will force you to handle the main challenge above. Here are some
-  hints how to pass test0:
+
Get started by modifying the kernel to jump to the alarm handler in
+user space, which will cause test0 to print "alarm!". Don't worry yet
+what happens after the "alarm!" output; it's OK for now if your
+program crashes after printing "alarm!". Here are some hints:
 
-
XXX alarm() needs to be defined somewhere.
-  
 
XXX it is surprising that test0() appears to work -perfectly, even though something is seriously wrong -with the way periodic() returns. we should recognize -that something odd is happening, maybe ask them to think -about it, and hint or say why they are not done even though -test0() works. +Chances are that alarmtest crashes at some point after it prints +"alarm!". Depending on how your solution works, that point may be in +test0, or it may be in test1. Crashes are likely caused +by the alarm handler (periodic in alarmtest.c) returning +to the wrong point in the user program. -
Test0 doesn't test whether the handler returns correctly to - the user instruction that was interrupted by the timer. - The previous section didn't require you to get this right. - If you didn't, test0 will probably succeed anyway, but - test1 will likely fail (the program crashes or the program - goes into an infinite loop). - Another challenge is that the register contents need to be - correct when control returns to the interrupted user instruction. +
+Your job now is to ensure that, when the alarm handler is done, +control returns to +the instruction at which the user program was originally +interrupted by the timer interrupt. You must also ensure that +the register contents are restored to values they held +at the time of the interrupt, so that the user program +can continue undisturbed after the alarm.
Your solution is likely to require you to save and restore registers---what registers do you need to save and restore to resume - the interrupted code correctly? (Hint: it will be many). There are - several ways to restore the registers; one convenient plan is to add another - system call sigreturn that the handler calls when it is + the interrupted code correctly? (Hint: it will be many). + Several approaches are possible; one convenient plan is to add another + system call sigreturn that the user-space alarm handler calls when it is done, and which restores registers and returns to the original interrupted user instruction. @@ -324,7 +312,7 @@ test0() works.