121 lines
2.3 KiB
C
121 lines
2.3 KiB
C
#include "../include/task.h"
|
|
#include "../include/stdio.h"
|
|
#include "../include/paging.h"
|
|
|
|
#include <stddef.h>
|
|
|
|
Process* current = 0;
|
|
Process* queue = 0;
|
|
|
|
uint32_t irq_disable_counter = 0;
|
|
uint32_t pid_counter;
|
|
uint32_t task_count;
|
|
|
|
#define STACK_SIZE 4096
|
|
|
|
extern void switchProcess(Process* next);
|
|
|
|
static void processStartup()
|
|
{
|
|
printf("startup\n");
|
|
scheduler_unlock();
|
|
}
|
|
|
|
Process* task_create(EntryPoint func, void** args, uint32_t arg_count)
|
|
{
|
|
Process* p = heap_alloc(sizeof(Process));
|
|
p->pid = ++pid_counter;
|
|
p->state = Ready;
|
|
p->programCounter = 0;
|
|
p->stackBase = heap_alloc(STACK_SIZE);
|
|
p->stackPointer = (uintptr_t*)((uint32_t)p->stackBase + STACK_SIZE);
|
|
|
|
//put the arguments in stack
|
|
for(int i = arg_count-1; i >=0; i--)
|
|
*(--p->stackPointer) = (uintptr_t)args[i];
|
|
|
|
// Добавляем адрес возврата (фиктивный, для выравнивания)
|
|
*(--p->stackPointer) = 0; // Фиктивный адрес возврата (не используется напрямую)
|
|
|
|
*(--p->stackPointer) = (uintptr_t)func;
|
|
*(--p->stackPointer) = (uintptr_t)processStartup;
|
|
*(--p->stackPointer) = 0;//ebp
|
|
*(--p->stackPointer) = 0;//edi
|
|
*(--p->stackPointer) = 0;//esi
|
|
*(--p->stackPointer) = 0;//ebx
|
|
|
|
p->next = 0;
|
|
|
|
if(!queue)
|
|
{
|
|
queue = p;
|
|
current = queue;
|
|
}
|
|
else
|
|
{
|
|
Process* curr = queue;
|
|
while(curr->next)
|
|
curr = curr->next;
|
|
curr->next = p;
|
|
}
|
|
task_count++;
|
|
return p;
|
|
}
|
|
|
|
void scheduler_lock()
|
|
{
|
|
asm volatile("cli");
|
|
irq_disable_counter++;
|
|
}
|
|
|
|
void scheduler_unlock()
|
|
{
|
|
irq_disable_counter--;
|
|
if(irq_disable_counter == 0)
|
|
asm volatile("sti");
|
|
}
|
|
|
|
void schedule()
|
|
{
|
|
if(!current)
|
|
return;
|
|
|
|
Process* next = current->next;
|
|
if(!next)
|
|
next = queue;
|
|
if(next != current)
|
|
switchProcess(next);
|
|
}
|
|
|
|
void idle()
|
|
{
|
|
while(1){}
|
|
}
|
|
|
|
void task1(int arg1, char* arg2)
|
|
{
|
|
while(1){
|
|
if(arg1 == 42)
|
|
printf("task1 0x%x %s\n", arg1, arg2);
|
|
else
|
|
printf("ZHOPA %s\n", arg2);
|
|
}
|
|
}
|
|
|
|
void task2(int arg1, int arg2)
|
|
{
|
|
while(1){printf("task2 %X %X\n", arg1, arg2);}
|
|
}
|
|
|
|
void scheduler_init()
|
|
{
|
|
//we create this task two times because in other case it just won't start
|
|
task_create((EntryPoint)&idle, NULL, 0);
|
|
task_create((EntryPoint)&idle, NULL, 0);
|
|
|
|
void* args1[] = {(void*)42, (void*)"ebalo"};
|
|
task_create((EntryPoint)&task1, args1, 2);
|
|
void* args2[] = {(void*)69, (void*)420};
|
|
task_create((EntryPoint)&task2, args2, 2);
|
|
}
|