-
Notifications
You must be signed in to change notification settings - Fork 17
Scheduling policies
C4Phone edited this page Dec 3, 2015
·
8 revisions
- Big picture:
- Creating new PIDs will always block the original thread
- Use fork() to create new thread 1. Thus spawning new process <=> fork() then exec()/makeKThread()
- different from Linux because of course requirements.
- exec() actually creates a new Process
- and it's the only function to create a new user process
- fork() creates a new Thread
- this is the only way to create a new task without blocking the original one
- Thus, this is very useful for instantiating multiple terminals
- makeKThread() creates a new Kernel "Process" (A new process with a single kernel thread).
- should be renamed to execKernel() (it also blocks the parent thread)
- which can call exec() to create a whole new user process.
- makeKThread accepts argument to customize everything about this "Kernel Process" 1. Although "Kernel Process" does not have its own memmap, 2. Kernel Process's execChild process inherit its Terminal/GUI client handle. 3. Thus we utilize makeKThread when creating new Terminals/GUIs
- We use makeKThread to instantiate the 4 different shells on the 4 Text-mode Terminals.
- Because: if we use fork() to accomplish this, fork() must be able to move some program from terminal 0 to terminal 3, which is unsafe and breaks abstraction.
Just use makeKThread() in the interrupt handler.
Easy. block the syscall and wake it when interrupt arrives.
We have to split all "blocking" into two pieces:
either interrupt handler & tasklet, or before-blocking and after-blocking.
There is a way to get signal and blocking working together. (draft)
- terminal is owned by single thread, not a whole process
- signal is sent between threads, not between whole processes
- there is a record about which thread is the "ui thread" so no worry.
- Two ways to implement "keyboard blocking":
- Keep the current approach and disable signals
- Use signals to implement all "blocking". Never provide other approaches:
0. BAD design: read() may fail due to other signals' interruption...
1. Define a SIG_BLKOVER signal.
- Currently we do not care about what the handler does.
- Its only function is to bring the task back into scheduler. 2. Then drivers can implement blocking in many ways. Here is a SIMPLE way (NOT best way):
- Upon syscall request: block the user thread by removing it from scheduler queues. Then the scheduler will find another active task to switch to.
- Don't worry about context though, when the syscall happened, everything has been saved to PCB.
- Driver should store the syscall arguments (such as
buffer, nbytes
) in PCB or File Descriptor. - Upon interrupt (completion of blocking): Read syscall arguments stored in File Descriptor or PCB, and Modify the user thread's PCB->getRegs() to complete the syscall. In the end, it sends a SYS_BLKOVER signal to that thread to wake it up.