diff --git a/labs/syscall.html b/labs/syscall.html index 662641c..2281f2e 100644 --- a/labs/syscall.html +++ b/labs/syscall.html @@ -117,72 +117,13 @@ time in xv6, determined by how often a hardware timer generates interrupts.
-You should put the following test program in user/alarmtest.c: +You'll find a file user/alarmtest.c in your xv6 +repository. Add it to the Makefile. It won't compile correctly +until you've added sigalarm and sigreturn +system calls (see below). -
-#include "kernel/param.h" -#include "kernel/types.h" -#include "kernel/stat.h" -#include "kernel/riscv.h" -#include "user/user.h" - -void test0(); -void test1(); -void periodic(); - -int -main(int argc, char *argv[]) -{ - test0(); - test1(); - exit(); -} - -void test0() -{ - int i; - printf(1, "test0 start\n"); - sigalarm(2, periodic); - for(i = 0; i < 1000*500000; i++){ - if((i % 250000) == 0) - write(2, ".", 1); - } - sigalarm(0, 0); - printf(1, "test0 done\n"); -} - -void -periodic() -{ - printf(1, "alarm!\n"); -} - -void __attribute__ ((noinline)) foo(int i, int *j) { - if((i % 2500000) == 0) { - write(2, ".", 1); - } - *j += 1; -} - -void test1() { - int i; - int j; - - printf(1, "test1 start\n"); - j = 0; - sigalarm(2, periodic); - for(i = 0; i < 1000*500000; i++){ - foo(i, &j); - } - if(i != j) { - printf(2, "i %d should = j %d\n", i, j); - exit(); - } - printf(1, "test1 done\n"); -} -- -The program calls sigalarm(2, periodic1) in test0 to +
+alarmtest calls sigalarm(2, periodic) in test0 to ask the kernel to force a call to periodic() every 2 ticks, and then spins for a while. You can see the assembly @@ -194,24 +135,23 @@ When you've finished the lab,
$ alarmtest test0 start -...................................................alarm! -.............................................................alarm! -(repeated many times) -test0 done +......................................alarm! +test0 passed test1 start ..alarm! ..alarm! ..alarm! -(repeated many times) -test1 done +.alarm! +..alarm! +..alarm! +..alarm! +..alarm! +..alarm! +..alarm! +test1 passed $-
-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 @@ -223,6 +163,9 @@ and doesn't print "alarm!".
Your solution will be only a few lines of code, but it may be tricky to get it right. +We'll test your code with the version of alarmtest.c in the original +repository; if you modify alarmtest.c, make sure your kernel changes +cause the original alarmtest to pass the tests.
int sigalarm(int ticks, void (*handler)()); + int sigreturn(void);
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). - 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 + Several approaches are possible; for this lab you should make + the sigreturn system call + restore registers and return to the original interrupted user instruction. + The user-space alarm handler + calls sigreturn when it is done. Some hints: