void timer_tick(int num_ticks)
{
/* see time_elapsed for time mgmt */
#ifdef DEFERRABLE
	{
		struct sched_thd *t;

		assert(num_ticks > 0);
		ticks += num_ticks;
		for (t = FIRST_LIST(&servers, sched_next, sched_prev) ;
		     t != &servers                                    ;
		     t = FIRST_LIST(t, sched_next, sched_prev))
		{
			struct sched_accounting *sa = sched_get_accounting(t);
			unsigned long T_exp = sa->T_exp, T = sa->T;
			assert(T);

			if (T_exp <= ticks) {
				unsigned long off = T - (ticks % T);

				//printc("(%ld+%ld/%ld @ %ld)\n", sa->C_used, (unsigned long)sa->pol_cycles, T, T_exp);
				sa->T_exp  = ticks + off;
				sa->C_used = 0;
//				sa->pol_cycles = 0;
				if (sched_thd_suspended(t)) {
					t->flags &= ~THD_SUSPENDED;
					if (sched_thd_ready(t)) {
						fp_add_thd(t, sched_get_metric(t)->priority);
					}
				}
			}
		}
	}
#endif
}
static int fp_thread_params(struct sched_thd *t, char *p)
{
	int prio, tmp;
	char curr = p[0];
	struct sched_thd *c;
	
	assert(t);
	switch (curr) {
	case 'r':
		/* priority relative to current thread */
		c = sched_get_current();
		assert(c);
		tmp = atoi(&p[1]);
		prio = sched_get_metric(c)->priority + tmp;
		memcpy(sched_get_accounting(t), sched_get_accounting(c), sizeof(struct sched_accounting));
#ifdef DEFERRABLE
		if (sched_get_accounting(t)->T) ADD_LIST(&servers, t, sched_next, sched_prev);
#endif

		if (prio > PRIO_LOWEST) prio = PRIO_LOWEST;
		break;
	case 'a':
		/* absolute priority */
		prio = atoi(&p[1]);
		break;
	case 'i':
		/* idle thread */
		prio = PRIO_LOWEST;
		break;
	case 't':
		/* timer thread */
		prio = PRIO_HIGHEST;
		break;
#ifdef DEFERRABLE
	case 'd':
	{
		prio = ds_parse_params(t, p);
		if (EMPTY_LIST(t, sched_next, sched_prev) && 
		    sched_get_accounting(t)->T) {
			ADD_LIST(&servers, t, sched_next, sched_prev);
		}
		fp_move_end_runnable(t);
		break;
	}
#endif
	default:
		printc("unknown priority option @ %s, setting to low\n", p);
		prio = PRIO_LOW;
	}
	if (sched_thd_ready(t)) fp_rem_thd(t);
	fp_add_thd(t, prio);

	return 0;
}
void thread_wakeup(struct sched_thd *t)
{
	assert(t);
	assert(!sched_thd_member(t));
	if (!sched_thd_suspended(t)) fp_add_thd(t, sched_get_metric(t)->priority);
}
Example #4
0
int
thread_param_set(struct sched_thd *t, struct sched_param_s *ps)
{
	unsigned int prio = PRIO_LOWEST;
	struct sched_thd *c = sched_get_current();
	
	assert(t);
	while (ps->type != SCHEDP_NOOP) {
		switch (ps->type) {
		case SCHEDP_RPRIO:
		case SCHEDP_RLPRIO:
			/* The relative priority has been converted to absolute priority in relative_prio_convert(). */
			prio = ps->value;
			/* FIXME: When the IPI handling thread is
			 * creating a thread (requested by a remote
			 * core) , since we can't copy accounting info
			 * from the actual parent (which is on a
			 * different core), we zero the accounting
			 * info instead of touching remote
			 * data-structures. */
			if (sched_curr_is_IPI_handler())
				sched_clear_accounting(t);
			else
				memcpy(sched_get_accounting(t), sched_get_accounting(c), sizeof(struct sched_accounting));
#ifdef DEFERRABLE
			if (sched_get_accounting(t)->T) ADD_LIST(&PERCPU_GET(fprr_state)->servers, t, sched_next, sched_prev);
#endif
			if (prio > PRIO_LOWEST) prio = PRIO_LOWEST;
			break;
		case SCHEDP_PRIO:
			/* absolute priority */
			prio = ps->value;
			break;
		case SCHEDP_IDLE:
			/* idle thread */
			prio = PRIO_LOWEST;
			break;
		case SCHEDP_INIT:
			/* idle thread */
			prio = PRIO_LOW;
			break;
		case SCHEDP_TIMER:
			/* timer thread */
			prio = PRIO_HIGHEST;
			break;
		case SCHEDP_IPI_HANDLER:
			prio = IPI_HANDLER_PRIO;
			break;
		case SCHEDP_CORE_ID:
			assert(ps->value == cos_cpuid());
			break;
#ifdef DEFERRABLE
		case SCHEDP_BUDGET:
			prio = sched_get_metric(t)->priority;
			sched_get_accounting(t)->C = ps->value;
			sched_get_accounting(t)->C_used = 0;
			fp_move_end_runnable(t);
			break;
		case SCHEDP_WINDOW:
			prio = sched_get_metric(t)->priority;
			sched_get_accounting(t)->T = ps->value;
			sched_get_accounting(t)->T_exp = 0;
			if (EMPTY_LIST(t, sched_next, sched_prev) && 
			    sched_get_accounting(t)->T) {
				ADD_LIST(&PERCPU_GET(fprr_state)->servers, t, sched_next, sched_prev);
			}
			fp_move_end_runnable(t);
			break;
#endif
		default:
			printc("fprr: core %ld received unknown priority option\n", cos_cpuid());
			prio = PRIO_LOW;
		}
		ps++;
	}
	/* printc("fprr: cpu %d has new thd %d @ prio %d\n", cos_cpuid(), t->id, prio); */
	if (sched_thd_ready(t)) fp_rem_thd(t);

	fp_add_thd(t, prio);
	
	return 0;
}