tasks will not switch? [FIXED]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
GLneo

tasks will not switch? [FIXED]

Post by GLneo »

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:

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);
}
and the asm:

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
I hope someone can trace though (_task_timer is called first) and find a problem, becouse I am having trouble, thx!
GLneo

Re:tasks will not switch?

Post by GLneo »

I now think some of my problem is the how values are returned, i push the value to send it, pop to get it from a c function, but now after bochs debuging it looks like it returns in eax?

Code: Select all

mov eax, dword ptr ss:[ebp+0xfffffffc]
leave
retn
;<< End C Code
pop eax
mov esp, eax
...
but if i dont pop eax it crashes bochs?

p.s. it seams c and asm just dont mix well :P
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:tasks will not switch?

Post by Pype.Clicker »

the C calling convention state that the caller should be cleaning up the stack, and that the value is returned in eax (or eax:edx).

If you don't want to waste registers in cleaning the stack, you can just do "add esp, 4" instead of "pop eax" :)
rootel77

Re:tasks will not switch?

Post by rootel77 »

push eax
here you push the original stack
call _task_timer_c
after this call, eax contains the new selected stack
pop eax
mov esp, eax
but here, pop eax will set eax (and overwrite the returned value) to the old stack (remember, puhed before the c function call).

As mentionned by Pype.Clicker, write "add esp, 4" instead of "pop eax" and the pb will be solved.
GLneo

Re:tasks will not switch?

Post by GLneo »

IT WORKED!!!, i've been working on this for several weeks, you guys are great!, thx ;D
Post Reply