[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