Exemplo n.º 1
0
/*!
 * Change scheduling parameters
 * \param thread User level thread descriptor
 * \param policy Thread scheduling policy
 * \param param Additional scheduling parameters (when policy != SCHED_FIFO)
 * \return 0
 */
int sys__pthread_setschedparam ( pthread_t *thread, int policy,
				 sched_param_t *param )
{
	kthread_t *kthread;
	int retval;

	SYS_ENTRY();

	kthread = thread->ptr;
	ASSERT_ERRNO_AND_EXIT ( kthread, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( kthread_get_id (kthread) == thread->id, ESRCH );
	ASSERT_ERRNO_AND_EXIT ( kthread_is_alive (kthread), ESRCH );

	ASSERT_ERRNO_AND_EXIT ( policy == SCHED_FIFO, ENOTSUP );

	if ( param )
	{
		ASSERT_ERRNO_AND_EXIT (
			param->sched_priority >= THREAD_MIN_PRIO &&
			param->sched_priority <= THREAD_MAX_PRIO, EINVAL );
	}

	retval = kthread_setschedparam ( kthread, policy, param );
	if ( retval == EXIT_SUCCESS )
		SYS_EXIT ( EXIT_SUCCESS, retval );
	else
		SYS_EXIT ( retval, EXIT_FAILURE );
}
Exemplo n.º 2
0
/*!
 * Change scheduling parameters
 * \param thread User level thread descriptor
 * \param policy Thread scheduling policy
 * \param param Additional scheduling parameters (when policy != SCHED_FIFO)
 * \return 0
 */
int sys__pthread_setschedparam ( void *p )
{
	pthread_t *thread;
	int policy;
	sched_param_t *param;

	kthread_t *kthread;

	thread = *( (pthread_t **) p );		p += sizeof (pthread_t *);
	policy = *( (int *) p );		p += sizeof (int);
	param =  *( (sched_param_t **) p );

	kthread = thread->ptr;
	ASSERT_ERRNO_AND_EXIT ( kthread, EINVAL );
	ASSERT_ERRNO_AND_EXIT ( kthread_get_id (kthread) == thread->id, ESRCH );
	ASSERT_ERRNO_AND_EXIT ( kthread_is_alive (kthread), ESRCH );

	ASSERT_ERRNO_AND_EXIT ( policy >= 0 && policy < SCHED_NUM, EINVAL );

	if ( param )
	{
		ASSERT_ERRNO_AND_EXIT (
			param->sched_priority >= THREAD_MIN_PRIO &&
			param->sched_priority <= THREAD_MAX_PRIO, EINVAL );
	}

	return kthread_setschedparam ( kthread, policy, param );
}
Exemplo n.º 3
0
static int edf_set_thread_sched_parameters ( ksched_t *ksched,
					     kthread_t *kthread,
					     sched_supp_t *params )
{
	timespec_t now;
	itimerspec_t alarm;
	kthread_sched2_t *tsched = kthread_get_sched2_param ( kthread );

	if ( ksched->params.edf.active == kthread )
		ksched->params.edf.active = NULL;

	kclock_gettime ( CLOCK_REALTIME, &now );

	if ( params->edf.flags & EDF_SET )
	{
		tsched->params.edf.period = params->edf.period;
		tsched->params.edf.relative_deadline = params->edf.deadline;
		tsched->params.edf.flags = params->edf.flags ^ EDF_SET;

		/* create and set periodic alarm */
		edf_create_alarm ( kthread, edf_period_alarm,
				   &tsched->params.edf.period_alarm );
		tsched->params.edf.next_run = now;
		time_add ( &tsched->params.edf.next_run, &params->edf.period );
		alarm.it_interval = tsched->params.edf.period;
		alarm.it_value = tsched->params.edf.next_run;
		ktimer_settime ( tsched->params.edf.period_alarm, TIMER_ABSTIME,
				 &alarm, NULL );

		/* adjust "next_run" and "deadline" for "0" period
		 * first "edf_wait" will set correct values for first period */
		tsched->params.edf.next_run = now;
		time_sub ( &tsched->params.edf.next_run, &params->edf.period );

		/* create and set deadline alarm */
		edf_create_alarm ( kthread, edf_deadline_alarm,
				   &tsched->params.edf.deadline_alarm );
		tsched->params.edf.active_deadline = now;
		time_add ( &tsched->params.edf.active_deadline,
			   &params->edf.deadline );
		TIME_RESET ( &alarm.it_interval );
		alarm.it_value = tsched->params.edf.active_deadline;
		ktimer_settime ( tsched->params.edf.deadline_alarm,
				 TIMER_ABSTIME, &alarm, NULL );

		/* move thread to edf scheduler */
		kthread_enqueue ( kthread, &ksched->params.edf.ready );
		edf_schedule (ksched);
	}
	else if ( params->edf.flags & EDF_WAIT )
	{
		if ( edf_check_deadline ( kthread ) )
			return EXIT_FAILURE;

		/* set times for next period */
		if ( time_cmp ( &now, &tsched->params.edf.next_run ) > 0 )
		{
			time_add ( &tsched->params.edf.next_run,
				   &tsched->params.edf.period );

			tsched->params.edf.active_deadline =
				tsched->params.edf.next_run;
			time_add ( &tsched->params.edf.active_deadline,
				   &tsched->params.edf.relative_deadline );

			if ( kthread == ksched->params.edf.active )
				ksched->params.edf.active = NULL;

			/* set (separate) alarm for deadline
			 * (periodic alarm is set only once as periodic) */

			TIME_RESET ( &alarm.it_interval );
			alarm.it_value = tsched->params.edf.active_deadline;
			ktimer_settime ( tsched->params.edf.deadline_alarm,
					 TIMER_ABSTIME, &alarm, NULL );
		}

		/* is task ready for execution, or must wait until next period*/
		if ( time_cmp ( &tsched->params.edf.next_run, &now ) > 0 )
		{
			/* wait till "next_run" */
			EDF_LOG ( "%x [EDF WAIT]", kthread );
			kthread_enqueue ( kthread, &ksched->params.edf.wait );
			edf_schedule (ksched);
		}
		else {
			/* "next_run" has already come,
			 * activate task => move it to "EDF ready tasks"
			 */
			EDF_LOG ( "%x [EDF READY]", kthread );
			kthread_enqueue ( kthread, &ksched->params.edf.ready );
			edf_schedule (ksched);
		}
	}
	else if ( params->edf.flags & EDF_EXIT )
	{
		if ( kthread == ksched->params.edf.active )
			ksched->params.edf.active = NULL;

		if ( edf_check_deadline ( kthread ) )
		{
			EDF_LOG ( "%x [EXIT-error]", kthread );
			return EXIT_FAILURE;
		}

		EDF_LOG ( "%x [EXIT-normal]", kthread );

		if ( tsched->params.edf.period_alarm )
		{
			/* disarm timer */
			TIME_RESET ( &alarm.it_interval );
			TIME_RESET ( &alarm.it_value );
			ktimer_settime ( tsched->params.edf.period_alarm, 0,
					 &alarm, NULL );
		}

		if ( tsched->params.edf.deadline_alarm )
		{
			/* disarm timer */
			TIME_RESET ( &alarm.it_interval );
			TIME_RESET ( &alarm.it_value );
			ktimer_settime ( tsched->params.edf.deadline_alarm, 0,
					 &alarm, NULL );
		}

		kthread_setschedparam ( kthread, SCHED_FIFO, NULL );
	}

	return 0;
}