+/*
+ * Sleep on chan at pri.
+ * Return in no more than the indicated number of seconds.
+ * (If seconds==0, no timeout implied)
+ * Return TS_OK if chan was awakened normally
+ * TS_TIME if timeout occurred
+ * TS_SIG if asynchronous signal occurred
+ *
+ * SHOULD HAVE OPTION TO SLEEP TO ABSOLUTE TIME OR AN
+ * INCREMENT IN MILLISECONDS!
+ */
+tsleep(chan, pri, seconds)
+ caddr_t chan;
+ int pri, seconds;
+{
+ label_t lqsav;
+ register struct proc *pp;
+ register sec, n, rval;
+
+ pp = u.u_procp;
+ n = spl7();
+ sec = 0;
+ rval = 0;
+ if (pp->p_clktim && pp->p_clktim<seconds)
+ seconds = 0;
+ if (seconds) {
+ pp->p_flag |= STIMO;
+ sec = pp->p_clktim-seconds;
+ pp->p_clktim = seconds;
+ }
+ bcopy((caddr_t)u.u_qsav, (caddr_t)lqsav, sizeof (label_t));
+ if (setjmp(u.u_qsav))
+ rval = TS_SIG;
+ else {
+ sleep(chan, pri);
+ if ((pp->p_flag&STIMO)==0 && seconds)
+ rval = TS_TIME;
+ else
+ rval = TS_OK;
+ }
+ pp->p_flag &= ~STIMO;
+ bcopy((caddr_t)lqsav, (caddr_t)u.u_qsav, sizeof (label_t));
+ if (sec > 0)
+ pp->p_clktim += sec;
+ else
+ pp->p_clktim = 0;
+ splx(n);
+ return (rval);
+}
+
+/*
+ * Remove a process from its wait queue
+ */
+unsleep(p)
+ register struct proc *p;
+{
+ register struct proc **hp;
+ register s;
+
+ s = spl6();
+ if (p->p_wchan) {
+ hp = &slpque[HASH(p->p_wchan)];
+ while (*hp != p)
+ hp = &(*hp)->p_link;
+ *hp = p->p_link;
+ p->p_wchan = 0;
+ }
+ splx(s);
+}
+