BarryServer : Git

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

// Related

Nucleus

Barry Multitasking support db9a0c1 (3 years, 3 months ago)
diff --git a/task/task.c b/task/task.c
new file mode 100644
index 0000000..507caae
--- /dev/null
+++ b/task/task.c
@@ -0,0 +1,88 @@
+/*
+ * This file is in control of initialising the tasking subsystem.  It also
+ * implements the Task object.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <nucleus/cpu.h>
+#include <nucleus/task.h>
+#include <nucleus/memory.h>
+#include <nucleus/object.h>
+
+void timer_handler(struct InterruptFrame *frame);
+
+static void *task_new(void);
+static void task_delete(Object *);
+
+/* Task object type */
+ObjectType taskType = {
+	.new = task_new,
+	.delete = task_delete,
+};
+
+Task *currentTask[MAX_CPUS];
+pid_t nextTid = 1;
+
+/* Create a new Task */
+static void *
+task_new(void)
+{
+	Task *task = kmalloc(sizeof(Task));
+	task->tid = nextTid++;
+	task->priority = NORMAL;
+	task->state = READY;
+	return task;
+}
+
+/* Destroy a Task */
+static void
+task_delete(Object *obj)
+{
+	kfree(obj);
+}
+
+extern char stackTop[];
+
+/* Move the stack */
+static void
+move_stack(uintptr_t top, size_t size)
+{
+	size_t offset;
+	uintptr_t oldStack, oldBase;
+	uintptr_t newStack, newBase;
+	top -= sizeof(uintptr_t);
+	asm volatile("mov %%esp, %0" : "=r" (oldStack));
+	asm volatile("mov %%ebp, %0" : "=r" (oldBase));
+	offset = top - (uintptr_t) stackTop;
+	newStack = oldStack + offset;
+	newBase = oldBase + offset;
+
+	memcpy((void *) newStack, (void *) oldStack, (size_t) stackTop - oldStack);
+
+	/* Update pointers on the stack */
+	uintptr_t i, tmp;
+	for (i = top; i > top - size; i -= sizeof(uintptr_t)) {
+		tmp = *(uintptr_t *) i;
+		if (tmp > oldStack && tmp < (uintptr_t) stackTop) {
+			tmp += offset;
+			*(uintptr_t *) i = tmp;
+		}
+	}
+
+	asm volatile("mov %0, %%esp" :: "r" (newStack));
+	asm volatile("mov %0, %%ebp" :: "r" (newBase));
+}
+
+/* Initialise tasking */
+void
+init_tasking(void)
+{
+	move_stack(0xF0800000, 0x2000);
+
+	current = new(&taskType);
+	asm volatile("mov %%cr3, %0" : "=r" (current->pageDir));
+
+	register_interrupt(0, timer_handler);
+}