1/** 2 * \file 3 * \brief Client for interacting with the name service 4 */ 5 6/* 7 * Copyright (c) 2010, 2011, 2012, 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, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich, 13 * Attn: Systems Group. 14 */ 15#include <stdio.h> 16 17#include <barrelfish/barrelfish.h> 18 19#include <xeon_phi/xeon_phi.h> 20#include <xeon_phi/xeon_phi_domain.h> 21#include <xeon_phi/xeon_phi_client.h> 22 23#include <if/octopus_defs.h> 24#include <if/octopus_defs.h> 25//#include <if/monitor_defs.h> 26#include <octopus/getset.h> // for oct_read TODO 27#include <octopus/trigger.h> // for NOP_TRIGGER 28 29#include "xeon_phi_client_internal.h" 30 31/** 32 * \brief builds the iface name representation 33 * 34 * \param iface Name of the domain 35 * \param xid Xeon Phi ID or XEON_PHI_DOMAIN_HOST the domain is runnig on 36 * \param core The core the domain is running on 37 * 38 * \returns string with the proper format 39 */ 40char *xeon_phi_domain_build_iface(const char *name, 41 xphi_id_t xid, 42 coreid_t core) 43{ 44 char *iface; 45 size_t ifacelen; 46 47 if (core != XEON_PHI_DOMAIN_DONT_CARE) { 48 if (xid != XEON_PHI_DOMAIN_DONT_CARE) { 49 ifacelen = strlen(name) + 8; 50 iface = malloc(ifacelen); 51 if (iface == NULL) { 52 return NULL; 53 } 54 snprintf(iface, ifacelen, "%s.%02x.%02x", name, xid, core); 55 } else { 56 ifacelen = snprintf(NULL, 0, "r'^%s\\.[0-9][0-9]\\.%u'", name, core) + 1; 57 iface = malloc(ifacelen); 58 if (iface == NULL) { 59 return NULL; 60 } 61 snprintf(iface, ifacelen, "r'^%s\\.[0-9][0-9]\\.%u'", name, core); 62 } 63 } else { 64 if (xid != XEON_PHI_DOMAIN_DONT_CARE) { 65 ifacelen = snprintf(NULL, 0, "r'^%s\\.%02x\\.'", name, xid)+1; 66 iface = malloc(ifacelen); 67 if (iface == NULL) { 68 return NULL; 69 } 70 snprintf(iface, ifacelen, "r'^%s\\.%02x\\.'", name, xid); 71 } else { 72 ifacelen = snprintf(NULL, 0, "r'^%s\\.'", name)+1; 73 iface = malloc(ifacelen); 74 if (iface == NULL) { 75 return NULL; 76 } 77 snprintf(iface, ifacelen, "r'^%s\\.'", name); 78 } 79 80 } 81 82 return iface; 83} 84 85/** 86 * \brief Non-blocking name service lookup 87 * 88 * \param iface Name of the domain 89 * \param retdomid returns the Xeon Phi Domain ID 90 */ 91errval_t xeon_phi_domain_lookup(const char *iface, 92 xphi_dom_id_t *retdomid) 93{ 94#ifdef __k1om__ 95 return xeon_phi_client_domain_lookup(iface, retdomid); 96#else 97 errval_t err; 98 99 struct octopus_binding *r = get_octopus_binding(); 100 if (r == NULL) { 101 return LIB_ERR_NAMESERVICE_NOT_BOUND; 102 } 103 104 struct octopus_get_response__rx_args reply; 105 err = r->rpc_tx_vtbl.get(r, iface, NOP_TRIGGER, reply.output, &reply.tid, &reply.error_code); 106 if (err_is_fail(err)) { 107 goto out; 108 } 109 err = reply.error_code; 110 if (err_is_fail(err)) { 111 if (err_no(err) == OCT_ERR_NO_RECORD) { 112 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 113 } 114 goto out; 115 } 116 117 xphi_dom_id_t domid = 0; 118 err = oct_read(reply.output, "_ { domid: %d }", &domid); 119 if (err_is_fail(err) || domid == 0) { 120 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 121 goto out; 122 } 123 124 if (retdomid != NULL) { 125 *retdomid = domid; 126 } 127 128 out: 129 return err; 130#endif 131} 132 133/** 134 * \brief Blocking name service lookup 135 * 136 * \param iface Name of the domain 137 * \param retdomid returns the Xeon Phi Domain ID 138 */ 139errval_t xeon_phi_domain_blocking_lookup(const char *iface, 140 xphi_dom_id_t *retdomid) 141{ 142#ifdef __k1om__ 143 return xeon_phi_client_domain_wait(iface, retdomid); 144#else 145 errval_t err; 146 147 struct octopus_binding *r = get_octopus_binding(); 148 if (r == NULL) { 149 return LIB_ERR_NAMESERVICE_NOT_BOUND; 150 } 151 152 struct octopus_wait_for_response__rx_args reply; 153 err = r->rpc_tx_vtbl.wait_for(r, iface, reply.record, &reply.error_code); 154 if (err_is_fail(err)) { 155 goto out; 156 } 157 err = reply.error_code; 158 if (err_is_fail(err)) { 159 if (err_no(err) == OCT_ERR_NO_RECORD) { 160 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 161 } 162 goto out; 163 } 164 165 xphi_dom_id_t domid = 0; 166 err = oct_read(reply.record, "_ { domid: %d }", &domid); 167 if (err_is_fail(err)) { 168 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 169 goto out; 170 } 171 if (retdomid != NULL) { 172 *retdomid = domid; 173 } 174 175 out: 176 return err; 177#endif 178} 179 180/** 181 * \brief Register with name service 182 * 183 * \param iface Name of the domain 184 * \param retdomid returns the Xeon Phi Domain ID 185 */ 186errval_t xeon_phi_domain_register(const char *iface, 187 xphi_dom_id_t domid) 188{ 189#ifdef __k1om__ 190 return -1; 191#else 192 errval_t err = SYS_ERR_OK; 193 194 struct octopus_binding *r = get_octopus_binding(); 195 if (r == NULL) { 196 return LIB_ERR_NAMESERVICE_NOT_BOUND; 197 } 198 199 // Format record 200 static const char* format = "%s { domid: %"PRIu64" }"; 201 size_t len = snprintf(NULL, 0, format, iface, domid); 202 char* record = malloc(len+1); 203 if (record == NULL) { 204 return LIB_ERR_MALLOC_FAIL; 205 } 206 snprintf(record, len+1, format, iface, domid); 207 208 octopus_trigger_id_t tid; 209 errval_t error_code; 210 err = r->rpc_tx_vtbl.set(r, record, 0, NOP_TRIGGER, 0, NULL, &tid, &error_code); 211 if (err_is_fail(err)) { 212 goto out; 213 } 214 err = error_code; 215 216 out: 217 free(record); 218 return err; 219#endif 220} 221 222