[NSWI004] [Assignment3] Need help with context switch
Vojtech Horky
horky at d3s.mff.cuni.cz
Fri Dec 6 13:55:17 CET 2019
Hello.
Dne 06. 12. 19 v 13:28 Tomáš Drozdík napsal(a):
> I assume that I need to memorize it's top of the stack so that
> function thread_switch_to(thread_t*) can properly call
> cpu_switch_context with saved top of the stack storing contents of all
> registers onto it including current rip.
> My problem with this is that at the moment a thread calls yield a new
> stack frame is allocated for the thread_yield function.
> However when the thread which yielded is rescheduled again it needs to
> set its RIP to the instruction following the call to yield, but I'm
> not sure how can I determine this instruction pointer.
Not really. cpu_switch_context is a normal function and when the thread
is scheduled again, it will return from inside that function. The only
difference to any other call is that this function can take quite a long
time to return (as another thread would be running for a while).
>
> FYI my thread_yield() implementation only calls
> scheduler_schedule_next() which determines next thread to run and
> calls thread_switch_to on this thread.
That is fine and correct.
> void thread_switch_to(thread_t* thread) {
> thread_t* current_thread = thread_get_current();
> current_thread->stack_top = (unative_t)debug_get_stack_pointer();
> void* stack_top_old = (void*)current_thread->stack_top;
>
> void* stack_top_new = (void*)thread->stack_top;
>
> cpu_switch_context(&stack_top_old, &stack_top_new, 1);
> }
> ```
>
> For an first switch to given thread a context_t is allocated at the
> top of the stack and thread->stack_top is set to this context_t
> structure so that thread_switch_to correctly calls entry function but
> after a yield and reschedule thread->stack_top with dump of all
> registers is at the top of the stack but RIP points to current
> instruction in thread_switch_to function which I believe is incorrect.
For completeness: the parameters to the cpu_switch_context are two
locations in memory where stack pointer will be stored to (or loaded
from). Rest of the registers (including PC via $ra) are stored on the
stack (i.e. relative to $sp).
Using real stack-top to store stack-top is rather fragile. Practically,
it is much better to reserve one unative_t in thread_t (as a fixed place
with well-defined address) where to let cpu_switch_context store $sp.
> Do I need to set RIP somehow manually i.e. add to it so that it skips
> following call or something like that?
No, that is done by cpu_switch_context. It remembers the original return
address and returns there (to keep the semantics of a normal function call).
Hope this helps,
- VH
More information about the NSWI004
mailing list