/* * This file is in control of initialising the tasking subsystem. It also * implements the Task object. */ #include #include #include #include #include #include #include #include void timer_handler(struct InterruptFrame *frame); void syscall_handler(struct InterruptFrame *frame); static void task_new(Object *); static void task_delete(Object *); /* Task object type */ ObjectType taskType = { .name = "TASK", .size = KERNEL_STACK_SIZE, //sizeof(Task), .new = task_new, .delete = task_delete, }; extern char stackTop[]; /* Create a new Task */ static void task_new(Object *obj) { static pid_t tid = 1; Task *task = (void *) obj; task->tid = tid++; task->tgid = task->tid; task->priority = NORMAL; task->state = READY; } /* Destroy a Task object */ static void task_delete(Object *obj) { Task *task = (void *) obj; if (task->executable) put(task->executable); if (task->target) put(task->target); if (task->wait) destroy_list(task->wait); if (task->fs) put(task->fs); if (task->files) put(task->files); if (task->vm) put(task->vm); if (task->signals) put(task->signals); } /* Initialise tasking */ void init_tasking(void) { current = new(&taskType); current->state = RUNNING; /* File System namespace */ current->fs = new(&fsType); /* Files namespace */ current->files = new(&filesType); /* Virtual Memory namespace */ current->vm = new(&virtualMemoryType); /* Signals namespace */ current->signals = new(&signalsType); cpu->scheduler->tasks = 1; register_interrupt(0, timer_handler); register_exception(128, syscall_handler); set_kernel_stack((uintptr_t) current + KERNEL_STACK_SIZE); } /* Get the current task's PID */ pid_t getpid(void) { return current->tgid; } /* Block a task */ void block_task(enum State reason, ObjectList *list) { lock(current); current->state = reason; if (list) add(list, current); unlock(current); schedule(); } /* Unblock a task */ void unblock_task(Task *task) { lock(task); task->state = READY; unlock(task); enqueue_task(task); } /* Find a task by ID */ Task * find_task(pid_t tid) { Task *task = NULL; foreach (taskType.objects, task) { if (task->tid == tid) break; } return task; }