tasks will not switch? [FIXED]
Posted: Sat Jun 17, 2006 9:40 am
Hi all, I have made my kernel use a variable to keep track of my running process (RUNNING_PROCESS), but now my kernel no longer switches what it does is just stay on the same task and I know the handler is being called and the scheduler works because task table says RUNNING_PROCESS is changing but it's stack doesn't pop or something ??? heres some code:
and the asm:
I hope someone can trace though (_task_timer is called first) and find a problem, becouse I am having trouble, thx!
Code: Select all
struct task_data
{
int ring;
struct stack_data *stack;
unsigned int stack_base;
char name[33];
unsigned int ss;
unsigned int kstack;
unsigned int PID;
unsigned int P_PID;
unsigned int time;
unsigned int priority;
unsigned int state;
struct task_data *prev;
};
Code: Select all
struct task_data * HEAD = NULL;
struct task_data * RUNNING_PROCESS = NULL;
void task0()
{
while(1)
{
puts("a");
}
}
void task1()
{
while(1)
{
puts("b");
}
}
void TaskTable(void)
{
struct task_data *p;
printf("\nTask Data:\n");
for(p = HEAD; p != NULL ;p = p -> prev)
{
char *state;
switch(p -> state)
{
case READY:
state="Ready";
break;
case RUNNING:
state="Running";
break;
case BLOCKED:
state="Blocked";
break;
case TERMINATED:
state="Terminated";
break;
default:
state="???";
break;
}
printf("\tPID %d (%s) is %s, ticks: %d\n", p->PID, (p -> ring == 3?"User":"Kernel"), state, p -> time);
}
}
int cur_task_time()
{
return RUNNING_PROCESS -> time;
}
int cur_task_pri()
{
return RUNNING_PROCESS -> priority;
}
void select()
{
if(RUNNING_PROCESS->state == RUNNING)
RUNNING_PROCESS->state = READY;
for(;;)
{
RUNNING_PROCESS = RUNNING_PROCESS->prev;
if(RUNNING_PROCESS == NULL)
RUNNING_PROCESS = HEAD;
if(RUNNING_PROCESS->state == READY)
break;
}
RUNNING_PROCESS->state = RUNNING;
}
void dec_cur_task_time()
{
RUNNING_PROCESS -> time--;
}
void cur_task_time_equ(int time)
{
RUNNING_PROCESS -> time = time;
}
int get_pri_time(int pri)
{
switch(pri)
{
case 0:
return 100;
break;
case 1:
return 10;
break;
case 2:
return 5;
break;
case 3:
return 2;
break;
case 4:
return 1;
break;
default:
return 0;
}
}
struct stack_data *schedule(struct stack_data *regs)
{
cur_task_time_equ(get_pri_time(cur_task_pri()));
RUNNING_PROCESS -> stack = regs;
select();
return RUNNING_PROCESS -> stack;
}
struct stack_data *task_timer_c(struct stack_data *regs)
{
clock();
outport(0x20, 0x20);
if(cur_task_time() > 0)
{
RUNNING_PROCESS -> time--;
return regs;
}
else
return schedule(regs);
}
void add_process(struct task_data *process)
{
process->prev = HEAD;
HEAD = process;
if(RUNNING_PROCESS == NULL)
RUNNING_PROCESS = process;
}
int remove_process(struct task_data *process)
{
struct task_data *temp;
if(process == NULL)
return 1;
if(process->PID == KERNEL_PID)
return 1;
if(process == HEAD)
{
HEAD = process->prev;
return 0;
}
else
{
for(temp = HEAD; temp != NULL; temp = temp->prev)
{
if(temp->prev == process)
{
temp->prev = process->prev;
return 0;
}
}
}
return 1;
}
void start_sys()
{
add_process(make_task("NOT_DOING_NOTHIN'_TASK", task0, 0));
add_process(make_task("task0", task0, 0));
add_process(make_task("task1", task1, 0));
set_a_idt(32, (unsigned)task_timer, 0x08, 0x8E);
}
Code: Select all
[BITS 32]
SECTION .text
KERNEL_DATA_SEL equ 0x10
GLOBAL _curr_task
GLOBAL _task_timer
EXTERN _task_timer_c
EXTERN _RUNNING_PROCESS
EXTERN _TSS
_task_timer:
cli
pushad
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
call _task_timer_c
pop eax
mov esp, eax
noswitch:
pop gs
pop fs
pop es
pop ds
popad
iretd