view cos/kernel/task.c @ 299:674789d9ff37

Added a doc
author Windel Bouwman
date Sun, 01 Dec 2013 18:37:23 +0100
parents 91f91ff07ea8
children
line wrap: on
line source

/* Scheduler functions */

#include "kernel.h"

// global variables:
uint64_t next_pid = 1;
task_t* ready_queue = 0; // Head of the queue of tasks.
task_t* current_task = 0; // Pointer to the currently running task.

void initialize_tasking()
{
   next_pid = 1;
}

/*
  Create a new task with some loaded program.
*/
void new_task()
{
   task_t* newtask = (task_t*)kmalloc(sizeof(task_t));
   newtask->pid = next_pid++;
   newtask->rip = 0;
   newtask->next = 0;

   // Append the new task to the ready queue:
   task_t* task = ready_queue;
   while (task->next != 0)
   {
      task = task->next;
   }
   task->next = newtask;
}

/* Fork function duplicates the process */
void task_fork()
{
   asm volatile("cli"); // Disable interrupts
   task_t *parent_task = current_task;

   // Create new task:
   task_t *new_task = (task_t*)kmalloc(sizeof(task_t));
   new_task->pid = next_pid++;
   new_task->rsp = 0;
   new_task->rbp = 0;
   new_task->rip = 0;
   new_task->next = 0;

   // Append to the queue:
   task_t* tmp_task = ready_queue;
   while (tmp_task->next != 0)
   {
      tmp_task = tmp_task->next;
   }
   tmp_task->next = new_task;

   uint64_t rip = read_rip();

   if (current_task == parent_task)
   {
      uint64_t rbp, rsp;
      asm volatile("mov %%rsp, %0" : "=r"(rsp));
      asm volatile("mov %%rbp, %0" : "=r"(rbp));
      new_task->rip = rip;

      asm volatile("sti");
   }
}

/*
  Scheduler function that switches tasks for multi tasking.
*/
void task_scheduler()
{
   if (current_task == 0)
   {
      return;
   }

   uint64_t rbp, rsp, rip;

   rip = 0;
   rsp = 0;
   rbp = 0;

   current_task->rip = rip; // TODO
   current_task->rsp = rsp;
   current_task->rbp = rbp;

   // Select next task:
   current_task = current_task->next;
   if (current_task == 0)
   {
      current_task = ready_queue;
   }

   // Set the rbp, rsp and rip registers:
   rsp = current_task->rsp;
   rbp = current_task->rbp;
}