| 1 | /* |
|---|
| 2 | * (C) 2001 Clemson University and The University of Chicago |
|---|
| 3 | * |
|---|
| 4 | * See COPYING in top-level directory. |
|---|
| 5 | */ |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | /* |
|---|
| 11 | * This is an example of a server program that uses the BMI |
|---|
| 12 | * library for communications |
|---|
| 13 | */ |
|---|
| 14 | |
|---|
| 15 | #include <stdio.h> |
|---|
| 16 | #include <errno.h> |
|---|
| 17 | #include <unistd.h> |
|---|
| 18 | #include <stdlib.h> |
|---|
| 19 | #include <string.h> |
|---|
| 20 | #include <netinet/in.h> |
|---|
| 21 | #include <sys/time.h> |
|---|
| 22 | #include <time.h> |
|---|
| 23 | #include <math.h> |
|---|
| 24 | |
|---|
| 25 | #include "pvfs2.h" |
|---|
| 26 | #include "bmi.h" |
|---|
| 27 | #include "gossip.h" |
|---|
| 28 | #include "test-bmi.h" |
|---|
| 29 | #include <src/common/misc/pvfs2-internal.h> /* lld(), llu() */ |
|---|
| 30 | |
|---|
| 31 | #include "pvfs2-test-config.h" |
|---|
| 32 | #include <test/shared/test-common.h> /* now lld(), llu() here */ |
|---|
| 33 | |
|---|
| 34 | #ifdef HAVE_ZLIB_H |
|---|
| 35 | #include <zlib.h> |
|---|
| 36 | #endif |
|---|
| 37 | |
|---|
| 38 | /************************************************************** |
|---|
| 39 | * Data structures |
|---|
| 40 | */ |
|---|
| 41 | |
|---|
| 42 | #define SERVER 1 |
|---|
| 43 | #define CLIENT 2 |
|---|
| 44 | #define MIN_BYTES 1 |
|---|
| 45 | #define MAX_BYTES (4<<20) |
|---|
| 46 | |
|---|
| 47 | #define RECV 0 |
|---|
| 48 | #define SEND 1 |
|---|
| 49 | |
|---|
| 50 | #define EXPECTED 0 |
|---|
| 51 | #define UNEXPECTED 1 |
|---|
| 52 | |
|---|
| 53 | #define ITERATIONS 10000 |
|---|
| 54 | |
|---|
| 55 | struct msg { |
|---|
| 56 | int test; |
|---|
| 57 | }; |
|---|
| 58 | |
|---|
| 59 | /* A little structure to hold program options, either defaults or |
|---|
| 60 | * specified on the command line |
|---|
| 61 | */ |
|---|
| 62 | struct options |
|---|
| 63 | { |
|---|
| 64 | char *hostid; /* host identifier */ |
|---|
| 65 | char *method; |
|---|
| 66 | int which; |
|---|
| 67 | int test; |
|---|
| 68 | int crc; |
|---|
| 69 | }; |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | /************************************************************** |
|---|
| 73 | * Internal utility functions |
|---|
| 74 | */ |
|---|
| 75 | |
|---|
| 76 | static struct options *parse_args(int argc, char *argv[]); |
|---|
| 77 | static int do_server(struct options *opts, bmi_context_id *context); |
|---|
| 78 | static int do_client(struct options *opts, bmi_context_id *context); |
|---|
| 79 | |
|---|
| 80 | static void print_usage(void) |
|---|
| 81 | { |
|---|
| 82 | fprintf(stderr, "usage: pingpong -h HOST_URI -s|-c [-u] [-r]\n"); |
|---|
| 83 | fprintf(stderr, " where:\n"); |
|---|
| 84 | fprintf(stderr, " HOST_URI is tcp://host:port, mx://host:board:endpoint, etc\n"); |
|---|
| 85 | fprintf(stderr, " -s is server and -c is client\n"); |
|---|
| 86 | fprintf(stderr, " -u will use unexpected messages (pass to client only)\n"); |
|---|
| 87 | fprintf(stderr, " -r will calculate and verify checksums (adler32)\n"); |
|---|
| 88 | return; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | /**************************************************************/ |
|---|
| 92 | |
|---|
| 93 | int main(int argc, char **argv) |
|---|
| 94 | { |
|---|
| 95 | struct options *opts = NULL; |
|---|
| 96 | int ret = -1; |
|---|
| 97 | bmi_context_id context; |
|---|
| 98 | |
|---|
| 99 | /* grab any command line options */ |
|---|
| 100 | opts = parse_args(argc, argv); |
|---|
| 101 | if (!opts) { |
|---|
| 102 | print_usage(); |
|---|
| 103 | return (-1); |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | /* set debugging stuff */ |
|---|
| 107 | gossip_enable_stderr(); |
|---|
| 108 | gossip_set_debug_mask(0, GOSSIP_BMI_DEBUG_ALL); |
|---|
| 109 | |
|---|
| 110 | /* initialize local interface (default options) */ |
|---|
| 111 | if (opts->which == SERVER) |
|---|
| 112 | ret = BMI_initialize(opts->method, opts->hostid, BMI_INIT_SERVER); |
|---|
| 113 | else |
|---|
| 114 | ret = BMI_initialize(NULL, NULL, 0); |
|---|
| 115 | |
|---|
| 116 | if (ret < 0) { |
|---|
| 117 | errno = -ret; |
|---|
| 118 | perror("BMI_initialize"); |
|---|
| 119 | return (-1); |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | ret = BMI_open_context(&context); |
|---|
| 123 | if (ret < 0) { |
|---|
| 124 | errno = -ret; |
|---|
| 125 | perror("BMI_open_context()"); |
|---|
| 126 | return (-1); |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | if (opts->which == SERVER) { |
|---|
| 130 | ret = do_server(opts, &context); |
|---|
| 131 | } else { |
|---|
| 132 | ret = do_client(opts, &context); |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | /* shutdown the local interface */ |
|---|
| 136 | BMI_close_context(context); |
|---|
| 137 | ret = BMI_finalize(); |
|---|
| 138 | if (ret < 0) { |
|---|
| 139 | errno = -ret; |
|---|
| 140 | perror("BMI_finalize"); |
|---|
| 141 | return (-1); |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | /* turn off debugging stuff */ |
|---|
| 145 | gossip_disable(); |
|---|
| 146 | |
|---|
| 147 | return (0); |
|---|
| 148 | } |
|---|
| 149 | |
|---|
| 150 | static int bytes_to_iterations(int bytes) |
|---|
| 151 | { |
|---|
| 152 | int ret = ITERATIONS; |
|---|
| 153 | if (bytes >= (128*1024)) ret = 5000; |
|---|
| 154 | if (bytes >= (256*1024)) ret = 2500; |
|---|
| 155 | if (bytes >= (1024*1024)) ret = 1000; |
|---|
| 156 | if (bytes >= (2*1024*1024)) ret = 500; |
|---|
| 157 | if (bytes >= (4*1024*1024)) ret = 250; |
|---|
| 158 | return ret; |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | static int do_server(struct options *opts, bmi_context_id *context) |
|---|
| 162 | { |
|---|
| 163 | int ret = 0; |
|---|
| 164 | int i = 0; |
|---|
| 165 | PVFS_BMI_addr_t peer_addr; |
|---|
| 166 | PVFS_BMI_addr_t server_addr; |
|---|
| 167 | void *recv_buffer = NULL; |
|---|
| 168 | void *send_buffer = NULL; |
|---|
| 169 | bmi_op_id_t op_id[2]; |
|---|
| 170 | bmi_error_code_t error_code; |
|---|
| 171 | int outcount = 0; |
|---|
| 172 | struct BMI_unexpected_info request_info; |
|---|
| 173 | bmi_size_t actual_size; |
|---|
| 174 | struct msg *tx_msg = NULL; |
|---|
| 175 | struct msg *rx_msg = NULL; |
|---|
| 176 | int bytes = MIN_BYTES; |
|---|
| 177 | int max_bytes = MAX_BYTES; |
|---|
| 178 | int warmup = 1; |
|---|
| 179 | int iterations = 0; |
|---|
| 180 | int msg_len = 0; |
|---|
| 181 | int run = 0; |
|---|
| 182 | |
|---|
| 183 | /* wait for an initial request to get size */ |
|---|
| 184 | do { |
|---|
| 185 | ret = BMI_testunexpected(1, &outcount, &request_info, 10); |
|---|
| 186 | } while (ret == 0 && outcount == 0); |
|---|
| 187 | |
|---|
| 188 | if (ret < 0) { |
|---|
| 189 | fprintf(stderr, "Request recv failure (bad state).\n"); |
|---|
| 190 | errno = -ret; |
|---|
| 191 | perror("BMI_testunexpected"); |
|---|
| 192 | return ret; |
|---|
| 193 | } |
|---|
| 194 | if (request_info.error_code != 0) { |
|---|
| 195 | fprintf(stderr, "Request recv failure (bad state).\n"); |
|---|
| 196 | return ret; |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | if (request_info.size != sizeof(struct msg)) { |
|---|
| 200 | fprintf(stderr, "Bad Request! Received %d bytes\n", |
|---|
| 201 | (int) request_info.size); |
|---|
| 202 | return ret; |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | rx_msg = (struct msg *) request_info.buffer; |
|---|
| 206 | opts->test = ntohl(rx_msg->test); |
|---|
| 207 | |
|---|
| 208 | printf("Starting %s test%s\n", opts->test == EXPECTED ? "expected" : "unexpected", |
|---|
| 209 | opts->crc ? " with checksums" : ""); |
|---|
| 210 | |
|---|
| 211 | peer_addr = request_info.addr; |
|---|
| 212 | |
|---|
| 213 | BMI_unexpected_free(peer_addr, request_info.buffer); |
|---|
| 214 | |
|---|
| 215 | ret = BMI_get_info(server_addr, BMI_CHECK_MAXSIZE, |
|---|
| 216 | (void *)&max_bytes); |
|---|
| 217 | if (ret < 0) { |
|---|
| 218 | fprintf(stderr, "BMI_get_info() returned %d\n", ret); |
|---|
| 219 | return ret; |
|---|
| 220 | } |
|---|
| 221 | if (max_bytes > MAX_BYTES) max_bytes = MAX_BYTES; |
|---|
| 222 | |
|---|
| 223 | if (opts->test == UNEXPECTED) { |
|---|
| 224 | ret = BMI_addr_lookup(&server_addr, opts->hostid); |
|---|
| 225 | if (ret < 0) { |
|---|
| 226 | errno = -ret; |
|---|
| 227 | perror("BMI_addr_lookup"); |
|---|
| 228 | return (-1); |
|---|
| 229 | } |
|---|
| 230 | ret = BMI_get_info(server_addr, BMI_GET_UNEXP_SIZE, |
|---|
| 231 | (void *)&max_bytes); |
|---|
| 232 | if (ret < 0) { |
|---|
| 233 | fprintf(stderr, "BMI_get_info() returned %d\n", ret); |
|---|
| 234 | return ret; |
|---|
| 235 | } |
|---|
| 236 | } else { |
|---|
| 237 | int maxsize = 0; |
|---|
| 238 | ret = BMI_get_info(server_addr, BMI_CHECK_MAXSIZE, |
|---|
| 239 | (void *)&maxsize); |
|---|
| 240 | if (ret < 0) { |
|---|
| 241 | fprintf(stderr, "BMI_get_info() returned %d\n", ret); |
|---|
| 242 | return ret; |
|---|
| 243 | } |
|---|
| 244 | if (maxsize < max_bytes) max_bytes = maxsize; |
|---|
| 245 | } |
|---|
| 246 | |
|---|
| 247 | msg_len = sizeof(struct msg); |
|---|
| 248 | |
|---|
| 249 | /* create an ack */ |
|---|
| 250 | send_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_SEND); |
|---|
| 251 | if (!send_buffer) { |
|---|
| 252 | fprintf(stderr, "BMI_memalloc failed.\n"); |
|---|
| 253 | return (-1); |
|---|
| 254 | } |
|---|
| 255 | memset(send_buffer, 0, max_bytes); |
|---|
| 256 | |
|---|
| 257 | tx_msg = (struct msg *) send_buffer; |
|---|
| 258 | tx_msg->test = htonl(opts->test); |
|---|
| 259 | |
|---|
| 260 | |
|---|
| 261 | /* create a buffer to recv into */ |
|---|
| 262 | recv_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_RECV); |
|---|
| 263 | if (!recv_buffer) { |
|---|
| 264 | fprintf(stderr, "BMI_memalloc failed.\n"); |
|---|
| 265 | return (-1); |
|---|
| 266 | } |
|---|
| 267 | |
|---|
| 268 | /* post the ack */ |
|---|
| 269 | ret = BMI_post_send(&(op_id[SEND]), peer_addr, tx_msg, |
|---|
| 270 | msg_len, BMI_PRE_ALLOC, 0, NULL, |
|---|
| 271 | *context, NULL); |
|---|
| 272 | if (ret < 0) { |
|---|
| 273 | fprintf(stderr, "BMI_post_send failure.\n"); |
|---|
| 274 | return (-1); |
|---|
| 275 | } else if (ret == 0) { |
|---|
| 276 | do { |
|---|
| 277 | ret = BMI_test(op_id[SEND], &outcount, &error_code, |
|---|
| 278 | &actual_size, NULL, 10, *context); |
|---|
| 279 | } while (ret == 0 && outcount == 0); |
|---|
| 280 | |
|---|
| 281 | if (ret < 0 || error_code != 0) { |
|---|
| 282 | fprintf(stderr, "ack send failed.\n"); |
|---|
| 283 | return (-1); |
|---|
| 284 | } |
|---|
| 285 | |
|---|
| 286 | if (actual_size != (bmi_size_t) msg_len) { |
|---|
| 287 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 288 | msg_len, llu(actual_size)); |
|---|
| 289 | } |
|---|
| 290 | } |
|---|
| 291 | |
|---|
| 292 | /* start iterations */ |
|---|
| 293 | while (bytes <= max_bytes) { |
|---|
| 294 | iterations = bytes_to_iterations(bytes); |
|---|
| 295 | |
|---|
| 296 | for (i=0; i < iterations; i++) { |
|---|
| 297 | /* receive the ping */ |
|---|
| 298 | if (opts->test == EXPECTED) { |
|---|
| 299 | ret = BMI_post_recv(&(op_id[RECV]), peer_addr, recv_buffer, |
|---|
| 300 | bytes, &actual_size, BMI_PRE_ALLOC, i, NULL, |
|---|
| 301 | *context, NULL); |
|---|
| 302 | |
|---|
| 303 | if (ret < 0) { |
|---|
| 304 | fprintf(stderr, "BMI_post_recv_failure.\n"); |
|---|
| 305 | return (-1); |
|---|
| 306 | } else if (ret == 0) { |
|---|
| 307 | do { |
|---|
| 308 | ret = BMI_test(op_id[RECV], &outcount, &error_code, |
|---|
| 309 | &actual_size, NULL, 10, *context); |
|---|
| 310 | } while (ret == 0 && outcount == 0); |
|---|
| 311 | |
|---|
| 312 | if (ret < 0 || error_code != 0) { |
|---|
| 313 | fprintf(stderr, "data recv failed.\n"); |
|---|
| 314 | return (-1); |
|---|
| 315 | } |
|---|
| 316 | if (actual_size != bytes) { |
|---|
| 317 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 318 | bytes, llu(actual_size)); |
|---|
| 319 | return (-1); |
|---|
| 320 | } |
|---|
| 321 | } |
|---|
| 322 | } else { /* UNEXPECTED */ |
|---|
| 323 | do { |
|---|
| 324 | ret = BMI_testunexpected(1, &outcount, &request_info, 10); |
|---|
| 325 | } while (ret == 0 && outcount == 0); |
|---|
| 326 | |
|---|
| 327 | if (ret < 0) { |
|---|
| 328 | fprintf(stderr, "Request recv failure (bad state).\n"); |
|---|
| 329 | errno = -ret; |
|---|
| 330 | perror("BMI_testunexpected"); |
|---|
| 331 | return ret; |
|---|
| 332 | } |
|---|
| 333 | if (request_info.error_code != 0) { |
|---|
| 334 | fprintf(stderr, "Request recv failure (bad state).\n"); |
|---|
| 335 | return ret; |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | if (request_info.size != bytes) { |
|---|
| 339 | fprintf(stderr, "Bad Request! Received %d bytes\n", |
|---|
| 340 | (int) request_info.size); |
|---|
| 341 | return ret; |
|---|
| 342 | } |
|---|
| 343 | } |
|---|
| 344 | /* send the pong */ |
|---|
| 345 | ret = BMI_post_send(&(op_id[SEND]), peer_addr, |
|---|
| 346 | (opts->test == EXPECTED ? |
|---|
| 347 | recv_buffer : request_info.buffer), |
|---|
| 348 | bytes, BMI_PRE_ALLOC, i, NULL, *context, NULL); |
|---|
| 349 | if (ret < 0) { |
|---|
| 350 | fprintf(stderr, "BMI_post_send failure.\n"); |
|---|
| 351 | return (-1); |
|---|
| 352 | } else if (ret == 0) { |
|---|
| 353 | do { |
|---|
| 354 | ret = BMI_test(op_id[SEND], &outcount, &error_code, |
|---|
| 355 | &actual_size, NULL, 10, *context); |
|---|
| 356 | } while (ret == 0 && outcount == 0); |
|---|
| 357 | |
|---|
| 358 | if (ret < 0 || error_code != 0) { |
|---|
| 359 | fprintf(stderr, "ack send failed.\n"); |
|---|
| 360 | return (-1); |
|---|
| 361 | } |
|---|
| 362 | if (actual_size != bytes) { |
|---|
| 363 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 364 | bytes, llu(actual_size)); |
|---|
| 365 | return (-1); |
|---|
| 366 | } |
|---|
| 367 | } |
|---|
| 368 | } |
|---|
| 369 | if (!warmup) { |
|---|
| 370 | bytes *= 2; |
|---|
| 371 | run++; |
|---|
| 372 | } |
|---|
| 373 | else warmup = 0; |
|---|
| 374 | } |
|---|
| 375 | |
|---|
| 376 | /* free up the message buffers */ |
|---|
| 377 | BMI_memfree(peer_addr, recv_buffer, max_bytes, BMI_RECV); |
|---|
| 378 | BMI_memfree(peer_addr, send_buffer, max_bytes, BMI_SEND); |
|---|
| 379 | |
|---|
| 380 | return ret; |
|---|
| 381 | } |
|---|
| 382 | |
|---|
| 383 | static int do_client(struct options *opts, bmi_context_id *context) |
|---|
| 384 | { |
|---|
| 385 | int ret = 0; |
|---|
| 386 | int i = 0; |
|---|
| 387 | PVFS_BMI_addr_t peer_addr; |
|---|
| 388 | void *recv_buffer = NULL; |
|---|
| 389 | void *send_buffer = NULL; |
|---|
| 390 | bmi_op_id_t op_id[2]; |
|---|
| 391 | bmi_error_code_t error_code; |
|---|
| 392 | int outcount = 0; |
|---|
| 393 | bmi_size_t actual_size; |
|---|
| 394 | struct msg *tx_msg = NULL; |
|---|
| 395 | int bytes = MIN_BYTES; |
|---|
| 396 | int max_bytes = MAX_BYTES; |
|---|
| 397 | int warmup = 1; |
|---|
| 398 | int iterations = 0; |
|---|
| 399 | int msg_len = 0; |
|---|
| 400 | int run = 0; |
|---|
| 401 | struct timeval start; |
|---|
| 402 | struct timeval end; |
|---|
| 403 | double *val = NULL; |
|---|
| 404 | double lat = 0.0; |
|---|
| 405 | double min = 99999.9; |
|---|
| 406 | double max = 0.0; |
|---|
| 407 | double avg = 0.0; |
|---|
| 408 | int offset; |
|---|
| 409 | #ifdef HAVE_LIBZ |
|---|
| 410 | unsigned long crc=0, rcrc=0; |
|---|
| 411 | #endif |
|---|
| 412 | |
|---|
| 413 | /* get a bmi_addr for the server */ |
|---|
| 414 | ret = BMI_addr_lookup(&peer_addr, opts->hostid); |
|---|
| 415 | if (ret < 0) { |
|---|
| 416 | errno = -ret; |
|---|
| 417 | perror("BMI_addr_lookup"); |
|---|
| 418 | return (-1); |
|---|
| 419 | } |
|---|
| 420 | |
|---|
| 421 | if (opts->test == UNEXPECTED) { |
|---|
| 422 | ret = BMI_get_info(peer_addr, BMI_GET_UNEXP_SIZE, |
|---|
| 423 | (void *)&max_bytes); |
|---|
| 424 | if (ret < 0) { |
|---|
| 425 | fprintf(stderr, "BMI_get_info() returned %d\n", ret); |
|---|
| 426 | return ret; |
|---|
| 427 | } |
|---|
| 428 | } else { |
|---|
| 429 | int maxsize = 0; |
|---|
| 430 | ret = BMI_get_info(peer_addr, BMI_CHECK_MAXSIZE, |
|---|
| 431 | (void *)&maxsize); |
|---|
| 432 | if (ret < 0) { |
|---|
| 433 | fprintf(stderr, "BMI_get_info() returned %d\n", ret); |
|---|
| 434 | return ret; |
|---|
| 435 | } |
|---|
| 436 | if (maxsize < max_bytes) max_bytes = maxsize; |
|---|
| 437 | } |
|---|
| 438 | |
|---|
| 439 | msg_len = sizeof(struct msg); |
|---|
| 440 | |
|---|
| 441 | /* create send buffer */ |
|---|
| 442 | send_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_SEND); |
|---|
| 443 | if (!send_buffer) { |
|---|
| 444 | fprintf(stderr, "BMI_memalloc failed.\n"); |
|---|
| 445 | return (-1); |
|---|
| 446 | } |
|---|
| 447 | |
|---|
| 448 | if(opts->crc) |
|---|
| 449 | { |
|---|
| 450 | for(i = 0; i < max_bytes; ++i) |
|---|
| 451 | { |
|---|
| 452 | ((char *)send_buffer)[i] = i; |
|---|
| 453 | } |
|---|
| 454 | } |
|---|
| 455 | else |
|---|
| 456 | { |
|---|
| 457 | memset(send_buffer, 0, max_bytes); |
|---|
| 458 | } |
|---|
| 459 | |
|---|
| 460 | tx_msg = (struct msg *) send_buffer; |
|---|
| 461 | tx_msg->test = htonl(opts->test); |
|---|
| 462 | |
|---|
| 463 | /* create a buffer to recv into */ |
|---|
| 464 | recv_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_RECV); |
|---|
| 465 | if (!recv_buffer) { |
|---|
| 466 | fprintf(stderr, "BMI_memalloc failed.\n"); |
|---|
| 467 | return (-1); |
|---|
| 468 | } |
|---|
| 469 | |
|---|
| 470 | /* post the test parameters */ |
|---|
| 471 | ret = BMI_post_sendunexpected(&(op_id[SEND]), peer_addr, tx_msg, |
|---|
| 472 | msg_len, BMI_PRE_ALLOC, 0, NULL, *context, NULL); |
|---|
| 473 | if (ret < 0) { |
|---|
| 474 | fprintf(stderr, "BMI_post_sendunexpected failure.\n"); |
|---|
| 475 | return (-1); |
|---|
| 476 | } else if (ret == 0) { |
|---|
| 477 | do { |
|---|
| 478 | ret = BMI_test(op_id[SEND], &outcount, &error_code, |
|---|
| 479 | &actual_size, NULL, 10, *context); |
|---|
| 480 | } while (ret == 0 && outcount == 0); |
|---|
| 481 | if (ret < 0 || error_code != 0) { |
|---|
| 482 | fprintf(stderr, "data send failed.\n"); |
|---|
| 483 | return (-1); |
|---|
| 484 | } |
|---|
| 485 | if (actual_size != msg_len) { |
|---|
| 486 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 487 | msg_len, llu(actual_size)); |
|---|
| 488 | return (-1); |
|---|
| 489 | } |
|---|
| 490 | } |
|---|
| 491 | |
|---|
| 492 | /* post a recv for the ack */ |
|---|
| 493 | ret = BMI_post_recv(&(op_id[RECV]), peer_addr, recv_buffer, |
|---|
| 494 | msg_len, &actual_size, BMI_PRE_ALLOC, 0, NULL, *context, NULL); |
|---|
| 495 | if (ret < 0) { |
|---|
| 496 | fprintf(stderr, "BMI_post_recv_failure.\n"); |
|---|
| 497 | return (-1); |
|---|
| 498 | } else if (ret == 0) { |
|---|
| 499 | do { |
|---|
| 500 | ret = BMI_test(op_id[RECV], &outcount, &error_code, |
|---|
| 501 | &actual_size, NULL, 10, *context); |
|---|
| 502 | } while (ret == 0 && outcount == 0); |
|---|
| 503 | |
|---|
| 504 | if (ret < 0 || error_code != 0) { |
|---|
| 505 | fprintf(stderr, "data recv failed.\n"); |
|---|
| 506 | return (-1); |
|---|
| 507 | } |
|---|
| 508 | if (actual_size != msg_len) { |
|---|
| 509 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 510 | msg_len, llu(actual_size)); |
|---|
| 511 | return (-1); |
|---|
| 512 | } |
|---|
| 513 | } |
|---|
| 514 | |
|---|
| 515 | val = calloc(ITERATIONS, sizeof(double)); |
|---|
| 516 | if (val == NULL) { |
|---|
| 517 | fprintf(stderr, "calloc() for val failed\n"); |
|---|
| 518 | return -1; |
|---|
| 519 | } |
|---|
| 520 | |
|---|
| 521 | /* make sure server has posted first recv */ |
|---|
| 522 | sleep(1); |
|---|
| 523 | |
|---|
| 524 | fprintf(stdout, " Bytes usecs MB/s StdDev Min Max\n"); |
|---|
| 525 | |
|---|
| 526 | /* start iterations */ |
|---|
| 527 | while (bytes <= max_bytes) { |
|---|
| 528 | |
|---|
| 529 | iterations = bytes_to_iterations(bytes); |
|---|
| 530 | |
|---|
| 531 | for (i=0; i < iterations; i++) { |
|---|
| 532 | |
|---|
| 533 | offset = random() % (max_bytes - bytes - 1); |
|---|
| 534 | gettimeofday(&start, NULL); |
|---|
| 535 | |
|---|
| 536 | #ifdef HAVE_LIBZ |
|---|
| 537 | if(opts->crc) |
|---|
| 538 | { |
|---|
| 539 | crc = adler32(0L, Z_NULL, 0); |
|---|
| 540 | crc = adler32(crc, ((unsigned char *)send_buffer + (unsigned int)offset), bytes); |
|---|
| 541 | } |
|---|
| 542 | #endif |
|---|
| 543 | |
|---|
| 544 | /* post the recv for the pong */ |
|---|
| 545 | ret = BMI_post_recv(&(op_id[RECV]), peer_addr, recv_buffer, |
|---|
| 546 | bytes, &actual_size, BMI_PRE_ALLOC, i, |
|---|
| 547 | NULL, *context, NULL); |
|---|
| 548 | |
|---|
| 549 | if (ret < 0) { |
|---|
| 550 | fprintf(stderr, "BMI_post_recv_failure.\n"); |
|---|
| 551 | return (-1); |
|---|
| 552 | } |
|---|
| 553 | |
|---|
| 554 | /* send the ping */ |
|---|
| 555 | if (opts->test == EXPECTED) { |
|---|
| 556 | ret = BMI_post_send(&(op_id[SEND]), peer_addr, ((char *)send_buffer) + offset, |
|---|
| 557 | bytes, BMI_PRE_ALLOC, i, NULL, *context, NULL); |
|---|
| 558 | } else { |
|---|
| 559 | ret = BMI_post_sendunexpected(&(op_id[SEND]), peer_addr, |
|---|
| 560 | ((char*)send_buffer) + offset, bytes, BMI_PRE_ALLOC, i, |
|---|
| 561 | NULL, *context, NULL); |
|---|
| 562 | } |
|---|
| 563 | if (ret < 0) { |
|---|
| 564 | fprintf(stderr, "BMI_post_sendunexpected failure.\n"); |
|---|
| 565 | return (-1); |
|---|
| 566 | } else if (ret == 0) { |
|---|
| 567 | do { |
|---|
| 568 | ret = BMI_test(op_id[SEND], &outcount, &error_code, |
|---|
| 569 | &actual_size, NULL, 10, *context); |
|---|
| 570 | } while (ret == 0 && outcount == 0); |
|---|
| 571 | |
|---|
| 572 | if (ret < 0 || error_code != 0) { |
|---|
| 573 | fprintf(stderr, "send ping failed.\n"); |
|---|
| 574 | return (-1); |
|---|
| 575 | } |
|---|
| 576 | if (actual_size != bytes) { |
|---|
| 577 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 578 | bytes, llu(actual_size)); |
|---|
| 579 | return (-1); |
|---|
| 580 | } |
|---|
| 581 | } |
|---|
| 582 | /* complete the receive for the pong */ |
|---|
| 583 | do { |
|---|
| 584 | ret = BMI_test(op_id[RECV], &outcount, &error_code, |
|---|
| 585 | &actual_size, NULL, 10, *context); |
|---|
| 586 | } while (ret == 0 && outcount == 0); |
|---|
| 587 | |
|---|
| 588 | if (ret < 0 || error_code != 0) { |
|---|
| 589 | fprintf(stderr, "data recv failed.\n"); |
|---|
| 590 | return (-1); |
|---|
| 591 | } |
|---|
| 592 | if (actual_size != bytes) { |
|---|
| 593 | fprintf(stderr, "Expected %d but received %llu\n", |
|---|
| 594 | bytes, llu(actual_size)); |
|---|
| 595 | return (-1); |
|---|
| 596 | } |
|---|
| 597 | |
|---|
| 598 | #ifdef HAVE_LIBZ |
|---|
| 599 | if(opts->crc && opts->test == EXPECTED) |
|---|
| 600 | { |
|---|
| 601 | rcrc = adler32(0L, Z_NULL, 0); |
|---|
| 602 | rcrc = adler32(rcrc, recv_buffer, bytes); |
|---|
| 603 | if(rcrc != crc) |
|---|
| 604 | { |
|---|
| 605 | fprintf(stderr, "CRC Mismatch! " |
|---|
| 606 | "Sent %llu but received %llu\n", |
|---|
| 607 | (long long unsigned int)crc, |
|---|
| 608 | (long long unsigned int)rcrc); |
|---|
| 609 | } |
|---|
| 610 | } |
|---|
| 611 | #endif |
|---|
| 612 | gettimeofday(&end, NULL); |
|---|
| 613 | |
|---|
| 614 | if (!warmup) { |
|---|
| 615 | val[i] = (double) end.tv_sec + |
|---|
| 616 | (double) end.tv_usec * 0.000001; |
|---|
| 617 | val[i] -= (double) start.tv_sec + |
|---|
| 618 | (double) start.tv_usec * 0.000001; |
|---|
| 619 | lat += val[i]; |
|---|
| 620 | } |
|---|
| 621 | } |
|---|
| 622 | if (!warmup) { |
|---|
| 623 | double stdev = 0.0; |
|---|
| 624 | |
|---|
| 625 | lat = lat / (double) iterations * 1000000.0 / 2.0; |
|---|
| 626 | min = 999999.9; |
|---|
| 627 | max = 0.0; |
|---|
| 628 | avg = 0.0; |
|---|
| 629 | |
|---|
| 630 | /* convert seconds to MB/s */ |
|---|
| 631 | for (i=0; i < iterations; i++) { |
|---|
| 632 | val[i] = (double) bytes * 2 / val[i] / 1000000.0; |
|---|
| 633 | avg += val[i]; |
|---|
| 634 | if (val[i] < min) min = val[i]; |
|---|
| 635 | if (val[i] > max) max = val[i]; |
|---|
| 636 | } |
|---|
| 637 | avg /= iterations; |
|---|
| 638 | |
|---|
| 639 | if (iterations > 1) { |
|---|
| 640 | for (i=0; i < iterations; i++) { |
|---|
| 641 | double diff = val[i] - avg; |
|---|
| 642 | stdev += diff * diff; |
|---|
| 643 | } |
|---|
| 644 | stdev = sqrt(stdev / (iterations - 1)); |
|---|
| 645 | } |
|---|
| 646 | |
|---|
| 647 | fprintf(stdout, "%10d %12.3f %12.3f +- %9.3f %12.3f %12.3f\n", bytes, lat, avg, stdev, min, max); |
|---|
| 648 | |
|---|
| 649 | lat = 0.0; |
|---|
| 650 | bytes *= 2; |
|---|
| 651 | run++; |
|---|
| 652 | } else warmup = 0; |
|---|
| 653 | } |
|---|
| 654 | |
|---|
| 655 | /* free up the message buffers */ |
|---|
| 656 | BMI_memfree(peer_addr, recv_buffer, max_bytes, BMI_RECV); |
|---|
| 657 | BMI_memfree(peer_addr, send_buffer, max_bytes, BMI_SEND); |
|---|
| 658 | |
|---|
| 659 | return ret; |
|---|
| 660 | } |
|---|
| 661 | |
|---|
| 662 | static int check_uri(char *uri) |
|---|
| 663 | { |
|---|
| 664 | int ret = 0; /* failure */ |
|---|
| 665 | if (uri[0] == ':' && uri[1] == '/' && uri[2] == '/') ret = 1; |
|---|
| 666 | return ret; |
|---|
| 667 | } |
|---|
| 668 | |
|---|
| 669 | |
|---|
| 670 | static void get_method(struct options *opts) |
|---|
| 671 | { |
|---|
| 672 | char *id = opts->hostid; |
|---|
| 673 | |
|---|
| 674 | if (id[0] == 't' && id[1] == 'c' && id[2] == 'p' && check_uri(&id[3])) { |
|---|
| 675 | opts->method = strdup("bmi_tcp"); |
|---|
| 676 | } else if (id[0] == 'g' && id[1] == 'm' && check_uri(&id[2])) { |
|---|
| 677 | opts->method = strdup("bmi_gm"); |
|---|
| 678 | } else if (id[0] == 'm' && id[1] == 'x' && check_uri(&id[2])) { |
|---|
| 679 | opts->method = strdup("bmi_mx"); |
|---|
| 680 | } else if (id[0] == 'i' && id[1] == 'b' && check_uri(&id[2])) { |
|---|
| 681 | opts->method = strdup("bmi_ib"); |
|---|
| 682 | } |
|---|
| 683 | return; |
|---|
| 684 | } |
|---|
| 685 | |
|---|
| 686 | static struct options *parse_args(int argc, char *argv[]) |
|---|
| 687 | { |
|---|
| 688 | |
|---|
| 689 | /* getopt stuff */ |
|---|
| 690 | extern char *optarg; |
|---|
| 691 | char flags[] = "h:scur"; |
|---|
| 692 | int one_opt = 0; |
|---|
| 693 | |
|---|
| 694 | struct options *opts = NULL; |
|---|
| 695 | |
|---|
| 696 | /* create storage for the command line options */ |
|---|
| 697 | opts = (struct options *) calloc(1, sizeof(struct options)); |
|---|
| 698 | if (!opts) { |
|---|
| 699 | goto parse_args_error; |
|---|
| 700 | } |
|---|
| 701 | |
|---|
| 702 | /* look at command line arguments */ |
|---|
| 703 | while ((one_opt = getopt(argc, argv, flags)) != EOF) { |
|---|
| 704 | switch (one_opt) { |
|---|
| 705 | case ('h'): |
|---|
| 706 | opts->hostid = (char *) strdup(optarg); |
|---|
| 707 | if (opts->hostid == NULL) { |
|---|
| 708 | goto parse_args_error; |
|---|
| 709 | } |
|---|
| 710 | get_method(opts); |
|---|
| 711 | break; |
|---|
| 712 | case ('s'): |
|---|
| 713 | if (opts->which == CLIENT) { |
|---|
| 714 | fprintf(stderr, "use -s OR -c, not both\n"); |
|---|
| 715 | goto parse_args_error; |
|---|
| 716 | } |
|---|
| 717 | opts->which = SERVER; |
|---|
| 718 | break; |
|---|
| 719 | case ('c'): |
|---|
| 720 | if (opts->which == SERVER) { |
|---|
| 721 | fprintf(stderr, "use -s OR -c, not both\n"); |
|---|
| 722 | goto parse_args_error; |
|---|
| 723 | } |
|---|
| 724 | opts->which = CLIENT; |
|---|
| 725 | break; |
|---|
| 726 | case ('u'): |
|---|
| 727 | opts->test = UNEXPECTED; |
|---|
| 728 | break; |
|---|
| 729 | case ('r'): |
|---|
| 730 | opts->crc = 1; |
|---|
| 731 | break; |
|---|
| 732 | default: |
|---|
| 733 | break; |
|---|
| 734 | } |
|---|
| 735 | } |
|---|
| 736 | |
|---|
| 737 | /* if we didn't get a host argument, bail: */ |
|---|
| 738 | if (opts->hostid == NULL) { |
|---|
| 739 | fprintf(stderr, "you must specify -h\n"); |
|---|
| 740 | goto parse_args_error; |
|---|
| 741 | } |
|---|
| 742 | if (opts->method == NULL) { |
|---|
| 743 | fprintf(stderr, "you must use a valid HOST_URI\n"); |
|---|
| 744 | goto parse_args_error; |
|---|
| 745 | } |
|---|
| 746 | if (opts->which == 0) { |
|---|
| 747 | fprintf(stderr, "you must specify -s OR -c\n"); |
|---|
| 748 | goto parse_args_error; |
|---|
| 749 | } |
|---|
| 750 | |
|---|
| 751 | return (opts); |
|---|
| 752 | |
|---|
| 753 | parse_args_error: |
|---|
| 754 | |
|---|
| 755 | /* if an error occurs, just free everything and return NULL */ |
|---|
| 756 | if (opts) { |
|---|
| 757 | if (opts->hostid) { |
|---|
| 758 | free(opts->hostid); |
|---|
| 759 | } |
|---|
| 760 | free(opts); |
|---|
| 761 | } |
|---|
| 762 | return (NULL); |
|---|
| 763 | } |
|---|
| 764 | |
|---|
| 765 | /* |
|---|
| 766 | * vim:expandtab:shiftwidth=8:tabstop=8: |
|---|
| 767 | */ |
|---|