diff options
Diffstat (limited to 'user')
| -rw-r--r-- | user/alarmtest.c | 193 | ||||
| -rw-r--r-- | user/bttest.c | 10 | ||||
| -rw-r--r-- | user/call.c | 17 | 
3 files changed, 220 insertions, 0 deletions
| diff --git a/user/alarmtest.c b/user/alarmtest.c new file mode 100644 index 0000000..b8d85f7 --- /dev/null +++ b/user/alarmtest.c @@ -0,0 +1,193 @@ +// +// test program for the alarm lab. +// you can modify this file for testing, +// but please make sure your kernel +// modifications pass the original +// versions of these tests. +// + +#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 test2(); +void test3(); +void periodic(); +void slow_handler(); +void dummy_handler(); + +int +main(int argc, char *argv[]) +{ +  test0(); +  test1(); +  test2(); +  test3(); +  exit(0); +} + +volatile static int count; + +void +periodic() +{ +  count = count + 1; +  printf("alarm!\n"); +  sigreturn(); +} + +// tests whether the kernel calls +// the alarm handler even a single time. +void +test0() +{ +  int i; +  printf("test0 start\n"); +  count = 0; +  sigalarm(2, periodic); +  for(i = 0; i < 1000*500000; i++){ +    if((i % 1000000) == 0) +      write(2, ".", 1); +    if(count > 0) +      break; +  } +  sigalarm(0, 0); +  if(count > 0){ +    printf("test0 passed\n"); +  } else { +    printf("\ntest0 failed: the kernel never called the alarm handler\n"); +  } +} + +void __attribute__ ((noinline)) foo(int i, int *j) { +  if((i % 2500000) == 0) { +    write(2, ".", 1); +  } +  *j += 1; +} + +// +// tests that the kernel calls the handler multiple times. +// +// tests that, when the handler returns, it returns to +// the point in the program where the timer interrupt +// occurred, with all registers holding the same values they +// held when the interrupt occurred. +// +void +test1() +{ +  int i; +  int j; + +  printf("test1 start\n"); +  count = 0; +  j = 0; +  sigalarm(2, periodic); +  for(i = 0; i < 500000000; i++){ +    if(count >= 10) +      break; +    foo(i, &j); +  } +  if(count < 10){ +    printf("\ntest1 failed: too few calls to the handler\n"); +  } else if(i != j){ +    // the loop should have called foo() i times, and foo() should +    // have incremented j once per call, so j should equal i. +    // once possible source of errors is that the handler may +    // return somewhere other than where the timer interrupt +    // occurred; another is that that registers may not be +    // restored correctly, causing i or j or the address ofj +    // to get an incorrect value. +    printf("\ntest1 failed: foo() executed fewer times than it was called\n"); +  } else { +    printf("test1 passed\n"); +  } +} + +// +// tests that kernel does not allow reentrant alarm calls. +void +test2() +{ +  int i; +  int pid; +  int status; + +  printf("test2 start\n"); +  if ((pid = fork()) < 0) { +    printf("test2: fork failed\n"); +  } +  if (pid == 0) { +    count = 0; +    sigalarm(2, slow_handler); +    for(i = 0; i < 1000*500000; i++){ +      if((i % 1000000) == 0) +        write(2, ".", 1); +      if(count > 0) +        break; +    } +    if (count == 0) { +      printf("\ntest2 failed: alarm not called\n"); +      exit(1); +    } +    exit(0); +  } +  wait(&status); +  if (status == 0) { +    printf("test2 passed\n"); +  } +} + +void +slow_handler() +{ +  count++; +  printf("alarm!\n"); +  if (count > 1) { +    printf("test2 failed: alarm handler called more than once\n"); +    exit(1); +  } +  for (int i = 0; i < 1000*500000; i++) { +    asm volatile("nop"); // avoid compiler optimizing away loop +  } +  sigalarm(0, 0); +  sigreturn(); +} + +// +// dummy alarm handler; after running immediately uninstall +// itself and finish signal handling +void +dummy_handler() +{ +  sigalarm(0, 0); +  sigreturn(); +} + +// +// tests that the return from sys_sigreturn() does not +// modify the a0 register +void +test3() +{ +  uint64 a0; + +  sigalarm(1, dummy_handler); +  printf("test3 start\n"); + +  asm volatile("lui a5, 0"); +  asm volatile("addi a0, a5, 0xac" : : : "a0"); +  for(int i = 0; i < 500000000; i++) +    ; +  asm volatile("mv %0, a0" : "=r" (a0) ); + +  if(a0 != 0xac) +    printf("test3 failed: register a0 changed\n"); +  else +    printf("test3 passed\n"); +} diff --git a/user/bttest.c b/user/bttest.c new file mode 100644 index 0000000..05405f9 --- /dev/null +++ b/user/bttest.c @@ -0,0 +1,10 @@ +#include "kernel/types.h" +#include "kernel/stat.h" +#include "user/user.h" + +int +main(int argc, char *argv[]) +{ +  sleep(1); +  exit(0); +} diff --git a/user/call.c b/user/call.c new file mode 100644 index 0000000..f725dcb --- /dev/null +++ b/user/call.c @@ -0,0 +1,17 @@ +#include "kernel/param.h" +#include "kernel/types.h" +#include "kernel/stat.h" +#include "user/user.h" + +int g(int x) { +  return x+3; +} + +int f(int x) { +  return g(x); +} + +void main(void) { +  printf("%d %d\n", f(8)+1, 13); +  exit(0); +} | 
