Creating new threads?
Creating new threads?
I've run into a slight issue with my threading code. I don't know how to create a new thread, with a new kernel stack.
My code can produce the virtual memory data structures necessary for the stack just fine, but I can't figure out how to fill the stack so as to simulate a natural stack frame from an interrupt, thereby letting the thread be used with SwitchThread().
Any tips?
P.S. to Brendan - Working on EDI. Will hopefully have a new version with the issues we talked about fixed done soon. Currently reading up on PThreads.
My code can produce the virtual memory data structures necessary for the stack just fine, but I can't figure out how to fill the stack so as to simulate a natural stack frame from an interrupt, thereby letting the thread be used with SwitchThread().
Any tips?
P.S. to Brendan - Working on EDI. Will hopefully have a new version with the issues we talked about fixed done soon. Currently reading up on PThreads.
Re:Creating new threads?
There are 2 things you could do, one is a fork-like function (I call mine branch) which creates a new thread whose stack is a copy of the current stack, the second is to do what you say - build the stack by hand to look like an interrupt state.
It helps if you have a C structure which represents the stack state during an interrupt. In my interrupt handler I fill this structure in reverse order. To initialize a new thread, I simply fill in the structure from a c function, positioning it at the start of the new stack.
It helps if you have a C structure which represents the stack state during an interrupt. In my interrupt handler I fill this structure in reverse order. To initialize a new thread, I simply fill in the structure from a c function, positioning it at the start of the new stack.
Re:Creating new threads?
hi,
I suppose, you have a structure that represents the cpu state as saved by an interrupt handler.
Just init that state for the new thread in its newly created stack and set eip to the start function of the thread, if the start function take a parameter(s) you may add a return addres, then the value of parameters.
if the start function have the folowing signature
the stack may have the following pattern
++++++++++++++++++++++++++++++++++
arg
++++++++++++++++++++++++++++++++++
return address for start
(normally 0 because start
should not return)
++++++++++++++++++++++++++++++++++
cpu state-> eflags
cs
eip = address of start
... (ex: ds, ss, es...)
+++++++++++++++++++++++++++++++++++
you may need to change the stack pattern for the user threads , especially add the saved user's ss and esp
I suppose, you have a structure that represents the cpu state as saved by an interrupt handler.
Just init that state for the new thread in its newly created stack and set eip to the start function of the thread, if the start function take a parameter(s) you may add a return addres, then the value of parameters.
if the start function have the folowing signature
Code: Select all
void start(void *arg);
++++++++++++++++++++++++++++++++++
arg
++++++++++++++++++++++++++++++++++
return address for start
(normally 0 because start
should not return)
++++++++++++++++++++++++++++++++++
cpu state-> eflags
cs
eip = address of start
... (ex: ds, ss, es...)
+++++++++++++++++++++++++++++++++++
you may need to change the stack pattern for the user threads , especially add the saved user's ss and esp
Re:Creating new threads?
Arguments are pushed before the return address, since it is the callers job to pop them off the stack after the called function has returned.
Re:Creating new threads?
i suppose this is what's shown in the stack pattern.paulbarker wrote: Arguments are pushed before the return address, since it is the callers job to pop them off the stack after the called function has returned.
Re:Creating new threads?
On second thoughts, I'm reading the damn thing upside down. Oops.
Re:Creating new threads?
Thanks for the help. I just hope that this doesn't mess with exception handling.
Re:Creating new threads?
i dont see any problem if the excpetion handler write the same thing on the stack.Crazed123 wrote: Thanks for the help. I just hope that this doesn't mess with exception handling.
you may have some kind of return_from_interrupt, return_from_exception functions that chooses the cpu state to restore (wich may be the same saved or another'state for a new sheduled thread)
Re:Creating new threads?
I meant language (Pascal) exception handling, ie: try...except and try...finally blocks.
Re:Creating new threads?
i dont know how exception handling is implemented in your pascal compiler,
i think if your main thread function contain a try/catch clause then you may need to build a stack frame as expected by the stack unwinder.
for other functions i think there is no problem.
i think if your main thread function contain a try/catch clause then you may need to build a stack frame as expected by the stack unwinder.
for other functions i think there is no problem.
Re:Creating new threads?
I hope you're right. I was thinking more along the lines of the fact that ThreadSwitch() calls numerous functions capable of throwing and handling exceptions.
The thread's function is expected to be able to run on a bare, "return a numeric exit code" stack.
The thread's function is expected to be able to run on a bare, "return a numeric exit code" stack.
Re:Creating new threads?
On second thought, this seems a bit more complicated. because ThreadSwitch() is not a normal function and it switchs stacks frames between multiples threads.Crazed123 wrote: I hope you're right. I was thinking more along the lines of the fact that ThreadSwitch() calls numerous functions capable of throwing and handling exceptions.
The thread's function is expected to be able to run on a bare, "return a numeric exit code" stack.
for example if ThreadSwitch() raises an exception after setting up a newly created thread, how the exception-support-code is supposed to walk the new stack, wich contains nothing more than the cpu state of the new thread.
i think this is not an issue if the exception support does not rely on the stack (like in the D compiler wich constructs statically a map of function/try/catch in the binary image)
<EDIT> No more success, On third thought we need always ths stack to trace the call chain </EDIT>
Re:Creating new threads?
Right, that being the issue. I can do some wizardry to create activation records for ContextSwitch() (the function which actually changes page directories, switching the kernel stack), ThreadSwitch() (switches the threads, uninterruptable), and return from there to start_thread (pops registers, irets), but I have no idea how to do any of these things with proper exception handling.