/* * This code is stolen from somewhere and adjusted for other purposes */ #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 globfd; void * open_worker(void *arg) { int i, fd, n; for (i = 0; i < N_ITER; i++) { fd = open(FILENAME, ttype == TYPE_RDONLY ? O_RDONLY : O_RDWR); if (fd < 0) err(1, "Error in open(%s)", FILENAME); //read(fd, &n, sizeof(n)); assert(fd == globfd); close(fd); } return (NULL); } void * read_worker(void *arg) { char buf[100]; int i; for (i = 0; i < N_ITER; i++) { if (read(globfd, buf, 100) == -1) { if (errno != EBADF) printf("%d\n", errno); } } 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; i = open(FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (i < 0) err(1, "Cannot create %s", FILENAME); write(i, &i, sizeof(i)); close(i); globfd = i; 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, open_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)); }