diff options
Diffstat (limited to 'user')
| -rw-r--r-- | user/sysinfotest.c | 153 | ||||
| -rw-r--r-- | user/trace.c | 27 | ||||
| -rw-r--r-- | user/user.h | 3 | ||||
| -rwxr-xr-x | user/usys.pl | 2 | 
4 files changed, 185 insertions, 0 deletions
| diff --git a/user/sysinfotest.c b/user/sysinfotest.c new file mode 100644 index 0000000..8a648a6 --- /dev/null +++ b/user/sysinfotest.c @@ -0,0 +1,153 @@ +#include "kernel/types.h" +#include "kernel/riscv.h" +#include "kernel/sysinfo.h" +#include "user/user.h" + + +void +sinfo(struct sysinfo *info) { +  if (sysinfo(info) < 0) { +    printf("FAIL: sysinfo failed"); +    exit(1); +  } +} + +// +// use sbrk() to count how many free physical memory pages there are. +// +int +countfree() +{ +  uint64 sz0 = (uint64)sbrk(0); +  struct sysinfo info; +  int n = 0; + +  while(1){ +    if((uint64)sbrk(PGSIZE) == 0xffffffffffffffff){ +      break; +    } +    n += PGSIZE; +  } +  sinfo(&info); +  if (info.freemem != 0) { +    printf("FAIL: there is no free mem, but sysinfo.freemem=%d\n", +      info.freemem); +    exit(1); +  } +  sbrk(-((uint64)sbrk(0) - sz0)); +  return n; +} + +void +testmem() { +  struct sysinfo info; +  uint64 n = countfree(); +   +  sinfo(&info); + +  if (info.freemem!= n) { +    printf("FAIL: free mem %d (bytes) instead of %d\n", info.freemem, n); +    exit(1); +  } +   +  if((uint64)sbrk(PGSIZE) == 0xffffffffffffffff){ +    printf("sbrk failed"); +    exit(1); +  } + +  sinfo(&info); +     +  if (info.freemem != n-PGSIZE) { +    printf("FAIL: free mem %d (bytes) instead of %d\n", n-PGSIZE, info.freemem); +    exit(1); +  } +   +  if((uint64)sbrk(-PGSIZE) == 0xffffffffffffffff){ +    printf("sbrk failed"); +    exit(1); +  } + +  sinfo(&info); +     +  if (info.freemem != n) { +    printf("FAIL: free mem %d (bytes) instead of %d\n", n, info.freemem); +    exit(1); +  } +} + +void +testcall() { +  struct sysinfo info; +   +  if (sysinfo(&info) < 0) { +    printf("FAIL: sysinfo failed\n"); +    exit(1); +  } + +  if (sysinfo((struct sysinfo *) 0xeaeb0b5b00002f5e) !=  0xffffffffffffffff) { +    printf("FAIL: sysinfo succeeded with bad argument\n"); +    exit(1); +  } +} + +void testproc() { +  struct sysinfo info; +  uint64 nproc; +  int status; +  int pid; +   +  sinfo(&info); +  nproc = info.nproc; + +  pid = fork(); +  if(pid < 0){ +    printf("sysinfotest: fork failed\n"); +    exit(1); +  } +  if(pid == 0){ +    sinfo(&info); +    if(info.nproc != nproc+1) { +      printf("sysinfotest: FAIL nproc is %d instead of %d\n", info.nproc, nproc+1); +      exit(1); +    } +    exit(0); +  } +  wait(&status); +  sinfo(&info); +  if(info.nproc != nproc) { +      printf("sysinfotest: FAIL nproc is %d instead of %d\n", info.nproc, nproc); +      exit(1); +  } +} + +void testbad() { +  int pid = fork(); +  int xstatus; +   +  if(pid < 0){ +    printf("sysinfotest: fork failed\n"); +    exit(1); +  } +  if(pid == 0){ +      sinfo(0x0); +      exit(0); +  } +  wait(&xstatus); +  if(xstatus == -1)  // kernel killed child? +    exit(0); +  else { +    printf("sysinfotest: testbad succeeded %d\n", xstatus); +    exit(xstatus); +  } +} + +int +main(int argc, char *argv[]) +{ +  printf("sysinfotest: start\n"); +  testcall(); +  testmem(); +  testproc(); +  printf("sysinfotest: OK\n"); +  exit(0); +} diff --git a/user/trace.c b/user/trace.c new file mode 100644 index 0000000..dd77760 --- /dev/null +++ b/user/trace.c @@ -0,0 +1,27 @@ +#include "kernel/param.h" +#include "kernel/types.h" +#include "kernel/stat.h" +#include "user/user.h" + +int +main(int argc, char *argv[]) +{ +  int i; +  char *nargv[MAXARG]; + +  if(argc < 3 || (argv[1][0] < '0' || argv[1][0] > '9')){ +    fprintf(2, "Usage: %s mask command\n", argv[0]); +    exit(1); +  } + +  if (trace(atoi(argv[1])) < 0) { +    fprintf(2, "%s: trace failed\n", argv[0]); +    exit(1); +  } +   +  for(i = 2; i < argc && i < MAXARG; i++){ +    nargv[i-2] = argv[i]; +  } +  exec(nargv[0], nargv); +  exit(0); +} diff --git a/user/user.h b/user/user.h index 16cf173..a076f37 100644 --- a/user/user.h +++ b/user/user.h @@ -1,4 +1,5 @@  struct stat; +struct sysinfo;  // system calls  int fork(void); @@ -30,6 +31,8 @@ int pgaccess(void *base, int len, void *mask);  // usyscall region  int ugetpid(void);  #endif +int trace(int); +int sysinfo(struct sysinfo*);  // ulib.c  int stat(const char*, struct stat*); diff --git a/user/usys.pl b/user/usys.pl index 6453fe9..9a93999 100755 --- a/user/usys.pl +++ b/user/usys.pl @@ -38,3 +38,5 @@ entry("sleep");  entry("uptime");  entry("connect");  entry("pgaccess"); +entry("trace"); +entry("sysinfo"); | 
