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); }
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; }