Home | History | Annotate | Download | only in pagingtest
      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 
     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