1 #include <errno.h> 2 #include <fcntl.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <sys/mman.h> 7 #include <sys/time.h> 8 9 #include "pagingtest.h" 10 11 int pageinout_test(int test_runs, unsigned long long file_size) { 12 int fd; 13 char tmpname[] = "pageinoutXXXXXX"; 14 unsigned char *vec; 15 int i; 16 long long j; 17 volatile char *buf; 18 int ret = -1; 19 int rc; 20 struct timeval begin_time, end_time, elapsed_time, total_time_in, total_time_out; 21 long pagesize = sysconf(_SC_PAGE_SIZE); 22 23 timerclear(&total_time_in); 24 timerclear(&total_time_out); 25 26 fd = create_tmp_file(tmpname, file_size); 27 if (fd < 0) { 28 return -1; 29 } 30 31 vec = alloc_mincore_vec(file_size); 32 if (vec == NULL) { 33 goto err_alloc; 34 } 35 36 buf = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0); 37 if (buf == ((void *)-1)) { 38 fprintf(stderr, "Failed to mmap file: %s\n", strerror(errno)); 39 goto err_mmap; 40 } 41 42 if (!check_caching((void *)buf, vec, file_size, false)) { 43 goto err; 44 } 45 46 for (i = 0; i < test_runs; i++) { 47 gettimeofday(&begin_time, NULL); 48 //Read backwards to prevent mmap prefetching 49 for (j = ((file_size - 1) & ~(pagesize - 1)); j >= 0; j -= pagesize) { 50 buf[j]; 51 } 52 gettimeofday(&end_time, NULL); 53 54 timersub(&end_time, &begin_time, &elapsed_time); 55 timeradd(&total_time_in, &elapsed_time, &total_time_in); 56 57 if (!check_caching((void *)buf, vec, file_size, true)) { 58 goto err; 59 } 60 61 gettimeofday(&begin_time, NULL); 62 rc = madvise((void *)buf, file_size, MADV_DONTNEED) || 63 posix_fadvise(fd, 0, file_size, POSIX_FADV_DONTNEED); 64 gettimeofday(&end_time, NULL); 65 if (rc) { 66 fprintf(stderr, "posix_fadvise/madvise DONTNEED failed\n"); 67 goto err; 68 } 69 70 timersub(&end_time, &begin_time, &elapsed_time); 71 timeradd(&total_time_out, &elapsed_time, &total_time_out); 72 73 if (!check_caching((void *)buf, vec, file_size, false)) { 74 goto err; 75 } 76 } 77 78 printf("page-in: %llu MB/s\n", (file_size * test_runs * USEC_PER_SEC) / 79 (1024 * 1024 * (total_time_in.tv_sec * USEC_PER_SEC + total_time_in.tv_usec))); 80 printf("page-out (clean): %llu MB/s\n", (file_size * test_runs * USEC_PER_SEC) / 81 (1024 * 1024 * (total_time_out.tv_sec * USEC_PER_SEC + total_time_out.tv_usec))); 82 83 ret = 0; 84 85 err: 86 munmap((void *)buf, file_size); 87 err_mmap: 88 free(vec); 89 err_alloc: 90 close(fd); 91 return ret; 92 } 93