+#include <kern/affinity.h>
+
+#include <stdatomic.h>
+
+#include <security/mac_mach_internal.h>
+
+static void act_abort(thread_t thread);
+
+static void thread_suspended(void *arg, wait_result_t result);
+static void thread_set_apc_ast(thread_t thread);
+static void thread_set_apc_ast_locked(thread_t thread);
+
+/*
+ * Internal routine to mark a thread as started.
+ * Always called with the thread mutex locked.
+ */
+void
+thread_start(
+ thread_t thread)
+{
+ clear_wait(thread, THREAD_AWAKENED);
+ thread->started = TRUE;
+}
+
+/*
+ * 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);