summaryrefslogtreecommitdiff
path: root/user
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2024-01-18 17:35:27 +0800
committerMole Shang <[email protected]>2024-02-05 18:10:56 +0800
commit283d5ab4c964ab525e45fcade06d6fd7e977c43e (patch)
treebc44a1e2c447fb965cf5d5c2cfdcfa71658dbbbf /user
parent0d6a64fa06ce6aae729fa05a539eadd88fa59007 (diff)
downloadxv6-labs-283d5ab4c964ab525e45fcade06d6fd7e977c43e.tar.gz
xv6-labs-283d5ab4c964ab525e45fcade06d6fd7e977c43e.tar.bz2
xv6-labs-283d5ab4c964ab525e45fcade06d6fd7e977c43e.zip
lab syscall: finish
Conflicts: kernel/syscall.c kernel/syscall.h user/user.h user/usys.pl
Diffstat (limited to 'user')
-rw-r--r--user/sysinfotest.c153
-rw-r--r--user/trace.c27
-rw-r--r--user/user.h3
-rwxr-xr-xuser/usys.pl2
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");