BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 6063f6693644654ed3fe8ed5c6ca6be311696132

// Related

Nucleus

Barry Fixed scheduler double-schedule bug 6063f66 (3 years, 2 months ago)
diff --git a/include/nucleus/task.h b/include/nucleus/task.h
index 5c3d606..17b5c09 100644
--- a/include/nucleus/task.h
+++ b/include/nucleus/task.h
@@ -39,7 +39,7 @@ struct Task {
 	enum Priority priority;
 	enum State state;
 	uint32_t inCriticalSection;
-	uint8_t inSyscall;
+	uint32_t inSyscall;
 
 	uintptr_t esi, edi, ebx;
 	uintptr_t esp, ebp, eip;
@@ -83,8 +83,24 @@ exit_critical_section(void)
 	__atomic_sub_fetch(&current->inCriticalSection, 1, __ATOMIC_RELAXED);
 }
 
+/* Enter system call context */
+static inline void
+enter_syscall_context(uint32_t syscall)
+{
+	current->inSyscall = syscall;
+}
+/* Exit system call context */
+static inline uint32_t
+exit_syscall_context(void)
+{
+	uint32_t syscall = current->inSyscall;
+	current->inSyscall = 0;
+	return syscall;
+}
+
 void init_tasking(void);
 void block_task(enum State reason, ObjectList *list);
+void unblock_task(Task *task);
 Task *find_task(pid_t tid);
 void schedule(void);
 pid_t clone(int flags);
diff --git a/task/clone.c b/task/clone.c
index 7516f18..fe0ad88 100644
--- a/task/clone.c
+++ b/task/clone.c
@@ -20,6 +20,11 @@ clone(int flags)
 	Task *parent = current, *child = new(&taskType), *tmp;
 	pid_t tid = 0;
 
+	if (flags & CLONE_THREAD) {
+		flags |= CLONE_PARENT;
+		flags |= CLONE_VM;
+	}
+
 	/* Clone parent's file system namespace */
 	if (flags & CLONE_FS)
 		child->fs = get(parent->fs);
diff --git a/task/exec.c b/task/exec.c
index 8f7da4e..d4b4c3d 100644
--- a/task/exec.c
+++ b/task/exec.c
@@ -132,7 +132,7 @@ execve(const char *file, char *argv[], char *envp[])
 	 * POINT OF NO RETURN
 	 */
 
-	current->inSyscall = 0;
+	exit_syscall_context();
 
 	/* Store everything (pointers adjusted) in temporary buffer */
 	uintptr_t esp = 0xE0000000 - ssz;
diff --git a/task/exit.c b/task/exit.c
index 52547b9..4069775 100644
--- a/task/exit.c
+++ b/task/exit.c
@@ -4,11 +4,9 @@
  * tasks and the parent.
  */
 
-#include <nucleus/panic.h>
+#include <nucleus/kernel.h>
 #include <nucleus/task.h>
 
-extern ObjectList *readyQueue[];
-
 /* Terminate the current task */
 _Noreturn void
 terminate(void)
@@ -20,7 +18,7 @@ terminate(void)
 	Task *tmp;
 	while (current->wait && count(current->wait)) {
 		tmp = pop_from_start(current->wait);
-		add(readyQueue[tmp->priority], tmp);
+		unblock_task(tmp);
 		put(tmp);
 	}
 
diff --git a/task/scheduler.c b/task/scheduler.c
index dc7551f..485301e 100644
--- a/task/scheduler.c
+++ b/task/scheduler.c
@@ -6,7 +6,7 @@
  * available.  This avoids the need for an idle task.
  */
 
-#include <nucleus/panic.h>
+#include <nucleus/kernel.h>
 #include <nucleus/task.h>
 
 #define PRIORITY_COUNT 6
@@ -28,7 +28,11 @@ 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;"
@@ -37,8 +41,8 @@ switch_to_task(Task *task)
 		"movl %3, %%cr3;"
 		"sti;"
 		"jmp *%%ecx"
-		:: "g" (current->eip), "g" (current->esp),
-		   "g" (current->ebp), "g" (current->pageDir)
+		:: "g" (eip), "g" (esp),
+		   "g" (ebp), "g" (current->pageDir)
 	);
 end:
 	/* This prevents GCC from optimising the jump to be after the return */
@@ -82,6 +86,8 @@ schedule(void)
 	/* Schedule next task */
 	task = pop_from_start(queue);
 	task->state = RUNNING;
+	if (task == current)
+		return;
 	if (current && current->state == RUNNING) {
 		current->state = READY;
 		add(readyQueue[current->priority], current);
diff --git a/task/task.c b/task/task.c
index a4d137d..597df30 100644
--- a/task/task.c
+++ b/task/task.c
@@ -29,6 +29,7 @@ ObjectType taskType = {
 Task *currentTask[MAX_CPUS];
 pid_t nextTid = 1;
 extern char stackTop[];
+extern ObjectList *readyQueue[];
 
 /* Create a new Task */
 static void
@@ -131,6 +132,16 @@ block_task(enum State reason, ObjectList *list)
 	schedule();
 }
 
+/* Unblock a task */
+void
+unblock_task(Task *task)
+{
+	lock(task);
+	task->state = READY;
+	add(readyQueue[task->priority], task);
+	unlock(task);
+}
+
 /* Find a task by ID */
 Task *
 find_task(pid_t tid)