/* * This code is stolen from somewhere and adjusted for other purposes */ #include #include #include #include #include #include #include #include #include #include #include #include #define N_ITER 1000000 //#define N_ITER 10000 #define FILENAME "footest" #define TYPE_RDONLY 1 #define TYPE_RDWR 2 int ttype = TYPE_RDONLY; int capped_fd; int uncapped_fd; int read_fd; void * dup2_worker(void *arg) { int i, fd, n; for (i = 0; i < N_ITER; i++) { if (dup2(capped_fd, read_fd) < 0) err(1, "dup2"); } return (NULL); } void * read_worker(void *arg) { char buf[100]; int i; for (i = 0; i < N_ITER; i++) { if (read(read_fd, buf, 100) == -1) { switch (errno) { case EAGAIN: case ENOTCAPABLE: break; default: printf("%d\n", errno); } } else { printf("read\n"); } } return (NULL); } double now() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)(tv.tv_usec) / 1000000; } int main(int argc, char **argv) { pthread_t *threads; int n_threads = 8, i; double t1, t2; cap_rights_t rights; int pipe_fd[2]; capped_fd = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644); if (capped_fd < 0) err(1, "Cannot create %s", FILENAME); cap_rights_init(&rights, 0); if (cap_rights_limit(capped_fd, &rights) < 0) err(1, "cap_rights_limit"); if (pipe2(pipe_fd, O_NONBLOCK) < 0) err(1, "pipe"); uncapped_fd = pipe_fd[0]; read_fd = pipe_fd[1] + 1; dup2(capped_fd, read_fd); while ((i = getopt(argc, argv, "n:t:h")) != -1) { switch (i) { case 'n': n_threads = atoi(optarg); break; case 't': if (strcmp(optarg, "r") == 0) ttype = TYPE_RDONLY; else if (strcmp(optarg, "w") == 0) ttype = TYPE_RDWR; else errx(1, "Unknown type: %s", optarg); break; case 'h': printf("usage: %s [-n n_threads] [-t r|w]\n", argv[0]); return 0; } } threads = malloc(sizeof(*threads) * n_threads); printf("%d threads, %d operations/thread\n", n_threads, N_ITER); pthread_create(&threads[0], NULL, dup2_worker, NULL); t1 = now(); for (i = 1; i < n_threads; i++) { if (pthread_create(&threads[i], NULL, read_worker, NULL) != 0) err(1, "pthread_create failed"); } for (i = 0; i < n_threads; i++) pthread_join(threads[i], NULL); t2 = now(); unlink(FILENAME); printf("%u operations done in %0.1lf seconds: %0.1lf ops/s\n", n_threads * N_ITER, t2-t1, (n_threads * N_ITER) / (t2-t1)); }