BarryServer : Git

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

// Related

Nucleus

Barry Kernel threads + threads share address space 6217f0d (3 years, 1 month ago)
/*
 * This file is in control of initialising the tasking subsystem.  It also
 * implements the Task object.
 */

#include <stddef.h>
#include <stdint.h>
#include <nucleus/cpu.h>
#include <nucleus/lib.h>
#include <nucleus/memory.h>
#include <nucleus/object.h>
#include <nucleus/task.h>
#include <nucleus/vfs.h>

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;
}