]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/thread_act.c
xnu-4903.270.47.tar.gz
[apple/xnu.git] / osfmk / kern / thread_act.c
index 3bd8b51829f748ea422e7c7040e9e476e984ade1..c93dda8e30ddad37935ad1d6390f52e418ac5fe8 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
@@ -49,6 +49,7 @@
  *
  *     Thread management routines
  */
+
 #include <mach/mach_types.h>
 #include <mach/kern_return.h>
 #include <mach/thread_act_server.h>
@@ -90,7 +91,7 @@ static void thread_set_apc_ast_locked(thread_t thread);
  */
 void
 thread_start(
-       thread_t                        thread)
+       thread_t                        thread)
 {
        clear_wait(thread, THREAD_AWAKENED);
        thread->started = TRUE;
@@ -104,7 +105,7 @@ thread_start(
  *
  * Always called with the thread mutex locked.
  *
- * Task and task_threads mutexes also held 
+ * Task and task_threads mutexes also held
  * (so nobody can set the thread running before
  * this point)
  *
@@ -113,7 +114,7 @@ thread_start(
  */
 void
 thread_start_in_assert_wait(
-       thread_t                        thread,
+       thread_t                        thread,
        event_t             event,
        wait_interrupt_t    interruptible)
 {
@@ -133,12 +134,12 @@ thread_start_in_assert_wait(
 
        /* 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);
+           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);
@@ -155,9 +156,9 @@ thread_start_in_assert_wait(
  */
 kern_return_t
 thread_terminate_internal(
-       thread_t                        thread)
+       thread_t                        thread)
 {
-       kern_return_t           result = KERN_SUCCESS;
+       kern_return_t           result = KERN_SUCCESS;
 
        thread_mtx_lock(thread);
 
@@ -166,24 +167,26 @@ thread_terminate_internal(
 
                act_abort(thread);
 
-               if (thread->started)
+               if (thread->started) {
                        clear_wait(thread, THREAD_INTERRUPTED);
-               else {
+               else {
                        thread_start(thread);
                }
-       }
-       else
+       } else {
                result = KERN_TERMINATED;
+       }
 
-       if (thread->affinity_set != NULL)
+       if (thread->affinity_set != NULL) {
                thread_affinity_terminate(thread);
+       }
 
        thread_mtx_unlock(thread);
 
-       if (thread != current_thread() && result == KERN_SUCCESS)
+       if (thread != current_thread() && result == KERN_SUCCESS) {
                thread_wait(thread, FALSE);
+       }
 
-       return (result);
+       return result;
 }
 
 /*
@@ -191,14 +194,16 @@ thread_terminate_internal(
  */
 kern_return_t
 thread_terminate(
-       thread_t                thread)
+       thread_t                thread)
 {
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        /* Kernel threads can't be terminated without their own cooperation */
-       if (thread->task == kernel_task && thread != current_thread())
-               return (KERN_FAILURE);
+       if (thread->task == kernel_task && thread != current_thread()) {
+               return KERN_FAILURE;
+       }
 
        kern_return_t result = thread_terminate_internal(thread);
 
@@ -216,7 +221,7 @@ thread_terminate(
                /* NOTREACHED */
        }
 
-       return (result);
+       return result;
 }
 
 /*
@@ -250,8 +255,9 @@ thread_release(thread_t thread)
        assertf(thread->suspend_count > 0, "thread %p over-resumed", thread);
 
        /* fail-safe on non-assert builds */
-       if (thread->suspend_count == 0)
+       if (thread->suspend_count == 0) {
                return;
+       }
 
        if (--thread->suspend_count == 0) {
                if (!thread->started) {
@@ -268,24 +274,27 @@ thread_suspend(thread_t thread)
 {
        kern_return_t result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL || thread->task == kernel_task)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL || thread->task == kernel_task) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
        if (thread->active) {
-               if (thread->user_stop_count++ == 0)
+               if (thread->user_stop_count++ == 0) {
                        thread_hold(thread);
+               }
        } else {
                result = KERN_TERMINATED;
        }
 
        thread_mtx_unlock(thread);
 
-       if (thread != current_thread() && result == KERN_SUCCESS)
+       if (thread != current_thread() && result == KERN_SUCCESS) {
                thread_wait(thread, FALSE);
+       }
 
-       return (result);
+       return result;
 }
 
 kern_return_t
@@ -293,15 +302,17 @@ thread_resume(thread_t thread)
 {
        kern_return_t result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL || thread->task == kernel_task)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL || thread->task == kernel_task) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
        if (thread->active) {
                if (thread->user_stop_count > 0) {
-                       if (--thread->user_stop_count == 0)
+                       if (--thread->user_stop_count == 0) {
                                thread_release(thread);
+                       }
                } else {
                        result = KERN_FAILURE;
                }
@@ -311,33 +322,34 @@ thread_resume(thread_t thread)
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
 /*
- *     thread_depress_abort:
+ *     thread_depress_abort_from_user:
  *
  *     Prematurely abort priority depression if there is one.
  */
 kern_return_t
-thread_depress_abort(
-       thread_t        thread)
+thread_depress_abort_from_user(thread_t thread)
 {
-       kern_return_t           result;
+       kern_return_t result;
 
-    if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
-    thread_mtx_lock(thread);
+       thread_mtx_lock(thread);
 
-       if (thread->active)
-               result = thread_depress_abort_internal(thread);
-       else
+       if (thread->active) {
+               result = thread_depress_abort(thread);
+       } else {
                result = KERN_TERMINATED;
+       }
 
-    thread_mtx_unlock(thread);
+       thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
 
@@ -349,15 +361,16 @@ thread_depress_abort(
  */
 static void
 act_abort(
-       thread_t        thread)
+       thread_t        thread)
 {
-       spl_t           s = splsched();
+       spl_t           s = splsched();
 
        thread_lock(thread);
 
        if (!(thread->sched_flags & TH_SFLAG_ABORT)) {
                thread->sched_flags |= TH_SFLAG_ABORT;
                thread_set_apc_ast_locked(thread);
+               thread_depress_abort_locked(thread);
        } else {
                thread->sched_flags &= ~TH_SFLAG_ABORTSAFELY;
        }
@@ -368,47 +381,50 @@ act_abort(
 
 kern_return_t
 thread_abort(
-       thread_t        thread)
+       thread_t        thread)
 {
-       kern_return_t   result = KERN_SUCCESS;
+       kern_return_t   result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
        if (thread->active) {
                act_abort(thread);
                clear_wait(thread, THREAD_INTERRUPTED);
-       }
-       else
+       } else {
                result = KERN_TERMINATED;
+       }
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
 kern_return_t
 thread_abort_safely(
-       thread_t                thread)
+       thread_t                thread)
 {
-       kern_return_t   result = KERN_SUCCESS;
+       kern_return_t   result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
        if (thread->active) {
-               spl_t           s = splsched();
+               spl_t           s = splsched();
 
                thread_lock(thread);
                if (!thread->at_safe_point ||
-                               clear_wait_internal(thread, THREAD_INTERRUPTED) != KERN_SUCCESS) {
+                   clear_wait_internal(thread, THREAD_INTERRUPTED) != KERN_SUCCESS) {
                        if (!(thread->sched_flags & TH_SFLAG_ABORT)) {
                                thread->sched_flags |= TH_SFLAG_ABORTED_MASK;
                                thread_set_apc_ast_locked(thread);
+                               thread_depress_abort_locked(thread);
                        }
                }
                thread_unlock(thread);
@@ -419,7 +435,7 @@ thread_abort_safely(
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
 /*** backward compatibility hacks ***/
@@ -429,40 +445,44 @@ thread_abort_safely(
 
 kern_return_t
 thread_info(
-       thread_t                        thread,
-       thread_flavor_t                 flavor,
-       thread_info_t                   thread_info_out,
-       mach_msg_type_number_t  *thread_info_count)
+       thread_t                        thread,
+       thread_flavor_t                 flavor,
+       thread_info_t                   thread_info_out,
+       mach_msg_type_number_t  *thread_info_count)
 {
-       kern_return_t                   result;
+       kern_return_t                   result;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
-       if (thread->active || thread->inspection)
+       if (thread->active || thread->inspection) {
                result = thread_info_internal(
-                                               thread, flavor, thread_info_out, thread_info_count);
-       else
+                       thread, flavor, thread_info_out, thread_info_count);
+       } else {
                result = KERN_TERMINATED;
+       }
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
-kern_return_t
-thread_get_state(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  state,                  /* pointer to OUT array */
-       mach_msg_type_number_t  *state_count)   /*IN/OUT*/
+static inline kern_return_t
+thread_get_state_internal(
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,                  /* pointer to OUT array */
+       mach_msg_type_number_t  *state_count,   /*IN/OUT*/
+       boolean_t                               to_user)
 {
-       kern_return_t           result = KERN_SUCCESS;
+       kern_return_t           result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
@@ -475,53 +495,92 @@ thread_get_state(
                        if (thread_stop(thread, FALSE)) {
                                thread_mtx_lock(thread);
                                result = machine_thread_get_state(
-                                                                               thread, flavor, state, state_count);
+                                       thread, flavor, state, state_count);
                                thread_unstop(thread);
-                       }
-                       else {
+                       } else {
                                thread_mtx_lock(thread);
                                result = KERN_ABORTED;
                        }
 
                        thread_release(thread);
-               }
-               else
+               } else {
                        result = machine_thread_get_state(
-                                                                       thread, flavor, state, state_count);
-       }
-       else if (thread->inspection)
-       {
+                               thread, flavor, state, state_count);
+               }
+       } else if (thread->inspection) {
                result = machine_thread_get_state(
-                                                                       thread, flavor, state, state_count);
-       }
-       else
+                       thread, flavor, state, state_count);
+       } else {
                result = KERN_TERMINATED;
+       }
+
+       if (to_user && result == KERN_SUCCESS) {
+               result = machine_thread_state_convert_to_user(thread, flavor, state,
+                   state_count);
+       }
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
+}
+
+/* No prototype, since thread_act_server.h has the _to_user version if KERNEL_SERVER */
+
+kern_return_t
+thread_get_state(
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  *state_count);
+
+kern_return_t
+thread_get_state(
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,                  /* pointer to OUT array */
+       mach_msg_type_number_t  *state_count)   /*IN/OUT*/
+{
+       return thread_get_state_internal(thread, flavor, state, state_count, FALSE);
+}
+
+kern_return_t
+thread_get_state_to_user(
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,                  /* pointer to OUT array */
+       mach_msg_type_number_t  *state_count)   /*IN/OUT*/
+{
+       return thread_get_state_internal(thread, flavor, state, state_count, TRUE);
 }
 
 /*
  *     Change thread's machine-dependent state.  Called with nothing
  *     locked.  Returns same way.
  */
-static kern_return_t
+static inline kern_return_t
 thread_set_state_internal(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  state_count,
-       boolean_t                               from_user)
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  state_count,
+       boolean_t                               from_user)
 {
-       kern_return_t           result = KERN_SUCCESS;
+       kern_return_t           result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
        if (thread->active) {
+               if (from_user) {
+                       result = machine_thread_state_convert_from_user(thread, flavor,
+                           state, state_count);
+                       if (result != KERN_SUCCESS) {
+                               goto out;
+                       }
+               }
                if (thread != current_thread()) {
                        thread_hold(thread);
 
@@ -530,59 +589,60 @@ thread_set_state_internal(
                        if (thread_stop(thread, TRUE)) {
                                thread_mtx_lock(thread);
                                result = machine_thread_set_state(
-                                                                               thread, flavor, state, state_count);
+                                       thread, flavor, state, state_count);
                                thread_unstop(thread);
-                       }
-                       else {
+                       } else {
                                thread_mtx_lock(thread);
                                result = KERN_ABORTED;
                        }
 
                        thread_release(thread);
-               }
-               else
+               } else {
                        result = machine_thread_set_state(
-                                                                       thread, flavor, state, state_count);
-       }
-       else
+                               thread, flavor, state, state_count);
+               }
+       } else {
                result = KERN_TERMINATED;
+       }
 
