__private_extern__ kern_return_t chudxnu_thread_set_state(thread_act_t thr_act, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t count, boolean_t user_only) { if(thr_act==current_act()) { if(flavor==PPC_THREAD_STATE || flavor==PPC_THREAD_STATE64) { struct savearea *sv; if(user_only) { sv = chudxnu_private_get_user_regs(); } else { sv = chudxnu_private_get_regs(); } return chudxnu_copy_threadstate_to_savearea(sv, flavor, tstate, &count); } else if(flavor==PPC_FLOAT_STATE && user_only) { #warning chudxnu_thread_set_state() does not yet support supervisor FP return machine_thread_set_state(current_act(), flavor, tstate, count); } else if(flavor==PPC_VECTOR_STATE && user_only) { #warning chudxnu_thread_set_state() does not yet support supervisor VMX return machine_thread_set_state(current_act(), flavor, tstate, count); } else { return KERN_INVALID_ARGUMENT; } } else { return machine_thread_set_state(thr_act, flavor, tstate, count); } }
/* * Change thread's machine-dependent state. Called with nothing * locked. Returns same way. */ static kern_return_t thread_set_state_internal( register 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; if (thread == THREAD_NULL) return (KERN_INVALID_ARGUMENT); thread_mtx_lock(thread); if (thread->active) { if (thread != current_thread()) { thread_hold(thread); thread_mtx_unlock(thread); if (thread_stop(thread, TRUE)) { thread_mtx_lock(thread); result = machine_thread_set_state( thread, flavor, state, state_count); thread_unstop(thread); } else { thread_mtx_lock(thread); result = KERN_ABORTED; } thread_release(thread); } else result = machine_thread_set_state( thread, flavor, state, state_count); } else result = KERN_TERMINATED; if ((result == KERN_SUCCESS) && from_user) extmod_statistics_incr_thread_set_state(thread); thread_mtx_unlock(thread); return (result); }
/* * thread_setstatus: * * Set the status of the specified thread. * Called with (and returns with) no locks held. */ kern_return_t thread_setstatus( register thread_act_t act, int flavor, thread_state_t tstate, mach_msg_type_number_t count) { kern_return_t result = KERN_SUCCESS; thread_t thread; thread = act_lock_thread(act); if ( act != current_act() && (act->suspend_count == 0 || thread == THREAD_NULL || (thread->state & TH_RUN) || thread->top_act != act) ) result = KERN_FAILURE; if (result == KERN_SUCCESS) result = machine_thread_set_state(act, flavor, tstate, count); act_unlock_thread(act); return (result); }
/* * Change thread's machine-dependent state. Called with nothing * locked. Returns same way. */ kern_return_t thread_set_state( register thread_act_t act, int flavor, thread_state_t state, mach_msg_type_number_t state_count) { kern_return_t result = KERN_SUCCESS; thread_t thread; if (act == THR_ACT_NULL || act == current_act()) return (KERN_INVALID_ARGUMENT); thread = act_lock_thread(act); if (!act->active) { act_unlock_thread(act); return (KERN_TERMINATED); } thread_hold(act); for (;;) { thread_t thread1; if ( thread == THREAD_NULL || thread->top_act != act ) break; act_unlock_thread(act); if (!thread_stop(thread)) { result = KERN_ABORTED; (void)act_lock_thread(act); thread = THREAD_NULL; break; } thread1 = act_lock_thread(act); if (thread1 == thread) break; thread_unstop(thread); thread = thread1; } if (result == KERN_SUCCESS) result = machine_thread_set_state(act, flavor, state, state_count); if ( thread != THREAD_NULL && thread->top_act == act ) thread_unstop(thread); thread_release(act); act_unlock_thread(act); return (result); }
__private_extern__ kern_return_t chudxnu_thread_set_state( thread_t thread, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t count, boolean_t user_only) { #pragma unused (user_only) return machine_thread_set_state(thread, flavor, tstate, count); }
/** * act_thread_catt * * Restore the current thread context, used for the internal uthread structure. * (We should also restore VFP state...) */ void act_thread_catt(void *ctx) { thread_t thr_act = current_thread(); kern_return_t kret; if (ctx == (void *)NULL) return; struct arm_thread_state_t *ts = (struct arm_thread_state_t*)ctx; machine_thread_set_state(thr_act, ARM_THREAD_STATE, (thread_state_t)ts, ARM_THREAD_STATE_COUNT); kfree(ts, sizeof(struct arm_thread_state)); }
static kern_return_t thread_create_running_internal2( register task_t task, int flavor, thread_state_t new_state, mach_msg_type_number_t new_state_count, thread_t *new_thread, boolean_t from_user) { register kern_return_t result; thread_t thread; if (task == TASK_NULL || task == kernel_task) return (KERN_INVALID_ARGUMENT); result = thread_create_internal(task, -1, (thread_continue_t)thread_bootstrap_return, TH_OPTION_NONE, &thread); if (result != KERN_SUCCESS) return (result); result = machine_thread_set_state( thread, flavor, new_state, new_state_count); if (result != KERN_SUCCESS) { task_unlock(task); lck_mtx_unlock(&tasks_threads_lock); thread_terminate(thread); thread_deallocate(thread); return (result); } thread_mtx_lock(thread); thread_start_internal(thread); thread_mtx_unlock(thread); if (from_user) extmod_statistics_incr_thread_create(task); task_unlock(task); lck_mtx_unlock(&tasks_threads_lock); *new_thread = thread; return (result); }
/* * Set initial default state on a thread as stored in the MACHINE_TASK data. * Note: currently only debug state is supported. */ kern_return_t machine_thread_inherit_taskwide( thread_t thread, task_t parent_task) { if (parent_task->task_debug) { int flavor; mach_msg_type_number_t count; if (task_has_64BitAddr(parent_task)) { flavor = x86_DEBUG_STATE64; count = x86_DEBUG_STATE64_COUNT; } else { flavor = x86_DEBUG_STATE32; count = x86_DEBUG_STATE32_COUNT; } return machine_thread_set_state(thread, flavor, parent_task->task_debug, count); } return KERN_SUCCESS; }