Problem switching from userspace to userspace threads

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
iammisc
Member
Member
Posts: 269
Joined: Thu Nov 09, 2006 6:23 pm

Problem switching from userspace to userspace threads

Post by iammisc »

After spending days trying to get two userspace processes to work together, i have traced the problem to switching from a userspace thread to another userspace thread. This is why qemu sometimes crashes and sometimes doesn't, because sometimes the first thread is deleted before the other and sometimes it isn't(causing them to be switched).

i have two fuction switch_contexts_asm and switch_contexts_with_iret_asm that do the context switching. The switch_contexts_with_iret_asm is the function that is used to switch to a newly created thread and switch_contexts is what is normally used. Each function takes two arguments. %eax is a pointer to the thread structure and %ebx is a pointer to the pointer of the current thread for the current processor(i don't have smp but i took this step to get ready for it)..

Oh yeah, BTW, i know that it works to switch from userspace to kernel threads because if i override my scheduler to switch into my idle process(part of the kernel) before the next thread, it works perfectly.

i have included them in this post:

Code: Select all

.global switch_contexts_asm
.global switch_contexts_with_iret_asm

switch_contexts_asm:
		# we first need to pop cs and ip off the stack in order to be able to take the thread into eax
	# 4 + esp = cur
	cld
	
	pusha
	push %es
	push %ds
	push %fs
	push %gs

	# get current thread	
	cmp $0x0, (%ebx)

	jnz if_curr_neq
	jmp else_curr_neq
if_curr_neq:
	mov (%ebx), %edx # move cur's value into ebx
	mov %esp, (%edx) #copy new stack to current thread
else_curr_neq:
	
	mov %eax, (%ebx) # now thread is the current one

	mov 12(%eax),%ebx
	
	mov %ebx, %cr3 #paging
	
	mov (%eax),%esp # set our stack
	mov $kernel_tss,%edx
	mov %esp,4(%edx) #update current tss
	
	pop %gs
	pop %fs
	pop %ds
	pop %es
	popa
	
	sti
	
	ret

switch_contexts_with_iret_asm:
		# we first need to pop cs and ip off the stack in order to be able to take the thread into eax
	# 4 + esp = cur
	cld
	
	pusha
	push %es
	push %ds
	push %fs
	push %gs

	# get current thread	
	cmp $0x0, (%ebx)

	jnz if_curr_neq_1
	jmp else_curr_neq_1
if_curr_neq_1:
	mov (%ebx), %edx # move cur's value into ebx
	mov %esp, (%edx) #copy new stack to current thread
else_curr_neq_1:
	
	mov %eax, (%ebx) # now thread is the current one

	mov 12(%eax),%ebx
	
	lock
	mov %ebx, %cr3 #paging
	
	lock
	mov (%eax),%esp # set our stack
	lock
	mov $kernel_tss,%edx
	lock
	mov %esp,4(%edx) #update current tss
	
	pop %gs
	pop %fs
	pop %ds
	pop %es
	popa
	
	sti
	
	iret
[/code]
Post Reply