BarryServer : Git

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

// Related

Nucleus

Barry Improved context switching and interrupt handling d46e09a (3 years, 2 months ago)
diff --git a/task/scheduler.c b/task/scheduler.c
index 485301e..b35192c 100644
--- a/task/scheduler.c
+++ b/task/scheduler.c
@@ -11,6 +11,10 @@
 
 #define PRIORITY_COUNT 6
 
+void context_switch(uintptr_t eip, page_dir_t pagedir,
+                    uintptr_t esi, uintptr_t edi, uintptr_t ebx,
+                    uintptr_t ebp, uintptr_t esp);
+
 ObjectList *readyQueue[PRIORITY_COUNT];
 
 /* Switch to a task */
@@ -20,6 +24,9 @@ switch_to_task(Task *task)
 	/* Save current task state */
 	if (__builtin_expect(!!current, 1)) {
 		lock(current);
+		asm volatile("mov %%esi, %0" : "=r" (current->esi));
+		asm volatile("mov %%edi, %0" : "=r" (current->edi));
+		asm volatile("mov %%ebx, %0" : "=r" (current->ebx));
 		asm volatile("mov %%esp, %0" : "=r" (current->esp));
 		asm volatile("mov %%ebp, %0" : "=r" (current->ebp));
 		current->eip = (uintptr_t) &&end;
@@ -28,22 +35,9 @@ switch_to_task(Task *task)
 	}
 
 	/* Switch to new context */
-	uintptr_t eip, esp, ebp;
 	current = task; /* Given reference, so no get() */
-	eip = current->eip;
-	esp = current->esp;
-	ebp = current->ebp;
-	asm volatile (
-		"cli;"
-		"movl %0, %%ecx;"
-		"movl %1, %%esp;"
-		"movl %2, %%ebp;"
-		"movl %3, %%cr3;"
-		"sti;"
-		"jmp *%%ecx"
-		:: "g" (eip), "g" (esp),
-		   "g" (ebp), "g" (current->pageDir)
-	);
+	context_switch(current->eip, current->pageDir, current->esi,
+	               current->edi, current->ebx, current->ebp, current->esp);
 end:
 	/* This prevents GCC from optimising the jump to be after the return */
 	asm volatile("":::"memory");