+#ifdef __KERNEL__
+
+static int
+lnet_eq_wait_locked(int *timeout_ms)
+{
+ int tms = *timeout_ms;
+ int wait;
+ cfs_waitlink_t wl;
+ cfs_time_t now;
+
+ if (tms == 0)
+ return -1; /* don't want to wait and no new event */
+
+ cfs_waitlink_init(&wl);
+ cfs_set_current_state(CFS_TASK_INTERRUPTIBLE);
+ cfs_waitq_add(&the_lnet.ln_eq_waitq, &wl);
+
+ LNET_UNLOCK();
+
+ if (tms < 0) {
+ cfs_waitq_wait(&wl, CFS_TASK_INTERRUPTIBLE);
+
+ } else {
+ struct timeval tv;
+
+ now = cfs_time_current();
+ cfs_waitq_timedwait(&wl, CFS_TASK_INTERRUPTIBLE,
+ cfs_time_seconds(tms) / 1000);
+ cfs_duration_usec(cfs_time_sub(cfs_time_current(), now), &tv);
+ tms -= (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
+ if (tms < 0) /* no more wait but may have new event */
+ tms = 0;
+ }
+
+ wait = tms != 0; /* might need to call here again */
+ *timeout_ms = tms;
+
+ LNET_LOCK();
+ cfs_waitq_del(&the_lnet.ln_eq_waitq, &wl);
+
+ return wait;
+}
+
+#else /* !__KERNEL__ */
+
+# ifdef HAVE_LIBPTHREAD
+static void
+lnet_eq_cond_wait(struct timespec *ts)
+{
+ if (ts == NULL) {
+ pthread_cond_wait(&the_lnet.ln_eq_cond, &the_lnet.ln_lock);
+ } else {
+ pthread_cond_timedwait(&the_lnet.ln_eq_cond,
+ &the_lnet.ln_lock, ts);
+ }
+}
+# endif
+
+static int
+lnet_eq_wait_locked(int *timeout_ms)
+{
+ lnet_ni_t *eq_waitni = NULL;
+ int tms = *timeout_ms;
+ int wait;
+ struct timeval then;
+ struct timeval now;
+
+ if (the_lnet.ln_eq_waitni != NULL) {
+ /* I have a single NI that I have to call into, to get
+ * events queued, or to block. */
+ eq_waitni = the_lnet.ln_eq_waitni;
+ lnet_ni_addref_locked(eq_waitni);
+
+ LNET_UNLOCK();
+
+ if (tms <= 0) { /* even for tms == 0 */
+ (eq_waitni->ni_lnd->lnd_wait)(eq_waitni, tms);
+
+ } else {
+ gettimeofday(&then, NULL);
+
+ (eq_waitni->ni_lnd->lnd_wait)(eq_waitni, tms);
+
+ gettimeofday(&now, NULL);
+ tms -= (now.tv_sec - then.tv_sec) * 1000 +
+ (now.tv_usec - then.tv_usec) / 1000;
+ if (tms < 0)
+ tms = 0;
+ }
+
+ LNET_LOCK();
+ lnet_ni_decref_locked(eq_waitni);
+ } else { /* w/o eq_waitni */
+# ifndef HAVE_LIBPTHREAD
+ /* If I'm single-threaded, LNET fails at startup if it can't
+ * set the_lnet.ln_eqwaitni correctly. */
+ LBUG();
+# else /* HAVE_LIBPTHREAD */
+ struct timespec ts;
+
+ if (tms == 0) /* don't want to wait and new event */
+ return -1;
+
+ if (tms < 0) {
+ lnet_eq_cond_wait(NULL);
+
+ } else {
+
+ gettimeofday(&then, NULL);
+
+ ts.tv_sec = then.tv_sec + tms / 1000;
+ ts.tv_nsec = then.tv_usec * 1000 +
+ (tms % 1000) * 1000000;
+ if (ts.tv_nsec >= 1000000000) {
+ ts.tv_sec++;
+ ts.tv_nsec -= 1000000000;
+ }
+
+ lnet_eq_cond_wait(&ts);
+
+ gettimeofday(&now, NULL);
+ tms -= (now.tv_sec - then.tv_sec) * 1000 +
+ (now.tv_usec - then.tv_usec) / 1000;
+ if (tms < 0)
+ tms = 0;
+ }
+# endif /* HAVE_LIBPTHREAD */
+ }
+
+ wait = tms != 0;
+ *timeout_ms = tms;
+
+ return wait;
+}
+
+#endif /* __KERNEL__ */
+
+