Пример #1
0
__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);
	}
}
Пример #2
0
/*
 *	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);
}
Пример #3
0
/*
 *	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);
}
Пример #4
0
/*
 *	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);
}
Пример #5
0
__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);
}
Пример #6
0
/** 
 * 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));
}
Пример #7
0
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);
}
Пример #8
0
/*
 * 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;
}