aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bringelle.c4
-rw-r--r--src/core/scheduler.c58
-rw-r--r--src/core/scheduler.h25
3 files changed, 51 insertions, 36 deletions
diff --git a/src/bringelle.c b/src/bringelle.c
index 38c066e..167e6d5 100644
--- a/src/bringelle.c
+++ b/src/bringelle.c
@@ -49,10 +49,10 @@ void bringelle(){
print("Launch user tasks \n");
int* page_dir=paging_allocate(2);
- task_create(page_dir, utask,100);
+ task_create(page_dir, utask,100, 0xFF);
int* page_dir2=paging_allocate(2);
- task_create(page_dir2, utask2,100);
+ task_create(page_dir2, utask2,100,0xFF);
scheduler_start();
diff --git a/src/core/scheduler.c b/src/core/scheduler.c
index fffeaf2..d046298 100644
--- a/src/core/scheduler.c
+++ b/src/core/scheduler.c
@@ -10,45 +10,44 @@ u16 current_id;
u16 nproc;
void schedule(u32 *stack){
- // Note that this function is called by clock
- // clock is called by INT_CLOCK (core/int.S)
- // which store all the process information on
- // the stack. Thus, knowing the C calling conventions
- // and that schedule() is call by two functions with no parameters,
- // the first process register can be accessed by ebp+2
-
- // No proc to schedule
+ // Note that this function is called by clock()
+ // and clock() is called by INT_CLOCK (cf core/int.S)
+ // which stores all the processes registers on
+ // the stack.
+
+ // No proc to schedule, just skip this function
if(nproc<2)
return;
PROC *p=&procs[current_id];
- p->regs.gs=stack[2]; // ebp+2=gs cf note above
- p->regs.fs=stack[3];
- p->regs.es=stack[4];
- p->regs.ds=stack[5];
- p->regs.edi=stack[6];
- p->regs.esi=stack[7];
- p->regs.ebp=stack[8];
- // We do not take p->regs.esp=stack[9]
+ p->regs.gs=stack[0]; // cf function specification in scheduler.h
+ p->regs.fs=stack[1];
+ p->regs.es=stack[2];
+ p->regs.ds=stack[3];
+ p->regs.edi=stack[4];
+ p->regs.esi=stack[5];
+ p->regs.ebp=stack[6];
+ // We do not take p->regs.esp=stack[7]
// since it corresponds to the kernel stack
// (it was push during the interruption)
- p->regs.edx=stack[10];
- p->regs.ecx=stack[11];
- p->regs.ebx=stack[12];
- p->regs.eax=stack[13];
- p->regs.eip=stack[14];
- p->regs.cs=stack[15];
- p->regs.eflags=stack[16];
- p->regs.esp=stack[17];
- p->regs.ss=stack[18];
-
+ p->regs.edx=stack[8];
+ p->regs.ecx=stack[9];
+ p->regs.ebx=stack[10];
+ p->regs.eax=stack[11];
+ p->regs.eip=stack[12];
+ p->regs.cs=stack[13];
+ p->regs.eflags=stack[14];
+ p->regs.esp=stack[15];
+ p->regs.ss=stack[16];
+
+ // Get the next task to run
current_id++;
if(current_id>=nproc)
current_id=0;
p=&procs[current_id];
// Have a clean stack on next interrupt
- TSS.esp0=(u32)stack+19;
+ TSS.esp0=(u32)stack+17;
asm("mov %%ss, %0": "=m" (TSS.ss0));
// Ensure interrupts are activated and NT flag is clear
@@ -66,6 +65,7 @@ void schedule(u32 *stack){
void clock(){
u32* stack;
asm("mov %%ebp, %0":"=r" (stack));
+ stack=&stack[2]; // Make stack pointing to gs
static int tic=0;
static int sec=0;
@@ -80,11 +80,11 @@ void clock(){
schedule(stack);
}
-void task_create(int *page_dir, void *task, int task_size){
+void task_create(int *page_dir, void *task, int task_size, int stack_offset){
if(nproc<=MAX_PROC){
// Compute various addresses
void *entry_point=PAGING_ENTRY_POINT_VIRT;
- void *ustack=(void*)(PAGING_ENTRY_POINT_VIRT+0xFF);
+ void *ustack=(void*)(PAGING_ENTRY_POINT_VIRT+stack_offset);
// Load the task into memory
memcpy(task,PAGING_ENTRY_POINT_PHY(page_dir), task_size);
diff --git a/src/core/scheduler.h b/src/core/scheduler.h
index fbcf6bd..ecb9428 100644
--- a/src/core/scheduler.h
+++ b/src/core/scheduler.h
@@ -3,7 +3,6 @@
#include "mem.h"
-
#define MAX_PROC 10
// If you change the following struct
@@ -29,11 +28,27 @@ typedef struct PROC {
extern char show_tics;
extern char scheduler_on;
extern PROC procs[MAX_PROC];
-extern u16 current_id;
-extern u16 nproc;
+extern u16 current_id; // Current running task PID/id
+extern u16 nproc; // Number of active tasks
+/**
+ * Must be called at each clock interrupt
+ */
void clock();
-void schedule();
-void task_create(int *page_dir, void *task, int task_size);
+/**
+ * Called by clock() and schedule the next task
+ * Stack is a pointer pointing to the gs register on the stack.
+ * The stack must contains the interrupted process registers in the following
+ * order: gs,fs,es,ds,edi,esi,ebp,UNUSED,edx,ecx,ebx,eax,eip,cs,eflags,esp,ss
+ */
+void schedule(u32 *stack);
+/**
+ * Create a new task to be schedule
+ */
+void task_create(int *page_dir, void *task, int task_size, int stack_offset);
+/**
+ * Stack the scheduler starting by task with PID 0
+ */
void scheduler_start();
+
#endif \ No newline at end of file