/* * How to stress epoll * * This program uses many pipes and two threads. * First we open as many pipes we can. (see ulimit -n) * Then we create a worker thread. * The worker thread will send bytes to random pipes. * The main thread uses epoll to collect ready pipes and read them. * Each second, a number of collected bytes is printed on stderr * * Usage : epoll_bench [-n X] */ #include #include #include #include #include #include #include #include #include int nbpipes = 1024; struct pipefd { int fd[2]; } *tab; int epoll_fd; static int alloc_pipes() { int i; epoll_fd = epoll_create(nbpipes); if (epoll_fd == -1) { perror("epoll_create"); return -1; } tab = malloc(sizeof(struct pipefd) * nbpipes); if (tab ==NULL) { perror("malloc"); return -1; } for (i = 0 ; i < nbpipes ; i++) { struct epoll_event ev; if (pipe(tab[i].fd) == -1) break; ev.events = EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLPRI | EPOLLET; ev.data.u64 = (uint64_t)i; epoll_ctl(epoll_fd, EPOLL_CTL_ADD, tab[i].fd[0], &ev); } nbpipes = i; printf("%d pipes setup\n", nbpipes); return 0; } unsigned long nbhandled; static void timer_func() { char buffer[32]; size_t len; static unsigned long old; unsigned long delta = nbhandled - old; old = nbhandled; len = sprintf(buffer, "%lu\n", delta); write(2, buffer, len); } static void timer_setup() { struct itimerval it; struct sigaction sg; memset(&sg, 0, sizeof(sg)); sg.sa_handler = timer_func; sigaction(SIGALRM, &sg, 0); it.it_interval.tv_sec = 1; it.it_interval.tv_usec = 0; it.it_value.tv_sec = 1; it.it_value.tv_usec = 0; if (setitimer(ITIMER_REAL, &it, 0)) perror("setitimer"); } static void * worker_thread_func(void *arg) { int fd; char c = 1; for (;;) { fd = rand() % nbpipes; write(tab[fd].fd[1], &c, 1); } } int main(int argc, char *argv[]) { char buff[1024]; pthread_t tid; int c; while ((c = getopt(argc, argv, "n:")) != EOF) { if (c == 'n') nbpipes = atoi(optarg); } alloc_pipes(); pthread_create(&tid, NULL, worker_thread_func, (void *)0); timer_setup(); for (;;) { struct epoll_event events[128]; int nb = epoll_wait(epoll_fd, events, 128, 10000); int i, fd; for (i = 0 ; i < nb ; i++) { fd = tab[events[i].data.u64].fd[0]; if (read(fd, buff, 1024) > 0) nbhandled++; } } }