static void *mca_btl_ugni_prog_thread_fn(void * data) { uint32_t which; gni_return_t status; gni_cq_handle_t cq_vec[2]; struct mca_btl_ugni_module_t *btl = (mca_btl_ugni_module_t *)data; /* * need to block signals */ cq_vec[0] = btl->smsg_remote_irq_cq; cq_vec[1] = btl->rdma_local_irq_cq; while (stop_progress_thread == 0) { /* * this ugni call doesn't need a lock */ status = GNI_CqVectorMonitor(cq_vec, 2, -1, &which); if (status == GNI_RC_NOT_DONE) continue; if ((status == GNI_RC_SUCCESS) && (stop_progress_thread == 0)) { mca_btl_ugni_progress_thread_wakeups++; opal_progress(); } } return (void *) (intptr_t) OPAL_SUCCESS; }
/* * this function is intended to be invoked as an argument to pthread_create, */ static void *__gnix_nic_prog_thread_fn(void *the_arg) { int ret = FI_SUCCESS, prev_state; int retry = 0; uint32_t which; struct gnix_nic *nic = (struct gnix_nic *)the_arg; sigset_t sigmask; gni_cq_handle_t cqv[2]; gni_return_t status; gni_cq_entry_t cqe; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); /* * temporarily disable cancelability while we set up * some stuff */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &prev_state); /* * help out Cray core-spec, say we're not an app thread * and can be run on core-spec cpus. */ ret = _gnix_task_is_not_app(); if (ret) GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_task_is_not_app call returned %d\n", ret); /* * block all signals, don't want this thread to catch * signals that may be for app threads */ memset(&sigmask, 0, sizeof(sigset_t)); ret = sigfillset(&sigmask); if (ret) { GNIX_WARN(FI_LOG_EP_CTRL, "sigfillset call returned %d\n", ret); } else { ret = pthread_sigmask(SIG_SETMASK, &sigmask, NULL); if (ret) GNIX_WARN(FI_LOG_EP_CTRL, "pthread_sigmask call returned %d\n", ret); } /* * okay now we're ready to be cancelable. */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &prev_state); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); cqv[0] = nic->tx_cq_blk; cqv[1] = nic->rx_cq_blk; try_again: status = GNI_CqVectorMonitor(cqv, 2, -1, &which); switch (status) { case GNI_RC_SUCCESS: /* * first dequeue RX CQEs */ if (which == 1) { do { status = GNI_CqGetEvent(nic->rx_cq_blk, &cqe); } while (status == GNI_RC_SUCCESS); } _gnix_nic_progress(nic); retry = 1; break; case GNI_RC_TIMEOUT: retry = 1; break; case GNI_RC_NOT_DONE: retry = 1; break; case GNI_RC_INVALID_PARAM: case GNI_RC_INVALID_STATE: case GNI_RC_ERROR_RESOURCE: case GNI_RC_ERROR_NOMEM: retry = 0; GNIX_WARN(FI_LOG_EP_CTRL, "GNI_CqGetEvent returned %s\n", gni_err_str[status]); break; default: retry = 0; GNIX_WARN(FI_LOG_EP_CTRL, "GNI_CqGetEvent returned unexpected code %s\n", gni_err_str[status]); break; } if (retry) goto try_again; return NULL; }