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