Page 1 of 1

kernel threading again

Posted: Fri Aug 14, 2009 9:19 am
by xvedejas
Switching stacks seems to corrupt the stack and mess up my memory manager... I've labeled the spot where it dies:

Code: Select all


u32int next_thread_id = 1;
volatile thread_t *current_thread = 0;

void new_stack(thread_t *thread, u32int current_esp, u32int current_ebp)
{
	u32int size, offset, new_stack_start, i;
	size = current_thread->stack_start - current_esp;
	thread->stack = (u32int)malloc(0x2000); // reserve 8192 bytes for stack
	// start of stack is at _end_ of allocation
	new_stack_start = thread->stack + 0x2000;
	offset = new_stack_start - current_thread->stack_start;
	// find the esp and ebp for the new stack
	thread->stack_start = new_stack_start;
	thread->esp = current_esp + offset;
	thread->ebp = current_ebp + offset;
	// copy over the old stack to the new one
	memcpyd((u32int*)thread->esp, (u32int*)current_esp, size);
	u32int *tmp;
	for (tmp = thread->esp; tmp <= thread->stack_start; tmp++)
	{
		if (*tmp < current_thread->stack_start && *tmp > current_esp)
		{
			*tmp += offset;
		}
	}
	thread->stack_start = new_stack_start;
	thread->stack_size = size;
}
void threads_install()
{
	u32int esp, ebp;
	current_thread = (thread_t*)malloc(sizeof(thread_t));
	current_thread->stack_start = initial_esp;
	asm volatile("mov %%esp, %0" : "=r"(esp));
	asm volatile("mov %%ebp, %0" : "=r"(ebp));
	new_stack(current_thread, esp, ebp);
	asm volatile("mov %0, %%esp" :: "r"(current_thread->esp));
	asm volatile("mov %0, %%ebp" :: "r"(current_thread->ebp));
	current_thread->id = next_thread_id++;
	current_thread->status = 0;
	current_thread->next = current_thread;
	current_thread->previous = current_thread;
	current_thread->priority = 20;
	current_thread->counter = 20;
}
u32int fork()
{   // make new thread
	__asm__ __volatile__("cli");
	thread_t *parent_thread = (thread_t*)current_thread;
	thread_t *new_thread = (thread_t*)malloc(sizeof(thread_t));
	new_thread-> id = next_thread_id++;
	new_thread->next = parent_thread->next;
	new_thread->next->previous = new_thread;
	parent_thread->next = new_thread;
	new_thread->previous = parent_thread;
	new_thread->priority = parent_thread->priority;
	new_thread->counter = new_thread->priority;
	new_thread->status = 1; // ready
	current_thread->counter = 0;
	switch_thread(); // force switch to new thread
	__asm__ __volatile__("sti");
	if (current_thread == parent_thread)
		return new_thread->id;
	return 0;
}
void switch_thread()
{
	if (current_thread->counter)
	{
		current_thread->counter--;
		return;
	}
	
	if (current_thread->next == current_thread) return;
	// reset counter
	current_thread->counter = current_thread->priority;
	// get stack
	u32int esp, ebp;
	asm volatile("mov %%esp, %0" : "=r"(esp));
	asm volatile("mov %%ebp, %0" : "=r"(ebp));
	// save stack
	current_thread->esp = esp;
	current_thread->ebp = ebp;
	// advance current_thread
	thread_t *working_thread = current_thread;
	do
	{
		working_thread = working_thread->next;
		switch (working_thread->status)
		{
			case 1: // ready
				new_stack(working_thread, esp, ebp);
				working_thread->status = 0;
			break;
			case 3: // zombie
				working_thread->previous->next = working_thread->next;
				working_thread->next->previous = working_thread->previous;
				free(working_thread->stack);
				free(working_thread);
			break;
		}
	}
	while (working_thread->status);
	current_thread = working_thread;
	// switch stack
	esp = current_thread->esp;
	ebp = current_thread->ebp;
	/// CRASH ///
	__asm__ __volatile__("mov %0, %%esp" :: "r"(esp));
	__asm__ __volatile__("mov %0, %%ebp" :: "r"(ebp));
}
void exit()
{
	current_thread->status = 3; // zombie
	current_thread->counter = 0;
	switch_thread();
	panic("Failed to kill thread\n");
}
u32int get_pid()
{
	return current_thread->id;
}
Am I handling the stack wrong? I think the answer is yes, now the question is how?

Re: kernel threading again

Posted: Fri Aug 14, 2009 9:33 am
by NickJohnson
Within your malloc() implementation, do you make sure to use invlpg to partially flush the TLB when allocating new pages into the heap? 90% of the time I have some sort of stack corruption near thread duplication, the TLB has been the problem.

Re: kernel threading again

Posted: Fri Aug 14, 2009 9:56 am
by xvedejas
Pages? My memory allocation deals with physical memory. There are no "pages".

Hrm... the stack doesn't need to be aligned does it?

Re: kernel threading again

Posted: Fri Aug 14, 2009 10:11 am
by NickJohnson
xvedejas wrote:Pages? My memory allocation deals with physical memory. There are no "pages".
Sorry, I just assumed you were using paging.
xvedejas wrote:Hrm... the stack doesn't need to be aligned does it?
I think the stack may need to be dword aligned, but definitely not page aligned.

Hmm...

Code: Select all

   esp = current_thread->esp;
   ebp = current_thread->ebp;
   /// CRASH ///
   __asm__ __volatile__("mov %0, %%esp" :: "r"(esp));
   __asm__ __volatile__("mov %0, %%ebp" :: "r"(ebp));
You're not trying to load the stack pointers with data potentially coming from the current stack, are you? :wink:

I'd recommend having an in-kernel stack for doing process manipulation and using pure assembly in an interrupt handler to mess with the stack position. I don't know if that will work in your kernel though, especially b/c it doesn't use paging and I think you're trying to make in-kernel threads.

Re: kernel threading again

Posted: Fri Aug 14, 2009 12:12 pm
by xvedejas
I think the stack may need to be dword aligned, but definitely not page aligned.
Everything should be dword aligned.
You're not trying to load the stack pointers with data potentially coming from the current stack, are you?
Hrm that's probably something to look into...
I'd recommend having an in-kernel stack for doing process manipulation and using pure assembly in an interrupt handler to mess with the stack position. I don't know if that will work in your kernel though, especially b/c it doesn't use paging and I think you're trying to make in-kernel threads.
Yes, they are in-kernel threads... and I try to shy away from assembly as much as possible.

Re: kernel threading again

Posted: Fri Aug 14, 2009 7:37 pm
by xvedejas
That doesn't seem to be the problem... Hrm...