/* * Chained pipe test with 900,000 processes and 900,000 pipes * * Requires system w/ 128GB+ of ram, kern.maxproc=4000000 set in * /boot/loader.conf. 80 second stabilization time after last * process is forked. * * Also test tear-down by ^C'ing the test. */ #include #include #include #include #include #include #include #include #include #include #define COUNT 900000 int main(int ac, char **av) { int status; int i; int j; int idno; int fdsbeg[2]; int fdsend[2]; char *path; char *id; char c; if (ac == 1) { pipe(fdsbeg); for (i = 0; i < COUNT; i += 100) { #if 0 asprintf(&path, "cp %s /tmp/x%06d", av[0], i); system(path); free(path); asprintf(&path, "/tmp/x%06d", i); #else asprintf(&path, "%s", av[0]); #endif asprintf(&id, "%d", i); pipe(fdsend); if (vfork() == 0) { close(fdsbeg[1]); dup2(fdsbeg[0], 0); dup2(fdsend[1], 1); close(fdsbeg[0]); close(fdsend[1]); execl(path, path, id, NULL); _exit(0); } close(fdsbeg[0]); close(fdsend[1]); fdsbeg[0] = fdsend[0]; if (i % 1000 == 0) { printf("running %d\r", i); fflush(stdout); } free(path); free(id); } } else { idno = strtol(av[1], NULL, 0); setpriority(PRIO_PROCESS, 0, 5); for (j = 0; j < 100; ++j) { if (j != 99) pipe(fdsend); else fdsend[1] = 1; if (j == 99 || fork() == 0) { if (fdsend[1] != 1) { dup2(fdsend[1], 1); close(fdsend[1]); } if (j != 99) close(fdsend[0]); setpriority(PRIO_PROCESS, 0, 15); while (1) { if (read(0, &c, 1) < 0) break; #if 0 fprintf(stderr, "x%d\n", idno + j); fflush(stderr); #endif write(1, &c, 1); } _exit(0); } dup2(fdsend[0], 0); close(fdsend[1]); close(fdsend[0]); } while (wait3(NULL, 0, NULL) >= 0 || errno == EINTR) ; _exit(0); } printf("running %d\n", i); for (;;) { write(fdsbeg[1], &c, 1); if (read(fdsend[0], &c, 1) < 0) break; write(2, "x", 1); } return 0; }