1#include <stdlib.h>
2#include <stdbool.h>
3#include <stdio.h>
4#include <string.h>
5#include <barrelfish/barrelfish.h>
6#include <barrelfish/types.h>
7#include <barrelfish/cap_predicates.h>
8#include <bench/bench.h>
9
10#include "mdb_bench.h"
11
12static void clear_mdb(char *base, size_t size)
13{
14    RESET_ROOT();
15    memset(base, 0, size);
16}
17
18static void reset_mdb_seq_1b_ram(char *base, size_t size)
19{
20    clear_mdb(base, size);
21
22    // generate 1-byte ctes corresponding to index
23    struct cte *ctes = (struct cte*)base;
24    size_t num_caps = size / sizeof(struct cte);
25    for (int i = 0; i < num_caps; i++) {
26        struct RAM ram = {
27            .base = i,
28            .bytes = 0,
29        };
30        struct capability cap = {
31            .type = ObjType_RAM,
32            .rights = CAPRIGHTS_ALLRIGHTS,
33            .u.ram = ram,
34        };
35        ctes[i].cap = cap;
36    }
37}
38
39static void reset_mdb_random_nat_ram(char *base, size_t size)
40{
41    clear_mdb(base, size);
42
43    // generate naturally-aligned RAM caps
44    struct cte *ctes = (struct cte*)base;
45    size_t num_caps = size / sizeof(struct cte);
46    for (int i = 0; i < num_caps; i++) {
47        int bits = rand() % 16;
48        struct RAM ram = {
49            .base = ((uint32_t)rand())<<bits,
50            .bytes = 1UL << bits,
51        };
52        struct capability cap = {
53            .type = ObjType_RAM,
54            .rights = CAPRIGHTS_ALLRIGHTS,
55            .u.ram = ram,
56        };
57        ctes[i].cap = cap;
58    }
59}
60
61static void reset_mdb_propszrand_nat_ram(char *base, size_t size)
62{
63    clear_mdb(base, size);
64
65    // generate naturally-aligned RAM caps
66    struct cte *ctes = (struct cte*)base;
67    size_t num_caps = size / sizeof(struct cte);
68
69    size_t size_bits = 0;
70    while ((1<<size_bits) < size) { size_bits++; }
71    size_bits += 2;
72
73    for (int i = 0; i < num_caps; i++) {
74        genpaddr_t capbase = rand() % (1<<(size_bits+2));
75        int capbits = 0;
76        while (capbase & (1<<(size_bits+1))) { capbase <<= 1; capbits++; }
77
78        struct RAM ram = {
79            .base = capbase & ((1<<size_bits)-1),
80            .bytes = 1UL << capbits,
81        };
82        struct capability cap = {
83            .type = ObjType_RAM,
84            .rights = CAPRIGHTS_ALLRIGHTS,
85            .u.ram = ram,
86        };
87        ctes[i].cap = cap;
88    }
89}
90
91static void reset_mdb_szprob_cp_nat_ram(char *base, size_t size)
92{
93    clear_mdb(base, size);
94
95    // generate naturally-aligned RAM caps
96    struct cte *ctes = (struct cte*)base;
97    size_t num_caps = size / sizeof(struct cte);
98
99    size_t size_bits = 0;
100    while ((1<<size_bits) < size) { size_bits++; }
101    size_bits += 2;
102
103    for (int i = 0; i < num_caps; i++) {
104        if (i > 1 && (rand() % 10) == 0) {
105            // force a copy
106
107            // randomly select source cap, not assuming i is power-of-two
108            size_t pos, mod = 1;
109            while (mod < i) { mod <<= 1; }
110            do {
111                pos = rand() % mod;
112            } while (pos >= i);
113            struct cte *cte = &ctes[pos];
114
115            // make cpoy
116            ctes[i].cap = cte->cap;
117        }
118        else {
119            // generate caps with P[capbits=x]=(1<<(max_bits-x-1))/(1<<max_bits)
120
121            genpaddr_t capbase = rand() % (1<<(size_bits+2));
122            int capbits = 0;
123            while (capbase & (1<<(size_bits+1))) { capbase <<= 1; capbits++; }
124
125            struct RAM ram = {
126                .base = capbase & ((1<<size_bits)-1),
127                .bytes = 1UL << capbits,
128            };
129            struct capability cap = {
130                .type = ObjType_RAM,
131                .rights = CAPRIGHTS_ALLRIGHTS,
132                .u.ram = ram,
133            };
134            ctes[i].cap = cap;
135        }
136    }
137}
138
139struct reset_opt reset_opts[] = {
140    { "random_nat_ram", reset_mdb_random_nat_ram, },
141    { "propszrand_nat_ram", reset_mdb_propszrand_nat_ram, },
142    { "seq_1b_ram", reset_mdb_seq_1b_ram, },
143    { "szprob_cp_nat_ram", reset_mdb_szprob_cp_nat_ram, },
144    { NULL, NULL, },
145};
146