The operating system utilizes signals as a form of asynchronous communication between processes. They are the operating system's system for notifying a process that an event has occurred. Signals allow for the interrupt of user process as well as inter-process communication (IPC) such as Pipes. When a process receives a signal, it calls its function specific signal handler, generally setting a few flags and returning to previously executing instruction, unless the process has been killed.
For example, if Process A calls write() and Process B calls read() through a pipe, when does Process B get the message?
Process B only gets the message when it reads on the pipe file descriptor.
Why would Process B not be reading?
What if the message is urgent?
In the worst case, Process B gets the message at most in 1 sec (arbitrary number). This occurs because even during busy waiting/polling, ever second Process B will check for a message. If there is no message it will continue with its busy work.
Need User Level Interrupts
User Level Interrupts preemptively interrupt a running process to execute a specific signal handler. Once the receiver of the signal receives the interrupt, it halts all computation and jumps to its specific signal handler function with its own stack. The specific function is specified in the interrupt command.
kill ( pid_t p, int signo) This delivers a user level interrupt number “signo” to the process with id “p”
Note: Kill must interrupt other system calls so the receiver of the signal, if it is in a system call, returns early.
If it is the case that the process was interrupted while in a system call, then the system call will return -1 on the error and also will set the global variable ERRNO == EINTR.
During the user level interrupt hardware and kernel interrupts are still active such as the timer interrupt.
OS Goal: To effectively multiplex the physical machine's resources among the abstract machines
A main task for the OS is to schedule the various processes on the machine and distribute the resources. The scheduling system must determine which of the runnable processes will run next and how much CPU time it will be given. There are numerous techniques to determine the order execution and amount of CPU time, which will be discussed below.
Process State Diagram
To schedule the various runnable processes, chunks of CPU time are assigned to each abstract machine. Scheduling problems arise because of the variety of execution deadlines and the difficulty to meet each of them.
Scheduling Metrics
Scheduling metrics are measurements that tell how good a schedule is. There are several different types of scheduling metrics:
Preferences: We want to influence the schedulers decision in order to achieve the following user goals:
Scheduling 4 jobs
Let's say we are given the following four jobs to schedule along with their service times T:
| Job | Τ (time to complete) |
|---|---|
| A | 5 |
| B | 2 |
| C | 9 |
| D | 4 |
We assume that all processes start running at the same time.
First Come First Serve (FCFS)
If we execute A, followed by B, followed by C, followed by D, we get the following Gantt Chart:
| 0 | 5 | 7 | 16 |
|---|---|---|---|
| ----A------ | --B-- | --------C---------- | ----D----- |
Note: When we switch from one process to another we encounter a delay known as the contact switch time. We will denote the contact switch by using C.
Analysis of responsiveness and turnaround time:
| Job | W | TTRND |
|---|---|---|
| A | 0 | 5 |
| B | 5 + C | 7 + C |
| C | 7 + 2C | 16 + 2C |
| D | 16 + 3C | 20 + 3C |
| Average | 7 + 1.5C | 12 + 1.5C |
Analysis of CPU utilization: Since the CPU is not used during contact switches, the utilization is ρ = 20/(20+3C).
FCFS Predictions
We have stable load which means that we can always get a good idea of the average TTRND. Lets says that L processes are waiting in a queue while 1 process is running. If we get a new job, we can easily estimate the new average turnaround time. Below is the formula that computes it:
L*TTRND+TTRND+.5*TTRND
The first term is the turnaround time of the L queued jobs. The second term is the turnaround time of the new job. The third term is the turnaround time of the current running job.
Shortest Job First (SJF)
If we execute the jobs in order of the time they take, we get the following Gantt Chart:
| 0 | 2 | 6 | 11 |
|---|---|---|---|
| --B--- | ----D---- | -----A----- | ---------C--------- |
Analysis of responsiveness and turnaround time:
| Job | W | TTRND |
|---|---|---|
| A | 6 + 2C | 11 + 2C |
| B | 0 | 2 |
| C | 11 + 3C | 20 + 3C |
| D | 2 + C | 6 + C |
| Average | 4.75 + 1.5C | 9.75 + 1.5C |
Analysis of Shortest Job First Algorithm
Example of Starvation:
| Time | Job:T |
|---|---|
| 0 | A:2 , B:1 |
| 1 | C:1 |
| 2 | D:1 |
Since job A takes 2 units of time, it will be executed after job B. However, if jobs that take 1 unit of time keep appearing each second (like C and D), job A might never be executed. In this example, at time t, t+2 units of work will remain. This is known as CPU saturation.
In practice, however, CPU starvation is generally unlikely.
The FCFS and SJF algorithms are examples of cooperative scheduling. This works great for some cases but not for other cases such as the following:
| Job | T | Arriving Time |
|---|---|---|
| A | 10100 | 0 |
| B | 1 | 1 |
In this case, we want job B to preempt or interrupt job A.
Preemptive Scheduling
Round Robin
Example:
If Q = 3,
We get the following Gantt Chart:
| 0 | 3 | 5 | 8 | 11 | 13 | 16 | 17 |
|---|---|---|---|---|---|---|---|
| ---A--- | --B-- | ---C--- | ---D--- | --A-- | ---C--- | -D- | ---C--- |
Analysis of responsiveness and turnaround time:
| Job | W | TTRND |
|---|---|---|
| A | 0 | 13 + 4C |
| B | 3 + C | 5 + C |
| C | 5 + 2C | 20 + 7C |
| D | 8 + 3C | 17 + 6C |
| Average | 4 + 1.5C | 12.75 + 4.5C |
If Q = 2,
We get:
W = 3 + 1.5C
TTRND = 13.25 + 6C
Priority
Example:
While still using Q = 3,
We augment our process list:
| Job | Τ | Priority |
|---|---|---|
| A | 5 | 2 |
| B | 2 | 2 |
| C | 9 | 0 |
| D | 4 | 1 |
We get the following Gantt Chart:
| 0 | 3 | 6 | 9 | 12 | 13 | 16 | 18 |
|---|---|---|---|---|---|---|---|
| ---C--- | ---C--- | ---C--- | ---D--- | -D- | ---A--- | --B-- | ---A--- |
Analysis of responsiveness and turnaround time:
| Job | W | TTRND |
|---|---|---|
| A | 13 + 5C | 20 + 7C |
| B | 16 + 6C | 18 + 6C |
| C | 0 | 9 + 3C |
| D | 9 + 3C | 13 + 4C |
| Average | 9.5 + 3.5C | 15 + 5C |
Multi-Level Priority System
Priority Inversion
Privilege and Priority
Multi-Level Feedback Queues
p_estcpu: process's estimated CPU utilization p_nice: normal priority
p_usrpri = 1/4 * ( 50 + 1/4 * p_estcpu + 2 * p_nice )