Multiple thread switching issue

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
prasoc
Member
Member
Posts: 30
Joined: Fri Feb 10, 2017 8:25 am

Multiple thread switching issue

Post by prasoc »

Hi all,

I have been implementing a thread system and am implementing a VERY basic time slicing algorithm to start. I have been having issues with the instruction pointer being corrupted after a few cycles.
It switches between two separate threads (which are essentially just an address to a function located in the kernel) but after a few switches, my eip register gets corrupt and manages to take one thread out. The other one seems to be stable, so it's very confusing as to why only a single thread has this issue.

Here is the basic outline of my code, a few lines removed for clarity:

Code: Select all

static int cTask = 0;
std::vector<Thread *> thread_list;

void schedule_next(registers * r) {
    if(cTask == 0) {
        if(thread_list[thread_list.size()-1]->ran) 
            thread_list[thread_list.size()-1]->eip = r->eip;
    } else {
        thread_list[cTask-1]->eip = r->eip;
    }

    thread_list[cTask]->ran = true;

    r->eip = thread_list[cTask]->eip;
    cTask++;

    if(cTask >= thread_list.size()) {
        cTask = 0;
    }
}
This function is called in my timer interrupt every 10 ticks (which is where the "register * r" parameter comes from)

Is this the direction that I need to take for thread switching?

-----

Here are my thread functions, purely for clarity's sake:

Code: Select all

static void test_thread() {
	for(;;) {
		BochsConsolePrintChar('a');
	}
}

static void test_thread2() {
	for(;;) {
		BochsConsolePrintChar('b');
	}
}
so just saving "eip" should be enough for how simple the functions are
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Multiple thread switching issue

Post by Korona »

Err, what makes you think that only EIP needs to be saved? The compiler will surely generate code that uses other registers and unless your debugging function is completely inlined it will manipulate your stack. EIP then gets corrupted on function return. You need to save all GPRs.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
prasoc
Member
Member
Posts: 30
Joined: Fri Feb 10, 2017 8:25 am

Re: Multiple thread switching issue

Post by prasoc »

Of course, now it makes more sense. I thought that such simple functions wouldn't need registers, as it's an infinite for(;;) loop calling a #define function. Turns out that the definition of BochsConsolePrintChar() makes use of one of my IO functions "outb". This would explain the value of my trashed EIP being 0xE9, as that is one of the parameters passed through to my outb() call. I will see what improving my register save code does to switching.

Thanks for the quick reply
prasoc
prasoc
Member
Member
Posts: 30
Joined: Fri Feb 10, 2017 8:25 am

Re: Multiple thread switching issue

Post by prasoc »

It seems to be mostly functional now, great help! When my scheduler gets initialized, I save a copy of the registers and copy them to each thread. From there, I can switch the registers according to what the thread vector element stores

edit: after running the scheduler for 30 minutes with no issues, i'm sure that it's stable enough to build upon :)
Post Reply