예제 #1
0
파일: thread.c 프로젝트: bkolobara/Benu-pi
void kthread_cleanup ( kthread_t *kthread )
{
	kthread_restore_state ( kthread );
	kthread->ref_cnt--;
	if ( !kthread->ref_cnt )
		kthread_remove_descriptor ( kthread );
}
예제 #2
0
파일: thread.c 프로젝트: l30nard0/Benu
/*! Get exit status of finished thread (and free descriptor) */
void kthread_collect_status ( kthread_t *waited, void **retval )
{
	ASSERT ( waited );

	if ( retval )
		*retval = waited->state.exit_status;

	if ( !waited->ref_cnt )
		kthread_remove_descriptor ( waited );
}
예제 #3
0
파일: thread.c 프로젝트: l30nard0/Benu
/*!
 * Cancel thread (or restore it to previous state)
 * \param kthread Thread descriptor
 */
int kthread_exit ( kthread_t *kthread, void *exit_status, int force )
{
	kthread_state_t *prev;
	int restored = FALSE;
	kthread_t *released;
	kthread_q *q;
	void **p;

	ASSERT ( kthread );

	do {
		prev = list_get ( &kthread->states, FIRST );
		if ( prev )
			restored = kthread_restore_state ( kthread );
	}
	while ( prev && force ); /* if cancel is called, destroy all states */

	if ( restored && !force ) /* restored to previous state */
	{
		if ( kthread == active_thread )
			kthread->state.state = THR_STATE_ACTIVE;

		kthreads_schedule ();

		return EXIT_SUCCESS;
	}

	if ( kthread->state.state == THR_STATE_PASSIVE )
		return EXIT_SUCCESS; /* thread is already finished */

	if ( kthread->state.state == THR_STATE_READY )
	{
		/* remove target 'thread' from its queue */
		if ( !kthread_remove_from_ready ( kthread ) )
			ASSERT ( FALSE );
	}
	else if ( kthread->state.state == THR_STATE_WAIT )
	{
		/* remove target 'thread' from its queue */
		if ( !kthreadq_remove ( kthread->queue, kthread ) )
			ASSERT ( FALSE );
	}
	else if ( kthread->state.state == THR_STATE_SUSPENDED )
	{
		/* cancellation routine */
		if ( kthread->state.cancel_suspend_handler )
			kthread->state.cancel_suspend_handler ( kthread,
				kthread->state.cancel_suspend_param );
	}
	else if ( kthread->state.state == THR_STATE_ACTIVE )
	{
		if ( kthread != active_thread )
			return ESRCH; /* thread descriptor corrupted ! */
	}
	else {
		return ESRCH; /* thread descriptor corrupted ! */
	}

	kthread->state.state = THR_STATE_PASSIVE;
	kthread->ref_cnt--;
	kthread->state.exit_status = exit_status;
	kthread->proc->thread_count--;

	arch_destroy_thread_context ( &kthread->state.context );

	kthread_restore_state ( kthread );

	q = &kthread->join_queue;

	while ( (released = kthreadq_remove ( q, NULL )) != NULL )
	{
		/* save exit status to all waiting threads */
		p = kthread_get_private_param ( released );
		if ( p )
			*p = exit_status;

		kthread_move_to_ready ( released, LAST );
		kthread->ref_cnt--;
	}

	if ( !kthread->ref_cnt )
		kthread_remove_descriptor ( kthread );

	if ( kthread == active_thread )
	{
		active_thread = NULL;
		kthreads_schedule ();
	}

	return EXIT_SUCCESS;
}