00001
00002
00003
00004
00005
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
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
00168 gm_bzero (endpoints, (VI_GM_MAX_NICS * VI_GM_MAX_PORTS
00169 * sizeof (VIP_ENDPOINT)));
00170
00171
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
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
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
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
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
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
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
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
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