From 956bcb354186bcfff47aadf69eac03e8adcfd622 Mon Sep 17 00:00:00 2001
From: Armin Luntzer <armin.luntzer@univie.ac.at>
Date: Tue, 22 Oct 2019 16:48:29 +0200
Subject: [PATCH] in this config, the stack is being fucked :(

---
 include/kernel/kthread.h |  2 ++
 init/main.c              | 64 +++++++++++++++++++++++++++++-----------
 kernel/sched/edf.c       | 34 ++++++++++++++-------
 3 files changed, 71 insertions(+), 29 deletions(-)

diff --git a/include/kernel/kthread.h b/include/kernel/kthread.h
index ab0c7a8..89598fd 100644
--- a/include/kernel/kthread.h
+++ b/include/kernel/kthread.h
@@ -76,6 +76,8 @@ struct task_struct {
 	 */
 	int				unused;
 
+	ktime				last_visit;
+	ktime				last_adjust;
 	ktime				runtime; /* remaining runtime in this period  */
 	ktime				wakeup; /* start of next period */
 	ktime				deadline; /* deadline of current period */
diff --git a/init/main.c b/init/main.c
index 0607103..d6dc232 100644
--- a/init/main.c
+++ b/init/main.c
@@ -45,7 +45,19 @@
 #endif /* GCC_VERSION */
 
 volatile int inc;
-volatile int xa, xb, xc;
+volatile unsigned int xa, xb, xc, xd;
+
+int task0(void *data)
+{
+	while (1) {
+
+		xd++;
+
+	//	printk("t1 %d %llu\n", leon3_cpuid(), ktime_to_us(ktime_get()));
+	//	sched_yield();
+	}
+}
+
 int task1(void *data)
 {
 	while (1) {
@@ -70,12 +82,8 @@ int task2(void *data)
 	//	sched_yield();
 	}
 }
-static int cnt;
-static	ktime buf[1024];
 int task3(void *data)
 {
-	ktime last = 0;
-
 	while (1) {
 #if 0
 		ktime now;
@@ -99,14 +107,19 @@ int task3(void *data)
 }
 #include <kernel/sysctl.h>
 extern ktime sched_last_time;
+	void sched_print_edf_list_internal(struct task_queue *tq, int cpu, ktime now);
 extern uint32_t sched_ev;
-int task0(void *data)
+
+
+extern struct scheduler sched_edf;
+int task_rr(void *data)
 {
 	int last = 0;
 	int curr = 0;
 	char buf1[64];
 
 	uint32_t last_call = 0;
+	int a, b, c, d;
 
 	ktime sched_time;
 	struct sysobj *sys_irq = NULL;
@@ -117,20 +130,19 @@ int task0(void *data)
 	sys_irq = sysset_find_obj(sys_set, "/sys/irl/primary");
 
 
-	int a, b, c;
 	while (1) {
 
-
+#if 0
 		if (sys_irq)
 			sysobj_show_attr(sys_irq, "irl", buf1);
 
 		a = xa;
 		b = xb;
 		c = xc;
+		d = xd;
 		sched_time = sched_last_time;
 		curr = atoi(buf1)/2;
-		printk("%d %d %d %llu ", a, b, c, ktime_get());
-		printk("irq: %s %d per sec; ", buf1, (curr -last));
+		printk("%u %u %u %u %llu ", a, b, c, d, ktime_get());
 //		printk("sched %llu us ", ktime_to_us(sched_last_time));
 		printk("%llu per call ", sched_last_time /sched_ev);
 //		printk("calls %d ", sched_ev - last_call);
@@ -140,6 +152,14 @@ int task0(void *data)
 
 		last = curr;
 		last_call = sched_ev;
+#endif
+
+		sched_print_edf_list_internal(&sched_edf.tq[0], 0, ktime_get());
+		sched_print_edf_list_internal(&sched_edf.tq[1], 1, ktime_get());
+
+
+
+
 		sched_yield();
 	}
 }
@@ -290,14 +310,14 @@ int kernel_main(void)
 #endif
 
 
-#if 1
+#if 0
 
-	t = kthread_create(task0, NULL, KTHREAD_CPU_AFFINITY_NONE, "res");
+	t = kthread_create(task0, NULL, KTHREAD_CPU_AFFINITY_NONE, "task0");
 	sched_get_attr(t, &attr);
 	attr.policy = SCHED_EDF;
 	attr.period       = ms_to_ktime(100);
 	attr.deadline_rel = ms_to_ktime(90);
-	attr.wcet         = ms_to_ktime(30);
+	attr.wcet         = ms_to_ktime(39);
 	sched_set_attr(t, &attr);
 	kthread_wake_up(t);
 #endif
@@ -310,18 +330,18 @@ int kernel_main(void)
 	attr.policy = SCHED_EDF;
 	attr.period       = ms_to_ktime(50);
 	attr.deadline_rel = ms_to_ktime(40);
-	attr.wcet         = ms_to_ktime(31);
+	attr.wcet         = ms_to_ktime(33);
 	sched_set_attr(t, &attr);
 	kthread_wake_up(t);
 #endif
 
-#if 1
+#if 0
 	t = kthread_create(task2, NULL, KTHREAD_CPU_AFFINITY_NONE, "task2");
 	sched_get_attr(t, &attr);
 	attr.policy = SCHED_EDF;
 	attr.period       = ms_to_ktime(40);
-	attr.deadline_rel = ms_to_ktime(25);
-	attr.wcet         = ms_to_ktime(20);
+	attr.deadline_rel = ms_to_ktime(22);
+	attr.wcet         = ms_to_ktime(17);
 	sched_set_attr(t, &attr);
 	kthread_wake_up(t);
 #endif
@@ -332,12 +352,20 @@ int kernel_main(void)
 	attr.policy = SCHED_EDF;
 	attr.period       = ms_to_ktime(80);
 	attr.deadline_rel = ms_to_ktime(70);
-	attr.wcet         = ms_to_ktime(10);
+	attr.wcet         = ms_to_ktime(13);
 	sched_set_attr(t, &attr);
 	kthread_wake_up(t);
 #endif
 
 
+#if 0
+	t = kthread_create(task_rr, NULL, KTHREAD_CPU_AFFINITY_NONE, "task_rr");
+	sched_get_attr(t, &attr);
+	attr.policy = SCHED_RR;
+	attr.priority = 1;
+	sched_set_attr(t, &attr);
+	kthread_wake_up(t);
+#endif
 
 #endif
 
diff --git a/kernel/sched/edf.c b/kernel/sched/edf.c
index 5617fb3..f7b88b4 100644
--- a/kernel/sched/edf.c
+++ b/kernel/sched/edf.c
@@ -27,8 +27,8 @@ void sched_print_edf_list_internal(struct task_queue *tq, int cpu, ktime now)
 	ktime prev = 0;
 	ktime prevd = 0;
 
-	printk("\nktime: %lld\n", ktime_to_ms(now));
-	printk("S\tDeadline\tWakeup\t\tdelta W\tdelta P\tt_rem\ttotal\tslices\tName\twcet\tavg\n");
+	printk("\nktime: %lld CPU %d\n", ktime_to_ms(now), cpu);
+	printk("S\tDeadline\tWakeup\t\tdelta W\tdelta P\tt_rem\ttotal\tslices\tName\t\twcet\tavg\n");
 	printk("---------------------------------------------------------------------------------------------------------------------------------\n");
 	list_for_each_entry_safe(tsk, tmp, &tq->run, node) {
 
@@ -104,11 +104,16 @@ static inline bool schedule_edf_can_execute(struct task_struct *tsk, int cpu, kt
 
 
 	/* should to consider twice the min tick period for overhead */
+	if (tsk->runtime < 0)
+		return false;
+
 	if (tsk->runtime <= (tick_get_period_min_ns() << 1))
 		return false;
 
 	to_deadline = ktime_delta(tsk->deadline, now);
 
+	barrier();
+	tsk->last_visit = now;
 	/* should to consider twice the min tick period for overhead */
 	if (to_deadline <= (tick_get_period_min_ns() << 1))
 		return false;
@@ -119,25 +124,31 @@ static inline bool schedule_edf_can_execute(struct task_struct *tsk, int cpu, kt
 
 static inline void schedule_edf_reinit_task(struct task_struct *tsk, ktime now)
 {
+	ktime new_wake;
+	
+	BUG_ON(tsk->runtime == tsk->attr.wcet);
+
 	tsk->state = TASK_IDLE;
 
-	tsk->wakeup = ktime_add(tsk->wakeup, tsk->attr.period);
+	new_wake = ktime_add(tsk->wakeup, tsk->attr.period);
 #if 1
 	/* need FDIR procedure for this situation */
-	if (ktime_after(now, tsk->wakeup)){ /* deadline missed earlier? */
-		printk("%s delta %lld\n",tsk->name, ktime_us_delta(tsk->wakeup, now));
-		printk("%s violated, %lld %lld, dead %lld wake %lld now %lld start %lld\n", tsk->name,
-		       tsk->runtime, ktime_us_delta(tsk->deadline, now),
-		       tsk->deadline, tsk->wakeup, now, tsk->exec_start);
+	if (ktime_after(now, new_wake)){ /* deadline missed earlier? */
+		printk("%s violated, rt: %lld %lld, last_visit %lld, last_adjust %lld delta %lld next wake: %lld %llx\n", tsk->name,
+		       tsk->runtime, ktime_to_us(tsk->last_visit), ktime_to_us(tsk->last_adjust), ktime_us_delta(tsk->last_visit, tsk->last_adjust), ktime_to_us(tsk->wakeup), tsk->attr.period);
 		sched_print_edf_list_internal(&tsk->sched->tq[tsk->on_cpu], tsk->on_cpu, now);
 		BUG();
 	}
 #endif
 
+	tsk->wakeup = new_wake;
+
 	tsk->deadline = ktime_add(tsk->wakeup, tsk->attr.deadline_rel);
 
 	tsk->runtime = tsk->attr.wcet;
 
+	tsk->last_adjust = now;
+
 	tsk->slices++;
 }
 
@@ -252,7 +263,7 @@ static ktime edf_hyperperiod(struct task_queue tq[], int cpu, const struct task_
  *
  *	 XXX function needs adaptation
  */
-#define UTIL_MAX 0.8
+#define UTIL_MAX 0.9
 static int edf_schedulable(struct task_queue tq[], const struct task_struct *task)
 {
 	struct task_struct *tsk = NULL;
@@ -364,6 +375,7 @@ if (1)
 	printk("t0: %s (cpu %d)\n", t0->name, cpu);
 	h = p / t0->attr.period;
 
+	h = 1;
 	printk("Period factor %lld, duration %lld actual period: %lld\n", h, ktime_to_ms(p), ktime_to_ms(t0->attr.period));
 
 
@@ -554,7 +566,7 @@ if (1)
 		printk("changed task mode to RR\n", u);
 	}
 
-	printk("Utilisation: %g\n---\n", u);
+	printk("Utilisation: %g CPU %d", u, cpu);
 
 
 	/* TODO check against projected interrupt rate, we really need a limit
@@ -917,7 +929,7 @@ ktime edf_task_ready_ns(struct task_queue *tq, int cpu, ktime now)
 }
 
 
-static struct scheduler sched_edf = {
+struct scheduler sched_edf = {
 	.policy           = SCHED_EDF,
 	.pick_next_task   = edf_pick_next,
 	.wake_next_task   = edf_wake_next,
-- 
GitLab