Problem switching from userspace to userspace threads
Posted: Wed Apr 04, 2007 5:28 pm
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]
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