Page 1 of 1

multitask switch base software

Posted: Thu Jun 21, 2012 6:52 am
by orighost
I just want to realize multitask switch base software.

//the main function

Code: Select all

    // the stack size: 4k.   move the pointer to the end
    uint32_t *stack = kmalloc(0x400) + 0x3F0;

    //0x567 is arbitrarily
    thread_t *t = create_thread(&fn, (void*)0x567, stack);
    init_scheduler(t);
    uint32_t *stack1 = kmalloc(0x400) + 0x3F0;
    thread_t *t1 = create_thread(&fn1, (void*)0x567, stack1);

    init_timer(20);
    asm volatile("sti");
	for(;;) ;
//the create thread function

Code: Select all

thread_t *create_thread(int (*fn)(void*), void *arg, uint32_t *stack)
{
    thread_t *thread = (thread_t*)kmalloc(sizeof(thread_t));
    memset(thread, 0, sizeof(thread_t));
    thread->id = next_tid++;

    *--stack = (uint32_t)arg;
    *--stack = (uint32_t)&thread_exit;
    *--stack = (uint32_t)fn;

    thread->esp = (uint32_t)stack;
    thread->ebp = 0;
    thread->eflags = 0x200;
    thread_is_ready(thread);
    return thread;
}
//the schedule algorithm

Code: Select all

void schedule()
{
    if(!ready_queue) return;        //deque empty

    //iterator through the ready queue to the end
    thread_list_t *iterator = ready_queue;
    while(iterator->next)
        iterator = iterator->next;

    //add the old thread to the end of the deque, and remove it from the start
    iterator->next = current_thread;
    current_thread->next = 0;
    thread_list_t *new_thread = ready_queue;
    ready_queue = ready_queue->next;

    //switch to the new thread.
    switch_thread(new_thread);
}
// timer callback function

Code: Select all

static void timer_callback(registers_t *regs)
{
    tick++;
//    if(tick%20)
//        return;

    monitor_write("Tick: ");
    monitor_write_dec(tick);
    monitor_write("\n");
    schedule();
}
//test functions

Code: Select all

int fn(void *arg)
{
    for(;;)
    {
        monitor_write("a");
    }

    return 0;
}

int fn1(void *arg)
{
    for(;;)
    {
        monitor_write("b");
    }
    return 0;
}

Code: Select all

switch_thread:
    mov eax, [current_thread]   ;assign the pointer address to eax
    mov eax, [eax]

    mov [eax+0],  esp           ; save
    mov [eax+4],  ebp
    mov [eax+8],  ebx
    mov [eax+12], esi
    mov [eax+16], edi

    pushf                       ; update eflags
    pop ecx
    mov [eax+20], ecx

    mov eax, [esp+4]            ; argument: pointer address

    mov [current_thread], eax   ; update pointer
    mov eax, [eax]              ; the read current_thread object

    mov esp, [eax+0]            ; load
    mov ebp, [eax+4]
    mov ebx, [eax+8]
    mov esi, [eax+12]
    mov edi, [eax+16]

    mov eax, [eax+20]           ; load eflags
    push eax
    popf

    ret                         ; esp: the address of function fn.  Then jmp there
when I run the kernel, I found it loop on the fun1 function and print some "b" on the screen. Through debug it, I found the timer callback function only run one times, and funtion fn didn't run,at the same time IF flags was enabled.

Re: multitask switch base software

Posted: Thu Jun 21, 2012 8:01 am
by Combuster
I found the timer callback function only run one times
-1 for not reading the FAQ
-1 for not reducing the problem

Re: multitask switch base software

Posted: Thu Jun 21, 2012 8:51 am
by orighost
Combuster wrote:
I found the timer callback function only run one times
-1 for not reading the FAQ
-1 for not reducing the problem
I have read it . When I comment the schedule function call, the timer callback function work well.So the timer interrupt has no problem.

Re: multitask switch base software

Posted: Thu Jun 21, 2012 10:36 am
by Combuster
So your schedule function is the thing breaking interrupts? (interrupts not working, FAQ, checklist, hint hint).

Re: multitask switch base software

Posted: Thu Jun 21, 2012 10:39 am
by bluemoon
orighost wrote:I found the timer callback function only run one times
What's the call path from timer irq to timer_callback and task switch? are you sure you have EOI?

Furthermore, you thread function do not gracefully withdraw time-slice, and you it can do thousand of monitor_write loop before timer kicks in.

Re: multitask switch base software

Posted: Thu Jun 21, 2012 9:49 pm
by orighost
For the programe into loop,so it can not reach the stub(send eoi).
Myabe I misunderstand the multitasking switch base software,can anyone descript how to realize it or give me a demo?

Re: multitask switch base software

Posted: Fri Jun 22, 2012 1:34 am
by orighost
I think the interrupt priority is same, so it must wait for the previous interrupt stub 's finish.
I should send eoi sigonal before the iret instruction.

Re: multitask switch base software

Posted: Fri Jun 22, 2012 2:55 am
by JamesM
That looks suspiciously like the code I wrote. What's the difference between your code and the sample code on my website? (that'll help you narrow down the problem).

Perhaps you're not sending an EOI to the timer after you switch threads.

Re: multitask switch base software

Posted: Sun Jun 24, 2012 8:57 pm
by orighost
I have rewrite this part code, and it works. But when it run some times,occured the error that "gethostmemaddr voted direct read ad [addr]". I don't known what does it mean.

Re: multitask switch base software

Posted: Mon Jun 25, 2012 12:59 am
by Combuster
orighost wrote:"gethostmemaddr voted direct read ad [addr]". I don't known what does it mean.
Typically, executing code from MMIO (or anywhere else you can't sanely be running code from). Which in turn typically means stack corruption.

You might have asked yourself the other question: why would your code be accessing that specific address?