void uthread_exit ()
{
	size_t space_for_mem_alloc_hdr[16]; /* just in case ... */
	uthread_t *cur_thread, *new_thread, tmp;

	/* active thread is exiting */
	cur_thread = list_remove ( &active, FIRST, NULL );

	space_for_mem_alloc_hdr[0] = (size_t) cur_thread;
	/*remove compiler 'not-used' warning */

	free ( cur_thread->stack );
	/* freeing it, but using it still - till the end of this function
	   (parameters are on stack!) */

	tmp = *cur_thread;
	free ( cur_thread );

	/* pick next ready thread */
	new_thread = list_remove ( &ready, FIRST, NULL );
	/* make it active */
	list_append ( &active, new_thread, &new_thread->list );
	/* switch to it */
	arch_switch_to_thread ( &tmp.context, &new_thread->context );
}
void uthread_yield ()
{
	uthread_t *cur_thread, *new_thread;

	/* remove current thread from 'active' and put it as last in 'ready' */
	cur_thread = list_remove ( &active, FIRST, NULL );
	list_append ( &ready, cur_thread, &cur_thread->list );

	/* remove first thread from 'ready' and put it in 'active' */
	new_thread = list_remove ( &ready, FIRST, NULL );
	list_append ( &active, new_thread, &new_thread->list );

	/* switch to new active thread */
	arch_switch_to_thread ( &cur_thread->context, &new_thread->context );
}
示例#3
0
/*! Switch to other thread */
void kthread_switch_to_thread ( kthread_t *from, kthread_t *to )
{
	ASSERT ( to == active_thread );

	if ( from && ( from->state.flags & THR_FLAG_DELETE ) )
	{
		/* delete thread resources with switch */
		from->state.flags &= ~THR_FLAG_DELETE;

		arch_switch_to_thread_with_cleanup (
			from, kthread_get_context ( to )
		);
	}
	else {
		arch_switch_to_thread (
		/* from */	( from ? kthread_get_context ( from ) : NULL ),
		/* to */	kthread_get_context ( to )
		);
	}
}
示例#4
0
文件: uthread.c 项目: kavefish/Benu
void uthread_exit ()
{
    uthread_t *cur_thread, *new_thread;

    /* active thread is exiting */
    cur_thread = list_remove ( &active, FIRST, NULL );

    free ( cur_thread->stack );
    /* freeing it, but using it still - till the end of this function
       (parameters are on stack!) */

    free ( cur_thread );

    /* pick next ready thread */
    new_thread = list_remove ( &ready, FIRST, NULL );
    /* make it active */
    list_append ( &active, new_thread, &new_thread->list );
    /* switch to it */
    arch_switch_to_thread ( NULL, &new_thread->context );
}
示例#5
0
/*!
 * 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;
			arch_switch_to_thread ( NULL, &kthread->state.context );
		}
		else {
			ASSERT (FALSE); /* hum, rethink this */
			/* move to ready? */
		}

		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->state.exit_status = exit_status;

	/* remove it from its scheduler */
	ksched2_thread_remove ( kthread );

	/* any thread waiting on this? */
	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--;
	}

	/* defer removing thread resources until last moment */
	kthread->state.flags |= THR_FLAG_DELETE;

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

	return EXIT_SUCCESS;
}