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