1/** \file 2 * \brief Example application using THC stubs 3 */ 4 5/* 6 * Copyright (c) 2010, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#include <stdio.h> 15#include <string.h> 16 17#include <barrelfish/barrelfish.h> 18 19#include <thc/thc.h> 20 21#include <if/xmplthc_defs.h> 22#include <if/xmplthc_thc.h> 23 24const char *service_name = "xmplthc_binding_service"; 25 26/* --------------------- Client ------------------------------ */ 27 28static void run_client(struct xmplthc_thc_client_binding_t *cl) 29{ 30 int i = 42; 31 32 char s[512]; 33 34 // regular message 35 cl->send.mymsg(cl, i); 36 debug_printf("client: sent msg: %d\n", i); 37 38 // call/response 39 cl->send.mycall(cl, i); 40 debug_printf("client: sent mycall: %d\n", i); 41 cl->recv.myresponse(cl, s); 42 debug_printf("client: received myresponse: '%s'\n", s); 43 44 // rpc as call/response 45 cl->send.myrpc(cl, i); 46 debug_printf("client: sent myrpc call msg: %d\n", i); 47 cl->recv.myrpc(cl, s); 48 debug_printf("client: received myrpc response msg: '%s'\n", s); 49 50 // rpc 51 cl->call_seq.myrpc(cl, i, s); 52 debug_printf("client: returned from myrpc(%d, '%s')\n", i, s); 53 54 debug_printf("finished client\n"); 55} 56 57 58static void start_client(void) 59{ 60 errval_t err; 61 62 struct xmplthc_binding *b; 63 struct xmplthc_thc_client_binding_t *cl; 64 65 err = xmplthc_thc_connect_by_name(service_name, 66 get_default_waitset(), 67 IDC_BIND_FLAGS_DEFAULT, 68 &b); 69 if (err_is_fail(err)) { 70 USER_PANIC_ERR(err, "could not bind (thc)"); 71 } 72 73 cl = malloc(sizeof(struct xmplthc_thc_client_binding_t)); 74 assert(cl != NULL); 75 76 err = xmplthc_thc_init_client(cl, b, b); 77 if (err_is_fail(err)) { 78 USER_PANIC_ERR(err, "could not init client (thc)"); 79 } 80 81 run_client(cl); 82} 83 84 85/* --------------------- Server ------------------------------ */ 86 87static void rx_xmplthc_myrpc(struct xmplthc_thc_service_binding_t *sv, 88 int i) 89{ 90 debug_printf("server: received xmplthc_myrpc_call: %d\n", i); 91 92 // send reply 93 char *s = malloc(20); 94 if (s != NULL) { 95 snprintf(s, 20, "!%d!", i); 96 } 97 sv->send.myrpc(sv, s); 98} 99 100 101 102static void rx_xmplthc_mycall(struct xmplthc_thc_service_binding_t *sv, 103 int i) 104{ 105 debug_printf("server: received xmplthc_mycall: %d\n", i); 106 107 // send reply 108 char *s = malloc(20); 109 if (s != NULL) { 110 snprintf(s, 20, "!%d!", i); 111 } 112 sv->send.myresponse(sv, s); 113} 114 115 116static void rx_xmplthc_mymsg(struct xmplthc_thc_service_binding_t *sv, 117 int i) 118{ 119 debug_printf("server: received xmplthc_msg: %d\n", i); 120} 121 122static void run_server(struct xmplthc_thc_service_binding_t *sv) 123{ 124 xmplthc_service_msg_t msg; 125 bool loop = true; 126 127 // this is the bitmap of messages we are interested in receiving 128 struct xmplthc_service_selector selector = { 129 .mymsg = 1, 130 .mycall = 1, 131 .myrpc = 1, 132 }; 133 134 while (loop) { 135 136 // receive any message 137 sv->recv_any(sv, &msg, selector); 138 139 // dispatch it 140 switch(msg.msg) { 141 case xmplthc_mymsg: 142 rx_xmplthc_mymsg(sv, msg.args.mymsg.i); 143 break; 144 case xmplthc_mycall: 145 rx_xmplthc_mycall(sv, msg.args.mycall.i); 146 break; 147 case xmplthc_myrpc: 148 rx_xmplthc_myrpc(sv, msg.args.myrpc.in.i); 149 break; 150 default: 151 debug_printf("unexpected message: %d\n", msg.msg); 152 loop = false; 153 break; 154 } 155 } 156} 157 158 159 160static void start_server(void) 161{ 162 163 errval_t err; 164 165 struct xmplthc_thc_export_info e_info; 166 struct xmplthc_thc_service_binding_t *sv; 167 struct xmplthc_binding *b; 168 iref_t iref; 169 170 err = xmplthc_thc_export(&e_info, service_name, 171 get_default_waitset(), 172 IDC_EXPORT_FLAGS_DEFAULT, 173 &iref); 174 if (err_is_fail(err)) { 175 USER_PANIC_ERR(err, "thc export failed"); 176 } 177 178 err = xmplthc_thc_accept(&e_info, &b); 179 if (err_is_fail(err)) { 180 USER_PANIC_ERR(err, "thc accept failed"); 181 } 182 183 sv = malloc(sizeof(struct xmplthc_thc_service_binding_t)); 184 assert(sv != NULL); 185 186 err = xmplthc_thc_init_service(sv, b, b); 187 if (err_is_fail(err)) { 188 USER_PANIC_ERR(err, "thc init failed"); 189 } 190 191 run_server(sv); 192} 193 194 195 196/* --------------------- Main ------------------------------ */ 197int main(int argc, char *argv[]) 198{ 199 if ((argc >= 2) && (strcmp(argv[1], "client") == 0)) { 200 start_client(); 201 } else if ((argc >= 2) && (strcmp(argv[1], "server") == 0)) { 202 start_server(); 203 } else { 204 printf("usage: %s client|server\n", argv[0]); 205 return EXIT_FAILURE; 206 } 207 208 return EXIT_SUCCESS; 209} 210