BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 571b85e49316f720119ae757e3a983831d91b4ae / task

// Related

Nucleus

Barry Exiting interrupt context on clone() child 571b85e (3 years, 3 months ago)
diff --git a/task/clone.c b/task/clone.c
index 4dd15e7..22d737b 100644
--- a/task/clone.c
+++ b/task/clone.c
@@ -7,6 +7,7 @@
 #include <sys/sched.h>
 #include <nucleus/task.h>
 #include <nucleus/vfs.h>
+#include <io.h>
 
 extern ObjectList *readyQueue[];
 
@@ -14,7 +15,7 @@ extern ObjectList *readyQueue[];
 pid_t
 clone(int flags)
 {
-	uintptr_t ints = irq_disable();
+	enter_critical_section();
 
 	Task *parent = current, *child = new(&taskType), *tmp;
 	pid_t tid = 0;
@@ -41,7 +42,12 @@ clone(int flags)
 	add(readyQueue[child->priority], child);
 	tid = child->tid;
 	put(child);
+	exit_critical_section();
 end:
-	irq_restore(ints);
+	if (!tid) {
+		outb(0x20, 0x20);
+		LAPIC(0xB0) = 0;
+	}
+
 	return tid;
 }
diff --git a/task/scheduler.c b/task/scheduler.c
index 7b08fc2..1bc0f55 100644
--- a/task/scheduler.c
+++ b/task/scheduler.c
@@ -38,6 +38,8 @@ switch_to_task(Task *task)
 		   "g" (current->ebp), "g" (current->pageDir)
 	);
 end:
+	/* This prevents GCC from optimising the jump to be after the return */
+	__atomic_thread_fence(__ATOMIC_ACQ_REL);
 }
 
 /* Find the next schedulable ready queue */
@@ -56,6 +58,9 @@ highest_priority_queue(void)
 void
 schedule(void)
 {
+	if (current->inCriticalSection)
+		return;
+
 	Task *task = current;
 	ObjectList *queue = highest_priority_queue();