Files
graphene/LibOS/shim/test/native/pipe_latency.c

147 lines
3.4 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/time.h>
#define NTRIES 10000
#define TEST_TIMES 32
int main(int argc, char ** argv)
{
int times = TEST_TIMES;
int pipes[6];
int pids[TEST_TIMES][2];
int i = 0;
if (argc >= 2) {
times = atoi(argv[1]) / 2;
if (times > TEST_TIMES)
return -1;
}
pipe(&pipes[0]);
pipe(&pipes[2]);
pipe(&pipes[4]);
for (i = 0 ; i < times ; i++ ) {
int pair_pipes[4];
pipe(&pair_pipes[0]);
pipe(&pair_pipes[2]);
pids[i][0] = fork();
if (pids[i][0] < 0) {
printf("fork failed\n");
return -1;
}
if (pids[i][0] == 0) {
close(pipes[0]);
close(pipes[1]);
close(pipes[3]);
close(pipes[4]);
close(pipes[5]);
close(pair_pipes[1]);
close(pair_pipes[2]);
char byte;
for (int i = 0 ; i < NTRIES ; i++) {
read(pair_pipes[0], &byte, 1);
write(pair_pipes[3], &byte, 1);
}
read(pipes[2], &byte, 1);
close(pipes[2]);
close(pair_pipes[0]);
close(pair_pipes[3]);
exit(0);
}
pids[i][1] = fork();
if (pids[i][1] < 0) {
printf("fork failed\n");
return -1;
}
if (pids[i][1] == 0) {
close(pipes[1]);
close(pipes[3]);
close(pipes[4]);
close(pair_pipes[0]);
close(pair_pipes[3]);
char byte;
read(pipes[0], &byte, 1);
struct timeval timevals[2];
gettimeofday(&timevals[0], NULL);
for (int i = 0 ; i < NTRIES ; i++) {
write(pair_pipes[1], &byte, 1);
read(pair_pipes[2], &byte, 1);
}
gettimeofday(&timevals[1], NULL);
close(pair_pipes[1]);
close(pair_pipes[2]);
close(pipes[0]);
write(pipes[5], timevals, sizeof(struct timeval) * 2);
close(pipes[5]);
read(pipes[2], &byte, 1);
close(pipes[2]);
exit(0);
}
}
close(pipes[0]);
close(pipes[2]);
close(pipes[5]);
sleep(1);
char bytes[times * 2];
write(pipes[1], bytes, times);
close(pipes[1]);
unsigned long long start_time = 0;
unsigned long long end_time = 0;
struct timeval timevals[2];
for (int i = 0 ; i < times ; i++) {
read(pipes[4], timevals, sizeof(struct timeval) * 2);
unsigned long s = timevals[0].tv_sec * 1000000ULL +
timevals[0].tv_usec;
unsigned long e = timevals[1].tv_sec * 1000000ULL +
timevals[1].tv_usec;
if (!start_time || s < start_time)
start_time = s;
if (!end_time || e > end_time)
end_time = e;
}
close(pipes[4]);
write(pipes[3], bytes, times * 2);
close(pipes[3]);
for (i = 0 ; i < times ; i++) {
waitpid(pids[i][0], NULL, 0);
waitpid(pids[i][1], NULL, 0);
}
printf("throughput for %d processes to send %d message: %lf bytes/second\n",
times, NTRIES,
1.0 * NTRIES * 2 * times * 1000000 / (end_time - start_time));
return 0;
}