+}
+
+/*
+ * Internal routine to mark a thread as waiting
+ * right after it has been created. The caller
+ * is responsible to call wakeup()/thread_wakeup()
+ * or thread_terminate() to get it going.
+ *
+ * Always called with the thread mutex locked.
+ *
+ * Task and task_threads mutexes also held
+ * (so nobody can set the thread running before
+ * this point)
+ *
+ * Converts TH_UNINT wait to THREAD_INTERRUPTIBLE
+ * to allow termination from this point forward.
+ */
+void
+thread_start_in_assert_wait(
+ thread_t thread,
+ event_t event,
+ wait_interrupt_t interruptible)
+{
+ struct waitq *waitq = assert_wait_queue(event);
+ wait_result_t wait_result;
+ spl_t spl;
+
+ spl = splsched();
+ waitq_lock(waitq);
+
+ /* clear out startup condition (safe because thread not started yet) */
+ thread_lock(thread);
+ assert(!thread->started);
+ assert((thread->state & (TH_WAIT | TH_UNINT)) == (TH_WAIT | TH_UNINT));
+ thread->state &= ~(TH_WAIT | TH_UNINT);
+ thread_unlock(thread);
+
+ /* assert wait interruptibly forever */
+ wait_result = waitq_assert_wait64_locked(waitq, CAST_EVENT64_T(event),
+ interruptible,
+ TIMEOUT_URGENCY_SYS_NORMAL,
+ TIMEOUT_WAIT_FOREVER,
+ TIMEOUT_NO_LEEWAY,
+ thread);
+ assert(wait_result == THREAD_WAITING);
+
+ /* mark thread started while we still hold the waitq lock */
+ thread_lock(thread);
+ thread->started = TRUE;
+ thread_unlock(thread);
+
+ waitq_unlock(waitq);
+ splx(spl);