-       if ((result == KERN_SUCCESS) && from_user)
+       if ((result == KERN_SUCCESS) && from_user) {
                extmod_statistics_incr_thread_set_state(thread);
+       }
 
+out:
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
-/* No prototype, since thread_act_server.h has the _from_user version if KERNEL_SERVER */ 
+/* No prototype, since thread_act_server.h has the _from_user version if KERNEL_SERVER */
 kern_return_t
 thread_set_state(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  state_count);
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  state_count);
 
 kern_return_t
 thread_set_state(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  state_count)
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  state_count)
 {
        return thread_set_state_internal(thread, flavor, state, state_count, FALSE);
 }
+
 kern_return_t
 thread_set_state_from_user(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  state_count)
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  state_count)
 {
        return thread_set_state_internal(thread, flavor, state, state_count, TRUE);
 }
+
 /*
  * Kernel-internal "thread" interfaces used outside this file:
  */
@@ -592,12 +652,13 @@ thread_set_state_from_user(
  */
 kern_return_t
 thread_state_initialize(
-       thread_t                thread)
+       thread_t                thread)
 {
-       kern_return_t           result = KERN_SUCCESS;
+       kern_return_t           result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
@@ -611,35 +672,35 @@ thread_state_initialize(
                                thread_mtx_lock(thread);
                                result = machine_thread_state_initialize( thread );
                                thread_unstop(thread);
-                       }
-                       else {
+                       } else {
                                thread_mtx_lock(thread);
                                result = KERN_ABORTED;
                        }
 
                        thread_release(thread);
-               }
-               else
+               } else {
                        result = machine_thread_state_initialize( thread );
-       }
-       else
+               }
+       } else {
                result = KERN_TERMINATED;
+       }
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
 
 kern_return_t
 thread_dup(
-       thread_t        target)
+       thread_t        target)
 {
-       thread_t                        self = current_thread();
-       kern_return_t           result = KERN_SUCCESS;
+       thread_t                        self = current_thread();
+       kern_return_t           result = KERN_SUCCESS;
 
-       if (target == THREAD_NULL || target == self)
-               return (KERN_INVALID_ARGUMENT);
+       if (target == THREAD_NULL || target == self) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(target);
 
@@ -650,37 +711,39 @@ thread_dup(
 
                if (thread_stop(target, TRUE)) {
                        thread_mtx_lock(target);
-                       result = machine_thread_dup(self, target);
-                       if (self->affinity_set != AFFINITY_SET_NULL)
+                       result = machine_thread_dup(self, target, FALSE);
+
+                       if (self->affinity_set != AFFINITY_SET_NULL) {
                                thread_affinity_dup(self, target);
+                       }
                        thread_unstop(target);
-               }
-               else {
+               } else {
                        thread_mtx_lock(target);
                        result = KERN_ABORTED;
                }
 
                thread_release(target);
-       }
-       else
+       } else {
                result = KERN_TERMINATED;
+       }
 
        thread_mtx_unlock(target);
 
