From c07ff5000bc27fba9639a34f84bd1f2af8c313d4 Mon Sep 17 00:00:00 2001
From: Ollrogge <nils-ollrogge@outlook.de>
Date: Wed, 14 Sep 2022 11:37:31 +0200
Subject: [PATCH] pb.c: handle dead program before we start

---
 kernel/sched/pb.c                 | 26 +++++++++++++++++++++++---
 pb_utils/pb_submitter/test_prog.c |  8 ++++----
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/kernel/sched/pb.c b/kernel/sched/pb.c
index 704c6f03da93..31b59f1ffba9 100644
--- a/kernel/sched/pb.c
+++ b/kernel/sched/pb.c
@@ -137,7 +137,7 @@ EXPORT_SYMBOL(set_pb_plan_entry);
 // called by core.c sched_init
 void init_pb_rq(struct pb_rq *pb_rq)
 {
-	pb_rq->n_pb_cycles = 20;
+	pb_rq->n_pb_cycles = 100;
 	pb_rq->count_pb_cycles = 0;
 	pb_rq->n_admin_cycles = 20;
 	pb_rq->count_admin_cycles = 0;
@@ -192,6 +192,20 @@ static struct task_struct * pick_next_task_pb(struct rq *rq,
 	next_mode = determine_next_mode_pb(rq);
 	pb->mode = next_mode;
 
+	/**
+	 * This handles the case where the program to be run is dead before the
+	 * pb scheduler starting executing
+	 */
+	if (current_mode == PB_DISABLED_MODE && current_mode != next_mode) {
+		if (pb->c_entry < pb->size && pb->plan[pb->c_entry].task_struct->state == TASK_DEAD) {
+			pb->mode = PB_DISABLED_MODE;
+			next_mode = PB_DISABLED_MODE;
+			picked = NULL;
+			pb->is_initialized = 0;
+			printk(KERN_WARNING "PLAN TERMINATED PREMATURELY \n");
+		}
+	}
+
 	if (current_mode != next_mode) {
 		printk("SWITCHING MODES\n");
 		pb->count_admin_cycles = 0;
@@ -243,7 +257,7 @@ static struct task_struct * pick_next_task_pb(struct rq *rq,
 		 * Don't schedule a task that is dead. (e.g. plan was incorrect and program finished quicker)
 		 * todo: if we have multiple tasks structs just try the next plan entry
 		 */
-		if (pb->plan[pb->c_entry].task_struct->state == TASK_DEAD) {
+		if (pb->c_entry < pb->size && pb->plan[pb->c_entry].task_struct->state == TASK_DEAD) {
 			premature_finish = true;
 		}
 
@@ -258,7 +272,13 @@ static struct task_struct * pick_next_task_pb(struct rq *rq,
 			next_mode = PB_DISABLED_MODE;
 			picked = NULL;
 			pb->is_initialized = 0;
-			printk(KERN_WARNING "PLAN DONE \n");
+
+			if (premature_finish) {
+				printk(KERN_WARNING "PLAN TERMINATED PREMATURELY \n");
+			}
+			else {
+				printk(KERN_WARNING "PLAN DONE \n");
+			}
 		}
 		pb->is_in_critical = false;
 		printk("DONE");
diff --git a/pb_utils/pb_submitter/test_prog.c b/pb_utils/pb_submitter/test_prog.c
index 3c28f823f380..a1260e89cfbf 100644
--- a/pb_utils/pb_submitter/test_prog.c
+++ b/pb_utils/pb_submitter/test_prog.c
@@ -3,16 +3,16 @@
 
 int main(void)
 {
+    // Make sure program is not finished before pb scheduler takes control
     sleep(1);
-    unsigned int c = 0;
     int a = 0;
     int b = 0;
     for (;b < 100; b++) {
-      // check if program runs && syscall to switch tasks
-      puts("loop");
       for (;a < 100000; a++){asm("");}
+      // check if program runs && syscall to switch tasks
+      printf("loop run: %d \n", b);
+      usleep(1);
     }
-    c++;
     return 0;
 }
 
-- 
GitLab