1 #include "pagingtest.h" 2 3 #include <errno.h> 4 #include <fcntl.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <sys/mman.h> 9 #include <sys/stat.h> 10 #include <sys/types.h> 11 #include <unistd.h> 12 13 #define TEST_RUNS 10 14 #define ALLOC_SIZE (10 * 1024 * 1024) 15 #define FILE_SIZE (10 * 1024 * 1024) 16 17 int create_tmp_file(char *filename, off_t size) { 18 void *buf; 19 ssize_t rc; 20 int fd; 21 int urandom; 22 23 fd = mkstemp(filename); 24 if (fd < 0) { 25 fprintf(stderr, "unable to create temp file: %s\n", strerror(errno)); 26 goto err_mkstemp; 27 } 28 29 urandom = open("/dev/urandom", O_RDONLY); 30 if (urandom < 0) { 31 fprintf(stderr, "unable to open urandom: %s\n", strerror(errno)); 32 goto err_open; 33 } 34 35 if (unlink(filename)) { 36 fprintf(stderr, "unable to unlink temp file: %s\n", strerror(errno)); 37 goto err_unlink; 38 } 39 40 if (ftruncate(fd, size)) { 41 fprintf(stderr, "unable to allocate temp file: %s\n", strerror(errno)); 42 goto err_truncate; 43 } 44 45 buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0); 46 if (buf == (void *)-1) { 47 fprintf(stderr, "unable to mmap temp file: %s\n", strerror(errno)); 48 goto err_mmap; 49 } 50 51 rc = read(urandom, buf, size); 52 53 if (rc < 0) { 54 fprintf(stderr, "write random data failed: %s\n", strerror(errno)); 55 goto err; 56 } 57 58 if (rc != size) { 59 fprintf(stderr, "write random data incomplete\n"); 60 goto err; 61 } 62 63 if (madvise(buf, size, MADV_DONTNEED)) { 64 fprintf(stderr, "madvise DONTNEED failed: %s\n", strerror(errno)); 65 goto err; 66 } 67 68 if (fsync(fd) < 0) { 69 fprintf(stderr, "fsync failed: %s\n", strerror(errno)); 70 goto err; 71 } 72 73 rc = posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED); 74 if (rc) { 75 fprintf(stderr, "fadvise DONTNEED failed: %s\n", strerror(errno)); 76 goto err; 77 } 78 79 munmap(buf, size); 80 close(urandom); 81 return fd; 82 83 err: 84 munmap(buf, size); 85 err_mmap: 86 err_truncate: 87 err_unlink: 88 close(urandom); 89 err_open: 90 close(fd); 91 err_mkstemp: 92 return -1; 93 } 94 95 unsigned char *alloc_mincore_vec(size_t size) { 96 unsigned char *vec; 97 98 vec = malloc(mincore_vec_len(size)); 99 if (vec == NULL) { 100 fprintf(stderr, "malloc failed\n"); 101 } 102 103 return vec; 104 } 105 106 bool check_caching(void *buf, unsigned char *vec, size_t size, bool is_cached) { 107 bool ret = true; 108 size_t i; 109 110 if (mincore(buf, size, vec)) { 111 fprintf(stderr, "mincore failed: %s\n", strerror(errno)); 112 return false; 113 } 114 115 if (is_cached) { 116 for (i = 0; i < mincore_vec_len(size); i++) { 117 if (!(vec[i] & 0x1)) { 118 fprintf(stderr, "found an uncached page at page offset %zd\n", i); 119 ret = false; 120 } 121 } 122 } else { 123 for (i = 0; i < mincore_vec_len(size); i++) { 124 if (vec[i] & 0x1) { 125 fprintf(stderr, "found a cached page at page offset %zd\n", i); 126 ret = false; 127 } 128 } 129 } 130 131 return ret; 132 } 133 134 int main(int argc, char **argv) { 135 unsigned long long alloc_size = 0ULL; 136 unsigned long long file_size = 0ULL; 137 int test_runs = 0; 138 int rc; 139 140 //arguments: <program> [test_runs [alloc_size [file_size]]] 141 if (argc >= 2) { 142 test_runs = atoi(argv[1]); 143 } 144 if (test_runs <= 0) { 145 test_runs = TEST_RUNS; 146 } 147 if (argc >= 3) { 148 alloc_size = strtoull(argv[2], NULL, 10); 149 } 150 if (!alloc_size) { 151 alloc_size = ALLOC_SIZE; 152 } 153 if (argc >= 4) { 154 file_size = strtoull(argv[3], NULL, 10); 155 } 156 if (!file_size) { 157 file_size = FILE_SIZE; 158 } 159 160 rc = mmap_test(test_runs, alloc_size); 161 if (rc) { 162 return rc; 163 } 164 rc = pageinout_test(test_runs, file_size); 165 if (rc) { 166 return rc; 167 } 168 rc = thrashing_test(test_runs); 169 170 return rc; 171 } 172