1/*
2 * Copyright (c) 2009, 2010, 2011, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <string.h>
11#include <stdio.h>
12#include <assert.h>
13#include <inttypes.h>
14#include <barrelfish/barrelfish.h>
15#include <barrelfish/nameservice_client.h>
16#include <barrelfish/sys_debug.h>
17#include <bench/bench.h>
18
19#define FRAME_SIZE 16384 // 16kb
20
21#ifdef LOADGEN
22// XXX: this should create a infinite loop!
23#define RUN_COUNT -1
24#else
25#define RUN_COUNT 1000
26#endif
27
28#define THRESH 200000
29
30int main(int argc, char *argv[])
31{
32    errval_t err;
33
34    bench_init();
35
36    size_t pt_bits, ret_bytes;
37    // XXX: X86_64 only
38    pt_bits = vnode_objbits(ObjType_VNode_x86_64_ptable);
39
40    struct capref ram;
41    struct capref pagetable;
42    struct capref frame;
43    struct capref mapping;
44    err = ram_alloc(&ram, pt_bits);
45    assert(err_is_ok(err));
46    err = slot_alloc(&pagetable);
47    assert(err_is_ok(err));
48    err = cap_retype(pagetable, ram, 0, ObjType_VNode_x86_64_ptable, 1UL << pt_bits, 1);
49    assert(err_is_ok(err));
50    err = frame_alloc(&frame, FRAME_SIZE, &ret_bytes);
51    assert(err_is_ok(err));
52    err = slot_alloc(&mapping);
53    assert(err_is_ok(err));
54
55    // map and unmap one frame 100 times in a row
56#ifndef LOADGEN
57    cycles_t runs[RUN_COUNT];
58#endif
59    cycles_t start, end;
60    paging_x86_64_flags_t flags =
61        PTABLE_USER_SUPERVISOR | PTABLE_EXECUTE_DISABLE |
62        PTABLE_READ_WRITE;
63
64    for (uint64_t i = 0; i < RUN_COUNT; i++) {
65        start = bench_tsc();
66        err = vnode_map(pagetable,frame,(cslot_t)(i%512),flags,0,1, mapping);
67        assert(err_is_ok(err));
68        end = bench_tsc();
69#ifndef LOADGEN
70        runs[i] = end - start;
71        if (runs[i] > THRESH) {
72            runs[i] = BENCH_IGNORE_WATERMARK;
73        }
74#endif
75        err = vnode_unmap(pagetable,mapping);
76        assert(err_is_ok(err));
77        err = cap_delete(mapping);
78        assert(err_is_ok(err));
79    }
80
81#ifndef LOADGEN
82    printf("mapping 1 page:\n");
83    printf("  avg. cycles %"PRIuCYCLES", variance %"PRIuCYCLES"\n",
84            bench_avg(runs, RUN_COUNT),
85            bench_variance(runs, RUN_COUNT));
86
87    printf("\n\n");
88    for (int i = 0; i < RUN_COUNT; i+=4) {
89        printf("%d: %"PRIuCYCLES" %"PRIuCYCLES" %"PRIuCYCLES" %"PRIuCYCLES"\n",
90                i, runs[i], i+1 < RUN_COUNT ? runs[i+1] : 0,
91                i+2 < RUN_COUNT ? runs[i+2] : 0,
92                i+3 < RUN_COUNT ? runs[i+3] : 0);
93    }
94
95#else
96    printf("after infinite loop?");
97#endif
98    return 0;
99}
100