tos arno puder
play

TOS Arno Puder 1 Objectives Explain non-preemptive scheduling - PowerPoint PPT Presentation

TOS Arno Puder 1 Objectives Explain non-preemptive scheduling Explain step-by-step how a context switch works in TOS 2 Status Quo We can create new processes in TOS. New processes are added to the ready queue. The


  1. TOS Arno Puder 1

  2. Objectives • Explain non-preemptive scheduling • Explain step-by-step how a context switch works in TOS 2

  3. Status Quo • We can create new processes in TOS. • New processes are added to the ready queue. • The ready queue contains all runnable processes. • BUT: so far, none of these new processes ever gets executed. • What is missing: running those processes! • What needs to be done: implement a function that switches the context, so that another process gets the chance to run. 3

  4. Context switching in TOS • First step: cooperative multi-tasking – Pre-emptive multi-tasking will come later – For now, a process voluntarily gives up the CPU by calling the function resign() • Eventually control is passed back to the original caller because it is assumed that other processes also call resign() • Therefore, from a process ’ perspective, resign() is not doing anything, except causing a delay before resign() returns 4

  5. resign() example • Assumption: there is only . . one process in the ready . queue kprintf ( “ Location A\n ” ); resign(); • In this example, kprintf ( “ Location B\n ” ); resign() simply does . . nothing, like a function . call that immediately returns. Output • active_proc is not Location A Location B changed 5

  6. resign() example • Assumption: after the call to void process_a (PROCESS self, PARAM param) { create_process(), there kprintf ( “ Location C\n ” ); are two processes on the ready assert (self == active_proc); queue and process_a has a while (1); higher priority } • Call to resign() does a context switch to process_a , void kernel_main() because it has the higher { priority init_process(); active_proc changes after • init_dispatcher(); resign create_process (process_a, 5, 0, “ Process A ” ); kprintf ( “ Location A\n ” ); Output resign(); Location A kprintf ( “ Location B\n ” ); Location C while (1); } 6

  7. resign() example • Assumption: after the call to void process_a (PROCESS self, PARAM param) create_process(), there are { two processes on the ready queue and kprintf ( “ Location C\n ” ); process_a has a higher priority remove_ready_queue (self); First call to resign() switches • resign(); context to process_a kprintf ( “ Location D\n ” ); process_a removes itself from the • while (1); ready queue and then calls resign() } again. This will do a context switch back to the first process. void kernel_main() • If remove_ready_queue(self) { were not called, the program would init_process(); print “ Location D ” instead of “ Location B ” init_dispatcher(); create_process (process_a, 5, 0 “ Process A ” ); Output kprintf ( “ Location A\n ” ); resign(); Location A kprintf ( “ Location B\n ” ); Location C while (1); Location B } 7

  8. Understanding resign() • resign() implements a context switch, i.e. it gives another process the chance to run. • Conceptually, resign() is doing the following: – Save the context of the current process pointed to by active_proc – active_proc = dispatcher() – Restore the context – RET But how does it work exactly? 8

  9. Implementing resign() • Process 2 previously Used stack called resign() return addr • Process 1 calls resign(), EAX Stack frame of process 2 ECX the stacks are as shown EDX EBX • The goal is to “ suspend ” EBP ESI EDI process 1 within resign() and “ resume ” where process 2 left off in resign() Used stack • First step: save the EIP (RET) %ESP Stack frame of process 1 registers for process 1 9

  10. Implementing resign() • State of process 1 is Used stack saved -- now we actually return addr make the switch: EAX Stack frame of process 2 ECX EDX EBX EBP active_proc->esp = %ESP; ESI EDI active_proc = dispatcher(); %ESP = active_proc->esp; Used stack EIP (RET) Stack frame of process 1 EAX ECX EDX EBX EBP ESI EDI %ESP 10

  11. Implementing resign() • Finally, we restore the Used stack state of process 2 by return addr popping the saved EAX Stack frame of process 2 ECX register values from the EDX EBX stack EBP ESI • Note, the registers were EDI %ESP stored on the stack when process 2 entered resign() Used stack EIP (RET) Stack frame of process 1 EAX ECX EDX EBX EBP ESI EDI 11

  12. Implementing resign() • We ’ re done -- when we Used stack finish with the ret return addr instruction, we jump back %ESP Stack frame of process 2 to where process 2 called resign() Used stack EIP (RET) Stack frame of process 1 EAX ECX EDX EBX EBP ESI EDI 12

  13. Understanding resign() • It is especially important to note that the context pushed is not necessarily the same as the context popped – recall that active_proc and (hence) %ESP register changed in between push and pop context. – then we aren ’ t looking at the same stack now! – but how can we be sure that the ESP register is pointing to some stack? 13

  14. Understanding resign() • We made the assumption that wherever active_proc->esp points to is where context of the current process is saved • To satisfy this assumption, we always need to save the context of a process so that it can be popped at some time in the future • We have already done this! – for a new process we setup the stack (see create_process() ) – for process calling resign() we setup the stack (identical to the way we did it for create_process()) before call to dispatch() – now you should be able to connect the dots 14

  15. Implementing resign() • By creating the initial param stack frame carefully in self create_process() , we func Stack frame of process 2 (EAX) ensure that resign() (ECX) (EDX) can switch to a brand (EBX) (EBP) new process as well as (ESI) (EDI) one that previously called resign() • Process 1 is active Used stack • Process 2 was created EIP (RET) %ESP Stack frame of process 1 with create_process() but has never run. 15

  16. Understanding resign() • And don ’ t forget – because the context popped was different than the context pushed in the beginning of resign(), the return address also is different • So resign() pushed one return address and popped another return address by clever ESP register manipulation • What does this mean? resign() returns to some other address, not to the caller process • tada! we have a context switch! 16

  17. Notes on inline assembly • As explained earlier, resign() does amongst others the following: active_proc->esp = %ESP; active_proc = dispatcher(); %ESP = active_proc->esp; • The first and the third instruction require inline assembly, because the %ESP register is accessed. • There is no C-instruction with which this could be achieved, that is why inline assembly is necessary. 17

  18. Accessing the Stack Pointer • This can be accomplished with the following instructions: /* Save the stack pointer to the PCB */ asm ("movl %%esp,%0" : "=r" (active_proc->esp) : ); /* Select a new process to run */ active_proc = dispatcher(); /* Load the stack pointer from the PCB */ asm ("movl %0,%%esp" : : "r" (active_proc->esp)); • Notes: – The register name %ESP has to be prefixed with another % – The specifier “ =r ” means “ an output parameter that should be placed in an x86 register ” – The specifier “ r ” means “ an input parameter that should be placed in an x86 register ” 18

  19. Example of resign() • Process 1 is active, it calls resign() • Process 2 previously called resign() , it is ready to run but not currently running. • Inside resign() , assume that dispatcher() returns process 2 so we must perform a switch from process 1 to process 2. 19

  20. Example of resign() Used stack PCB active_proc: return addr name: “ Process 2 ” EAX esp: ECX Stack frame of process 2 EDX EBX EBP ESI EDI PCB name: “ Process 1 ” Used stack Stack frame of process 1 esp: return addr %ESP • First step: save the registers for process 1 20

  21. Example of resign() Used stack PCB active_proc: return addr name: “ Process 2 ” EAX esp: ECX Stack frame of process 2 EDX EBX EBP ESI EDI PCB name: “ Process 1 ” Used stack esp: return addr EAX ECX EDX Stack frame of process 1 EBX EBP ESI EDI %ESP • First step: save the registers for process 1 21

  22. Example of resign() Used stack PCB active_proc: return addr name: “ Process 2 ” EAX esp: ECX Stack frame of process 2 EDX EBX EBP ESI EDI PCB name: “ Process 1 ” Used stack esp: return addr EAX ECX EDX Stack frame of process 1 EBX EBP ESI EDI %ESP • Next step: save the stack pointer for process 1 22

  23. Example of resign() Used stack PCB active_proc: return addr name: “ Process 2 ” EAX esp: ECX Stack frame of process 2 EDX EBX EBP ESI EDI PCB name: “ Process 1 ” Used stack esp: return addr EAX ECX EDX Stack frame of process 1 EBX EBP ESI EDI %ESP • Next step: choose new process- dispatcher() 23

  24. Example of resign() Used stack PCB active_proc: return addr name: “ Process 2 ” EAX esp: ECX Stack frame of process 2 EDX EBX EBP ESI EDI PCB name: “ Process 1 ” Used stack esp: return addr EAX ECX EDX Stack frame of process 1 EBX EBP ESI EDI %ESP • Next step: choose new process- dispatcher() 24

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend