實驗測試方法
實驗的測試方法主要有2個:
- 進入到Xv6系統中,執行相應的命令
- 使用實驗提供的評分測試
- 對于單個實驗,可以使用
make GRADEFLAGS=application grade
其中application為要測試的實驗應用,例如sleep實驗對應的評分測試命令為make GRADEFLAGS=sleep grade
; - 對于整個實驗,可以直接使用
make grade
進行評測
- 對于單個實驗,可以使用
對于Lab1的評分測試,感覺不太穩定,多次測試中會隨機出現測試失敗的情況,但是根據失敗的測試樣例進入到Xv6中模擬測試又沒發現什么錯誤。換了機器測試又沒這種情況了,或許與測試環境有關?或者是Xv6在返回結果的過程中引入了其他未知問題,暫時找不到原因,不糾結這個了,還是干正事要緊。
已做的練習提交到github中,可以自行拉取并切換到相應的分支查看。https://github.com/kk140906/mit6s081_labs.git 。
sleep(easy)
Implement the UNIX program
sleep
for xv6; yoursleep
should pause for a user-specified number of ticks. A tick is a notion of time defined by the xv6 kernel, namely the time between two interrupts from the timer chip. Your solution should be in the fileuser/sleep.c
.
user/sleep.c
#include "kernel/types.h"
#include "user/user.h"int main(int argc ,char **argv) {if (argc != 2) {const char *info = "sleep take one argument.\n";write(2,info,strlen(info));exit(1);}int ticks = atoi(argv[1]);sleep(ticks);exit(0);
}
更改 Makefile
Makefile位于xv6-labs-2020實驗的根目錄下,打開后定位到 “UPROGS=\” 在最后添加 “$U/_sleep\”。
pingpong(easy)
Write a program that uses UNIX system calls to ‘‘ping-pong’’ a byte between two processes over a pair of pipes, one for each direction. The parent should send a byte to the child; the child should print “: received ping”, where is its process ID, write the byte on the pipe to the parent, and exit; the parent should read the byte from the child, print “: received pong”, and exit. Your solution should be in the file
user/pingpong.c
user/pingpong.c
#include "kernel/types.h"
#include "user/user.h"int main(int argc, char** argv)
{int p[2];char buf[512] = { 0 };pipe(p);if (fork() == 0 && read(p[0], buf, sizeof(buf) - 1) == 1) {printf("%d: received ping\n", getpid());// printf("%s\n", buf);write(p[1], "c", 1);close(p[0]);close(p[1]);exit(0);}write(p[1], "p", 1);wait(0);if (read(p[0], buf, sizeof(buf) - 1) == 1)printf("%d: recieved pong\n", getpid());// printf("%s\n", buf);close(p[0]);close(p[1]);exit(0);
}
更改 Makefile
Makefile位于xv6-labs-2020實驗的根目錄下,打開后定位到 “UPROGS=\” 在最后添加 “$U/_pingpong\”。
primes(moderate/hard)
Write a concurrent version of prime sieve using pipes. This idea is due to Doug McIlroy, inventor of Unix pipes. The picture halfway down this page and the surrounding text explain how to do it. Your solution should be in the file
user/primes.c
.
user/primes.c
#include "kernel/types.h"
#include "user/user.h"#define MAX_PRIMES 35void pipeline(int fd) {int prime;// 進入管線中時先讀一次,把這一次的數值作為當前管線的處理的基礎數值if (read(fd, &prime, sizeof(int)) <= 0) {close(fd);exit(1); }printf("prime %d\n", prime);int p[2] = {-1};pipe(p);if (fork() == 0) {close(p[1]);pipeline(p[0]);exit(0);}close(p[0]);int val;while (read(fd, &val, sizeof(int))) {if (val % prime == 0)continue;write(p[1], &val, sizeof(int));}close(fd);close(p[1]);wait(0);exit(0);
}int main(int argc, char **argv) {int p[2] = {-1};pipe(p);if (fork() == 0) {// xv6 資源不多,能提前關閉的文件描述符都需要提前關閉close(p[1]);// p[0] 在管線中關閉pipeline(p[0]);exit(0);}close(p[0]);for (int i = 2; i <= MAX_PRIMES; ++i) {write(p[1], &i, sizeof(int));}close(p[1]);wait(0);exit(0);
}
更改 Makefile
Makefile位于xv6-labs-2020實驗的根目錄下,打開后定位到 “UPROGS=\” 在最后添加 “$U/_primes\”。
find (moderate)
Write a simple version of the UNIX find program: find all the files in a directory tree with a specific name. Your solution should be in the file
user/find.c
.
user/find.c
#include "kernel/types.h"
#include "kernel/fcntl.h"
#include "kernel/fs.h"
#include "kernel/stat.h"
#include "user/user.h"#define MAX_PATH_LEN 256
typedef enum { false, true } bool;
bool match(const char *dirs, const char *file) {const char *p = dirs + strlen(dirs);char formated_dirs[MAX_PATH_LEN];while (*p != '/')p--;strcpy(formated_dirs, ++p);return !strcmp(formated_dirs, file);
}void find(char *dir, const char *file) {int fd;if ((fd = open(dir, O_RDONLY)) < 0) {fprintf(2, "find: cannot open %s\n", dir);return;}struct stat st;if (fstat(fd, &st) < 0) {fprintf(2, "find: cannot stat %s\n", dir);close(fd);return;}char dirs[MAX_PATH_LEN] = {0};struct dirent de;char *p;switch (st.type) {case T_DIR:strcpy(dirs, dir);p = dirs + strlen(dirs);*p++ = '/';while (read(fd, &de, sizeof(de)) == sizeof(de)) {// 不再繼續處理 "." 和 ".." 目錄if (de.inum == 0 || !strcmp(de.name,".") || !strcmp(de.name,".."))continue;memmove(p, de.name, DIRSIZ);p[DIRSIZ] = 0;if (stat(dirs, &st) < 0) {fprintf(2, "find: cannot stat %s\n", dir);close(fd);}if (st.type == T_FILE && match(dirs, file)) {printf("%s\n", dirs);} else if (st.type == T_DIR && dirs[strlen(dirs) - 1] != '.' ) {find(dirs, file);}}break;default:break;}
}int main(int argc, char **argv) {if (argc != 3) {fprintf(2, "usage: find [dir] [file].");exit(1);}find(argv[1], argv[2]);exit(0);
}
更改 Makefile
Makefile位于xv6-labs-2020實驗的根目錄下,打開后定位到 “UPROGS=\” 在最后添加 “$U/_find\”。
xargs (moderate)
Write a simple version of the UNIX xargs program: read lines from the standard input and run a command for each line, supplying the line as arguments to the command. Your solution should be in the file
user/xargs.c
.
user/xargs.c
#include "kernel/param.h"
#include "kernel/types.h"
#include "user/user.h"int getline(char *buf) {char c;char *s = buf;while (read(0, &c, 1) == 1 && c != '\n') {*buf++ = c;}return strlen(s);
}int main(int argc, char **argv) {if (argc < 2) {fprintf(2, "xargs take one argument at least.");exit(1);}char *args[MAXARG];for (int i = 0; i < argc - 1; ++i) {args[i] = argv[i + 1];}char buf[MAXPATH] = {0};while (getline(buf)) {args[argc - 1] = buf;args[argc] = 0;if (fork() == 0) {exec(argv[1], args);exit(0);}wait(0);memset(buf, 0, MAXPATH);}exit(0);
}
更改 Makefile
Makefile位于xv6-labs-2020實驗的根目錄下,打開后定位到 “UPROGS=\” 在最后添加 “$U/_xargs\”。
原文地址:https://blog.nas-kk.top/?p=385