Recently I’ve started following MIT 6.828 Operating System Engineering. Without further ado, this is my solution to its first exercise, 1.6.1:
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. Measure the program’s performance, in exchanges per second (19).
Russ Cox, Frans Kaashoek, Robert Morris. xv6: a simple, Unix-like teaching operating system. October 27, 2019
//ping-pong.c #include<sys/types.h> #include<sys/wait.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<time.h> int main() { int p1[2], p2[2]; pipe(p1); pipe(p2); if (fork() != 0) { //parent close(p1[0]); close(p2[1]); char ping[1] = "B"; clock_t start, end; double rtt; start = clock(); for (int i=0; i<100000; i++) { write(p1[1], ping, 1); read(p2[0], ping, 1); } end = clock(); wait(0); close(p1[1]); close(p2[0]); rtt = (((double)(end - start)) / CLOCKS_PER_SEC) / 100000; printf("average RTT: %f ms\n", (rtt * 1000)); printf("exchanges per second: %ld times\n", (unsigned long)(1 / rtt)); } else { //child close(p1[1]); close(p2[0]); char pong[1]; for (int j=0; j<100000; j++) { read(p1[0], pong, 1); write(p2[1], pong, 1); } close(p1[0]); close(p2[1]); exit(0); } return 0; }
Well, printf()
is not a syscall, but, ugh…:-)
Anyway, let’s run it:
peilin@PWN:~/6.828/1.6.1-ping_pong$ gcc -o ping_pong ping_pong.c
peilin@PWN:~/6.828/1.6.1-ping_pong$ ./ping_pong
average RTT: 0.001964 ms
exchanges per second: 509053 times
More than 500,000 times on my sluggish VM. Pretty impressive to me.
Another trivia: When initializing pong
, char *pong;
doesn’t work, since this declaration is not actually allocating any memory for the buffer, and I can’t read()
to an nonexistent buffer. One may want to do char pong[1];
instead. Maybe I’ve written too much Python. Ugh.
So, that’s it! Looking forward to learn a lot from this course.