BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / c530261a6ef76632384504044bc0b0519a33938e / task / scheduler.c

// Related

Nucleus

Barry Task queues and full scheduling c530261 (3 years, 3 months ago)
diff --git a/task/scheduler.c b/task/scheduler.c
index 9ad1405..95e3990 100644
--- a/task/scheduler.c
+++ b/task/scheduler.c
@@ -9,6 +9,8 @@
 #include <nucleus/panic.h>
 #include <nucleus/task.h>
 
+TaskQueue *readyQueue[HIGHEST];
+
 /* Read the EIP */
 static uintptr_t
 read_eip(void)
@@ -25,14 +27,13 @@ switch_to_task(Task *task)
 	uintptr_t esp, ebp, eip;
 	asm volatile("mov %%esp, %0" : "=r" (esp));
 	asm volatile("mov %%ebp, %0" : "=r" (ebp));
-	eip = read_eip();
-	if (eip == 0x10032004) /* Magic number */
-		return;
+	eip = (uintptr_t) &&end;
 
 	current->esp = esp;
 	current->ebp = ebp;
 	current->eip = eip;
-	current = task;
+	put(current);
+	current = task; /* Use the passed reference */
 	esp = current->esp;
 	ebp = current->ebp;
 	eip = current->eip;
@@ -43,11 +44,11 @@ switch_to_task(Task *task)
 		"movl %1, %%esp;"
 		"movl %2, %%ebp;"
 		"movl %3, %%cr3;"
-		"movl $0x10032004, %%eax;"
 		"sti;"
 		"jmp *%%ecx"
 		:: "g" (eip), "g" (esp), "g" (ebp), "g" (current->pageDir)
 	);
+end:
 }
 
 /* Schedule the next task */
@@ -55,7 +56,35 @@ void
 schedule(void)
 {
 	Task *task = current;
-	if (!task->next)
-		return;
-	switch_to_task(task->next);
+
+	/* Next schedulable task */
+	if (readyQueue[NORMAL]->start) {
+		task = pop_from_queue(readyQueue[NORMAL]);
+		task->state = RUNNING;
+		if (current->state == RUNNING) {
+			current->state = READY;
+			add_to_queue(readyQueue[current->priority], current);
+		}
+		switch_to_task(task);
+	/* Idle */
+	} else if (current->state != RUNNING) {
+		current = NULL;
+		asm volatile("sti");
+		while (!readyQueue[NORMAL]->start)
+			asm volatile("hlt");
+		asm volatile("cli");
+		current = task;
+		task = pop_from_queue(readyQueue[NORMAL]);
+		task->state = RUNNING;
+		switch_to_task(task);
+	}
+}
+
+/* Initialise the scheduler */
+void
+init_scheduler(void)
+{
+	enum Priority p;
+	for (p = NONE; p <= HIGHEST; p++)
+		readyQueue[p] = new(&taskQueueType);
 }