-       return (result);
+       return result;
 }
 
 
 kern_return_t
 thread_dup2(
-       thread_t        source,
-       thread_t        target)
+       thread_t        source,
+       thread_t        target)
 {
-       kern_return_t           result = KERN_SUCCESS;
-       uint32_t                active = 0;
+       kern_return_t           result = KERN_SUCCESS;
+       uint32_t                active = 0;
 
-       if (source == THREAD_NULL || target == THREAD_NULL || target == source)
-               return (KERN_INVALID_ARGUMENT);
+       if (source == THREAD_NULL || target == THREAD_NULL || target == source) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(source);
        active = source->active;
@@ -699,24 +762,24 @@ thread_dup2(
 
                if (thread_stop(target, TRUE)) {
                        thread_mtx_lock(target);
-                       result = machine_thread_dup(source, target);
-                       if (source->affinity_set != AFFINITY_SET_NULL)
+                       result = machine_thread_dup(source, target, TRUE);
+                       if (source->affinity_set != AFFINITY_SET_NULL) {
                                thread_affinity_dup(source, target);
+                       }
                        thread_unstop(target);
-               }
-               else {
+               } else {
                        thread_mtx_lock(target);
                        result = KERN_ABORTED;
                }
 
                thread_release(target);
-       }
-       else
+       } else {
                result = KERN_TERMINATED;
+       }
 
        thread_mtx_unlock(target);
 
