コード例 #1
0
ファイル: pthread.c プロジェクト: l30nard0/Benu
static int cond_release ( void *p, int release_all )
{
	pthread_cond_t *cond;

	kpthread_cond_t *kcond;
	kpthread_mutex_t *kmutex;
	kobject_t *kobj_cond, *kobj_mutex;
	kthread_t *kthread;
	int retval = 0;

	cond = *( (pthread_cond_t **) p );
	ASSERT_ERRNO_AND_EXIT ( cond, EINVAL );

	kobj_cond = cond->ptr;
	ASSERT_ERRNO_AND_EXIT ( kobj_cond, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj_cond->list ),
				EINVAL );
	kcond = kobj_cond->kobject;
	ASSERT_ERRNO_AND_EXIT ( kcond && kcond->id == cond->id, EINVAL );

	kthread_set_errno ( kthread_get_active (), EXIT_SUCCESS );

	if ( (kthread = kthreadq_remove ( &kcond->queue, NULL )) )
	{
		kobj_mutex = kthread_get_private_param ( kthread );
		kmutex = kobj_mutex->kobject;

		retval = mutex_lock ( kmutex, kthread );
		if ( retval == 0 )
			kthread_move_to_ready ( kthread, LAST );

		/* process other threads in queue */
		while ( release_all &&
			(kthread = kthreadq_remove ( &kcond->queue, NULL )) )
		{
			kthread_set_errno ( kthread, EXIT_SUCCESS );

			kobj_mutex = kthread_get_private_param ( kthread );
			kmutex = kobj_mutex->kobject;

			kthread_enqueue(kthread, &kmutex->queue, 0, NULL, NULL);
		}
	}

	if ( retval > -1 )
		kthreads_schedule ();

	return EXIT_SUCCESS;
}
コード例 #2
0
ファイル: time.c プロジェクト: bkolobara/Benu-pi
/*!
 * Resume suspended thread (called on timer activation)
 * \param sigval Thread that should be released
 */
static void kclock_wake_thread ( sigval_t sigval )
{
	kthread_t *kthread;
	ktimer_t *ktimer;
	int retval = 0;

	kthread = sigval.sival_ptr;
	ASSERT ( kthread );
	ASSERT ( kthread_check_kthread ( kthread ) ); /* is this valid thread */
	ASSERT ( kthread_is_suspended ( kthread, NULL, NULL ) );

	ktimer = kthread_get_private_param ( kthread );
	timespec_t *remain = ktimer->param;
	if ( remain )
		TIME_RESET ( remain ); /* timer expired */

	kthread_move_to_ready ( kthread, LAST );

	retval += ktimer_delete ( ktimer );
	ASSERT ( retval == EXIT_SUCCESS );

	kthreads_schedule ();
}
コード例 #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;
}
コード例 #4
0
ファイル: thread.c プロジェクト: bkolobara/Benu-pi
/*!
 * 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;
}