diff --git a/Makefile b/Makefile index 4906e16..35a280e 100644 --- a/Makefile +++ b/Makefile @@ -189,6 +189,7 @@ UPROGS=\ $U/_wc\ $U/_zombie\ $U/_trace\ + $U/_sysinfotest\ diff --git a/kernel/defs.h b/kernel/defs.h index a3c962b..4238154 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -63,6 +63,7 @@ void ramdiskrw(struct buf*); void* kalloc(void); void kfree(void *); void kinit(void); +int size_of_freemem(void); // log.c void initlog(int, struct superblock*); @@ -106,6 +107,7 @@ void yield(void); int either_copyout(int user_dst, uint64 dst, void *src, uint64 len); int either_copyin(void *dst, int user_src, uint64 src, uint64 len); void procdump(void); +int number_of_process(void); // swtch.S void swtch(struct context*, struct context*); diff --git a/kernel/kalloc.c b/kernel/kalloc.c index 0699e7e..13ce5bc 100644 --- a/kernel/kalloc.c +++ b/kernel/kalloc.c @@ -80,3 +80,18 @@ kalloc(void) memset((char*)r, 5, PGSIZE); // fill with junk return (void*)r; } + +int +size_of_freemem(void) +{ + struct run *r; + int count = 0; + acquire(&kmem.lock); + r = kmem.freelist; + while (r) { + count ++; + r = r->next; + } + release(&kmem.lock); + return count * PGSIZE; +} \ No newline at end of file diff --git a/kernel/proc.c b/kernel/proc.c index 00f2121..bb9b0e4 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -681,3 +681,14 @@ procdump(void) printf("\n"); } } + +int +number_of_process(void) +{ + struct proc *p; + int count = 0; + for (p = proc; p < &proc[NPROC]; p ++) { + if (p->state != UNUSED) count ++; + } + return count; +} \ No newline at end of file diff --git a/kernel/syscall.c b/kernel/syscall.c index 21ee02a..bb385ad 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -102,6 +102,7 @@ extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); extern uint64 sys_trace(void); +extern uint64 sys_sysinfo(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -128,6 +129,7 @@ static uint64 (*syscalls[])(void) = { [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, [SYS_trace] sys_trace, +[SYS_sysinfo] sys_sysinfo, }; char syscall_name[][8] = { diff --git a/kernel/sysproc.c b/kernel/sysproc.c index 2300f3b..a452fe7 100644 --- a/kernel/sysproc.c +++ b/kernel/sysproc.c @@ -5,6 +5,7 @@ #include "memlayout.h" #include "spinlock.h" #include "proc.h" +#include "sysinfo.h" uint64 sys_exit(void) @@ -101,4 +102,21 @@ sys_trace(void) myproc()->tracemask = mask; release(&myproc()->lock); return 0; +} + +uint64 +sys_sysinfo(void) +{ + struct sysinfo info; + uint64 addr; + argaddr(0, &addr); + info.nproc = number_of_process(); + info.freemem = size_of_freemem(); + acquire(&myproc()->lock); + if(copyout(myproc()->pagetable, addr, (char *)&info, sizeof(info)) < 0){ + release(&myproc()->lock); + return -1; + } + release(&myproc()->lock); + return 0; } \ No newline at end of file diff --git a/time.txt b/time.txt new file mode 100644 index 0000000..e440e5c --- /dev/null +++ b/time.txt @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/user/user.h b/user/user.h index 0bf4333..14f69e5 100644 --- a/user/user.h +++ b/user/user.h @@ -1,4 +1,5 @@ struct stat; +struct sysinfo; // system calls int fork(void); @@ -23,6 +24,7 @@ char* sbrk(int); int sleep(int); int uptime(void); 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 9c97b05..bc109fd 100755 --- a/user/usys.pl +++ b/user/usys.pl @@ -37,3 +37,4 @@ entry("sbrk"); entry("sleep"); entry("uptime"); entry("trace"); +entry("sysinfo");