CS452 F23 Lecture Notes
Lecture 06 - 26 Sep 2023
1. Scheduling
- For K1, nothing blocks a task
- only task states are Ready, Running, at most one is Running (we are only using one core)
- For K1, no preemption of Running task (no interrupts)
- kernel only regains control when the running task makes a system call
- Suppose there is only one priority
- if P1 is Running and makes a system call, it becomes Ready
- which Ready task should the kernel scheduler choose to run next?
- round robin?
- round robin with a minimum quantum?
- Suppose there are two priorities
- low priority task should never be running if there is a high priority ready task
- if a high priority task is running and enters kernel because of a system call, what
could prevent it from running again?
- there is another Ready high priority task
- the system call is Exit()
- if a low priority task is running and enters kernel because of a system call, what
could prevent it from running again?
- there is another Ready low priority task
- the system call is Create, creating a high(er) priority task
- How to implement scheduling?
- maintain a single Ready queue in priority order
- insert Running task into the queue when it enters the kernel
- scheduler chooses first task to run next
- but - complicated insertion
- maintain a Ready queue per priority level
- insertion and scheduling both fairly easy
- each task is on at most one ready queue, so only one “next” pointer
- maintain a single Ready queue in priority order
2. Memory and Synchonization
- although we are not implementing mechanisms to enforce these rules
- tasks should not share data with other tasks
- tasks should not share data with the kernel
- no shared data means no need for synchronization objects (locks, semaphores)
- to communicate with each other, tasks will exchange messages - instead of sharing data
- message passing API also provides for process synchronization
- related issue: device sharing
- suppose there is only room for 1 more character in UART send FIFO, and two processes try to write a character
- we’ll address this by limiting tasks that will use a device
- kernel AwaitEvent API will provide device synchronization, e.g, block until space is available in FIFO -
3. Message Passing
- synchronous communication: Send/Receive/Reply
- data flows when both sender and receiver are ready
- no need to buffer data that has been sent but not recieved
- introduces the need to “block” tasks in the kernel
- kernel needs to track why a task is blocked, so that it knows when to unblock
- Sending task can be blocked:
- waiting for sent message to be delivered (task state: SendWait)
- waiting for reply to be delivered (task state: ReplyWait)
- Receiving task can be blocked:
- waiting for a message to be sent (task state: ReceiveWait)
- Sending task can be blocked:
- kernel needs to track why a task is blocked, so that it knows when to unblock
- Send/Receive Scenario 1: Send first
- On Ts doing Send(Tr,…), kernel finds that receiver task Tr is not in ReceiveWait state
- kernel blocks sender (Ready -> SendWait)
- kernel adds Ts to list of senders blocked waiting for Tr to receive
- On Tr doing Receive()
- kernel sees that Tr has waiting sender
- kernel moves Ts from SendWait to ReplyWait
- kernel copies message from Ts to Tr
- Tr remains Ready
- On Ts doing Send(Tr,…), kernel finds that receiver task Tr is not in ReceiveWait state
- Send/Receive Scenario 2: Receive first
- On Tr doing Receive(), kernel finds there are no waiting Sends for Tr
- Tr blocks (Ready -> ReceiveWait)
- On Ts doing Send(Tr,…), kernel finds that Tr is in ReceiveWait state
- Ts blocks (Ready->ReplyWait)
- Add Ts to list of tasks waiting for reply from Tr
- Tr becomes unblocks (ReceiveWait -> Ready)
- kernel copies message from Ts to Tr
- Ts blocks (Ready->ReplyWait)
- On Tr doing Receive(), kernel finds there are no waiting Sends for Tr
- When Tr eventuallly does Reply(Ts,…)
- kernel checks that Ts is in ReplyWait state and on list of tasks waiting for reply from Tr
- Tr remains ready
- Ts unblocks (ReplyWait -> Ready)
- kernel copies reply from Tr to Ts
- Notice that Tr:
- only blocks on Receive if there are no Sends waiting
- never blocks on Reply