/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ #include #include #include #include #include #include #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; }