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