I post the code:
This is the interrupt handler of the pit:
Code: Select all
asm(".globl pit_ISR \n"
"pit_ISR: \n"
"cli \n"
"pusha \n"
"movl %esp, %eax \n"
"pushl %eax \n"
"call pit_handler \n"
"popl %eax \n"
"mov %eax, %esp \n"
"popa \n"
"sti \n"
"iret \n");
Code: Select all
void task1(void);
void task2(void);
void task3(void);
void task4(void);
void switch_task(unsigned int stack)
{
asm("mov %0, %%esp /*reimposto lo stack*/ \n" "popa /*ripristino tutti i registri*/ \n" "sti /*riabilito gli interrupt*/ \n" "iret /*esco dall'interrupt */ \n": :"a"(stack));
}
void *make_tss(void (*func) (), void (*end_func) ())
{
struct TSS *mytss = (struct TSS *) ((unsigned int) malloc(0x5000) + 0x5000 - 100);
mytss->eip = (unsigned int) func;
mytss->cs = 8;
mytss->eflags = 0x202;
mytss->fine = (unsigned int)end_func;
return mytss;
}
void del_tss(void *tss)
{
free(tss);
return;
}
struct task_descriptor tasks[1000];
unsigned int current_task = 0;
unsigned int num_task = 1;
int active = 0;
unsigned int tasktask=2;
volatile unsigned int tick;
unsigned int find_next_task()
{
do
if(++tasktask >= num_task)
tasktask=0;
while(tasks[tasktask].stato != ESECUZIONE);
return tasktask;
}
void scheduler(unsigned int * stack)
{
if (!active)
return;
unsigned int one_task;
tasks[current_task].esp = *stack;
one_task = find_next_task();
switch (tasks[one_task].stato)
{
case ESECUZIONE:
current_task = one_task;
*stack = tasks[current_task].esp;
//switch_task(*stack);
break;
case ADDORMENTATO:
if (tasks[one_task].dormo.tick)
{
if ((tasks[one_task].dormo.tick + tasks[one_task].dormo.secondi) <= tick)
{
tasks[one_task].stato = ESECUZIONE;
current_task = one_task;
*stack = tasks[current_task].esp;
//switch_task(*stack);
}
else
{
scheduler(stack);
}
}
else
{
scheduler(stack);
}
break;
case MORTO:
del_tss(tasks[one_task].tss);
scheduler(stack);
break;
}
}
void attiva_scheduler()
{
active = 1;
}
void disattiva_scheduler()
{
active = 0;
}
void init_scheduler()
{
active = 1;
current_task = 0;
add_task(task1, "Task 1");
add_task(task2, "Task 2");
add_task(task3, "Task 3");
add_task(task4, "Task 4");
return;
}
unsigned int add_task(void (*func) (), char *nome)
{
asm("cli");
//kout << endl << num_task << " task creato" << endl;
tasks[num_task].tss = (void *)make_tss(func, suicide);
tasks[num_task].esp = (unsigned int) tasks[num_task].tss;
//imposto il nome del task
strncpy(tasks[num_task].nome, nome, 50);
//ne imposto lo stato
tasks[num_task].stato = ESECUZIONE;
tasks[num_task].process_id = num_task;
++num_task;
asm("sti");
return num_task - 1;
}
unsigned int get_current_task()
{
return current_task;
}
void kill(unsigned int id)
{
tasks[id].stato = MORTO;
while (1);
}
char *get_task_name(unsigned int id, char *nome)
{
strcpy(nome, tasks[id].nome);
return nome;
}
void suicide()
{
kill(get_current_task());
}
void sleep(unsigned int centesimi)
{
asm("cli");
tasks[get_current_task()].stato = ADDORMENTATO;
tasks[get_current_task()].dormo.tick = tick;
tasks[get_current_task()].dormo.secondi = centesimi;
asm("sti");
while (tick == tasks[get_current_task()].dormo.tick);
}
void addormenta(unsigned int pid)
{
asm("cli");
tasks[pid].stato = ADDORMENTATO;
tasks[pid].dormo.tick = 0;
if (pid == get_current_task()) {
unsigned int mytick = tick;
asm("sti");
while (tick == mytick);
}
else
{
asm("sti");
}
}
void sveglia(unsigned int pid)
{
tasks[pid].stato = ESECUZIONE;
}
void task1()
{
printf("CIAO");
while(1);
}
void task2()
{
char asssd = getch();
printf(asssd);
while(1);
}
void task3()
{
printf("HALO");
while(1);
}
void task4()
{
printf("Who Ming");
while(1);
}
Code: Select all
#define ESECUZIONE 1
#define ADDORMENTATO 2
#define MORTO 3
struct sleep_t
{
unsigned int tick;
unsigned int secondi;
};
struct task_descriptor
{
unsigned int esp;
void *tss;
char nome[50];
unsigned int process_id;
int stato;
struct sleep_t dormo;
};
Code: Select all
struct TSS
{
unsigned int edi; //+0
unsigned int esi; //+1
unsigned int ebp; //+2
unsigned int null; //+3
unsigned int ecx; //+4
unsigned int edx; //+5
unsigned int ebx; //+6
unsigned int eax; //+7
unsigned int eip; //+8
unsigned int cs; //+9
unsigned int eflags; //+10
unsigned int fine;
};