/*!
 * End current thread (exit from it)
 * \param status Exit status number
 */
int sys__thread_exit ( void *p )
{
	int status;

	status = *( (int *) p );

	active_thread->state = THR_STATE_PASSIVE;
	active_thread->ref_cnt--;
	active_thread->exit_status = status;

#ifdef	MESSAGES
	k_msgq_clean ( &active_thread->msg.msgq );
#endif
	/* release thread stack */
	if ( active_thread->stack )
		kfree ( active_thread->stack );

	k_delete_thread_private_storage ( active_thread,
					  active_thread->private_storage );

	if ( !active_thread->ref_cnt )
	{
		k_remove_thread_descriptor ( active_thread );

		active_thread = NULL;
	}
	else {
		k_release_all_threads ( &active_thread->join_queue );
	}

	k_schedule_threads ();

	return 0;
}
Пример #2
0
/*!
 * Wait for thread termination
 * \param thread Thread descriptor (user level descriptor)
 * \param wait Wait if thread not finished (!=0) or not (0)?
 * \return 0 if thread already gone; -1 if not finished and 'wait' not set;
 *         'thread exit status' otherwise
 */
int sys__wait_for_thread ( void *p )
{
	thread_t *thread;
	int wait;
	kthread_t *kthr;
	int ret_value = 0;

	thread = U2K_GET_ADR ( *( (void **) p ), active_thread->proc );
	p += sizeof (void *);

	wait = *( (int *) p );

	ASSERT_ERRNO_AND_EXIT ( thread && thread->thread, E_INVALID_HANDLE );

	kthr = thread->thread;

	if ( kthr->id != thread->thr_id ) /* at 'kthr' is now something else */
	{
		ret_value = -SUCCESS;
		SET_ERRNO ( SUCCESS );
	}
	else if ( kthr->state != THR_STATE_PASSIVE && !wait )
	{
		ret_value = -E_NOT_FINISHED;
		SET_ERRNO ( E_NOT_FINISHED );
	}
	else if ( kthr->state != THR_STATE_PASSIVE )
	{
		kthr->ref_cnt++;

		ret_value = -E_RETRY; /* retry (collect thread status) */
		SET_ERRNO ( E_RETRY );

		k_enqueue_thread ( NULL, &kthr->join_queue );

		k_schedule_threads ();
	}
	else {
		/* kthr->state == THR_STATE_PASSIVE, but thread descriptor still
		   not freed - some thread still must collect its status */
		SET_ERRNO ( SUCCESS );
		ret_value = kthr->exit_status;

		kthr->ref_cnt--;

		if ( !kthr->ref_cnt )
			k_remove_thread_descriptor ( kthr );
	}

	return ret_value;
}
Пример #3
0
/*!
 * End current thread (exit from it)
 * \param status Exit status number
 */
int sys__thread_exit ( void *p )
{
	int status;

	status = *( (int *) p );

	active_thread->state = THR_STATE_PASSIVE;
	active_thread->ref_cnt--;
	active_thread->exit_status = status;

	active_thread->proc->thr_count--;

#ifdef	MESSAGES
	k_msgq_clean ( &active_thread->msg.msgq );
#endif
	/* release thread stack */
	if ( active_thread->stack )
	{
		if ( active_thread->proc->m.start ) /* user level thread */
			ffs_free ( active_thread->proc->stack_pool,
				   active_thread->stack );
		else /* kernel level thread */
			kfree ( active_thread->stack );
	}

	k_delete_thread_private_storage ( active_thread,
					  active_thread->private_storage );

	if ( active_thread->proc->thr_count == 0 && active_thread->proc->pi )
	{
		/* last (non-kernel) thread - remove process */
		ASSERT ( list_remove ( &procs, FIRST, &active_thread->proc->all ) );
		active_thread->proc->prog->started = FALSE;
		kfree ( active_thread->proc );
	}

	if ( !active_thread->ref_cnt )
	{
		k_remove_thread_descriptor ( active_thread );

		active_thread = NULL;
	}
	else {
		k_release_all_threads ( &active_thread->join_queue );
	}

	k_schedule_threads ();

	return 0;
}