-       return (result);
+       return result;
 }
 
 /*
@@ -727,13 +790,22 @@ thread_dup2(
  */
 kern_return_t
 thread_setstatus(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  tstate,
-       mach_msg_type_number_t  count)
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  count)
 {
+       return thread_set_state(thread, flavor, tstate, count);
+}
 
-       return (thread_set_state(thread, flavor, tstate, count));
+kern_return_t
+thread_setstatus_from_user(
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  count)
+{
+       return thread_set_state_from_user(thread, flavor, tstate, count);
 }
 
 /*
@@ -743,12 +815,22 @@ thread_setstatus(
  */
 kern_return_t
 thread_getstatus(
-       thread_t                thread,
-       int                                             flavor,
-       thread_state_t                  tstate,
-       mach_msg_type_number_t  *count)
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  *count)
+{
+       return thread_get_state(thread, flavor, tstate, count);
+}
+
+kern_return_t
+thread_getstatus_to_user(
+       thread_t                thread,
+       int                                             flavor,
+       thread_state_t                  tstate,
+       mach_msg_type_number_t  *count)
 {
-       return (thread_get_state(thread, flavor, tstate, count));
+       return thread_get_state_to_user(thread, flavor, tstate, count);
 }
 
 /*
@@ -757,13 +839,14 @@ thread_getstatus(
  */
 kern_return_t
 thread_set_tsd_base(
-       thread_t                        thread,
-       mach_vm_offset_t        tsd_base)
+       thread_t                        thread,
+       mach_vm_offset_t        tsd_base)
 {
-       kern_return_t           result = KERN_SUCCESS;
+       kern_return_t           result = KERN_SUCCESS;
 
-       if (thread == THREAD_NULL)
-               return (KERN_INVALID_ARGUMENT);
+       if (thread == THREAD_NULL) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
        thread_mtx_lock(thread);
 
@@ -777,23 +860,22 @@ thread_set_tsd_base(
                                thread_mtx_lock(thread);
                                result = machine_thread_set_tsd_base(thread, tsd_base);
                                thread_unstop(thread);
-                       }
-                       else {
+                       } else {
                                thread_mtx_lock(thread);
                                result = KERN_ABORTED;
                        }
 
                        thread_release(thread);
-               }
-               else
+               } else {
                        result = machine_thread_set_tsd_base(thread, tsd_base);
-       }
-       else
+               }
+       } else {
                result = KERN_TERMINATED;
+       }
 
        thread_mtx_unlock(thread);
 
