1/** 2 * \file 3 * \brief Flounder stubs 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2010, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <barrelfish/barrelfish.h> 17#include <string.h> 18#include <barrelfish/nameservice_client.h> 19#include <barrelfish/spawn_client.h> 20#include <bench/bench.h> 21#include <if/bench_defs.h> 22 23static char my_name[100]; 24 25static struct bench_binding *binding; 26static coreid_t my_core_id; 27 28#define MAX_COUNT 1000 29 30struct timestamp { 31 cycles_t time0; 32 cycles_t time1; 33}; 34static struct timestamp timestamps[MAX_COUNT]; 35static int benchmark_type = 0; 36 37static void experiment(void) 38{ 39 errval_t err; 40 static bool flag = false; 41 static int i = 0; 42 43 // Experiment finished 44 if (i == MAX_COUNT - 1) { 45 timestamps[i].time1 = bench_tsc(); 46 47 for (int j = MAX_COUNT / 10; j < MAX_COUNT; j++) { 48 printf("page %d took %"PRIuCYCLES"\n", j, 49 timestamps[j].time1 - bench_tscoverhead() - 50 timestamps[j].time0); 51 } 52 53 printf("client done\n"); 54 return; 55 } 56 57 if (!flag) { // Start experiment 58 timestamps[i].time0 = bench_tsc(); 59 flag = true; 60 } else { // Continue experiment 61 timestamps[i].time1 = bench_tsc(); 62 timestamps[i+1].time0 = timestamps[i].time1; 63 i++; 64 } 65 66 switch(benchmark_type) { 67 case 0: 68 err = binding->tx_vtbl.fsb_payload32_1_request(binding, NOP_CONT, 1); 69 break; 70 71 case 1: 72 err = binding->tx_vtbl.fsb_payload32_2_request(binding, NOP_CONT, 1, 2); 73 break; 74 75 case 2: 76 err = binding->tx_vtbl.fsb_payload32_4_request(binding, NOP_CONT, 1, 2, 3, 4); 77 break; 78 79 case 3: 80 err = binding->tx_vtbl.fsb_payload32_8_request(binding, NOP_CONT, 1, 2, 3, 4, 5, 6, 7, 8); 81 break; 82 83 case 4: 84 err = binding->tx_vtbl.fsb_payload32_16_request(binding, NOP_CONT, 1, 2, 3, 4, 5, 6, 7, 8, 85 9, 10, 11, 12, 13, 14, 15, 16); 86 break; 87 88 default: 89 printf("unknown benchmark type\n"); 90 abort(); 91 break; 92 } 93 94 assert(err_is_ok(err)); 95} 96 97static void fsb_init_msg(struct bench_binding *b, coreid_t id) 98{ 99 binding = b; 100 printf("Running flounder_stubs_payload32 between core %d and core %d\n", my_core_id, 1); 101 experiment(); 102} 103 104static void fsb_payload32_1_reply(struct bench_binding *b, 105 int32_t p0) 106{ 107 experiment(); 108} 109 110static void fsb_payload32_2_reply(struct bench_binding *b, 111 int32_t p0, int32_t p1) 112{ 113 experiment(); 114} 115 116static void fsb_payload32_4_reply(struct bench_binding *b, 117 int32_t payload0, int32_t payload1, 118 int32_t payload2, int32_t payload3) 119{ 120 experiment(); 121} 122 123static void fsb_payload32_8_reply(struct bench_binding *b, 124 int32_t p0, int32_t p1, int32_t p2, int32_t p3, 125 int32_t p4, int32_t p5, int32_t p6, int32_t p7) 126{ 127 experiment(); 128} 129 130static void fsb_payload32_16_reply(struct bench_binding *b, 131 int32_t p0, int32_t p1, int32_t p2, int32_t p3, 132 int32_t p4, int32_t p5, int32_t p6, int32_t p7, 133 int32_t p8, int32_t p9, int32_t p10, int32_t p11, 134 int32_t p12, int32_t p13, int32_t p14, int32_t p15) 135{ 136 experiment(); 137} 138 139 140static void fsb_payload32_1_request(struct bench_binding *b, 141 int32_t payload0) 142{ 143 errval_t err; 144 err = b->tx_vtbl.fsb_payload32_1_reply(b, NOP_CONT, 1); 145 assert(err_is_ok(err)); 146} 147 148static void fsb_payload32_2_request(struct bench_binding *b, 149 int32_t payload0, int32_t payload1) 150{ 151 errval_t err; 152 err = b->tx_vtbl.fsb_payload32_2_reply(b, NOP_CONT, 1, 2); 153 assert(err_is_ok(err)); 154} 155 156static void fsb_payload32_4_request(struct bench_binding *b, 157 int32_t payload0, int32_t payload1, 158 int32_t payload2, int32_t payload3) 159{ 160 errval_t err; 161 err = b->tx_vtbl.fsb_payload32_4_reply(b, NOP_CONT, 1, 2, 3, 4); 162 assert(err_is_ok(err)); 163} 164 165static void fsb_payload32_8_request(struct bench_binding *b, 166 int32_t payload0, int32_t payload1, 167 int32_t payload2, int32_t payload3, 168 int32_t payload4, int32_t payload5, 169 int32_t payload6, int32_t payload7) 170{ 171 errval_t err; 172 err = b->tx_vtbl.fsb_payload32_8_reply(b, NOP_CONT, 1, 2, 3, 4, 5, 6, 7, 8); 173 assert(err_is_ok(err)); 174} 175 176static void fsb_payload32_16_request(struct bench_binding *b, 177 int32_t payload0, int32_t payload1, 178 int32_t payload2, int32_t payload3, 179 int32_t payload4, int32_t payload5, 180 int32_t payload6, int32_t payload7, 181 int32_t payload8, int32_t payload9, 182 int32_t payload10, int32_t payload11, 183 int32_t payload12, int32_t payload13, 184 int32_t payload14, int32_t payload15) 185{ 186 errval_t err; 187 err = b->tx_vtbl.fsb_payload32_16_reply(b, NOP_CONT, 1, 2, 3, 4, 5, 6, 7, 8, 188 9, 10, 11, 12, 13, 14, 15, 16); 189 assert(err_is_ok(err)); 190} 191 192static struct bench_rx_vtbl rx_vtbl = { 193 .fsb_init_msg = fsb_init_msg, 194 .fsb_payload32_1_request = fsb_payload32_1_request, 195 .fsb_payload32_2_request = fsb_payload32_2_request, 196 .fsb_payload32_4_request = fsb_payload32_4_request, 197 .fsb_payload32_8_request = fsb_payload32_8_request, 198 .fsb_payload32_16_request = fsb_payload32_16_request, 199 .fsb_payload32_1_reply = fsb_payload32_1_reply, 200 .fsb_payload32_2_reply = fsb_payload32_2_reply, 201 .fsb_payload32_4_reply = fsb_payload32_4_reply, 202 .fsb_payload32_8_reply = fsb_payload32_8_reply, 203 .fsb_payload32_16_reply = fsb_payload32_16_reply, 204}; 205 206static void bind_cb(void *st, errval_t binderr, struct bench_binding *b) 207{ 208 // copy my message receive handler vtable to the binding 209 b->rx_vtbl = rx_vtbl; 210 211 errval_t err; 212 err = b->tx_vtbl.fsb_init_msg(b, NOP_CONT, my_core_id); 213 assert(err_is_ok(err)); 214} 215 216static void export_cb(void *st, errval_t err, iref_t iref) 217{ 218 if (err_is_fail(err)) { 219 DEBUG_ERR(err, "export failed"); 220 abort(); 221 } 222 223 // register this iref with the name service 224 err = nameservice_register("fsb_server", iref); 225 if (err_is_fail(err)) { 226 DEBUG_ERR(err, "nameservice_register failed"); 227 abort(); 228 } 229} 230 231static errval_t connect_cb(void *st, struct bench_binding *b) 232{ 233 // copy my message receive handler vtable to the binding 234 b->rx_vtbl = rx_vtbl; 235 236 // accept the connection 237 return SYS_ERR_OK; 238} 239 240int main(int argc, char *argv[]) 241{ 242 errval_t err; 243 244 /* Set my core id */ 245 my_core_id = disp_get_core_id(); 246 strcpy(my_name, argv[0]); 247 248 bench_init(); 249 250 // Default first arg 251 if(argc == 1) { 252 argc = 2; 253 argv[1] = "0"; 254 } 255 256 if (argc == 2) { /* bsp core */ 257 benchmark_type = atoi(argv[1]); 258 259 /* 260 1. spawn domain, 261 2. setup a server, 262 3. wait for client to connect, 263 4. run experiment 264 */ 265 char *xargv[] = {my_name, "dummy", "dummy", "dummy", NULL}; 266 err = spawn_program(1, my_name, xargv, NULL, 267 SPAWN_FLAGS_DEFAULT, NULL); 268 assert(err_is_ok(err)); 269 270 /* Setup a server */ 271 err = bench_export(NULL, export_cb, connect_cb, get_default_waitset(), 272 IDC_BIND_FLAGS_DEFAULT); 273 assert(err_is_ok(err)); 274 } else { 275 /* Connect to the server */ 276 iref_t iref; 277 278 err = nameservice_blocking_lookup("fsb_server", &iref); 279 if (err_is_fail(err)) { 280 DEBUG_ERR(err, "nameservice_blocking_lookup failed"); 281 abort(); 282 } 283 284 err = bench_bind(iref, bind_cb, NULL, 285 get_default_waitset(), IDC_BIND_FLAGS_DEFAULT); 286 if (err_is_fail(err)) { 287 DEBUG_ERR(err, "bind failed"); 288 abort(); 289 } 290 } 291 292 messages_handler_loop(); 293} 294