/* * gcc -Wall -o reader reader.c -lpthread */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include struct thread_data { int fd; int read_size; size_t size; }; static void *drop_pages(void *arg) { struct thread_data *td = arg; int ret; while (1) { ret = posix_fadvise(td->fd, 0, td->size, POSIX_FADV_DONTNEED); if (ret < 0) err(1, "fadvise dontneed"); } return NULL; } #define READ_BUF (2 * 1024 * 1024) static void *read_pages(void *arg) { struct thread_data *td = arg; char buf[READ_BUF]; ssize_t ret; loff_t offset = 8192; while (1) { ret = pread(td->fd, buf, td->read_size, offset); if (ret < 0) err(1, "read"); if (ret == 0) break; } return NULL; } int main(int ac, char **av) { int fd; int ret; struct stat st; int sizes[9] = { 0, 0, 8192, 16834, 32768, 65536, 128 * 1024, 256 * 1024, 1024 * 1024 }; int nr_tids = 9; struct thread_data tds[9]; int i; int sleeps = 0; pthread_t tids[nr_tids]; if (ac != 2) err(1, "usage: reader filename\n"); fd = open(av[1], O_RDONLY, 0600); if (fd < 0) err(1, "unable to open %s", av[1]); ret = fstat(fd, &st); if (ret < 0) err(1, "stat"); for (i = 0; i < nr_tids; i++) { struct thread_data *td = tds + i; td->fd = fd; td->size = st.st_size; td->read_size = sizes[i]; if (i < 2) ret = pthread_create(tids + i, NULL, drop_pages, td); else ret = pthread_create(tids + i, NULL, read_pages, td); if (ret) err(1, "pthread_create"); } for (i = 0; i < nr_tids; i++) { pthread_detach(tids[i]); } while(1) { sleep(122); sleeps++; fprintf(stderr, ":%d:", sleeps * 122); } }