Something about multitasking

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.
User avatar
Agola
Member
Member
Posts: 155
Joined: Sun Nov 20, 2016 7:26 am
Location: Somewhere

Something about multitasking

Post by Agola »

Hi forum.

I'm debugging my multitasking code, because sometimes system goes crazy because of multitasking.

I suspect the code that jumps to first task;

Code: Select all

void start_tasking()
{
   asm volatile ("mov %0, %%eax" : : "a"(first_task->regs->eax));
   asm volatile ("mov %0, %%ebx" : : "b"(first_task->regs->ebx));
   asm volatile ("mov %0, %%ecx" : : "c"(first_task->regs->ecx));
   asm volatile ("mov %0, %%edx" : : "d"(first_task->regs->edx));
   asm volatile ("mov %0, %%esi" : : "S"(first_task->regs->esi));
   asm volatile ("mov %0, %%edi" : : "D"(first_task->regs->edi));

   asm volatile ("pushl $0x10"); // ss (kernel)
   asm volatile ("pushl %0" : : "m"(first_task->regs->esp)); // esp
   asm volatile ("pushf"); // flags
   asm volatile ("pushl $0x8"); // cs (kernel)
   asm volatile ("pushl %0" : : "m"(first_task->regs->eip)); // eip
   
   asm volatile("iret"); 
}
It simply uses iret to make cpu pop eip, esp, cs, ss, and flags. For testing I used their default values for flags, ss and cs, but I'm going to change them after tracking the bug.

What can I do?
Other code is good I think. I miss something that in front of my eyes. #-o

Thanks
Last edited by Agola on Thu Jan 26, 2017 1:35 pm, edited 1 time in total.
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: Something about multitasking

Post by dozniak »

You can write this code correctly in the first place.

Have you tried disassembling this pile of poo to see what is actually in there?
Learn to read.
User avatar
Ch4ozz
Member
Member
Posts: 170
Joined: Mon Jul 18, 2016 2:46 pm
Libera.chat IRC: esi

Re: Something about multitasking

Post by Ch4ozz »

You can start coding this in a new asm file.
Your compiler is an ******* (never forget this) and will never do what you say.
It will create function prologue and epilogue if you dont declare the function as naked, it also can mix all the asm lines in terms of order as it likes because you didnt make it into one asm statement.
The next thing is, it usually uses ecx, edx etc as base pointers to dereference values.
So your compiler overwrites all the registers you just set...
Drag this into https://www.onlinedisassembler.com/static/home/ or IDA or whatever disasm you like to check if its what you expected.
User avatar
Agola
Member
Member
Posts: 155
Joined: Sun Nov 20, 2016 7:26 am
Location: Somewhere

Re: Something about multitasking

Post by Agola »

dozniak wrote:You can write this code correctly in the first place.

Have you tried disassembling this pile of poo to see what is actually in there?
Yes, didn't see anything strange.

Code: Select all

   asm volatile ("mov %0, %%eax" : : "a"(first_task->regs->eax));
   asm volatile ("mov %0, %%ebx" : : "b"(first_task->regs->ebx));
   asm volatile ("mov %0, %%ecx" : : "c"(first_task->regs->ecx));
   asm volatile ("mov %0, %%edx" : : "d"(first_task->regs->edx));
   asm volatile ("mov %0, %%esi" : : "S"(first_task->regs->esi));
   asm volatile ("mov %0, %%edi" : : "D"(first_task->regs->edi));
Compiler replaced here with pushes of each member of first_task->regs, and pops of them to registers, which is more elegant I think.

Then does the other pushes and calls iret, nothing strange.
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Something about multitasking

Post by iansjack »

What happens when you single-step through the code in your debugger? At what point does it fail?
User avatar
Agola
Member
Member
Posts: 155
Joined: Sun Nov 20, 2016 7:26 am
Location: Somewhere

Re: Something about multitasking

Post by Agola »

iansjack wrote:What happens when you single-step through the code in your debugger? At what point does it fail?
That happens not very often, so I haven't catch it with debugger yet.
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Something about multitasking

Post by iansjack »

Do you have interrupt handlers for all interrupts and exceptions, including spurious interrupts?
User avatar
Agola
Member
Member
Posts: 155
Joined: Sun Nov 20, 2016 7:26 am
Location: Somewhere

Re: Something about multitasking

Post by Agola »

After debugging, I've just found the problem.

Newlib is not thread-safe. I'm using mutex for thread-safeness, but sometimes it even can't do anything. Then boom, crash.
How can I patch newlib to be thread-safe?

One more possibility is Newlib is already thread-safe and I haven't seen it yet. :|
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.
mikegonta
Member
Member
Posts: 229
Joined: Thu May 19, 2011 5:13 am
Contact:

Re: Something about multitasking

Post by mikegonta »

