static void shortest_path(lash_t * p_lash, int ir) { switch_t **switches = p_lash->switches, *sw, *swi; unsigned int i; cl_list_t bfsq; cl_list_construct(&bfsq); cl_list_init(&bfsq, 20); enqueue(&bfsq, switches[ir]); while (!cl_is_list_empty(&bfsq)) { dequeue(&bfsq, &sw); for (i = 0; i < sw->node->num_links; i++) { swi = switches[sw->node->links[i]->switch_id]; if (swi->q_state == UNQUEUED) { enqueue(&bfsq, swi); sw->dij_channels[sw->used_channels++] = swi->id; } } } cl_list_destroy(&bfsq); }
/* this is the callback function of the timer */ void __osm_transaction_mgr_callback(IN void *context) { osm_transaction_mgr_t *trans_mgr_p; osm_vendor_t *p_vend = (osm_vendor_t *) context; cl_list_item_t *p_list_item; cl_list_item_t *p_list_next_item; osm_madw_req_t *osm_madw_req_p; uint64_t current_time; /* [usec] */ uint32_t new_timeout; /* [msec] */ cl_status_t cl_status; ib_mad_t *p_mad; #ifdef OSM_VENDOR_INTF_MTL osm_mtl_bind_info_t *p_bind; #else osm_ts_bind_info_t *p_bind; #endif cl_list_t tmp_madw_p_list; /* this list will include all the madw_p that should be removed. */ cl_list_t retry_madw_p_list; /* this list will include all the madw_p that were retried and need to be removed. */ osm_madw_t *madw_p; OSM_LOG_ENTER(p_vend->p_log); trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; /* initialize the tmp_madw_p_list */ cl_list_construct(&tmp_madw_p_list); cl_status = cl_list_init(&tmp_madw_p_list, 50); if (cl_status != CL_SUCCESS) { osm_log(p_vend->p_log, OSM_LOG_ERROR, "__osm_transaction_mgr_callback : ERROR 1000: " "Failed to create tmp_madw_p_list\n"); } cl_list_construct(&retry_madw_p_list); cl_status = cl_list_init(&retry_madw_p_list, 50); if (cl_status != CL_SUCCESS) { osm_log(p_vend->p_log, OSM_LOG_ERROR, "__osm_transaction_mgr_callback : ERROR 1000: " "Failed to create retry_madw_p_list\n"); } current_time = cl_get_time_stamp(); cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock)); p_list_item = cl_qlist_head(trans_mgr_p->madw_reqs_list_p); if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { /* the list is empty - nothing to do */ cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock); osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osm_transaction_mgr_callback : Nothing to do\n"); goto Exit; } /* non empty list: */ /* get the osm_madw_req_p */ osm_madw_req_p = PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item); while (osm_madw_req_p->waking_time <= current_time) { /* this object was supposed to have gotten a response */ /* we need to decide if we need to retry or done with it. */ if (osm_madw_req_p->retry_cnt > 0) { /* add to the list of the retrys : */ cl_list_insert_tail(&retry_madw_p_list, osm_madw_req_p); /* update wakeup time and retry count */ osm_madw_req_p->waking_time = p_vend->timeout * 1000 + cl_get_time_stamp(); osm_madw_req_p->retry_cnt--; /* make sure we will get some timer call if not earlier */ osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osm_transaction_mgr_callback : Timer restart:%u\n", p_vend->timeout); cl_status = cl_timer_start(&trans_mgr_p->madw_list_timer, p_vend->timeout); /* go to the next object and check if it also needs to be removed - didn't receive response */ /* we need to do it before we move current item to the end of the list */ p_list_next_item = cl_qlist_next(p_list_item); /* remove from the head */ cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p, &(osm_madw_req_p->list_item)); /* insert the object to the qlist and the qmap */ cl_qlist_insert_tail(trans_mgr_p->madw_reqs_list_p, &(osm_madw_req_p->list_item)); } else { /* go to the next object and check if it also needs to be removed - didn't receive response */ p_list_next_item = cl_qlist_next(p_list_item); /* remove from the head */ cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p, &(osm_madw_req_p->list_item)); /* add it to the tmp_madw_p_list to be removed */ cl_list_insert_tail(&tmp_madw_p_list, osm_madw_req_p->p_madw); osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osm_transaction_mgr_callback : Found failed transaction madw: %p\n", osm_madw_req_p->p_madw); } /* Advance */ p_list_item = p_list_next_item; if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { /* the list is empty - nothing to do */ break; } /* get the osm_madw_req_p */ osm_madw_req_p = PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item); } /* look at the current p_list_item. If it is not the end item - then we need to */ /* re-start the timer */ if (p_list_item != cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { /* get the osm_madw_req_p */ osm_madw_req_p = PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item); /* we have the object that still didn't get response - re-start the timer */ /* start the timer to the timeout (in miliseconds) */ new_timeout = (osm_madw_req_p->waking_time - cl_get_time_stamp()) / 1000 + 1; cl_status = cl_timer_start(&trans_mgr_p->madw_list_timer, new_timeout); osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osm_transaction_mgr_callback : Timer restart:%u\n", new_timeout); if (cl_status != CL_SUCCESS) { osm_log(p_vend->p_log, OSM_LOG_ERROR, "__osm_transaction_mgr_callback : ERROR 1000: " "Failed to start timer\n"); } } /* if not empty - retry on retry list: */ if (!cl_is_list_empty(&retry_madw_p_list)) { /* remove all elements that were retried: */ osm_madw_req_p = (osm_madw_req_t *) (cl_list_remove_head(&retry_madw_p_list)); while (osm_madw_req_p != NULL) { /* resend: */ osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osm_transaction_mgr_callback : " "Retry %d of madw %p\n", OSM_DEFAULT_RETRY_COUNT - osm_madw_req_p->retry_cnt, osm_madw_req_p->p_madw); /* actually send it */ #ifdef OSM_VENDOR_INTF_MTL osm_mtl_send_mad((osm_mtl_bind_info_t *) osm_madw_req_p->p_bind, osm_madw_req_p->p_madw); #else ib_api_status_t osm_ts_send_mad(osm_ts_bind_info_t * p_bind, osm_madw_t * const p_madw); osm_ts_send_mad((osm_ts_bind_info_t *) osm_madw_req_p-> p_bind, osm_madw_req_p->p_madw); #endif /* next one */ osm_madw_req_p = (osm_madw_req_t *) (cl_list_remove_head(&retry_madw_p_list)); } } /* if the tmp_madw_p_list has elements - need to call the send_err_callback */ madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list)); while (madw_p != NULL) { /* need to remove it from pool */ /* obtain the madw_p stored as the wrid in the send call */ p_mad = osm_madw_get_mad_ptr(madw_p); p_bind = madw_p->h_bind; /* Return any wrappers to the pool that may have been pre-emptively allocated to handle a receive. */ if (madw_p->vend_wrap.p_resp_madw) { #ifdef OSM_VENDOR_INTF_MTL osm_mad_pool_put(p_bind->p_osm_pool, madw_p->vend_wrap.p_resp_madw); #else osm_mad_pool_put(p_bind->p_osm_pool, madw_p->vend_wrap.p_resp_madw); #endif madw_p->vend_wrap.p_resp_madw = NULL; } /* invoke the CB */ (*(osm_vend_mad_send_err_callback_t) (p_bind->send_err_callback)) (p_bind->client_context, madw_p); madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list)); } Exit: OSM_LOG_EXIT(p_vend->p_log); }