Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

vipl_priv_conn_mgr.c

Go to the documentation of this file.
00001 /********************************************************
00002  * Myricom VI-GM  networking software and documentation *
00003  * Copyright (c) 2001 by Myricom, Inc.                  *
00004  * All rights reserved.                                 *
00005  * See the file `COPYING' for copyright notice.         *
00006  ********************************************************/
00007 
00013 #ifndef WIN32
00014 #include <unistd.h>
00015 #endif
00016 #include <string.h>
00017 
00018 #include "vipl_priv.h"
00019 
00020 
00023 typedef struct _VIP_CONN_MGR_ENTRY
00024 {
00026   VIP_NET_UINT32 net_srv_magic;
00028   gm_alarm_t alarm;
00029 }
00030 VIP_ENDPOINT;
00031 
00032 
00046 void
00047 vip_conn_mgr_dead_endpoint (void *ptr)
00048 {
00049   VIP_ENDPOINT *vip_endpoint_ptr;
00050   VIP_DEBUG_LABEL (("vip_conn_mgr_dead_endpoint"));
00051 
00052   vip_endpoint_ptr = (VIP_ENDPOINT *) ptr;
00053   VIP_ASSERT (VIP_NTOH_UINT32 (vip_endpoint_ptr->net_srv_magic) != 0);
00054   vip_endpoint_ptr->net_srv_magic = VIP_HTON_UINT32 (0);
00055   VIP_DEBUG (("Keep alive timeout, endpoint is deregistered"));
00056 }
00057 
00074 void
00075 vip_conn_mgr_send_callback (struct gm_port *gm_port,
00076                             void *context, 
00077                             gm_status_t status)
00078 {
00079   if (status != GM_SUCCESS)
00080     {
00081       VIP_PACKET_CONN_LIST *pkt_ptr;
00082       unsigned int gm_id;
00083       unsigned int port_id;
00084       
00085       pkt_ptr = (VIP_PACKET_CONN_LIST *) context;
00086       gm_unique_id_to_node_id (gm_port, pkt_ptr->gm_unique_id, &gm_id);
00087       port_id = pkt_ptr->port_id;
00088       fprintf (stderr, "Connection manager: error sending message "
00089                "to GM id %d / GM port %d (%s)\n", gm_id, port_id,
00090                gm_strerror (status));
00091       gm_resume_sending (gm_port, GM_LOW_PRIORITY, gm_id, port_id,
00092                          vip_conn_mgr_send_callback, context);
00093       return;
00094     }
00095 
00096   gm_provide_receive_buffer (gm_port, context, VI_GM_CTRL_GM_SIZE,
00097                              GM_LOW_PRIORITY);
00098 }
00099 
00100 
00127 int
00128 main (void)
00129 {
00130   struct gm_port *gm_port;
00131   gm_status_t gm_status;
00132   gm_alarm_t *alarm_ptr;
00133   gm_recv_event_t *gm_event;
00134   VIP_UCHAR port_id;
00135   VIP_UINT16 gm_id;
00136   unsigned int node_id;
00137   VIP_UINT32 i;
00138   VIP_UINT32 j;
00139   VIP_UINT32 recv_tokens;
00140   VIP_PACKET *pkt_ptr;
00141   VIP_PVOID recv_buffers;
00142   VIP_UCHAR gm_hostname[GM_MAX_HOST_NAME_LEN];
00143   VIP_UCHAR gm_nicname[GM_MAX_HOST_NAME_LEN];
00144   VIP_ENDPOINT endpoints[VI_GM_MAX_NICS][VI_GM_MAX_PORTS];
00145   VIP_UINT32 board_gm_ids[VI_GM_MAX_NICS];
00146   VIP_DEBUG_LABEL (("Connection manager"));
00147 
00148 
00149   /* open the GM port */
00150   i = 15;
00151   do
00152     {
00153       vip_millisleep ((15-i) * 1000);
00154       gm_status = gm_open (&gm_port, 0, VI_GM_PORT_CONN_MANAGER,
00155                            "VI-GM  Connection Manager", GM_API_VERSION_1_6);
00156     }
00157   while ((i-- > 0) && (gm_status == GM_STILL_SHUTTING_DOWN));
00158 
00159   if (gm_status != GM_SUCCESS)
00160     {
00161       fprintf (stderr, "Connection manager: Cannot open GM port %d "
00162                "on the Myrinet board 0 (%s)\n",
00163                VI_GM_PORT_CONN_MANAGER, gm_strerror (gm_status));
00164       goto out;
00165     }
00166 
00167   /* init endpoints matrix */
00168   gm_bzero (endpoints, (VI_GM_MAX_NICS * VI_GM_MAX_PORTS
00169                         * sizeof (VIP_ENDPOINT)));
00170 
00171   /* get hostame */
00172   gm_status = gm_get_host_name (gm_port, gm_hostname);
00173   if (gm_status != GM_SUCCESS)
00174     {
00175       fprintf (stderr, "Connection manager: Cannot get GM hostname (%s)\n",
00176                gm_strerror (gm_status));
00177       goto out_with_gm_port;
00178     }
00179 
00180   /* get the gm id */
00181   gm_status = gm_get_node_id (gm_port, &(board_gm_ids[0]));
00182   if (gm_status != GM_SUCCESS)
00183     {
00184       fprintf (stderr, "Connection manager: Cannot get GM id (%s)\n",
00185                gm_strerror (gm_status));
00186       goto out_with_gm_port;
00187     }
00188 
00189   /* fill GM id of boards, if any */
00190   for (i = 1; i < VI_GM_MAX_NICS; i++)
00191     {
00192       sprintf (gm_nicname, "%s:%d", gm_hostname, i);
00193       board_gm_ids[i] = gm_host_name_to_node_id (gm_port, gm_nicname);
00194     }
00195 
00196   /* init recv buffers */
00197   recv_tokens = gm_num_send_tokens (gm_port);
00198   recv_buffers = gm_dma_malloc (gm_port, recv_tokens
00199                                 * sizeof (VIP_PACKET_CONN_LIST));
00200 
00201   if (recv_buffers == NULL)
00202     {
00203       fprintf (stderr, "Connection manager: Cannot allocate GM "
00204                "receive buffers, not enough DMA-able memory available\n");
00205       goto out_with_gm_port;
00206     }
00207 
00208   /* post recv buffers */
00209   for (i = 0; i < recv_tokens; i++)
00210     {
00211       gm_provide_receive_buffer (gm_port, &(((VIP_PACKET_CONN_LIST *)
00212                                              recv_buffers)[i]),
00213                                  VI_GM_CTRL_GM_SIZE, GM_LOW_PRIORITY);
00214     }
00215 
00216   /* recv loop */
00217   while (1)
00218     {
00219     begin_loop:
00220       gm_event = gm_blocking_receive_no_spin (gm_port);
00221 
00222       switch (gm_ntohc (gm_event->recv.type))
00223         {
00224         case GM_NO_RECV_EVENT:
00225           break;
00226 
00227         case GM_RECV_EVENT:
00228         case GM_HIGH_RECV_EVENT:
00229         case GM_PEER_RECV_EVENT:
00230         case GM_HIGH_PEER_RECV_EVENT:
00231           pkt_ptr = (VIP_PACKET *) (gm_ntohp (gm_event->recv.buffer));
00232 
00233           switch (VIP_NTOH_UCHAR (pkt_ptr->type))
00234             {
00235             case VIP_ALIVE_PKT:
00236               gm_id = gm_ntohs (gm_event->recv.sender_node_id);
00237               port_id = gm_ntohc (gm_event->recv.sender_port_id);
00238               VIP_DEBUG (("Received a ALIVE packet from %d/%d", gm_id,
00239                           port_id));
00240 
00241               for (i = 0; i < VI_GM_MAX_NICS; i++)
00242                 {
00243                   if (board_gm_ids[i] == gm_id)
00244                     {
00245                       /* found the associated board index */
00246                       alarm_ptr = &(endpoints[i][port_id].alarm);
00247                       if (VIP_NTOH_UINT32
00248                           (endpoints[i][port_id].net_srv_magic) == 0)
00249                         {
00250                           VIP_DEBUG (("New VI-GM endpoint registered"));
00251                           endpoints[i][port_id].net_srv_magic =
00252                             pkt_ptr->vip_pkt_alive.net_srv_magic;
00253                           gm_initialize_alarm (alarm_ptr);
00254                         }
00255                       else
00256                         {
00257                           if (memcmp (&(endpoints[i][port_id].net_srv_magic),
00258                                       &(pkt_ptr->vip_pkt_alive.net_srv_magic),
00259                                       sizeof (VIP_NET_UINT32)) != 0)
00260                             {
00261                               VIP_DEBUG
00262                                 (("New VI-GM endpoint replace old one"));
00263                               endpoints[i][port_id].net_srv_magic =
00264                                 pkt_ptr->vip_pkt_alive.net_srv_magic;
00265                             }
00266                         }
00267 
00268                       /* set an alarm to remove dead endpoint */
00269                       gm_set_alarm (gm_port, alarm_ptr,
00270                                     (VI_GM_CONN_MGR_TTL * 1000),
00271                                     vip_conn_mgr_dead_endpoint,
00272                                     &(endpoints[i][port_id]));
00273                       i = VI_GM_MAX_NICS;
00274                     }
00275                 }
00276               break;
00277 
00278             case VIP_CONN_LIST_REQ_PKT:
00279               gm_unique_id_to_node_id(gm_port, pkt_ptr->vip_pkt_conn_list.gm_unique_id, &node_id);
00280               gm_id = node_id;
00281               VIP_DEBUG (("Received a CONN_LIST request about GM_id %d "
00282                           "from (%d/%d)", gm_id,
00283                           gm_ntohs (gm_event->recv.sender_node_id), 
00284                           gm_ntohc (gm_event->recv.sender_port_id)));
00285               pkt_ptr->vip_pkt_conn_list.type =
00286                 VIP_HTON_UCHAR (VIP_CONN_LIST_REPLY_PKT);
00287 
00288               for (i = 0; i < VI_GM_MAX_NICS; i++)
00289                 {
00290                   if (board_gm_ids[i] == gm_id)
00291                     {
00292                       /* found the associated board index */
00293                       gm_id = gm_ntohs (gm_event->recv.sender_node_id);
00294                       port_id = gm_ntohc (gm_event->recv.sender_port_id);
00295 
00296                       for (j = 0; j < VI_GM_MAX_PORTS; j++)
00297                         {
00298                           pkt_ptr->vip_pkt_conn_list.net_srv_magic[j] =
00299                             endpoints[i][j].net_srv_magic;
00300                         }
00301 
00302                       pkt_ptr->vip_pkt_conn_list.port_id = port_id;
00303                       gm_node_id_to_unique_id(gm_port, gm_id, pkt_ptr->vip_pkt_conn_list.gm_unique_id);
00304                       gm_send_with_callback (gm_port, pkt_ptr,
00305                                              VI_GM_CTRL_GM_SIZE,
00306                                              sizeof (VIP_PACKET_CONN_LIST),
00307                                              GM_LOW_PRIORITY,
00308                                              gm_id, port_id,
00309                                              vip_conn_mgr_send_callback,
00310                                              pkt_ptr);
00311                       VIP_DEBUG (("Send a CONN_LIST reply for board %d", i));
00312                       goto begin_loop;
00313                     }
00314                 }
00315               break;
00316 
00317             default:
00318               VIP_DEBUG (("Unknown packet type received (%d)",
00319                           VIP_NTOH_UCHAR (pkt_ptr->type)));
00320             }
00321 
00322           gm_provide_receive_buffer (gm_port, pkt_ptr,
00323                                      VI_GM_CTRL_GM_SIZE, GM_LOW_PRIORITY);
00324           break;
00325 
00326         default:
00327           gm_unknown (gm_port, gm_event);
00328         }
00329     }
00330 
00331   gm_dma_free (gm_port, recv_buffers);
00332 
00333 out_with_gm_port:
00334   gm_close (gm_port);
00335 out:
00336   return 1;
00337 }
00338 
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.