Lab01:Xv6 and Unix utilities

实验测试方法

实验的测试方法主要有2个:

  1. 进入到Xv6系统中,执行相应的命令
  2. 使用实验提供的评分测试
    • 对于单个实验,可以使用 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; your sleep 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 file user/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 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

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

你可能感兴趣的:(C/C++,操作系统,操作系统,risc-v)