BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / 64f99b69846435d14a53742b996a850223f49f5e / task / task.c

// Related

Nucleus

Barry File system namespace b085b26 (3 years, 3 months ago)
/*
 * 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 init_scheduler(void);
void timer_handler(struct InterruptFrame *frame);

static void task_new(Object *);

/* Task object type */
ObjectType taskType = {
	.size = sizeof(Task),
	.new = task_new,
};

Task *currentTask[MAX_CPUS];
pid_t nextTid = 1;

/* Create a new Task */
static void
task_new(Object *obj)
{
	Task *task = (void *) obj;
	task->tid = nextTid++;
	task->priority = NORMAL;
	task->state = READY;
}

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));
	current->state = RUNNING;

	/* File System namespace */
	current->fs = new(&fsType);

	init_scheduler();
	register_interrupt(0, timer_handler);

}