实验的测试方法主要有2个:
make GRADEFLAGS=application grade
其中application为要测试的实验应用,例如sleep实验对应的评分测试命令为 make GRADEFLAGS=sleep grade
;make grade
进行评测对于Lab1的评分测试,感觉不太稳定,多次测试中会随机出现测试失败的情况,但是根据失败的测试样例进入到Xv6中模拟测试又没发现什么错误。换了机器测试又没这种情况了,或许与测试环境有关?或者是Xv6在返回结果的过程中引入了其他未知问题,暂时找不到原因,不纠结这个了,还是干正事要紧。
已做的练习提交到github中,可以自行拉取并切换到相应的分支查看。https://github.com/kk140906/mit6s081_labs.git 。
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
.
#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位于xv6-labs-2020实验的根目录下,打开后定位到 “UPROGS=\” 在最后添加 “$U/_sleep\”。
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
#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位于xv6-labs-2020实验的根目录下,打开后定位到 “UPROGS=\” 在最后添加 “$U/_pingpong\”。
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
.
#include "kernel/types.h"
#include "user/user.h"
#define MAX_PRIMES 35
void 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位于xv6-labs-2020实验的根目录下,打开后定位到 “UPROGS=\” 在最后添加 “$U/_primes\”。
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
.
#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位于xv6-labs-2020实验的根目录下,打开后定位到 “UPROGS=\” 在最后添加 “$U/_find\”。
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
.
#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位于xv6-labs-2020实验的根目录下,打开后定位到 “UPROGS=\” 在最后添加 “$U/_xargs\”。
原文地址:https://blog.nas-kk.top/?p=385