home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / test / io / bmi / test-bmi-client-eagerbug.c < prev    next >
C/C++ Source or Header  |  2008-11-26  |  9KB  |  421 lines

  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 client program that uses the BMI library
  12.  * 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.  
  21. #include "pvfs2.h"
  22. #include "bmi.h"
  23. #include "test-bmi.h"
  24. #include "gossip.h"
  25.  
  26. /**************************************************************
  27.  * Data structures 
  28.  */
  29.  
  30. /* A little structure to hold program options, either defaults or
  31.  * specified on the command line 
  32.  */
  33. struct options
  34. {
  35.     char *hostid;        /* host identifier */
  36.     int message_size;        /* message size */
  37. };
  38.  
  39.  
  40. /**************************************************************
  41.  * Internal utility functions
  42.  */
  43.  
  44. static struct options *parse_args(
  45.     int argc,
  46.     char *argv[]);
  47.  
  48.  
  49. /**************************************************************/
  50.  
  51. int main(
  52.     int argc,
  53.     char **argv)
  54. {
  55.  
  56.     struct options *user_opts = NULL;
  57.     struct server_request *my_req = NULL;
  58.     struct server_ack *my_ack = NULL;
  59.     int ret = -1;
  60.     PVFS_BMI_addr_t server_addr;
  61.     void *send_buffer = NULL;
  62.     bmi_op_id_t client_ops[2];
  63.     int outcount = 0;
  64.     bmi_error_code_t error_code;
  65.     void *in_test_user_ptr = &server_addr;
  66.     void *out_test_user_ptr = NULL;
  67.     bmi_size_t actual_size;
  68.     bmi_context_id context;
  69.     char method[24], *cp;
  70.     int len;
  71.     char testeagerbuf1[] = "aaaccc";
  72.  
  73.     /* grab any command line options */
  74.     user_opts = parse_args(argc, argv);
  75.     if (!user_opts)
  76.     {
  77.     return (-1);
  78.     }
  79.  
  80.     /* set debugging stuff */
  81.     gossip_enable_stderr();
  82.     /* gossip_set_debug_mask(1, GOSSIP_BMI_DEBUG_ALL); */
  83.  
  84.     /* convert address to bmi method type by prefixing bmi_ */
  85.     cp = strchr(user_opts->hostid, ':');
  86.     if (!cp)
  87.         return 1;
  88.     len = cp - user_opts->hostid;
  89.     strcpy(method, "bmi_");
  90.     strncpy(method + 4, user_opts->hostid, len);
  91.     method[4+len] = '\0';
  92.  
  93.     /* initialize local interface */
  94.     ret = BMI_initialize(NULL, NULL, 0);
  95.     if (ret < 0)
  96.     {
  97.     errno = -ret;
  98.     perror("BMI_initialize");
  99.     return (-1);
  100.     }
  101.  
  102.     ret = BMI_open_context(&context);
  103.     if (ret < 0)
  104.     {
  105.     errno = -ret;
  106.     perror("BMI_open_context()");
  107.     return (-1);
  108.     }
  109.  
  110.     /* get a bmi_addr for the server */
  111.     ret = BMI_addr_lookup(&server_addr, user_opts->hostid);
  112.     if (ret < 0)
  113.     {
  114.     errno = -ret;
  115.     perror("BMI_addr_lookup");
  116.     return (-1);
  117.     }
  118.  
  119.     /* allocate a buffer for the initial request and ack */
  120.     my_req = (struct server_request *) BMI_memalloc(server_addr,
  121.                             sizeof(struct
  122.                                server_request),
  123.                             BMI_SEND);
  124.     my_ack =
  125.     (struct server_ack *) BMI_memalloc(server_addr,
  126.                        sizeof(struct server_ack), BMI_RECV);
  127.     if (!my_req || !my_ack)
  128.     {
  129.     fprintf(stderr, "BMI_memalloc failed.\n");
  130.     return (-1);
  131.     }
  132.  
  133.     my_req->size = user_opts->message_size;
  134.  
  135.     /* send the initial request on its way */
  136.     ret = BMI_post_sendunexpected(&(client_ops[1]), server_addr, my_req,
  137.                   sizeof(struct server_request), BMI_PRE_ALLOC,
  138.                   0, in_test_user_ptr, context, NULL);
  139.     if (ret < 0)
  140.     {
  141.     errno = -ret;
  142.     perror("BMI_post_send");
  143.     return (-1);
  144.     }
  145.     if (ret == 0)
  146.     {
  147.     /* turning this into a blocking call for testing :) */
  148.     /* check for completion of request */
  149.     do
  150.     {
  151.         ret = BMI_test(client_ops[1], &outcount, &error_code, &actual_size,
  152.                &out_test_user_ptr, 10, context);
  153.     } while (ret == 0 && outcount == 0);
  154.  
  155.     if (ret < 0 || error_code != 0)
  156.     {
  157.         fprintf(stderr, "Request send failed.\n");
  158.         if (ret < 0)
  159.         {
  160.         errno = -ret;
  161.         perror("BMI_test");
  162.         }
  163.         return (-1);
  164.     }
  165.  
  166.     out_test_user_ptr = NULL;
  167.     }
  168.  
  169.     /* post a recv for the server acknowledgement */
  170.     ret = BMI_post_recv(&(client_ops[0]), server_addr, my_ack,
  171.             sizeof(struct server_ack), &actual_size, BMI_PRE_ALLOC,
  172.             0, in_test_user_ptr, context, NULL);
  173.     if (ret < 0)
  174.     {
  175.     errno = -ret;
  176.     perror("BMI_post_recv");
  177.     return (-1);
  178.     }
  179.     if (ret == 0)
  180.     {
  181.     /* turning this into a blocking call for testing :) */
  182.     /* check for completion of ack recv */
  183.     do
  184.     {
  185.         ret = BMI_test(client_ops[0], &outcount, &error_code,
  186.                &actual_size, &out_test_user_ptr, 10, context);
  187.     } while (ret == 0 && outcount == 0);
  188.  
  189.     if (ret < 0 || error_code != 0)
  190.     {
  191.         fprintf(stderr, "Ack recv failed.\n");
  192.         return (-1);
  193.     }
  194.     out_test_user_ptr = NULL;
  195.     }
  196.     else
  197.     {
  198.     if (actual_size != sizeof(struct server_ack))
  199.     {
  200.         printf("Short recv.\n");
  201.         return (-1);
  202.     }
  203.     }
  204.  
  205.     /* look at the ack */
  206.     if (my_ack->status != 0)
  207.     {
  208.     fprintf(stderr, "Request denied.\n");
  209.     return (-1);
  210.     }
  211.  
  212.     /* create a buffer to send */
  213.     send_buffer = BMI_memalloc(server_addr, user_opts->message_size, BMI_SEND);
  214.     if (!send_buffer)
  215.     {
  216.     fprintf(stderr, "BMI_memalloc.\n");
  217.     return (-1);
  218.     }
  219.  
  220.     /* send the data payload on its way */
  221.     /* NOTE: intentionally sending short message here, testing
  222.      * ability to match eager send with rend. receive
  223.      */
  224.     ret = BMI_post_send(&(client_ops[0]), server_addr, send_buffer,
  225.             15000, BMI_PRE_ALLOC, 0, in_test_user_ptr, context, NULL);
  226.     if (ret < 0)
  227.     {
  228.     errno = -ret;
  229.     perror("BMI_post_send");
  230.     return (-1);
  231.     }
  232.     if (ret == 0)
  233.     {
  234.     /* turning this into a blocking call for testing :) */
  235.     /* check for completion of data payload send */
  236.     do
  237.     {
  238.         ret = BMI_test(client_ops[0], &outcount, &error_code,
  239.                &actual_size, &out_test_user_ptr, 10, context);
  240.     } while (ret == 0 && outcount == 0);
  241.  
  242.     if (ret < 0 || error_code != 0)
  243.     {
  244.         fprintf(stderr, "Data payload send failed.\n");
  245.         return (-1);
  246.     }
  247.     if (in_test_user_ptr != out_test_user_ptr)
  248.     {
  249.         fprintf(stderr, "3rd ptr failure.\n");
  250.     }
  251.     else
  252.     {
  253.         fprintf(stderr, "3rd ptr success.\n");
  254.     }
  255.     out_test_user_ptr = NULL;
  256.     }
  257.  
  258.     /* final send to test eager bug *****************************/
  259.     ret = BMI_post_send(&(client_ops[0]), server_addr, testeagerbuf1,
  260.             6, BMI_EXT_ALLOC, 1, NULL, context, NULL);
  261.     if (ret < 0)
  262.     {
  263.     errno = -ret;
  264.     perror("BMI_post_send");
  265.     return (-1);
  266.     }
  267.     if (ret == 0)
  268.     {
  269.     /* turning this into a blocking call for testing :) */
  270.     /* check for completion of data payload send */
  271.     do
  272.     {
  273.         ret = BMI_test(client_ops[0], &outcount, &error_code,
  274.                &actual_size, NULL, 10, context);
  275.     } while (ret == 0 && outcount == 0);
  276.  
  277.     if (ret < 0 || error_code != 0)
  278.     {
  279.         fprintf(stderr, "Data payload send failed.\n");
  280.         return (-1);
  281.     }
  282.     }
  283.  
  284.     /* let the server get ahead of us */
  285.     sleep(10);
  286.  
  287.     ret = BMI_post_send(&(client_ops[0]), server_addr, testeagerbuf1,
  288.             6, BMI_EXT_ALLOC, 1, NULL, context, NULL);
  289.     if (ret < 0)
  290.     {
  291.     errno = -ret;
  292.     perror("BMI_post_send");
  293.     return (-1);
  294.     }
  295.     if (ret == 0)
  296.     {
  297.     /* turning this into a blocking call for testing :) */
  298.     /* check for completion of data payload send */
  299.     do
  300.     {
  301.         ret = BMI_test(client_ops[0], &outcount, &error_code,
  302.                &actual_size, NULL, 10, context);
  303.     } while (ret == 0 && outcount == 0);
  304.  
  305.     if (ret < 0 || error_code != 0)
  306.     {
  307.         fprintf(stderr, "Data payload send failed.\n");
  308.         return (-1);
  309.     }
  310.     }
  311.  
  312.     /* free up the message buffers */
  313.     BMI_memfree(server_addr, send_buffer, user_opts->message_size, BMI_SEND);
  314.     BMI_memfree(server_addr, my_req, sizeof(struct server_request), BMI_SEND);
  315.     BMI_memfree(server_addr, my_ack, sizeof(struct server_ack), BMI_RECV);
  316.  
  317.     /* try out rev lookup */
  318.     /* printf("rev_lookup() output: %s\n", BMI_addr_rev_lookup(server_addr)); */
  319.  
  320.     /* shutdown the local interface */
  321.     BMI_close_context(context);
  322.     ret = BMI_finalize();
  323.     if (ret < 0)
  324.     {
  325.     errno = -ret;
  326.     perror("BMI_finalize");
  327.     return (-1);
  328.     }
  329.  
  330.     /* turn off debugging stuff */
  331.     gossip_disable();
  332.  
  333.     free(user_opts->hostid);
  334.     free(user_opts);
  335.  
  336.     return (0);
  337. }
  338.  
  339.  
  340. static struct options *parse_args(
  341.     int argc,
  342.     char *argv[])
  343. {
  344.     const char flags[] = "h:s:";
  345.     int one_opt = 0;
  346.  
  347.     struct options *tmp_opts = NULL;
  348.     int len = -1;
  349.     int ret = -1;
  350.  
  351.     /* create storage for the command line options */
  352.     tmp_opts = malloc(sizeof(struct options));
  353.     if (!tmp_opts)
  354.     {
  355.     goto parse_args_error;
  356.     }
  357.  
  358.     /* fill in defaults (except for hostid) */
  359.     tmp_opts->hostid = NULL;
  360.     tmp_opts->message_size = 32000;
  361.  
  362.     /* look at command line arguments */
  363.     while ((one_opt = getopt(argc, argv, flags)) != EOF)
  364.     {
  365.     switch (one_opt)
  366.     {
  367.     case ('h'):
  368.         len = (strlen(optarg)) + 1;
  369.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  370.         {
  371.         goto parse_args_error;
  372.         }
  373.         memcpy(tmp_opts->hostid, optarg, len);
  374.         break;
  375.     case ('s'):
  376.         ret = sscanf(optarg, "%d", &tmp_opts->message_size);
  377.         if (ret < 1)
  378.         {
  379.         goto parse_args_error;
  380.         }
  381.         break;
  382.     default:
  383.         break;
  384.     }
  385.     }
  386.  
  387.     /* if we didn't get a host argument, fill in a default: */
  388.     if (tmp_opts->hostid == NULL) {
  389.         len = (strlen(DEFAULT_HOSTID)) + 1;
  390.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  391.         {
  392.             goto parse_args_error;
  393.         }
  394.         memcpy(tmp_opts->hostid, DEFAULT_HOSTID, len);
  395.     }
  396.  
  397.     return (tmp_opts);
  398.  
  399.   parse_args_error:
  400.  
  401.     /* if an error occurs, just free everything and return NULL */
  402.     if (tmp_opts)
  403.     {
  404.     if (tmp_opts->hostid)
  405.     {
  406.         free(tmp_opts->hostid);
  407.     }
  408.     free(tmp_opts);
  409.     }
  410.     return (NULL);
  411. }
  412.  
  413. /*
  414.  * Local variables:
  415.  *  c-indent-level: 4
  416.  *  c-basic-offset: 4
  417.  * End:
  418.  *
  419.  * vim: ts=8 sts=4 sw=4 expandtab
  420.  */
  421.