+ *qp->sq_tailp = p;
+ *(qp->sq_tailp = &p->p_link) = 0;
+ if (timo)
+ timeout(endtsleep, (void *)p, timo);
+ /*
+ * We put ourselves on the sleep queue and start our timeout
+ * before calling CURSIG, as we could stop there, and a wakeup
+ * or a SIGCONT (or both) could occur while we were stopped.
+ * A SIGCONT would cause us to be marked as SSLEEP
+ * without resuming us, thus we must be ready for sleep
+ * when CURSIG is called. If the wakeup happens while we're
+ * stopped, p->p_wchan will be 0 upon return from CURSIG.
+ */
+ if (catch) {
+ p->p_flag |= SSINTR;
+ if (sig = CURSIG(p)) {
+ if (p->p_wchan)
+ unsleep(p);
+ p->p_stat = SRUN;
+ goto resume;
+ }
+ if (p->p_wchan == 0) {
+ catch = 0;
+ goto resume;
+ }
+ } else
+ sig = 0;
+ p->p_stat = SSLEEP;
+ p->p_stats->p_ru.ru_nvcsw++;
+ swtch();
+resume:
+ curpri = p->p_usrpri;
+ splx(s);
+ p->p_flag &= ~SSINTR;
+ if (p->p_flag & STIMO) {
+ p->p_flag &= ~STIMO;
+ if (sig == 0) {
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_CSW))
+ ktrcsw(p->p_tracep, 0, 0);
+#endif
+ return (EWOULDBLOCK);
+ }
+ } else if (timo)
+ untimeout(endtsleep, (void *)p);
+ if (catch && (sig != 0 || (sig = CURSIG(p)))) {
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_CSW))
+ ktrcsw(p->p_tracep, 0, 0);
+#endif
+ if (p->p_sigacts->ps_sigintr & sigmask(sig))
+ return (EINTR);
+ return (ERESTART);
+ }
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_CSW))
+ ktrcsw(p->p_tracep, 0, 0);
+#endif
+ return (0);
+}
+
+/*
+ * Implement timeout for tsleep.
+ * If process hasn't been awakened (wchan non-zero),
+ * set timeout flag and undo the sleep. If proc
+ * is stopped, just unsleep so it will remain stopped.
+ */
+void
+endtsleep(arg)
+ void *arg;
+{
+ register struct proc *p;
+ int s;
+
+ p = (struct proc *)arg;
+ s = splhigh();
+ if (p->p_wchan) {
+ if (p->p_stat == SSLEEP)
+ setrun(p);
+ else
+ unsleep(p);
+ p->p_flag |= STIMO;
+ }
+ splx(s);
+}
+
+/*
+ * Short-term, non-interruptable sleep.
+ */
+void
+sleep(chan, pri)
+ void *chan;
+ int pri;
+{
+ register struct proc *p = curproc;
+ register struct slpque *qp;
+ register s;
+ extern int cold;
+
+#ifdef DIAGNOSTIC