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.