Agola wrote:After debugging, I've just found the problem.
Newlib is not thread-safe. I'm using mutex for thread-safeness, but sometimes it even can't do anything. Then boom, crash.
How can I patch newlib to be thread-safe?
One more possibility is Newlib is already thread-safe and I haven't seen it yet. :|
Last edited by mikegonta on Sat Apr 01, 2017 10:00 am, edited 2 times in total.
Mike Gonta
look and see - many look but few see

https://mikegonta.com
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Something about multitasking

Post by gerryg400 »

Agola wrote:After debugging, I've just found the problem.

Newlib is not thread-safe. I'm using mutex for thread-safeness, but sometimes it even can't do anything. Then boom, crash.
How can I patch newlib to be thread-safe?

One more possibility is Newlib is already thread-safe and I haven't seen it yet. :|
Which particular part of newlib is not threadsafe?
If a trainstation is where trains stop, what is a workstation ?
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: Something about multitasking

Post by MollenOS »

I'm sorry for being skeptical and all that, but as another person in this thread mentioned that start_tasking code is a pile of poo, and I have a much easier time believing that it's your synchronization code and/or tasking code that is faulty.

Please do write all the tasking code in assembly where you can control prologue and epilogue, otherwise you'll end up destroying the stack. Also post your other tasking code.
User avatar
Agola
Member
Member
Posts: 155
Joined: Sun Nov 20, 2016 7:26 am
Location: Somewhere

Re: Something about multitasking

Post by Agola »

I rewrote the switch to new task code with assembly instead of c with inline assembly.
Then, found a new bug.

iret doesn't pop the esp off, causing a screw on idle task's stack.
Shouldn't iret pop the esp?

Also it even works with jmp with esp and ebp change.
But it need to work with iret, because I will use both user and kernel tasks, requiring cs and ss changes.

Code: Select all

.section .text

.align 16

.global switch_to_first_task
switch_to_first_task:
    push %ebp
    mov %esp, %ebp
    mov 8(%ebp), %eax
    mov 12(%ebp), %ebx
    mov %ebp, %esp
    pop %ebp

    mov %eax, %ebp
    mov %eax, %esp
    jmp %ebx
That works, but it doesn't work (iret doesn't pop the esp off)

Code: Select all

.section .text

.align 16

.global switch_to_first_task
switch_to_first_task:

    push %ebp
    mov %esp, %ebp
    mov 8(%ebp), %eax
    mov 12(%ebp), %ebx
    mov %ebp, %esp
    pop %ebp

    push $0x10
    push %eax
    pushf
    push $0x8
    push %ebx
    iret
Also found here: http://forum.osdev.org/viewtopic.php?f=1&t=24148

I'm afraid my code has more secret bugs that I haven't seen yet.
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: Something about multitasking

Post by MollenOS »

Code: Select all

iret
Only pops ESP and SS off in case you are returning to a Ring3 code-segment, in kernel tasks (Ring0) iret doesn't pop the stack off and stays in the stack it has.
User avatar
Agola
Member
Member
Posts: 155
Joined: Sun Nov 20, 2016 7:26 am
Location: Somewhere

Re: Something about multitasking

Post by Agola »

MollenOS wrote:

Code: Select all

iret
Only pops ESP and SS off in case you are returning to a Ring3 code-segment, in kernel tasks (Ring0) iret doesn't pop the stack off and stays in the stack it has.
Then I should write a seperate IRQ0 handler to prevent stack problems.

Code: Select all

irq_common:
    pusha

    /* Save segment registers */
    push %ds
    push %es
    push %fs
    push %gs

    /* Call interrupt handler */
    push %esp
    call irq_handler
    add $4, %esp

    /* Restore segment registers */
    pop %gs
    pop %fs
    pop %es
    pop %ds

    /* Restore all registers */
    popa
    /* Cleanup error code and IRQ # */
    add $8, %esp
    /* pop CS, EIP, EFLAGS, SS and ESP */
    iret
Then I can easily change the esp. Changing esp with common irq handler is not a good idea.

It pushes all registers to esp, then pushes esp as a pointer of registers_t structure for c irq handler.
Then I change registers from registers_t pointer, so stack.
After it pops to registers, so my register values changes to their new values.

But iret doesn't pop off the esp because of no privilege change. Then esp doesn't change, causes serious bugs sometimes.

I had a big mutitasking problem like that before, then I thought I fixed it, but looks I couldn't.
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.
MollenOS
Member
Member
Posts: 202
Joined: Wed Oct 26, 2011 12:00 pm

Re: Something about multitasking

Post by MollenOS »

Exactly, you need to handle the timer that handles task-switching a bit differently than a irq_common.

While they can share the entry point of the interrupt, you need to code a different exit function for the one that does the task switching, instead of letting the interrupt handler return on a normal way, call a new function next_thread or whatever you want, where you do the special-exit routine
Post Reply