summaryrefslogtreecommitdiff
path: root/tests/pagingtest/pagingtest.c
blob: e2bd792347e79db1dabaa1b05dc60423ffd7e83c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "pagingtest.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define TEST_RUNS 10
#define ALLOC_SIZE (10 * 1024 * 1024)
#define FILE_SIZE (10 * 1024 * 1024)

int create_tmp_file(char *filename, off_t size) {
    void *buf;
    ssize_t rc;
    int fd;
    int urandom;

    fd = mkstemp(filename);
    if (fd < 0) {
        fprintf(stderr, "unable to create temp file: %s\n", strerror(errno));
        goto err_mkstemp;
    }

    urandom = open("/dev/urandom", O_RDONLY);
    if (urandom < 0) {
        fprintf(stderr, "unable to open urandom: %s\n", strerror(errno));
        goto err_open;
    }

    if (unlink(filename)) {
        fprintf(stderr, "unable to unlink temp file: %s\n", strerror(errno));
        goto err_unlink;
    }

    if (ftruncate(fd, size)) {
        fprintf(stderr, "unable to allocate temp file: %s\n", strerror(errno));
        goto err_truncate;
    }

    buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
    if (buf == (void *)-1) {
        fprintf(stderr, "unable to mmap temp file: %s\n", strerror(errno));
        goto err_mmap;
    }

    rc = read(urandom, buf, size);

    if (rc < 0) {
        fprintf(stderr, "write random data failed: %s\n", strerror(errno));
        goto err;
    }

    if (rc != size) {
        fprintf(stderr, "write random data incomplete\n");
        goto err;
    }

    if (madvise(buf, size, MADV_DONTNEED)) {
        fprintf(stderr, "madvise DONTNEED failed: %s\n", strerror(errno));
        goto err;
    }

    if (fsync(fd) < 0) {
        fprintf(stderr, "fsync failed: %s\n", strerror(errno));
        goto err;
    }

    rc = posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED);
    if (rc) {
        fprintf(stderr, "fadvise DONTNEED failed: %s\n", strerror(errno));
        goto err;
    }

    munmap(buf, size);
    close(urandom);
    return fd;

err:
    munmap(buf, size);
err_mmap:
err_truncate:
err_unlink:
    close(urandom);
err_open:
    close(fd);
err_mkstemp:
    return -1;
}

unsigned char *alloc_mincore_vec(size_t size) {
    unsigned char *vec;

    vec = malloc(mincore_vec_len(size));
    if (vec == NULL) {
        fprintf(stderr, "malloc failed\n");
    }

    return vec;
}

bool check_caching(void *buf, unsigned char *vec, size_t size, bool is_cached) {
    bool ret = true;
    size_t i;

    if (mincore(buf, size, vec)) {
        fprintf(stderr, "mincore failed: %s\n", strerror(errno));
        return false;
    }

    if (is_cached) {
        for (i = 0; i < mincore_vec_len(size); i++) {
            if (!(vec[i] & 0x1)) {
                fprintf(stderr, "found an uncached page at page offset %zd\n", i);
                ret = false;
            }
        }
    } else {
        for (i = 0; i < mincore_vec_len(size); i++) {
            if (vec[i] & 0x1) {
                fprintf(stderr, "found a cached page at page offset %zd\n", i);
                ret = false;
            }
        }
    }

    return ret;
}

int main(int argc, char **argv) {
    unsigned long long alloc_size = 0ULL;
    unsigned long long file_size = 0ULL;
    int test_runs = 0;
    int rc;

    //arguments: <program> [test_runs [alloc_size [file_size]]]
    if (argc >= 2) {
        test_runs = atoi(argv[1]);
    }
    if (test_runs <= 0) {
        test_runs = TEST_RUNS;
    }
    if (argc >= 3) {
        alloc_size = strtoull(argv[2], NULL, 10);
    }
    if (!alloc_size) {
        alloc_size = ALLOC_SIZE;
    }
    if (argc >= 4) {
        file_size = strtoull(argv[3], NULL, 10);
    }
    if (!file_size) {
        file_size = FILE_SIZE;
    }

    rc = mmap_test(test_runs, alloc_size);
    if (rc) {
        return rc;
    }
    rc = pageinout_test(test_runs, file_size);
    if (rc) {
        return rc;
    }
    rc = thrashing_test(test_runs);

    return rc;
}