3. Introduction
1
An operating system runs more processes than it has processors
2
Needs some plan to time share the processors between the
processes
4. Introduction
1
An operating system runs more processes than it has processors
2
Needs some plan to time share the processors between the
processes
3
A common approach is to provide each process with a virtual
processor – An illusion that it has exclusive access to the
processor
5. Introduction
1
An operating system runs more processes than it has processors
2
Needs some plan to time share the processors between the
processes
3
A common approach is to provide each process with a virtual
processor – An illusion that it has exclusive access to the
processor
4
It is then the job of the OS to multiplex these multiple virtual
processors on the underlying physical processors
7. Scheduling triggers
1
A process does I/O, put it to sleep, and schedule another process
2
Use timer interrupts to stop running on a processor after a fixed
time quantum (100 msec)
9. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
10. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
1
Process’s kernel thread to the current CPU’s scheduler thread
11. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
1
2
Process’s kernel thread to the current CPU’s scheduler thread
Scheduler’s thread to a process’s kernel thread
12. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
1
2
Process’s kernel thread to the current CPU’s scheduler thread
Scheduler’s thread to a process’s kernel thread
• No direct switching from one user-space process to another
13. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
1
2
Process’s kernel thread to the current CPU’s scheduler thread
Scheduler’s thread to a process’s kernel thread
• No direct switching from one user-space process to another
• Each process has its own kernel stack and register set (its
context)
14. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
1
2
Process’s kernel thread to the current CPU’s scheduler thread
Scheduler’s thread to a process’s kernel thread
• No direct switching from one user-space process to another
• Each process has its own kernel stack and register set (its
context)
• Each CPU has its own scheduler thread
15. Context switching
• Used to achieve multiplexing
• Internally two low-level context switches are performed
1
2
Process’s kernel thread to the current CPU’s scheduler thread
Scheduler’s thread to a process’s kernel thread
• No direct switching from one user-space process to another
• Each process has its own kernel stack and register set (its
context)
• Each CPU has its own scheduler thread
• Context switch involves saving the old thread’s CPU registers and
restoring previously-saved registers of the new thread (enabled
by swtch)
17. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
18. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
19. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
• Each time a process has to give up the CPU, its kernel thread
invokes swtch to save its own context and switch to the
scheduler context
20. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
• Each time a process has to give up the CPU, its kernel thread
invokes swtch to save its own context and switch to the
scheduler context
• Flow in case of an interrupt:
21. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
• Each time a process has to give up the CPU, its kernel thread
invokes swtch to save its own context and switch to the
scheduler context
• Flow in case of an interrupt:
1 trap handles the interrupt and the calls yield
22. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
• Each time a process has to give up the CPU, its kernel thread
invokes swtch to save its own context and switch to the
scheduler context
• Flow in case of an interrupt:
1 trap handles the interrupt and the calls yield
2 yield makes a call to sched
23. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
• Each time a process has to give up the CPU, its kernel thread
invokes swtch to save its own context and switch to the
scheduler context
• Flow in case of an interrupt:
1 trap handles the interrupt and the calls yield
2 yield makes a call to sched
3 sched invokes swtch(&proc->context,
cpu->scheduler)
24. swtch
• Saves and restores contexts
• Takes two arguments: struct context **old and
struct context *new
• Replaces the former with the latter
• Each time a process has to give up the CPU, its kernel thread
invokes swtch to save its own context and switch to the
scheduler context
• Flow in case of an interrupt:
1 trap handles the interrupt and the calls yield
2 yield makes a call to sched
3 sched invokes swtch(&proc->context,
cpu->scheduler)
4 Control returns to the scheduler thread
26. Scheduling mechanism
• Each process that wants to give up the processor:
1 Acquires ptable.lock (process table lock)
27. Scheduling mechanism
• Each process that wants to give up the processor:
1 Acquires ptable.lock (process table lock)
2
Releases any other locks that it is holding
28. Scheduling mechanism
• Each process that wants to give up the processor:
1 Acquires ptable.lock (process table lock)
2
3
Releases any other locks that it is holding
Updates proc->state (its own state)
29. Scheduling mechanism
• Each process that wants to give up the processor:
1 Acquires ptable.lock (process table lock)
Releases any other locks that it is holding
Updates proc->state (its own state)
4 Calls sched
2
3
30. Scheduling mechanism
• Each process that wants to give up the processor:
1 Acquires ptable.lock (process table lock)
Releases any other locks that it is holding
Updates proc->state (its own state)
4 Calls sched
2
3
• Mechanism followed by yield, and sleep and exit
31. Scheduling mechanism
• Each process that wants to give up the processor:
1 Acquires ptable.lock (process table lock)
Releases any other locks that it is holding
Updates proc->state (its own state)
4 Calls sched
2
3
• Mechanism followed by yield, and sleep and exit
• sched ensures that these steps are followed
34. Scheduling mechanism (2)
• Why must a process acquire ptable.lock before a call to
swtch?
• Breaks the convention that the thread that acquires a lock is also
responsible for releasing the lock
35. Scheduling mechanism (2)
• Why must a process acquire ptable.lock before a call to
swtch?
• Breaks the convention that the thread that acquires a lock is also
responsible for releasing the lock
• Without acquiring ptable.lock, two CPUs might want to
schedule the same process because they can access ptable
37. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
38. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
39. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
1
Idle looping while holding a lock would not allow any other CPU to
access the process table
40. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
Idle looping while holding a lock would not allow any other CPU to
access the process table
2 Idle looping (all processes are waiting for I/O) while interrupts are
disabled would not allow any I/O to arrive
1
41. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
Idle looping while holding a lock would not allow any other CPU to
access the process table
2 Idle looping (all processes are waiting for I/O) while interrupts are
disabled would not allow any I/O to arrive
1
• The first process with p->state == RUNNABLE is selected
42. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
Idle looping while holding a lock would not allow any other CPU to
access the process table
2 Idle looping (all processes are waiting for I/O) while interrupts are
disabled would not allow any I/O to arrive
1
• The first process with p->state == RUNNABLE is selected
• The process is assigned to the per-CPU proc
43. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
Idle looping while holding a lock would not allow any other CPU to
access the process table
2 Idle looping (all processes are waiting for I/O) while interrupts are
disabled would not allow any I/O to arrive
1
• The first process with p->state == RUNNABLE is selected
• The process is assigned to the per-CPU proc
• The process’s page table is switched to via switchuvm
44. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
Idle looping while holding a lock would not allow any other CPU to
access the process table
2 Idle looping (all processes are waiting for I/O) while interrupts are
disabled would not allow any I/O to arrive
1
• The first process with p->state == RUNNABLE is selected
• The process is assigned to the per-CPU proc
• The process’s page table is switched to via switchuvm
• The process is marked as RUNNING
45. scheduler
• Simple loop: find a process to run, run it until it stops, repeat
• Acquires and releases ptable.lock, and enables interrupts
on every iteration. Why?
• If CPU is idle (no RUNNABLE)
Idle looping while holding a lock would not allow any other CPU to
access the process table
2 Idle looping (all processes are waiting for I/O) while interrupts are
disabled would not allow any I/O to arrive
1
• The first process with p->state == RUNNABLE is selected
• The process is assigned to the per-CPU proc
• The process’s page table is switched to via switchuvm
• The process is marked as RUNNING
• swtch is called to start running it
48. Sleep and wakeup
• sleep and wakeup enable an IPC mechanism
• Enable sequence coordination or conditional synchronization
49. Sleep and wakeup
• sleep and wakeup enable an IPC mechanism
• Enable sequence coordination or conditional synchronization
• sleep allows one process to sleep waiting for an event
50. Sleep and wakeup
• sleep and wakeup enable an IPC mechanism
• Enable sequence coordination or conditional synchronization
• sleep allows one process to sleep waiting for an event
• wakeup allows another process to wake up processes sleeping
on an event
58. Today’s Task
• ptable.lock is a very coarse-grained lock which protects the
entire process table
• Design a mechanism (in terms of pseudocode) that splits it up
into multiple locks
• Explain why your solution will improve performance while
ensuring protection
59. Reading(s)
• Chapter 5, “Scheduling” from “xv6: a simple, Unix-like teaching
operating system”