static void *psmx_progress_func(void *args) { struct psmx_fid_domain *domain = args; int affinity_set; int sleep_usec; struct timespec ts; FI_INFO(&psmx_prov, FI_LOG_CORE, "\n"); affinity_set = psmx_progress_set_affinity(psmx_env.prog_affinity); /* Negative sleep time means let the system choose the default. * If affinity is set, sleep a short time to get better latency. * If affinity is not set, short sleep time doesn't make difference. */ sleep_usec = psmx_env.prog_interval; if (sleep_usec < 0) { if (affinity_set) sleep_usec = 1; else sleep_usec = 1000; } ts.tv_sec = sleep_usec / 1000000; ts.tv_nsec = (sleep_usec % 1000000) * 1000; while (1) { psmx_progress(domain); nanosleep(&ts, NULL); } return NULL; }
static void *psmx_wait_progress(void *args) { struct psmx_fid_domain *domain = args; psmx_wait_thread_ready = 1; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); while (1) { pthread_mutex_lock(&psmx_wait_mutex); if (!psmx_wait_thread_enabled) pthread_cond_wait(&psmx_wait_cond, &psmx_wait_mutex); pthread_mutex_unlock(&psmx_wait_mutex); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); psmx_wait_thread_busy = 1; while (psmx_wait_thread_enabled) psmx_progress(domain); psmx_wait_thread_busy = 0; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } return NULL; }
static uint64_t psmx_cntr_read(struct fid_cntr *cntr) { struct psmx_fid_cntr *cntr_priv; static int poll_cnt = 0; cntr_priv = container_of(cntr, struct psmx_fid_cntr, cntr); if (poll_cnt++ == PSMX_CNTR_POLL_THRESHOLD) { psmx_progress(cntr_priv->domain); poll_cnt = 0; } return ofi_atomic_get64(&cntr_priv->counter); }
static uint64_t psmx_cntr_read(struct fid_cntr *cntr) { struct psmx_fid_cntr *cntr_priv; static int poll_cnt = 0; cntr_priv = container_of(cntr, struct psmx_fid_cntr, cntr); if (poll_cnt++ == PSMX_CNTR_POLL_THRESHOLD) { psmx_progress(cntr_priv->domain); poll_cnt = 0; } cntr_priv->counter_last_read = cntr_priv->counter; return cntr_priv->counter_last_read; }
static int psmx_cntr_wait(struct fid_cntr *cntr, uint64_t threshold, int timeout) { struct psmx_fid_cntr *cntr_priv; struct timespec ts0, ts; int msec_passed = 0; int ret = 0; cntr_priv = container_of(cntr, struct psmx_fid_cntr, cntr); clock_gettime(CLOCK_REALTIME, &ts0); while (cntr_priv->counter < threshold) { if (cntr_priv->wait) { ret = psmx_wait_wait((struct fid_wait *)cntr_priv->wait, timeout - msec_passed); if (ret == -FI_ETIMEDOUT) break; } else { psmx_progress(cntr_priv->domain); } if (cntr_priv->counter >= threshold) break; if (timeout < 0) continue; clock_gettime(CLOCK_REALTIME, &ts); msec_passed = (ts.tv_sec - ts0.tv_sec) * 1000 + (ts.tv_nsec - ts0.tv_nsec) / 1000000; if (msec_passed >= timeout) { ret = -FI_ETIMEDOUT; break; } } return ret; }