Skip to content
Snippets Groups Projects
Commit 2464b9f2 authored by Armin Luntzer's avatar Armin Luntzer
Browse files

saving somewhat working state

parent 870abf15
No related branches found
No related tags found
No related merge requests found
......@@ -44,7 +44,7 @@
#endif /* __OPTIMIZE__ */
#endif /* GCC_VERSION */
volatile int inc;
int task1(void *data)
{
......@@ -62,12 +62,27 @@ int task2(void *data)
sched_yield();
}
}
static int cnt;
static ktime buf[1024];
int task3(void *data)
{
ktime last = 0;
while (1) {
printk("x");
sched_yield();
#if 0
ktime now;
if (cnt < 1024) {
now = ktime_get();
buf[cnt] = ktime_delta(now, last);
last = now;
cnt++;
}
// else
// sched_yield();
#endif
printk("%llu\n", ktime_get());
// sched_yield();
}
}
......@@ -194,7 +209,7 @@ int kernel_main(void)
#if 1
{
struct sched_attr attr;
#if 0
t = kthread_create(task1, NULL, KTHREAD_CPU_AFFINITY_NONE, "print");
sched_get_attr(t, &attr);
attr.priority = 4;
......@@ -206,26 +221,68 @@ int kernel_main(void)
attr.priority = 8;
sched_set_attr(t, &attr);
kthread_wake_up(t);
#endif
#if 1
t = kthread_create(task3, NULL, KTHREAD_CPU_AFFINITY_NONE, "edfprint");
sched_get_attr(t, &attr);
attr.policy = SCHED_EDF;
attr.period = 9000000;
attr.deadline_rel = 1100000;
attr.wcet = 1000000;
attr.period = ms_to_ktime(3000);
attr.deadline_rel = ms_to_ktime(2000);
attr.wcet = ms_to_ktime(1000);
sched_set_attr(t, &attr);
kthread_wake_up(t);
#endif
}
#endif
while(1) {
#if 0
int val = inc;
static ktime last;
ktime now;
now = ktime_get();
static ktime delta;
delta = ktime_delta(last, now);
last = now;
printk("%d %lld\n", val, ktime_to_us(delta));
#endif
#if 0
static int i;
static ktime last;
ktime now;
now = ktime_get();
if (i == 10) {
printk("%lld\n", ktime_to_ms(ktime_delta(now, last)));
last = now;
i = 0;
}
i++;
#endif
// sched_yield();
if (cnt > 1023) {
int i;
for (i = 1; i < 1024; i++)
printk("%lld\n", buf[i]);
// cnt = 0;
break;
}
printk("xxx %llu\n", ktime_get());
//printk("%d\n", cnt);
while(1) {
//printk("|");
cpu_relax();
// sched_yield();
// cpu_relax();
}
//printk("%lld\n", buf[i]);
while(1)
cpu_relax();
/* never reached */
BUG();
......
......@@ -99,38 +99,6 @@ void sched_yield(void)
}
void sched_wake(struct task_struct *next, ktime now, int64_t slot_ns)
{
struct task_struct *task;
if (list_empty(&_kthreads.wake))
return;
task = list_entry(_kthreads.wake.next, struct task_struct, node);
if (task->attr.policy == SCHED_EDF) {
if (next->attr.policy == SCHED_EDF)
return;
/* initially set current time as wakeup */
task->wakeup = ktime_add(now, slot_ns);
task->deadline = ktime_add(task->wakeup, task->attr.deadline_rel);
task->first_wake = task->wakeup;
task->first_dead = task->deadline;
list_move(&task->node, &_kthreads.run);
}
if (task->attr.policy == SCHED_RR) {
task->state = TASK_RUN;
list_move(&task->node, &_kthreads.run);
}
}
__attribute__((unused))
/* static */ void kthread_set_sched_policy(struct task_struct *task,
enum sched_policy policy)
......
......@@ -34,16 +34,26 @@ void schedule(void)
struct task_struct *next = NULL;
struct task_struct *current;
struct task_struct *current = current_set[0]->task;
int64_t slot_ns;
int64_t wake_ns = 0;
static int once;
if (!once) {
// tick_set_mode(TICK_MODE_PERIODIC);
tick_set_next_ns(1e9); /* XXX default to 1s ticks initially */
once = 1;
return;
}
arch_local_irq_disable();
/* kthread_lock(); */
current->runtime = ktime_sub(current->exec_start, ktime_get());
/* XXX: for now, try to wake up any threads not running
* this is a waste of cycles and instruction space; should be
......@@ -59,7 +69,7 @@ void schedule(void)
* TODO: scheduler priority value
*/
list_for_each_entry(sched, &kernel_schedulers, node) {
// struct task_struct *tmpn;
next = sched->pick_next_task(&sched->tq);
/* check if we need to limit the next tasks timeslice;
......@@ -68,9 +78,27 @@ void schedule(void)
* we assume that the timeslice is reasonable; if not fix it in
* the corresponding scheduler
*/
//int64_t tmp;
if (!wake_ns)
wake_ns = sched->task_ready_ns(&sched->tq);
#if 0
if (next)
printk("next %s\n", next->name);
printk("wake_ns %llu\n", wake_ns);
#endif
#if 0
else {
tmp = sched->task_ready_ns(&sched->tq);
if (tmp > wake_ns) {
wake_ns = tmp;
next = tmpn;
}
}
if (!next)
next = tmpn;
#endif
if (next)
break;
}
......@@ -78,8 +106,9 @@ void schedule(void)
if (!next) {
/* nothing to do, check again later */
if (wake_ns)
if (wake_ns) {
tick_set_next_ns(wake_ns);
}
else
tick_set_next_ns(1e9); /* XXX pause for a second */
......@@ -87,17 +116,22 @@ void schedule(void)
}
/* see if we can use a full slice or if we have to wake earlier */
if (wake_ns)
slot_ns = wake_ns;
else
slot_ns = next->sched->timeslice_ns(next);
if (wake_ns < slot_ns)
slot_ns = wake_ns;
/* statistics */
next->exec_start = ktime_get();
// if (next)
// printk("real next %s %llu %llu\n", next->name, next->exec_start, slot_ns);
/* kthread_unlock(); */
tick_set_next_ns(slot_ns);
// printk("wake %llu\n", slot_ns);
/* subtract readout overhead */
tick_set_next_ns(ktime_sub(slot_ns, 1000LL));
// tick_set_next_ns(slot_ns);
prepare_arch_switch(1);
switch_to(next);
......
......@@ -116,11 +116,10 @@ static inline bool schedule_edf_can_execute(struct task_struct *tsk, ktime now)
if (tsk->runtime <= 0)
return false;
if (ktime_before(tsk->deadline, now)) {
printk("%s violated, %lld %lld, %lld %lld\n", tsk->name,
printk("%s violated, %lld %lld, dead %lld wake %lld now %lld\n", tsk->name,
tsk->runtime, ktime_us_delta(tsk->deadline, now),
tsk->deadline, now);
tsk->deadline, tsk->wakeup, now);
// sched_print_edf_list_internal(now);
BUG();
return false;
......@@ -673,7 +672,7 @@ static int edf_schedulable(struct task_queue *tq, const struct task_struct *task
return -EINVAL;
printk("changed task mode to RR\n", u);
} else {
printk("Utilisation %g\n", u);
printk("Utilisation: %g\n", u);
return 0;
}
}
......@@ -681,7 +680,7 @@ static int edf_schedulable(struct task_queue *tq, const struct task_struct *task
u = (double) (int32_t) task->attr.wcet / (double) (int32_t) task->attr.period;
printk("was the first task %g\n", u);
printk("was the first task, utilisation: %g\n", u);
return 0;
}
......@@ -694,7 +693,7 @@ static int64_t slot;
static struct task_struct *edf_pick_next(struct task_queue *tq)
{
#define SOME_DEFAULT_TICK_PERIOD_FOR_SCHED_MODE 10000000LL
#define SOME_DEFAULT_TICK_PERIOD_FOR_SCHED_MODE 100000LL
int64_t delta;
......@@ -705,26 +704,46 @@ static struct task_struct *edf_pick_next(struct task_queue *tq)
slot = SOME_DEFAULT_TICK_PERIOD_FOR_SCHED_MODE;
// printk("-\n");
list_for_each_entry_safe(tsk, tmp, &tq->run, node) {
/* time to wake up yet? */
delta = ktime_delta(tsk->wakeup, now);
if (delta >= 0) {
/* nope, just update minimum runtime for this slot */
if (delta < slot)
if (delta < slot) {
slot = delta;
// printk("d %lld now: %lld \n", ktime_to_us(delta), now);
}
// printk("delta %llu %llu\n", delta, tsk->wakeup);
continue;
// continue;
}
if (delta < 0) {
// printk("\n%lld %d\n", ktime_to_us(delta), tsk->state);
// printk("%s: %lld (%lld) deadline: %lld now: %lld state %d\n", tsk->name, ktime_to_ms(delta), tsk->wakeup, tsk->deadline, now, tsk->state);
}
/* if it's already running, see if there is time remaining */
if (tsk->state == TASK_RUN) {
if (!schedule_edf_can_execute(tsk, now)) {
schedule_edf_reinit_task(tsk, now);
/* nope, update minimum runtime for this slot */
delta = ktime_delta(tsk->wakeup, now);
#if 1
if (delta < 0) {
delta = tsk->attr.wcet;
slot = delta;
}
#endif
if (delta < slot)
slot = delta;
if (delta < 0)
printk("delta %lld %lld\n", ktime_to_us(delta), ktime_to_us(tick_get_period_min_ns()));
BUG_ON(delta < 0);
continue;
}
......@@ -822,9 +841,9 @@ static int edf_check_sched_attr(struct sched_attr *attr)
/* need only check WCET, all other times are longer */
if (attr->wcet < (ktime) tick_get_period_min_ns()) {
pr_err(MSG "Cannot schedule EDF task with WCET of %lld ns, "
"minimum tick duration is %ld\n", attr->wcet,
tick_get_period_min_ns());
pr_err(MSG "Cannot schedule EDF task with WCET of %llu ns, "
"minimum tick duration is %lld\n", attr->wcet,
(ktime) tick_get_period_min_ns());
goto error;
}
......@@ -835,14 +854,14 @@ static int edf_check_sched_attr(struct sched_attr *attr)
}
if (attr->wcet >= attr->deadline_rel) {
pr_err(MSG "Cannot schedule EDF task with WCET %u >= "
"DEADLINE %u !\n", attr->wcet, attr->deadline_rel);
pr_err(MSG "Cannot schedule EDF task with WCET %llu >= "
"DEADLINE %llu !\n", attr->wcet, attr->deadline_rel);
goto error;
}
if (attr->deadline_rel >= attr->period) {
pr_err(MSG "Cannot schedule EDF task with DEADLINE %u >= "
"PERIOD %u !\n", attr->deadline_rel, attr->period);
pr_err(MSG "Cannot schedule EDF task with DEADLINE %llu >= "
"PERIOD %llu !\n", attr->deadline_rel, attr->period);
goto error;
}
......@@ -895,7 +914,10 @@ ktime edf_task_ready_ns(struct task_queue *tq)
}
}
slot = 1000000;
/* subtract call overhead */
//slot = ktime_sub(slot, 10000ULL);
//slot = ktime_sub(slot, 2000ULL);
BUG_ON(slot < 0);
return slot;
......
......@@ -89,7 +89,7 @@ static void rr_enqueue(struct task_queue *tq, struct task_struct *task)
static ktime rr_timeslice_ns(struct task_struct *task)
{
return (ktime) task->attr.priority * tick_get_period_min_ns();
return (ktime) (task->attr.priority * tick_get_period_min_ns() * 1000);
}
......
......@@ -125,7 +125,7 @@ static void tick_calibrate_min(struct clock_event_device *dev)
{
#define RANDOM_TICK_RATE_NS 18000UL
tick_period_min_ns = RANDOM_TICK_RATE_NS;
#define MIN_SLICE 1000000UL
#define MIN_SLICE 100000UL
tick_period_min_ns = MIN_SLICE;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment