1/** 2 * \file 3 * \brief Test program for large page code 4 */ 5 6/* 7 * Copyright (c) 2013, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <barrelfish/barrelfish.h> 16#include <stdio.h> 17#include <stdlib.h> 18#include <string.h> 19#include <assert.h> 20#include <inttypes.h> 21#include <barrelfish/nameservice_client.h> 22#include <barrelfish/sys_debug.h> 23#include <bench/bench.h> 24 25#define SAFE_VADDR (genvaddr_t)(8ULL<<39) 26#define SAFE_PMAP_ADDR (genvaddr_t)(9ULL<<39) 27//0b 0000 0000 0000 0000 0000 0100 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 28#define SAFE_PMAP_ADDR_L ((genvaddr_t) (12ULL<<39)) 29// 40M 30#define DEFAULT_SIZE (30 * LARGE_PAGE_SIZE) 31 32 33#define RUN_COUNT 50 34 35unsigned long mean4k; 36unsigned long mean2m; 37unsigned long min4k; 38unsigned long min2m; 39unsigned long mean4krand; 40unsigned long mean2mrand; 41unsigned long min4krand; 42unsigned long min2mrand; 43unsigned long max4krand; 44unsigned long max2mrand; 45unsigned long max4k; 46unsigned long max2m; 47 48unsigned long mean4kshort; 49unsigned long mean2mshort; 50unsigned long mean4kshortrand; 51unsigned long mean2mshortrand; 52unsigned long min4kshort; 53unsigned long min2mshort; 54unsigned long min4kshortrand; 55unsigned long min2mshortrand; 56unsigned long max4kshort; 57unsigned long max2mshort; 58unsigned long max4kshortrand; 59unsigned long max2mshortrand; 60/*static paging_x86_64_flags_t PAGE_DEFAULT_ACCESS = 61 PTABLE_USER_SUPERVISOR | 62 PTABLE_EXECUTE_DISABLE | 63 PTABLE_READ_WRITE; 64 */ 65static vregion_flags_t PMAP_DEFAULT_ACCESS = 66 VREGION_FLAGS_READ_WRITE; 67 68static void test_region(uint32_t *buf, size_t size, bool large, bool area) 69{ 70 cycles_t runs[RUN_COUNT]; 71 cycles_t start, end; 72 uint64_t mean = 0; 73 unsigned long min = 0; 74 unsigned long max = 0; 75 printf("base address: %lx\n", (uint64_t) buf); 76 77 //sequential access 78 for (int j = 0; j < RUN_COUNT; j++) { 79 80 start = bench_tsc()/1000; 81 for (unsigned long i = 0; i < size; i+=4) { 82 83 buf[i/4] = i; 84 } 85 for (unsigned long i = 0; i < size; i+=4) { 86 assert(buf[i/4] == i); 87 } 88 end = bench_tsc()/1000; 89 runs[j] = end-start; 90 mean += (unsigned int) runs[j]; 91 if (runs[j] < min || j == 0) {min = runs[j];} 92 if (runs[j] > max) {max = runs[j];} 93 printf("run: %u, cycles: %u\n", j, (unsigned int) runs[j]); 94 } 95 mean = mean/RUN_COUNT; 96 printf("\naverage cycles to write the whole area: %u\n", (unsigned int) mean); 97 if(!large && !area) { 98 mean4k = mean; 99 min4k = min; 100 max4k = max; 101 } 102 else if (large && !area) { 103 mean2m = mean; 104 min2m = min; 105 max2m = max; 106 } 107 else if (!large && area) { 108 mean4kshort = mean; 109 min4kshort = min; 110 max4kshort = max; 111 } else { 112 mean2mshort = mean; 113 min2mshort = min; 114 max2mshort = max; 115 } 116 117 //random access 118 //generate 1M random number array 119 unsigned int* addrs; 120 min = 0; 121 max = 0; 122 mean = 0; 123 addrs = malloc(2000000*sizeof(unsigned int)); 124 printf("malloc'd\n"); 125 for (int i = 0; i<2000000; i++) 126 { 127 addrs[i] = (rand() % (size/4)); 128 } 129 printf("randomised\n"); 130 for (int j = 0; j < RUN_COUNT; j++) { 131 132 start = bench_tsc()/1000; 133 for (int i = 0; i < 2000000; i++) { 134 buf[addrs[i]] = addrs[i]; 135 } 136 for (unsigned long i = 0; i < 2000000; i++) { 137 assert(buf[addrs[i]] == addrs[i]); 138 } 139 end = bench_tsc()/1000; 140 runs[j] = end-start; 141 mean += (unsigned int) runs[j]; 142 if (runs[j] < min || j == 0) {min = runs[j];} 143 if (runs[j] > max) {max = runs[j];} 144 printf("run: %u, cycles: %u\n", j, (unsigned int) runs[j]); 145 } 146 mean = mean/RUN_COUNT; 147 printf("\naverage cycles to write the whole area randomly: %u\n", (unsigned int) mean); 148 if(!large && !area) { 149 mean4krand = mean; 150 min4krand = min; 151 max4krand = max; 152 } 153 else if (large && !area){ 154 mean2mrand = mean; 155 min2mrand = min; 156 max2mrand = max; 157 }else if (!large && area) { 158 mean4kshortrand = mean; 159 min4kshortrand = min; 160 max4kshortrand = max; 161 } else { 162 mean2mshortrand = mean; 163 min2mshortrand = min; 164 max2mshortrand = max; 165 } 166 167} 168 169int main(void) 170{ 171 struct capref frame; 172 size_t bytes = DEFAULT_SIZE; 173 errval_t err; 174 mean4k = 0; 175 mean2m = 0; 176 genvaddr_t address; 177 178 179 //normal pages via pmap interface 180 printf("\nstart 4k map with pmap\n"); 181 err = frame_alloc(&frame, bytes, &bytes); 182 if (err_is_fail(err)) 183 { 184 printf("error in frame_alloc: %s\n", err_getstring(err)); 185 exit(1); 186 } 187 assert(bytes >= DEFAULT_SIZE); 188 printf(" get pmap\n"); 189 struct pmap *pmap = get_current_pmap(); 190 191 printf(" obtain address\n"); 192 err = pmap->f.determine_addr_raw(pmap, bytes, BASE_PAGE_SIZE, &address); 193 if (err_is_fail(err)) 194 { 195 printf("error in determine_addr_raw: %s\n", err_getstring(err)); 196 exit(1); 197 } 198 199 printf(" map\n"); 200 err = pmap->f.map(pmap, address, frame, 0, bytes, PMAP_DEFAULT_ACCESS, NULL, &bytes); 201 if (err_is_fail(err)) 202 { 203 printf("error in pmap: %s\n", err_getstring(err)); 204 exit(1); 205 } 206 printf("addr: %lx\n", address); 207 test_region((uint32_t*)address, DEFAULT_SIZE, false, false); 208 209 printf("\tunmap\n"); 210 err = pmap->f.unmap(pmap, address, bytes, NULL); 211 if (err_is_fail(err)) 212 { 213 printf("error in unmap: %s\n", err_getstring(err)); 214 exit(1); 215 } 216 217 //large page via pmap interface 218 printf("start 2m map with pmap\n"); 219 bytes = DEFAULT_SIZE; 220 struct capref frame2; 221 err = frame_alloc(&frame2, bytes, &bytes); 222 if (err_is_fail(err)) 223 { 224 printf("error in frame_alloc: %s\n", err_getstring(err)); 225 exit(1); 226 } 227 assert(bytes >= DEFAULT_SIZE); 228 pmap = get_current_pmap(); 229 230 printf("determine address\n"); 231 err = pmap->f.determine_addr_raw(pmap, bytes, LARGE_PAGE_SIZE, &address); 232 if (err_is_fail(err)) 233 { 234 printf("error in determine_addr_raw: %s\n", err_getstring(err)); 235 exit(1); 236 } 237 238 printf("map\n"); 239 err = pmap->f.map(pmap, address, frame, 0, bytes, PMAP_DEFAULT_ACCESS | 0x0100, NULL, &bytes); 240 if (err_is_fail(err)) 241 { 242 printf("error in pmap: %s\n", err_getstring(err)); 243 exit(1); 244 } 245 printf("addr: %lx\n", address); 246 test_region((uint32_t*)address, DEFAULT_SIZE, true, false); 247 248 err = pmap->f.unmap(pmap, address, bytes, NULL); 249 if (err_is_fail(err)) 250 { 251 printf("error in unmap: %s\n", err_getstring(err)); 252 exit(1); 253 } 254 //small area 4k 255 bytes = LARGE_PAGE_SIZE; 256 err = frame_alloc(&frame, bytes, &bytes); 257 if (err_is_fail(err)) 258 { 259 printf("error in frame_alloc: %s\n", err_getstring(err)); 260 exit(1); 261 } 262 assert(bytes >= LARGE_PAGE_SIZE); 263 pmap = get_current_pmap(); 264 err = pmap->f.map(pmap, SAFE_PMAP_ADDR, frame, 0, bytes, PMAP_DEFAULT_ACCESS, NULL, &bytes); 265 if (err_is_fail(err)) 266 { 267 printf("error in pmap small 4k\n"); 268 exit(1); 269 } 270 test_region((uint32_t*) SAFE_PMAP_ADDR, LARGE_PAGE_SIZE, false, true); 271 272 //small area 2m 273 bytes = LARGE_PAGE_SIZE; 274 err = frame_alloc(&frame, bytes, &bytes); 275 if (err_is_fail(err)) 276 { 277 printf("error in frame_alloc: %s\n", err_getstring(err)); 278 exit(1); 279 } 280 assert(bytes >= LARGE_PAGE_SIZE); 281 pmap = get_current_pmap(); 282 283 printf("map\n"); 284 err = pmap->f.map(pmap, SAFE_PMAP_ADDR_L, frame, 0, bytes, PMAP_DEFAULT_ACCESS | 0x0100, NULL, &bytes); 285 if (err_is_fail(err)) 286 { 287 printf("error in pmap: %s\n", err_getstring(err)); 288 exit(1); 289 } 290 printf("addr: %lx\n", SAFE_PMAP_ADDR_L); 291 test_region((uint32_t*)SAFE_PMAP_ADDR_L, LARGE_PAGE_SIZE, true, true); 292 293 294 295 printf("large area\n"); 296 printf("average 4k: %lu, average 2m: %lu\n", mean4k, mean2m); 297 printf("minimal 4k: %lu, minimal 2m: %lu\n", min4k, min2m); 298 printf("maximal 4k: %lu, maximal 2m: %lu\n", max4k, max2m); 299 printf("random: average 4k: %lu, average 2m: %lu\n", mean4krand, mean2mrand); 300 printf("random:minimal 4k: %lu, minimal 2m: %lu\n", min4krand, min2mrand); 301 printf("random:maximal 4k: %lu, maximal 2m: %lu\n\n", max4krand, max2mrand); 302 printf("short area\n"); 303 printf("average 4k: %lu, average 2m: %lu\n", mean4kshort, mean2mshort); 304 printf("minimal 4k: %lu, minimal 2m: %lu\n", min4kshort, min2mshort); 305 printf("maximal 4k: %lu, maximal 2m: %lu\n", max4kshort, max2mshort); 306 printf("random: average 4k: %lu, average 2m: %lu\n", mean4kshortrand, mean2mshortrand); 307 printf("random:minimal 4k: %lu, minimal 2m: %lu\n", min4kshortrand, min2mshortrand); 308 printf("random:maximal 4k: %lu, maximal 2m: %lu\n", max4kshortrand, max2mshortrand); 309 printf("exited successfully\n"); 310 return 0; 311} 312