MIT 6.S081 Lab util: Unix utilities
MIT 6.S081 LAB 1 Review Part One
Lab util:Unix utilitie
1.sleep
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.
- Simplely use the kernel syscall function sleep
#include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" int main(int argc,char *argv[]){ int n; if (argc !=2 ) { fprintf(2,"please enter a number!\n"); exit(1); } else{ n = atoi(argv[1]); sleep(n); exit(0); } }
- Add the
U/_sleep
to UPROGS in Makefile. Test the code using grade-lab-syscall like the following command:$sudo python3 grade-lab-syscall sleep
2.pingpong
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.
-
Use the syscall function pipe to create a pipe so that parent process can communicate with child process.
1.1 pipe function use a argument like arg,arg[0] is used to read data from pipe and arg[1] can be used to wirte the date into pipe. -
The implemented code for the question is following:
#include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" int main(int argc,char *argv[]) { int p[2]; pipe(p); char buf[2]; char *recmsg="a"; char *sedmsg="b"; if(fork()==0) { //child if(read(p[0],buf,1)!=1) { fprintf(2,"can't read from parent!\n"); exit(1); } printf("child receive :%c\n",buf[0]); close(p[0]); printf("%d: received ping\n",getpid()); if(write(p[1],sedmsg,1)!=1) { fprintf(2,"can't write to parent!"); } close(p[1]); exit(0); } else{ if(write(p[1],recmsg,1)!=1) { fprintf(2,"Can't write to child!\n"); exit(1); } close(p[1]); wait(0); if(read(p[0],buf,1)!=1) { fprintf(2,"Can't read from child!"); exit(1); } printf("parent receive: %c\n",buf[0]); close(p[0]); printf("%d: received pong\n",getpid()); exit(0); } }
3.prime
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.
- In order to implement the code,we should understand the figure blow:
- According to the figure,we should use fork and pipe function to transmit the numbers which can't be divided by the first transmited number such as 2 in proc1 or 3 in proc2.In the method,we can collect all of the first number in every process and these number can be recognize as prime.
- The implemented code is below:
#include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" void primes(int *fd) { int p,d; close(fd[1]); if(read(fd[0],(void *)&p,sizeof(p))!= sizeof(p)) { fprintf(2,"Read fail!\n"); exit(1); } printf("prime %d\n",p); if(read(fd[0],(void *)&d,sizeof(d))) { int fd1[2]; pipe(fd1); if(fork()==0) { primes(fd1); } else{ close(fd1[0]); do{ if(d%p!=0) { write(fd1[1],(void *)&d,sizeof(d)); } }while(read(fd[0],(void *)&d,sizeof(d))); close(fd[0]); close(fd1[1]); wait(0); } exit(0); } } int main(int agrc,int *argv[]){ int fd[2]; int start = 2; int end = 35; pipe(fd); if(fork()==0) { primes(fd); } else{ close(fd[0]); for(int i=start;i<=end;i++) { if(write(fd[1],(void *)&i,sizeof(i))!=4) { fprintf(2,"Write fail!\n"); exit(1); } } close(fd[1]); wait(0); } exit(0); }
- You can test the above code like the method I have show in the frist problem sleep.