예제 #1
0
파일: sched.c 프로젝트: l30nard0/Benu
/*!
 * Select ready thread with highest priority  as active
 * - if different from current, move current into ready queue (id not NULL) and
 *   move selected thread from ready queue to active queue
 */
void kthreads_schedule ()
{
	kthread_t *curr, *next = NULL;

	curr = kthread_get_active();
	next = get_first_ready ();

	/* must exist an thread to return to, 'curr' or first from 'ready' */
	ASSERT ( ( curr && kthread_is_active ( curr ) ) || next );

	if ( !sys__feature ( FEATURE_SCHEDULER, FEATURE_GET, 0 ) &&
		curr && kthread_is_active ( curr ) )
		return;/*scheduler disabled, don't switch from current thread */

	if ( !curr || !kthread_is_active ( curr ) ||
		kthread_get_prio ( curr ) < kthread_get_prio ( next ) )
	{
		if ( curr && !kthread_is_passive (curr) ) /* deactivate curr */
		{
			/* move last active to ready queue, if still ready */
			if ( kthread_is_active ( curr ) )
				kthread_move_to_ready ( curr, LAST );

			/* deactivation might change ready thread list */
			next = get_first_ready ();
			ASSERT (next);
		}

		/* activate next */
		next = kthread_remove_from_ready ( next );
		ASSERT ( next );

		kthread_set_active ( next );
	}

	/* process pending signals (if any) */
	ksignal_process_pending ( kthread_get_active() );

	if ( curr != kthread_get_active() )
		kthread_switch_to_thread ( curr, kthread_get_active() );
	/* else => continue with current thread */
}
예제 #2
0
파일: sched.c 프로젝트: l30nard0/Benu
/*!
 * Simple Round-Robin scheduler:
 * - on timer tick move active into ready queue and pick next ready task
 */
static void  ksched_rr_tick ( sigval_t sigval )
{
	if ( sys__feature ( FEATURE_SCHED_RR, FEATURE_GET, 0 ) == 0 )
		return;

	kthread_t *active_thread = kthread_get_active();
	if ( kthread_is_active ( active_thread ) ) {
		kthread_move_to_ready ( active_thread, LAST );
		kthreads_schedule ();
	}
}
예제 #3
0
static int k_edf_schedule ()
{
	kthread_t *first, *next, *edf_active;
	kthread_sched_data_t *sch_first, *sch_next;
	ksched_t *gsched = ksched_get ( SCHED_EDF );
	int retval = 0;

	edf_active = gsched->params.edf.active;
	first = kthreadq_get ( &gsched->params.edf.ready );

	LOG( DEBUG, "%x [active]", edf_active );
	LOG( DEBUG, "%x [first]", first );
	//LOG( DEBUG, "%x [next]", next );

	if ( !first )
		return 0; /* no threads in edf.ready queue, edf.active unch. */

	if ( edf_active )
	{
		next = first;
		first = edf_active;
		LOG( DEBUG, "%x [next]", kthreadq_get_next ( next ) );
	}
	else {
		next = kthreadq_get_next ( first );
		LOG( DEBUG, "%x [next]", next );
	}

	while ( first && next )
	{

		sch_first = kthread_get_sched_param ( first );
		sch_next = kthread_get_sched_param ( next );

		if ( time_cmp ( &sch_first->params.edf.active_deadline,
			&sch_next->params.edf.active_deadline ) > 0 )
		{
			first = next;
		}

		next = kthreadq_get_next ( next );
	}

	if ( first && first != edf_active )
	{
		next = kthreadq_remove ( &gsched->params.edf.ready, first );
		LOG ( DEBUG, "%x removed, %x is now first", next, kthreadq_get ( &gsched->params.edf.ready ) );

		if ( edf_active )
		{
			LOG( DEBUG, "%x=>%x [EDF_SCHED_PREEMPT]",
			     edf_active, first );

			/*
			 * change active EDF thread:
			 * -remove it from active/ready list
			 * -put it into edf.ready list
			 */
			if ( kthread_is_ready (edf_active) )
			{
				if ( !kthread_is_active (edf_active) )
				{
					kthread_remove_from_ready (edf_active);

					/*
					 * set "deactivated" flag, don't need
					 * another call to "edf_schedule"
					 */
				}
				else {
					kthread_get_sched_param (edf_active)
						->activated = 0;
				}

				kthread_enqueue ( edf_active,
						  &gsched->params.edf.ready );
			}
			/* else = thread is blocked - leave it there */
		}

		gsched->params.edf.active = first;
		LOG( DEBUG, "%x [new active]", first );

		kthread_move_to_ready ( first, LAST );
		retval = 1;
	}

	return retval;
}
예제 #4
0
static int edf_schedule ( ksched_t *ksched )
{
	kthread_t *first, *next, *edf_active;
	kthread_sched2_t *sch_first, *sch_next, *ea;

	edf_active = ksched->params.edf.active;
	if ( edf_active && !kthread_is_ready ( edf_active ) )
	{
		ksched->params.edf.active = edf_active = NULL;
	}

	first = kthreadq_get ( &ksched->params.edf.ready );

	EDF_LOG ( "%x %x [active, first in queue]", edf_active, first );

	if ( !first )
	{
		kthreads_schedule ();
		return 0; /* no threads in edf.ready queue, edf.active unch. */
	}

	if ( edf_active )
	{
		next = first;
		first = edf_active;
	}
	else {
		next = kthreadq_get_next ( first );
	}

	while ( first && next )
	{

		sch_first = kthread_get_sched2_param ( first );
		sch_next = kthread_get_sched2_param ( next );

		if ( time_cmp ( &sch_first->params.edf.active_deadline,
			&sch_next->params.edf.active_deadline ) > 0 )
		{
			first = next;
		}

		next = kthreadq_get_next ( next );
	}

	if ( first && first != edf_active )
	{
		next = kthreadq_remove ( &ksched->params.edf.ready, first );
		EDF_LOG ( "%x removed, %x is now first", next,
			  kthreadq_get ( &ksched->params.edf.ready ) );

		if ( edf_active )
		{
			EDF_LOG ( "%x=>%x [EDF_SCHED_PREEMPT]",
				  edf_active, first );

			/*
			 * change active EDF thread:
			 * -remove it from active/ready list
			 * -put it into edf.ready list
			 */
			if ( kthread_is_ready (edf_active) )
			{
				if ( !kthread_is_active (edf_active) )
				{
					kthread_remove_from_ready (edf_active);

					/*
					 * set "deactivated" flag, don't need
					 * another call to "edf_schedule"
					 */
				}
				else {
				ea = kthread_get_sched2_param (edf_active);
				ea->activated = 0;
				}

				kthread_enqueue ( edf_active,
						  &ksched->params.edf.ready );
			}
			/* else = thread is blocked - leave it there */
		}

		ksched->params.edf.active = first;
		EDF_LOG ( "%x [new active]", first );

		kthread_move_to_ready ( first, LAST );
	}

	kthreads_schedule ();

	return 0;
}