1/** 2 * \file 3 * \brief UMP benchmarks 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 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 "ump_bench.h" 16#include <string.h> 17#include <barrelfish/nameservice_client.h> 18#include <barrelfish/spawn_client.h> 19 20static coreid_t num_cores; 21static char my_name[100]; 22 23struct bench_binding *array[MAX_CPUS] = {NULL}; 24coreid_t my_core_id; 25 26static void ump_init_msg(struct bench_binding *b, coreid_t id) 27{ 28 static int count = 0; 29 count++; 30 array[id] = b; 31 32 // All clients connected, run experiment 33 printf("%s: %d %d\n", __func__, count, num_cores); 34 if (count == num_cores) { 35 for (coreid_t i = 0; i < MAX_CPUS; i++) { 36 if (array[i]) { 37 experiment(i); 38 } 39 } 40 41 printf("client done\n"); 42 } 43} 44 45static struct bench_rx_vtbl rx_vtbl = { 46 .ump_init_msg = ump_init_msg, 47}; 48 49static void bind_cb(void *st, errval_t binderr, struct bench_binding *b) 50{ 51 errval_t err; 52 err = b->tx_vtbl.ump_init_msg(b, NOP_CONT, my_core_id); 53 assert(err_is_ok(err)); 54 55 struct bench_ump_binding *bu = (struct bench_ump_binding*)b; 56 struct flounder_ump_state *fus = &bu->ump_state; 57 struct ump_chan *chan = &fus->chan; 58 59 struct ump_chan_state *send = &chan->send_chan; 60 struct ump_chan_state *recv = &chan->endpoint.chan; 61 62 /* Wait for and reply to msgs */ 63 while (1) { 64 volatile struct ump_message *msg; 65 struct ump_control ctrl; 66 while (!(msg = ump_impl_recv(recv))); 67 ump_impl_free_message(msg); 68 while (!(msg = ump_impl_get_next(send, &ctrl))); 69 msg->header.control = ctrl; 70 } 71} 72 73static void export_cb(void *st, errval_t err, iref_t iref) 74{ 75 if (err_is_fail(err)) { 76 DEBUG_ERR(err, "export failed"); 77 abort(); 78 } 79 80 // register this iref with the name service 81 err = nameservice_register("ump_server", iref); 82 if (err_is_fail(err)) { 83 DEBUG_ERR(err, "nameservice_register failed"); 84 abort(); 85 } 86} 87 88static errval_t connect_cb(void *st, struct bench_binding *b) 89{ 90 // copy my message receive handler vtable to the binding 91 b->rx_vtbl = rx_vtbl; 92 93 // accept the connection 94 return SYS_ERR_OK; 95} 96 97int main(int argc, char *argv[]) 98{ 99 errval_t err; 100 101 /* Set my core id */ 102 my_core_id = disp_get_core_id(); 103 strcpy(my_name, argv[0]); 104 105 bench_init(); 106 107 if (argc == 1) { /* bsp core */ 108 109 /* 1. spawn domains, 110 2. setup a server, 111 3. wait for all clients to connect, 112 4. run experiments 113 */ 114 // Spawn domains 115 char *xargv[] = {my_name, "dummy", NULL}; 116 err = spawn_program_on_all_cores(false, xargv[0], xargv, NULL, 117 SPAWN_FLAGS_DEFAULT, NULL, &num_cores); 118 DEBUG_ERR(err, "spawn program on all cores (%"PRIuCOREID")", num_cores); 119 assert(err_is_ok(err)); 120 121 /* Setup a server */ 122 err = bench_export(NULL, export_cb, connect_cb, get_default_waitset(), 123 IDC_BIND_FLAGS_DEFAULT); 124 assert(err_is_ok(err)); 125 } else { 126 /* Connect to the server */ 127 iref_t iref; 128 129 err = nameservice_blocking_lookup("ump_server", &iref); 130 if (err_is_fail(err)) { 131 DEBUG_ERR(err, "nameservice_blocking_lookup failed"); 132 abort(); 133 } 134 135 err = bench_bind(iref, bind_cb, NULL, 136 get_default_waitset(), IDC_BIND_FLAGS_DEFAULT); 137 if (err_is_fail(err)) { 138 DEBUG_ERR(err, "bind failed"); 139 abort(); 140 } 141 } 142 143 messages_handler_loop(); 144} 145