-       return (result);
+       return result;
 }
 
 /*
@@ -826,16 +908,6 @@ thread_set_apc_ast(thread_t thread)
 static void
 thread_set_apc_ast_locked(thread_t thread)
 {
-       /*
-        * Temporarily undepress, so target has
-        * a chance to do locking required to
-        * block itself in thread_suspended.
-        *
-        * Leaves the depress flag set so we can reinstate when it's blocked.
-        */
-       if (thread->sched_flags & TH_SFLAG_DEPRESSED_MASK)
-               thread_recompute_sched_pri(thread, TRUE);
-
        thread_ast_set(thread, AST_APC);
 
        if (thread == current_thread()) {
@@ -861,9 +933,7 @@ thread_set_apc_ast_locked(thread_t thread)
  *
  * Continuation routine for thread suspension.  It checks
  * to see whether there has been any new suspensions.  If so, it
- * installs the AST_APC handler again.  Otherwise, it checks to see
- * if the current depression needs to be re-instated (it may have
- * been temporarily removed in order to get to this point in a hurry).
+ * installs the AST_APC handler again.
  */
 __attribute__((noreturn))
 static void
@@ -873,31 +943,14 @@ thread_suspended(__unused void *parameter, wait_result_t result)
 
        thread_mtx_lock(thread);
 
-       if (result == THREAD_INTERRUPTED)
+       if (result == THREAD_INTERRUPTED) {
                thread->suspend_parked = FALSE;
-       else
+       } else {
                assert(thread->suspend_parked == FALSE);
+       }
 
        if (thread->suspend_count > 0) {
                thread_set_apc_ast(thread);
-       } else {
-               spl_t s = splsched();
-
-               thread_lock(thread);
-               if (thread->sched_flags & TH_SFLAG_DEPRESSED_MASK) {
-                       thread->sched_pri = DEPRESSPRI;
-                       thread->last_processor->current_pri = thread->sched_pri;
-                       thread->last_processor->current_perfctl_class = thread_get_perfcontrol_class(thread);
-
-                       KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED, MACH_SCHED_CHANGE_PRIORITY),
-                                             (uintptr_t)thread_tid(thread),
-                                             thread->base_pri,
-                                             thread->sched_pri,
-                                             0, /* eventually, 'reason' */
-                                             0);
-               }
-               thread_unlock(thread);
-               splx(s);
        }
 
        thread_mtx_unlock(thread);
