static void *psmx2_progress_func(void *args) { struct psmx2_fid_domain *domain = args; int affinity_set; int sleep_usec; struct timespec ts; FI_INFO(&psmx2_prov, FI_LOG_CORE, "\n"); affinity_set = psmx2_progress_set_affinity(psmx2_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 = psmx2_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) { psmx2_progress(domain); nanosleep(&ts, NULL); } return NULL; }
static uint64_t psmx2_cntr_read(struct fid_cntr *cntr) { struct psmx2_fid_cntr *cntr_priv; static int poll_cnt = 0; cntr_priv = container_of(cntr, struct psmx2_fid_cntr, cntr); if (poll_cnt++ == PSMX2_CNTR_POLL_THRESHOLD) { psmx2_progress(cntr_priv->domain); poll_cnt = 0; } return atomic_get(&cntr_priv->counter); }
static int psmx2_cntr_wait(struct fid_cntr *cntr, uint64_t threshold, int timeout) { struct psmx2_fid_cntr *cntr_priv; struct timespec ts0, ts; int msec_passed = 0; int ret = 0; cntr_priv = container_of(cntr, struct psmx2_fid_cntr, cntr); clock_gettime(CLOCK_REALTIME, &ts0); while (cntr_priv->counter < threshold) { if (cntr_priv->wait) { ret = psmx2_wait_wait((struct fid_wait *)cntr_priv->wait, timeout - msec_passed); if (ret == -FI_ETIMEDOUT) break; } else { psmx2_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; }