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