@@ -938,7 +991,8 @@ thread_apc_ast(thread_t thread)
        /* If we're suspended, go to sleep and wait for someone to wake us up. */
        if (thread->suspend_count > 0) {
                thread->suspend_parked = TRUE;
-               assert_wait(&thread->suspend_count, THREAD_ABORTSAFE);
+               assert_wait(&thread->suspend_count,
+                   THREAD_ABORTSAFE | THREAD_WAIT_NOREPORT_USER);
                thread_mtx_unlock(thread);
 
                thread_block(thread_suspended);
@@ -951,56 +1005,79 @@ thread_apc_ast(thread_t thread)
 /* Prototype, see justification above */
 kern_return_t
 act_set_state(
-       thread_t                                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  count);
+       thread_t                                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  count);
 
 kern_return_t
 act_set_state(
-       thread_t                                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  count)
+       thread_t                                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  count)
 {
-    if (thread == current_thread())
-           return (KERN_INVALID_ARGUMENT);
+       if (thread == current_thread()) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
-    return (thread_set_state(thread, flavor, state, count));
-    
+       return thread_set_state(thread, flavor, state, count);
 }
 
 kern_return_t
 act_set_state_from_user(
-       thread_t                                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  count)
+       thread_t                                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  count)
 {
-    if (thread == current_thread())
-           return (KERN_INVALID_ARGUMENT);
+       if (thread == current_thread()) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
-    return (thread_set_state_from_user(thread, flavor, state, count));
-    
+       return thread_set_state_from_user(thread, flavor, state, count);
 }
 
+/* Prototype, see justification above */
+kern_return_t
+act_get_state(
+       thread_t                                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  *count);
+
 kern_return_t
 act_get_state(
-       thread_t                                thread,
-       int                                             flavor,
-       thread_state_t                  state,
-       mach_msg_type_number_t  *count)
+       thread_t                                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  *count)
+{
+       if (thread == current_thread()) {
+               return KERN_INVALID_ARGUMENT;
+       }
+
+       return thread_get_state(thread, flavor, state, count);
+}
+
+kern_return_t
+act_get_state_to_user(
+       thread_t                                thread,
+       int                                             flavor,
+       thread_state_t                  state,
+       mach_msg_type_number_t  *count)
 {
-    if (thread == current_thread())
-           return (KERN_INVALID_ARGUMENT);
+       if (thread == current_thread()) {
+               return KERN_INVALID_ARGUMENT;
+       }
 
-    return (thread_get_state(thread, flavor, state, count));
+       return thread_get_state_to_user(thread, flavor, state, count);
 }
 
 static void
 act_set_ast(
-           thread_t thread,
-           ast_t ast)
+       thread_t thread,
+       ast_t ast)
 {
        spl_t s = splsched();
 
@@ -1013,10 +1090,11 @@ act_set_ast(
                thread_lock(thread);
                thread_ast_set(thread, ast);
                processor = thread->last_processor;
-               if ( processor != PROCESSOR_NULL            &&
-                    processor->state == PROCESSOR_RUNNING  &&
-                    processor->active_thread == thread     )
+               if (processor != PROCESSOR_NULL &&
+                   processor->state == PROCESSOR_RUNNING &&
+                   processor->active_thread == thread) {
                        cause_ast_check(processor);
+               }
                thread_unlock(thread);
        }
 
@@ -1033,7 +1111,7 @@ act_set_ast(
  */
 static void
 act_set_ast_async(thread_t  thread,
-                  ast_t     ast)
+    ast_t     ast)
 {
        thread_ast_set(thread, ast);
 
@@ -1046,7 +1124,7 @@ act_set_ast_async(thread_t  thread,
 
 void
 act_set_astbsd(
-       thread_t        thread)
+       thread_t        thread)
 {
        act_set_ast( thread, AST_BSD );
 }
@@ -1062,12 +1140,14 @@ act_set_astkevent(thread_t thread, uint16_t bits)
 
 void
 act_set_kperf(
-       thread_t        thread)
+       thread_t        thread)
 {
        /* safety check */
-       if (thread != current_thread())
-               if( !ml_get_interrupts_enabled() )
+       if (thread != current_thread()) {
+               if (!ml_get_interrupts_enabled()) {
                        panic("unsafe act_set_kperf operation");
+               }
+       }
 
        act_set_ast( thread, AST_KPERF );
 }
@@ -1075,7 +1155,7 @@ act_set_kperf(
 #if CONFIG_MACF
 void
 act_set_astmacf(
-       thread_t        thread)
+       thread_t        thread)
 {
        act_set_ast( thread, AST_MACF);
 }
@@ -1106,4 +1186,3 @@ act_set_io_telemetry_ast(thread_t thread)
 {
        act_set_ast(thread, AST_TELEMETRY_IO);
 }
-