Introduction To Operating System
Introduction To Operating System
The 1960’s definition of an operating system is “the software that controls the hardware”.
However, today, due to microcode we need a better definition. We see an operating
system as the programs that make the hardware useable. In brief, an operating system is
the set of programs that controls a computer. Some examples of operating systems are
UNIX, MS-DOS, MS-Windows, Windows/NT, Chicago, OS/2, MacOS, VMS, MVS,
and VM, DOS, Symbian OS, Windows 95 / 98 / Me / , DOS, IBM , Linux OS, Windows
Controlling the computer involves software at several levels. We will differentiate kernel
services, library services, and application-level services, all of which are part of the
operating system. Processes run Applications, which are linked together with libraries
that perform standard services. The kernel supports the processes by providing a path to
the peripheral devices. The kernel responds to service calls from the processes and
interrupts from the devices. The core of the operating system is the kernel, a control
program that functions in privileged state (an execution context that allows all hardware
instructions to be executed), reacting to interrupts from external devices and to service
requests and traps from processes. Generally, the kernel is a permanent resident of the
computer. It creates and terminates processes and responds to their request for service.
Operating Systems are resource managers. The main resource is computer hardware in
the form of processors, storage, input/output devices, communication devices, and data.
Some of the operating system functions are: implementing the user interface, sharing
hardware among users, allowing users to share data among themselves, preventing users
from interfering with one another, scheduling resources among users, facilitating
input/output, recovering from errors, accounting for resource usage, facilitating parallel
operations, organizing data for secure and rapid access, and handling network
communications.
Modern Operating systems generally have following three major goals. Operating
systems generally accomplish these goals by running processes in low privilege and
providing service calls that invoke the operating system kernel in high-privilege state.
1
abstractions built by the operating system. There are several reasons for
abstraction.
First, the code needed to control peripheral devices is not standardized. Operating
systems provide subroutines called device drivers that perform operations on
behalf of programs for example, input/output operations.
Second, the operating system introduces new functions as it abstracts the
hardware. For instance, operating system introduces the file abstraction so that
programs do not have to deal with disks.
Third, the operating system transforms the computer hardware into multiple
virtual computers, each belonging to a different program. Each program that is
running is called a process. Each process views the hardware through the lens of
abstraction.
Fourth, the operating system can enforce security through abstraction.
One can view Operating Systems from two points of views: Resource manager and
Extended machines. Form Resource manager point of view Operating Systems manage
the different parts of the system efficiently and from extended machines point of view
Operating Systems provide a virtual machine to users that is more convenient to use. The
structurally Operating Systems can be design as a monolithic system, a hierarchy of
layers, a virtual machine system, an exokernel, or using the client-server model. The
basic concepts of Operating Systems are processes, memory management, I/O
management, the file systems, and security.
Historically operating systems have been tightly related to the computer architecture, it is
good idea to study the history of operating systems from the architecture of the computers
on which they run.
2
Operating systems have evolved through a number of distinct phases or generations
which corresponds roughly to the decades.
The earliest electronic digital computers had no operating systems. Machines of the time
were so primitive that programs were often entered one bit at time on rows of mechanical
switches (plug boards). Programming languages were unknown (not even assembly
languages). Operating systems were unheard of.
By the early 1950's, the routine had improved somewhat with the introduction of punch
cards. The General Motors Research Laboratories implemented the first operating
systems in early 1950's for their IBM 701. The system of the 50's generally ran one job at
a time. These were called single-stream batch processing systems because programs and
data were submitted in groups or batches.
The systems of the 1960's were also batch processing systems, but they were able to take
better advantage of the computer's resources by running several jobs at once. So
operating systems designers developed the concept of multiprogramming in which
several jobs are in main memory at once; a processor is switched from job to job as
needed to keep several jobs advancing while keeping the peripheral devices in use.
For example, on the system with no multiprogramming, when the current job paused to
wait for other I/O operation to complete, the CPU simply sat idle until the I/O finished.
The solution for this problem that evolved was to partition memory into several pieces,
with a different job in each partition. While one job was waiting for I/O to complete,
another job could be using the CPU.
Another major feature in third-generation operating system was the technique called
spooling (simultaneous peripheral operations on line). In spooling, a high-speed device
like a disk interposed between a running program and a low-speed device involved with
the program in input/output. Instead of writing directly to a printer, for example, outputs
are written to the disk. Programs can run to completion faster, and other programs can be
initiated sooner when the printer becomes available, the outputs may be printed.
Note that spooling technique is much like thread being spun to a spool so that it may be
later be unwound as needed.
3
Timesharing systems were developed to multiprogram large number of simultaneous
interactive users.
Fourth Generation
With the development of LSI (Large Scale Integration) circuits, chips, operating system
entered in the personal computer and the workstation age. Microprocessor technology
evolved to the point that it becomes possible to build desktop computers as powerful as
the mainframes of the 1970s. Two operating systems have dominated the personal
computer scene: MS-DOS, written by Microsoft, Inc. for the IBM PC and other machines
using the Intel 8088 CPU and its successors, and UNIX, which is dominant on the large
personal computers using the Motorola 6899 CPU family.
There are four general types of operating systems. Their use depends on the type of
computer and the type of applications that will be run on those computers.
4
found on most personal desktop and laptop computers. Microsoft Windows, Mac OS,
and Linux are three well-known examples of this type of system.
4. Multi-user operating systems allow multiple users to simultaneously use the
resources on a single computer. Unix is an example of a multi-user operating system.
By the time Windows 3.1 was released in 1991, Windows had gained significantly in
market share, and from the mid-1990s on, Microsoft dominated the operating-system
market. Microsoft released Windows 95 in August 1995. It was so well marketed and in
such high demand that people bought the operating system even if they did not own a
home computer. With each new release, from Windows 98 to Windows 2000 to
Windows XP to Windows Vista, Microsoft gained popularity. By 2004, Microsoft
commanded around 90 percent of the operating-system market. The latest Windows
release, Windows Vista, was introduced worldwide in January 2007, five years after the
introduction of its predecessor, Windows XP—the longest time between releases of
Windows. Vista is only slowly gaining in popularity, while Windows XP remains the
world's dominant operating system, commanding 79 percent market share in September
2007 (compared to only 7 percent for Vista).
5
The second-most popular family of operating systems is the Mac OS. Macintosh is often
credited with introducing the GUI-style operating system; Mac OS was not the first
graphical user interface, but it was the
first successful one, largely because competitors were so expensive—the Xerox Alto, the
first true GUI system, cost $32,000 to build while the Macintosh retailed for $2,500.
Because of its relative affordability, it immediately became much more popular than
other GUI computers. The first Mac OS, unnamed at the time but now known as “System
1,” was introduced in 1984. It had a desktop, windows, icons, a mouse, menus, and
scrollbars.
Early versions of the Mac OS could only be used on Apple computers. In 1991, Apple
introduced computers with PowerPC hardware; these computers could run either
Windows or Mac OS. The latest version of the Mac OS, OS X, was first introduced in
2000. It can be used in computers with both PowerPC and Intel processors, giving it
wider applicability and use. However, the Mac OS lags far behind Microsoft Windows.
In 2007, it was the world's third-most popular operating system—after Windows XP and
Windows Vista—but it commanded only slightly over 3 percent of the operating-system
market.
Linux is a UNIX variant that runs on several different hardware platforms. Linus
Torvalds, a student at the University of Helsinki in Finland, initially created it as a hobby.
The kernel, at the heart of all Linux systems, is developed and released under the General
Public License (GNU), and its source code is freely available to everyone. There are now
hundreds of companies, organizations, and individuals that have released their own
versions of operating systems based on the Linux kernel.
6
decade after its initial release, Linux is being adopted worldwide mainly as a server
platform. More and more people are starting to use Linux as a home and office desktop
operating system. The operating system can also be incorporated directly into microchips
in a process called “embedding.” Many appliances and devices are now starting to use
operating systems in this way.
Even though, not all systems have the same structure many modern operating systems
share the same goal of supporting the following types of system components.
Process Management
The operating system manages many kinds of activities ranging from user programs to
system programs like printer spooler, name servers, file server etc. Each of these
activities is encapsulated in a process. A process includes the complete execution context
(code, data, PC, registers, OS resources in use etc.).
It is important to note that a process is not a program. A process is only ONE instant of a
program in execution. Many processes can be running the same program. The five major
activities of an operating system in regard to process management are
Main-Memory Management
Keep track of the part of memory that is currently being used and by whom.
7
Decide which process is loaded into memory when memory space becomes
available.
Allocate and deallocate memory space as needed.
File Management
A file is a collection of related information defined by its creator. Computer can store
files on the disk (secondary storage), which provide long term storage. Some examples of
storage media are magnetic tape, magnetic disk and optical disk. Each of these media has
its own properties like speed, capacity, and data transfer rate and access methods.
File systems is normally organized into directories to ease their use. These directories
may contain files and other directions.
The five main activities of an operating system in regard to file management are
I/O subsystem hides the peculiarities of specific hardware devices from the user. Only the
device driver knows the peculiarities of the specific device to which it is assigned.
Secondary-Storage Management
Generally speaking, systems have several levels of storage, including primary storage,
secondary storage and cache storage. Instructions and data must be placed in primary
storage or cache to be referenced by a running program. Because main memory is too
small to accommodate all data and programs, and its data is lost when power is lost, the
computer system must provide secondary storage to back up main memory. Secondary
storage consists of tapes, disks, and other media designed to hold information that will
eventually be accessed in primary storage (primary, secondary, cache) is ordinarily
divided into bytes or words consisting of a fixed number of bytes. Each location in
storage has an address; the set of all addresses available to a program is called an address
space.
8
Networking
Protection of Systems
If computer systems have multiple users and allows the concurrent execution of multiple
processes, then the various processes must be protected from one another's activities.
Protection refers to mechanism for controlling the access of programs, processes, or users
to the resources defined by computer systems.
A command interpreter is an interface of the operating system with the user. The user
gives commands which are executed by operating system (usually by turning them into
system calls). The main function of a command interpreter is to get and execute the next
user specified command. Command-Interpreter is usually not part of the kernel, since
multiple command interpreters (shell, in UNIX terminology) may be supported by an
operating system, and they do not really need to run in kernel mode. There are two main
advantages of separating the command interpreter from the kernel.
1. If we want to change the way the command interpreter looks, i.e., I want to
change the interface of command interpreter, I am able to do that if the command
interpreter is separated from the kernel.
2. If the command interpreter is a part of the kernel it is possible for a malicious
process to gain access to certain part of the kernel. It is advantageous to have the
command interpreter separated from kernel.
Following are the five services provided by operating systems to the convenience of the
users.
Program Execution
The purpose of computer system is to allow the user to execute programs. So the
operating systems provide an environment where the user can conveniently run programs.
The user does not have to worry about the memory allocation or multitasking. These
things are taken care of by the operating systems.
9
Running a program involves the allocating and deallocating memory, CPU scheduling in
case of multiprocessing. These functions cannot be given to the user-level programs
because user-level programs cannot help the user to run programs independently without
the help from operating systems.
I/O Operations
Each program requires an input and produces output. This involves the use of I/O. The
operating systems hide from the user, the details of underlying hardware from I/O. All the
user sees is that the I/O has been performed without any details. The operating system
makes it convenient for the users to run programs.
The output of a program may need to be written into new files or input taken from some
files. The operating systems provide these services. The user does not have to worry
about secondary storage management. User gives a command for reading or writing to a
file and sees his task accomplished. Thus, operating systems make it easier for user
programs to accomplish their task.
This service involves secondary storage management. The speed of I/O that depends on
secondary storage management is critical to the speed of many programs and hence, it is
best relegated to the operating systems to manage it than giving individual users to
control it.
Communications
There are instances where processes need to communicate with each other to exchange
information. It may be between processes running on the same computer or running on
the different computers. By providing this service the operating system relieves the user
of the worry of passing messages between processes. If a case arises that the messages
need to be passed to processes on the other computers through a network it can be done
by the user programs. The user program may be customized to specific hardware through
which the message transits and provides the service interface to the operating system.
Error Detection
An error is one part of the system may cause malfunctioning of the complete system. To
avoid such a situation the operating system constantly monitors the system for detecting
the errors. This relieves the user of the worry of errors propagating to various part of the
system and causing malfunctioning.
10
faulty process. Or may be relinquishing the CPU of a process that goes into an infinite
loop. These tasks are too critical to be handed over to the user programs. A user program
if given these privileges can interfere with the correct (normal) operation of the operating
systems.
System calls provide an interface between the process and the operating system. System
calls allow user-level processes to request for some services from the operating system
which the process itself is not allowed to do. In handling the trap, the operating system
will enter in the kernel mode, where it has access to privileged instructions, and can
perform the desired service on the behalf of user-level process. It is because of the critical
nature of operations that the operating system itself does them every time they are
needed. For example, for I/O a process involves a system call telling the operating system
to read or write particular area and this request is satisfied by the operating system.
System programs provide basic functioning to users so that they do not need to write their
own environment for program development (editors, compilers) and program execution
(shells). In some sense, they are bundles of useful system calls.
In this case the system is easier to debug and modify, because changes affect only
limited portions of the code, and programmer does not have to know the details of the
other layers. Information is also kept only where it is needed and is accessible only in
certain ways, so bugs affecting that data are limited to a specific module or layer.
The policies define what is to be done while the mechanism specifies how it is to be
done. For instance, the timer construct for ensuring CPU protection is mechanism. On the
other hand, the decision of how long the timer is set for a particular user is a policy
decision.
Once the policy has been decided it gives the programmer the choice of using his/her
own implementation. Also, the underlying implementation may be changed for a more
efficient one without much trouble if the mechanism and policy are well defined.
11
Specifically, separating these two provides flexibility in a variety of ways. First, the same
mechanism can be used to implement a variety of policies, so changing the policy might
not require the development of a new mechanism, but just a change in parameters for that
mechanism. Second, the mechanism can be changed for example, to increase its
efficiency or to move to a new platform, without changing the overall policy.
3.0 PROCESS
Definition of Process
The notion of process is central to the understanding of operating systems. There are
quite a few definitions presented in the literature, but no "perfect" definition has yet
appeared.
Definition
The term "process" was first used by the designers of the MULTICS in 1960's. Since
then, the term process, used somewhat interchangeably with 'task' or 'job'. The process
has been given many definitions for instance
A program in Execution.
An asynchronous activity.
The 'animated sprit' of a procedure in execution.
The entity to which processors are assigned.
The 'dispatchable' unit.
Process is not the same as program. A process is more than a program code. A process is
an 'active' entity as oppose to program which consider being a 'passive' entity. A program
is an algorithm expressed in some suitable notation, (e.g., programming language).
Process, on the other hand, includes:
In Process model, all software on the computer is organized into a number of sequential
processes. A process includes PC, registers, and variables. Conceptually, each process
has its own virtual CPU. In reality, the CPU switches back and forth among processes.
(The rapid switching back and forth is called multiprogramming).
12
A multitasking* operating system may just switch between processes to give the
appearance of many processes executing concurrently or simultaneously, though in fact
only one process can be executing at any one time on a single-core CPU (unless using
multi-threading or other similar technology).[3]
It is usual to associate a single process with a main program, and 'daughter' ('child')
processes with any spin-off, parallel processes, which behave like asynchronous
subroutines. A process is said to own resources, of which an image of its program (in
memory) is one such resource. (Note, however, that in multiprocessing systems,
many processes may run off of, or share, the same reentrant program at the same location
in memory— but each process is said to own its own image of the program.)
Processes are often called tasks in embedded operating systems. The sense of 'process' (or
task) is 'something that takes up time', as opposed to 'memory', which is 'something that
takes up space'. (Historically, the terms 'task' and 'process' were used interchangeably, but
the term 'task' seems to be dropping from the computer lexicon.)
The above description applies to both processes managed by an operating system, and
processes as defined by process calculi.
If a process requests something for which it must wait, it will be blocked. When the
process is in the Blocked State, it is eligible for swapping to disk, but this is transparent
in a virtual memory system, where blocks of memory values may be really on disk and
not in main memory at any time. Note that even unused portions of active processes/tasks
(executing programs) are eligible for swapping to disk. All parts of an executing program
and its data do not have to be in physical memory for the associated process to be active.
______________________________
*Tasks and processes refer essentially to the same entity. And, although they have
somewhat different terminological histories, they have come to be used as synonyms.
Today, the term process is generally preferred over task, except when referring to
'multitasking', since the alternative term, 'multiprocessing', is too easy to confuse with
multiprocessor (which is a computer with two or more CPUs).
Process State
13
The process state consist of everything necessary to resume the process execution if it is
somehow put aside temporarily. The process state consists of at least the following:
Process Operations
Process Creation
System initialization.
Execution of a process Creation System calls by a running process.
A user request to create a new process.
Initialization of a batch job.
Foreground processes interact with users. Background processes that stay in background
sleeping but suddenly springing to life to handle activity such as email, webpage,
printing, and so on. Background processes are called daemons. This call creates an exact
clone of the calling process.
A process may create a new process such as ‘fork’. The process that created a new
14
process is called parent process while the created one is called the child process. Only
one parent is needed to create a child process. Note that unlike plants and animals that
use sexual representation, a process has only one parent. This creation of process
(processes) yields a hierarchical structure of processes. Note that each child has only one
parent but each parent may have many children. After the fork, the two processes, the
parent and the child, have the same memory image, the same environment strings and the
same open files. After a process is created, both the parent and child have their own
distinct address space. If either process changes a word in its address space, the change is
not visible to the other process.
Some program starts another process, e.g., Netscape calls xv to display a picture.
Process Termination
A process terminates when it finishes executing its last statement. Its resources are
returned to the system, and its process control block (PCB) is erased i.e., the PCB's
memory space is returned to a free memory pool. The new process terminates the existing
process in the following ways:
Normal Exist Most processes terminates because they have done their job. This
call is exist in UNIX.
Error Exist When process discovers a fatal error. For example, a user trying to
compile a program that does not exist.
Fatal Error An error caused by processes due to a bug in program for example,
executing an illegal instruction, referring non-existing memory or dividing by
zero.
Killed by another Process A process executes a system call telling the
Operating Systems to terminate some other process. In UNIX, this call is killing.
In some systems when a process kills all processes, it created ones are killed as
well (UNIX does not work this way).
Process States
15
Blocked (waiting) State When a process blocks, it does so because logically it
cannot continue, typically because it is waiting for input that is not yet available.
Formally, a process is said to be blocked if it is waiting for some event to happen
(such as an I/O completion) before it can proceed. In this state a process is unable
to run until some external event happens.
Running State A process is said t be running if it currently has the CPU that is,
actually using the CPU at that particular instant.
Ready State A process is said to be ready if it use of the CPU is available. It is
runnable but temporarily stopped to let another process run.
Logically, the 'Running' and 'Ready' states are similar. In both cases the process is willing
to run, only in the case of 'Ready' state, there is temporarily no CPU available for it. The
'Blocked' state is different from the 'Running' and 'Ready' states in that the process cannot
run, even if the CPU is available.
Following are six (6) possible transitions among above mentioned five (5) states
FIGURE
Transition 2 occurs when the scheduler decides that the running process has run
long enough and it is time to let another process have CPU time.
Transition 3 occurs when all other processes have had their share and it is time
for the first process to run again
Transition 4 occurs when the external event for which a process was waiting
(such as arrival of input) happens.
16
This state transition is:
The current state of the process i.e., whether it is ready, running, waiting, or
whatever.
Unique identification of the process in order to track "which is which"
information.
A pointer to parent process.
Similarly, a pointer to child process (if it exists).
The priority of process (a part of CPU scheduling information).
Pointers to locate memory of processes.
A register save area.
The processor it is running on.
The PCB is a central store of information that allows the operating systems to locate all
key information about a process. Thus, the PCB is the data structure that defines a
process to the operating systems.
4.0 Threads
17
Threads
Processes Vs Threads
Why Threads?
User-Level Threads
Kernel-Level Threads
Advantages of Threads over Multiple Processes
Disadvantages of Threads over Multiprocessing
Application that Benefits from Threads
Application that cannot benefit from Threads
Resources used in Thread creation and Process Creation
Context Switch
Major Steps of Context Switching
Action of Kernel to Context switch among threads
Action of kernel to Context switch among processes
Threads
Despite the fact that a thread must execute in process, the process and its associated
threads are different concept. Processes are used to group resources together and threads
are the entities scheduled for execution on the CPU.
A thread is a single sequence stream within a process. Because threads have some of the
properties of processes, they are sometimes called lightweight processes. In a process,
threads allow multiple executions of streams. In many respect, threads are popular way to
improve application through parallelism. The CPU switches rapidly back and forth
among the threads giving illusion that the threads are running in parallel. Like a
traditional process i.e., process with one thread, a thread can be in any of several states
(Running, Blocked, Ready or Terminated). Each thread has its own stack. Since thread
will generally call different procedures and thus a different execution history. This is why
thread needs its own stack. An operating system that has thread facility, the basic unit of
CPU utilization is a thread. A thread has or consists of a program counter (PC), a register
set, and a stack space. Threads are not independent of another like processes as a result
threads shares with other threads their code section, data section, OS resources also
known as task, such as open files and signals.
Processes Vs Threads
As we mentioned earlier that in many respect threads operate in the same way as that of
processes. Some of the similarities and differences are:
Similarities
Like processes threads share CPU and only one thread is active (running) at a
time.
Like processes, threads within processes execute sequentially.
Like processes, thread can create children.
And like process, if one thread is blocked, another thread can run.
18
Differences
Why Threads?
Following are some reasons why we use threads in designing operating systems.
1. A process with multiple threads make a great server for example printer server.
2. Because threads can share common data, they do not need to use interprocess
communication.
3. Because of the very nature, threads can take advantage of multiprocessors.
1. They only need a stack and storage for registers therefore, threads are cheap to
create.
2. Threads use very little resources of an operating system in which they are
working. That is, threads do not need new address space, global data, program
code or operating system resources.
3. Context switching are fast when working with threads. The reason is that we only
have to save and/or restore PC, SP and registers.
But this cheapness does not come free - the biggest drawback is that there is no protection
between threads.
User-Level Threads
User-level threads implement in user-level libraries, rather than via systems calls, so
thread switching does not need to call operating system and to cause interrupt to the
kernel. In fact, the kernel knows nothing about user-level threads and manages them as if
they were single-threaded processes.
Advantages:
The most obvious advantage of this technique is that a user-level threads package can be
implemented on an Operating System that does not support threads. Some other
advantages are
19
Simple Representation:
Each thread is represented simply by a PC, registers, stack and a small control
block, all stored in the user process address space.
Simple Management:
This simply means that creating a thread, switching between threads and
synchronization between threads can all be done without intervention of the
kernel.
Fast and Efficient:
Thread switching is not much more expensive than a procedure call.
Disadvantages:
Kernel-Level Threads
In this method, the kernel knows about and manages the threads. No runtime system is
needed in this case. Instead of thread table in each process, the kernel has a thread table
that keeps track of all threads in the system. In addition, the kernel also maintains the
traditional process table to keep track of processes. Operating Systems kernel provides
system call to create and manage threads.
Advantages:
Because kernel has full knowledge of all threads, Scheduler may decide to give
more time to a process having large number of threads than process having small
number of threads.
Kernel-level threads are especially good for applications that frequently block.
Disadvantages:
The kernel-level threads are slow and inefficient. For instance, threads operations
are hundreds of times slower than that of user-level threads.
Since kernel must manage and schedule threads as well as processes. It require a
full thread control block (TCB) for each thread to maintain information about
threads. As a result there is significant overhead and increased in kernel
complexity.
20
Context Switching Threads are very inexpensive to create and destroy, and
they are inexpensive to represent. For example, they require space to store, the
PC, the SP, and the general-purpose registers, but they do not require space to
share memory information, Information about open files of I/O devices in use,
etc. With so little context, it is much faster to switch between threads. In other
words, it is relatively easier for a context switch using threads.
Sharing Treads allow the sharing of a lot resources that cannot be shared in
process, for example, sharing code section, data section, Operating System
resources like open file etc.
Blocking The major disadvantage if the kernel is single threaded, a system call
of one thread will block the whole process and CPU may be idle during the
blocking period.
Security Since there is, an extensive sharing among threads there is a potential
problem of security. It is quite possible that one thread over writes the stack of
another thread (or damaged shared data) although it is very unlikely since threads
are meant to cooperate on a single task.
A proxy server satisfying the requests for a number of computers on a LAN would be
benefited by a multi-threaded process. In general, any program that has to do more than
one task at a time could benefit from multitasking. For example, a program that reads
input, process it, and outputs could have three threads, one for each task.
Any sequential process that cannot be divided into parallel task will not benefit from
thread, as they would block until the previous one completes. For example, a program
that displays the time of the day would not benefit from multiple threads.
21
When a new thread is created it shares its code section, data section and operating system
resources like open files with other threads. But it is allocated its own stack, register set
and a program counter.
The creation of a new process differs from that of a thread mainly in the fact that all the
shared resources of a thread are needed explicitly for each process. So though two
processes may be running the same piece of code they need to have their own copy of the
code in the main memory to be able to run. Two processes also do not share other
resources with each other. This makes the creation of a new process very costly
compared to that of a new thread.
Context Switch
To give each process a fair share of the CPU, a hardware clock generates interrupts
periodically. This allows the operating system to schedule all processes in main memory
(using scheduling algorithm) to run on the CPU at equal intervals. Each time a clock
interrupt occurs, the interrupt handler checks how much time the current running process
has used. If it has used up its entire time slice, then the CPU scheduling algorithm (in
kernel) picks a different process to run. Each switch of the CPU from one process to
another is called a context switch.
The values of the CPU registers are saved in the process table of the process that
was running just before the clock interrupt occurred.
The registers are loaded from the process picked by the CPU scheduler to run
next.
In a uniprocessor computing system, context switches occur frequently enough that all
processes appear to be running concurrently. If a process has more than one thread, the
Operating System can use the context switching technique to schedule the threads so they
appear to execute in parallel. This is the case if threads are implemented at the kernel
level. Threads can also be implemented entirely at the user level in run-time libraries.
Since in this case no thread scheduling is provided by the Operating System, it is the
responsibility of the programmer to yield the CPU frequently enough in each thread so all
threads in the process can make progress.
The threads share a lot of resources with other peer threads belonging to the same
process. So a context switch among threads for the same process is easy. It involves
switch of register set, the program counter and the stack. It is relatively easy for the
kernel to accomplish this task.
22
Context switches among processes are expensive. Before a process can be switched its
process control block (PCB) must be saved by the operating system. The PCB consists of
the following information:
When the PCB of the currently executing process is saved the operating system loads the
PCB of the next process that has to be run on CPU. This is a heavy task and it takes a lot
of time.
5.0 Deadlock
“Crises and deadlocks when they occur have at least this advantage that they force us
to think.”- Jawaharlal Nehru (1889 - 1964) Indian political leader
A set of process is in a deadlock state if each process in the set is waiting for an event that
can be caused by only another process in the set. In other words, each member of the set
of deadlock processes is waiting for a resource that can be released only by a deadlock
process. None of the processes can run, none of them can release any resources, and none
of them can be awakened. It is important to note that the number of processes and the
number and kind of resources possessed and requested are unimportant.
The resources may be either physical or logical. Examples of physical resources are
Printers, Tape Drivers, Memory Space, and CPU Cycles. Examples of logical resources
are Files, Semaphores, and Monitors.
The simplest example of deadlock is where process 1 has been allocated non-shareable
resources A, say, a tap drive, and process 2 has be allocated non-sharable resource B, say,
a printer. Now, if it turns out that process 1 needs resource B (printer) to proceed and
process 2 needs resource A (the tape drive) to proceed and these are the only two
processes in the system, each is blocked the other and all useful work in the system stops.
This situation ifs termed deadlock. The system is in deadlock state because each process
holds a resource being requested by the other process neither process is willing to release
the resource it holds.
23
Resources come in two flavors: preemptable and nonpreemptable. A preemptable
resource is one that can be taken away from the process with no ill effects. Memory is an
example of a preemptable resource. On the other hand, a nonpreemptable resource is one
that cannot be taken away from process (without causing ill effect). For example, CD
resources are not preemptable at an arbitrary moment.
Reallocating resources can resolve deadlocks that involve preemptable resources.
Deadlocks that involve nonpreemptable resources are difficult to deal with.
Coffman (1971) identified four (4) conditions that must hold simultaneously for there to
be a deadlock.
3. No-Preemptive Condition
Resources already allocated to a process cannot be preempted.
Explanation: Resources that cannot be removed from the processes are used in
completing or released voluntarily by the process holding it.
24
Consider each section of the street as a resource.
1. Mutual exclusion condition applies, since only one vehicle can be on a section of
the street at a time.
2. Hold-and-wait condition applies, since each vehicle is occupying a section of the
street, and waiting to move on to the next section of the street.
3. No-preemptive condition applies, since a section of the street that is occupied by a
vehicle cannot be taken away from it.
4. Circular wait condition applies, since each vehicle is waiting on the next vehicle
to move. That is, each vehicle in the traffic is waiting for a section of street held
by the next vehicle in the traffic.
The simple rule to avoid traffic deadlock is that a vehicle should only enter an
intersection if it is assured that it will not have to stop inside the intersection.
It is not possible to have a deadlock involving only one single process. The deadlock
involves a circular “hold-and-wait” condition between two or more processes, so “one”
process cannot hold a resource, yet be waiting for another resource that it is holding. In
addition, deadlock is not possible between two threads in a process, because it is the
process that holds resources, not the thread that is, each thread has access to the resources
held by the process.
25
1. The Ostrich Approach
Just ignore the deadlock problem altogether.
2. Deadlock Detection and Recovery
Detect deadlock and, when it occurs, take steps to recover.
3. Deadlock Avoidance
Avoid deadlock by careful resource scheduling.
4. Deadlock Prevention
Prevent deadlock by resource scheduling so as to negate at least one of the four
conditions.
Deadlock Prevention
Havender in his pioneering work showed that since all four of the conditions are
necessary for deadlock to occur, it follows that deadlock might be prevented by denying
any one of the conditions.
26
allow processes to hold resources while requesting additional resources. Consider
what happens when a request cannot be satisfied. A process holds resources a
second process may need in order to proceed while second process may hold the
resources needed by the first process. This is a deadlock. This strategy require that
when a process that is holding some resources is denied a request for additional
resources. The process must release its held resources and, if necessary, request
them again together with additional resources. Implementation of this strategy
denies the “no-preemptive” condition effectively.
High Cost When a process release resources the process may lose all its work to
that point. One serious consequence of this strategy is the possibility of indefinite
postponement (starvation). A process might be held off indefinitely as it
repeatedly requests and releases the same resources.
1 ≡ Card reader
2 ≡ Printer
3 ≡ Plotter
4 ≡ Tape drive
5 ≡ Card punch
Now the rule is this: processes can request resources whenever they want to, but
all requests must be made in numerical order. A process may request first printer
and then a tape drive (order: 2, 4), but it may not request first a plotter and then a
printer (order: 3, 2). The problem with this strategy is that it may be impossible to
find an ordering that satisfies everyone.
Deadlock Avoidance
This approach to the deadlock problem anticipates deadlock before it actually occurs.
This approach employs an algorithm to access the possibility that deadlock could occur
and acting accordingly. This method differs from deadlock prevention, which guarantees
that deadlock cannot occur by denying one of the necessary conditions of deadlock.
If the necessary conditions for a deadlock are in place, it is still possible to avoid
deadlock by being careful when resources are allocated. Perhaps the most famous
deadlock avoidance algorithm, due to Dijkstra [1965], is the Banker’s algorithm. So
named because the process is analogous to that used by a banker in deciding if a loan can
be safely made.
27
Banker’s Algorithm
In this analogy
Customer
≡ Processes
s
resources, say,
Units ≡
tape drive
Operating
Banker ≡
System
Customer
Used Max
s
A 0 6
B 0 5 Available
C 0 4 Units = 10
D 0 7
Fig. 1
In the above figure, we see four customers each of whom has been granted a number of
credit nits. The banker reserved only 10 units rather than 22 units to service them. At
certain moment, the situation becomes
CustomersUsed Max
A 1 6
B 1 5 Available
C 2 4 Units = 2
D 4 7
Fig. 2
Safe State The key to a state being safe is that there is at least one way for all users to
finish. In other analogy, the state of figure 2 is safe because with 2 units left, the banker
can delay any request except C's, thus letting C finish and release all four resources. With
four units in hand, the banker can let either D or B have the necessary units and so on.
Unsafe State Consider what would happen if a request from B for one more unit were
granted in above figure 2.
CustomersUsed Max
A 1 6
B 2 5 Available
C 2 4 Units = 1
D 4 7
28
Fig. 3
If all the customers namely A, B, C, and D asked for their maximum loans, then banker
could not satisfy any of them and we would have a deadlock.
Important Note: It is important to note that an unsafe state does not imply the
existence or even the eventual existence a deadlock. What an unsafe state does imply is
simply that some unfortunate sequence of events might lead to a deadlock.
The Banker's algorithm is thus to consider each request as it occurs, and see if granting it
leads to a safe state. If it does, the request is granted, otherwise, it postponed until later.
Haberman [1969] has shown that executing of the algorithm has complexity proportional
to N2 where N is the number of processes and since the algorithm is executed each time a
resource request occurs, the overhead is significant.
Deadlock Detection
Deadlock detection is the process of actually determining that a deadlock exists and
identifying the processes and resources involved in the deadlock.
The basic idea is to check allocation against resource availability for all possible
allocation sequences to determine if the system is in deadlocked state a. Of course, the
deadlock detection algorithm is only half of this strategy. Once a deadlock is detected,
there needs to be a way to recover several alternatives exists:
These methods are expensive in the sense that each iteration calls the detection algorithm
until the system proves to be deadlock free. The complexity of algorithm is O(N2) where
N is the number of proceeds. Another potential problem is starvation; same process killed
repeatedly.
There are two general strategies for communicating via the Internet: Asynchronous and
Synchronous. Each has its advantages and disadvantages.
Asynchronous communication and activities take place outside of real time. For
example, a learner sends you an e-mail message. You later read and respond to the
message. There is a time lag between the time the learner sent the message and you
replied, even if the lag time is short. Bulletin board messages can be added at any time
29
and read at your and the learners’ leisure; you do not read someone else’s message as it is
being created, and you can take as much time as you need to respond to the post.
Asynchronous activities take place whenever learners have the time to complete them.
For example, viewing videos linked to the course site, reading a textbook, and writing a
paper are all asynchronous activities.
There are some key advantages to asynchronous collaboration tools. For one thing,
they enable flexibility. Participants can receive the information when it's most convenient
for them. There's less pressure to act on the information or immediately respond in some
way. People have time to digest the information and put it in the proper context and
perspective. Another advantage is that some forms of asynchronous collaboration, such
as email, are ubiquitous. These days, it's hard to find a co-worker, customer, business
partner, consultant, or other party who doesn't have an email account.
The drawbacks of asynchronous collaboration are that they can lack a sense of
immediacy and drama. There's less immediate interaction. Sometimes people have to
wait hours, days, and even weeks to get a response to a message or feedback on a shared
document. The lack of immediacy means that information can be out of date by the time
someone views it. This is especially true in light of the rapid pace of change in today's
business environment [6].
One of the advantages of synchronous collaboration is its immediacy. You can send
and receive information right away. This more closely resembles a face-to-face or
telephone conversation between two or more people, so can present a more natural way
of communicating. The sense of immediacy is more like to solicit a timely response from
people. Synchronous collaboration, in general, is more interactive than asynchronous. [4]
The downside of synchronous collaboration is that not everyone uses it. Although instant
messaging, chat, and other such tools are becoming more common, they're still not as
ubiquitous as technology such as email. Another drawback is that synchronous
collaboration is not as flexible as asynchronous. All the parties involved must be ready
and willing to collaborate at a given moment-or the session doesn't work as well. Also,
not everyone does well with this kind of collaboration, particularly people who like to
think over what they want to communicate [6].
30
When should you use asynchronous and synchronous collaboration? Much of the
decision-making on this involves common sense. Asynchronous collaboration, such as
email and document sharing, can certainly be used for day-to-day communications when
an urgent response isn't needed. This sort of communication is suitable for sending out
broadcast messages that don't necessarily need to be acted on right away, or for
corresponding with clients, customers. and business partners without putting pressure on
them to respond immediately.
On the other hand, you wouldn't want to use asynchronous collaboration if you need
immediate interaction with people or if you seek to collaborate with a large group at the
same time. Email wouldn't work, for example, as the sole means of conducting a staff
meeting.
Synchronous collaboration wouldn't be suitable for situations that call for less immediate
response or where parties aren't able to respond right away. For example, it might not
work as a way to collaborate with customers on new product design or development.
Accidents: Problems of this kind are easy to solve (can do things to make the
likelihood small).
Malicious abuse: Problems of this kind are very hard to completely eliminate
(cannot leave any loopholes, cannot play on probabilities).
Even the slightest flaw in any of these areas may ruin the whole protection mechanism.
Authentication
31
User identification is most often done with passwords. This is a relatively weak form of
protection.
A password is a secret piece of information used to establish the identity of a user.
Passwords should not be stored in a readable form. One-way transformations
should be used.
Passwords should be relatively long and obscure.
Key paradox: key must be cheap to make, hard to duplicate. This means there must be
some trick (i.e. secret) that has to be protected.
Once identification is complete, the system must be sure to protect the identity since
other parts of the system will rely on it.
Authorization Determination
Must indicate who is allowed to do what with what. Draw the general form as an access
matrix with one row per user, one column per file. Each entry indicates the privileges of
that user on that object. There are two general ways of storing this information: access
lists and capabilities.
Access Lists: with each file, indicate which users are allowed to perform which
operations.
Capabilities: with each user, indicate which files may be accessed, and in what ways.
Store a list of pairs with each user. This is called a capability list.
Typically, capability systems use a different naming arrangement, where the
capabilities are the only names of objects. You cannot even name objects not
referred to in your capability list.
In access-list systems, the default is usually for everyone to be able to access a
file. In capability-based systems, the default is for no-one to be able to access a
file unless they have been given a capability. There is no way of even naming an
object without a capability.
32
Capabilities are usually used in systems that need to be very secure. However,
capabilities can make it difficult to share information: nobody can get access to
your stuff unless you explicitly give it to them.
Protection Keys
Page tables
Access Enforcement
Some part of the system must be responsible for enforcing access controls and protecting
the authorization and identification information.
Obviously, this portion of the system must run unprotected. Thus it should be as
small and simple as possible. Example: the portion of the system that sets up
memory mapping tables.
The portion of the system that provides and enforces protection is called the
security kernel. Most systems, like Unix, do not have a security kernel. As a
consequence, the systems are not very secure.
What is needed is a hierarchy of levels of protection, with each level getting the
minimum privilege necessary to do its job. However, this is likely to be slow
(crossing levels takes time).
Security Abuses
33
In general, protecting a computer system is extremely difficult. There is no completely
secure computer system in existence. Some common problems:
Once the system has been penetrated, it may be impossible to secure it again: hooks could
have been left around for the imposter to regain control.
It is not always possible to tell when the system has been penetrated, since the villain can
clean up all traces behind himself.
If we can never be sure that there are no bugs, then we can never be sure that the system
is secure, since bugs could provide loopholes in the protection mechanisms.
Logging: record all important actions and uses of privilege in an indelible file.
Can be used to catch imposters during their initial attempts and failures. E.g.
record all attempts to specify an incorrect password, all super-user logins. Even
better is to get humans involved at key steps (this is one of the solutions for EFT).
Principle of minimum privilege ("need-to-know" principle): each piece of the
system has access to the minimum amount of information, for the minimum
possible amount of time. E.g. file system cannot touch memory map, memory
manager cannot touch disk allocation tables. This reduces the chances of
accidental or intentional damage. Note that capabilities are an implementation of
this idea. It is very hard to provide fool-proof information containment: e.g. a
Trojan horse could write characters to a tty, or take page faults, in Morse code, as
a signal to another process.
34
Correctness proofs. These are very hard to do. Even so, this only proves that the
system works according to spec. It does not mean that the spec. is necessarily
right, and it does not deal with Trojan Horses.
Encryption
Key technology: encryption. Store and transmit information in an encoded form that does
not make any sense.
Start with text to be protected. Initial readable text is called clear text.
Encrypt the clear text so that it does not make any sense at all. The nonsense text
is called cipher text. The encryption is controlled by a secret password or number;
this is called the encryption key.
35
The encryption function cannot easily be inverted (cannot get back to clear text
unless you know the decryption key).
The encryption and decryption must be done in some safe place so the clear text
cannot be stolen.
The keys must be protected. In most systems, can compute one key from the other
(sometimes the encryption and decryption keys are identical), so cannot afford to
let either key leak out.
Public key encryption: new mechanism for encryption where knowing the encryption key
does not help you to find decryption key, or vice versa.
User provides a single password, system uses it to generate two keys (use a one-
way function, so cannot derive password from either key).
In these systems, keys are inverses of each other: could just as easily encrypt with
decryption key and then use encryption key to recover clear text.
Each user keeps one key secret, publicizes the other. Cannot derive private key
from public. Public keys are made available to everyone, in a phone book for
example.
Safe mail:
It is a nice scheme because the user only has to remember one key, and all senders can
use the same key. However, how does receiver know for sure who it is getting mail from?
Digital Signatures
To certify your identity, use your private key to encrypt a text message, e.g. "I
agree to pay Mary Wallace $100 per year for the duration of life."
You can give the encrypted message to anybody, and they can certify that it came
from you by seeing if it decrypts with your public key. Anything that decrypts
into readable text with your public key must have come from you! This can be
made legally binding as a form of electronic signature.
This is really even better than signatures: harder to forge, and can change if
compromised. Note that this idea was developed by an undergraduate (Loren Kohnfelder)
in 1978 as part of his undergraduate thesis (at MIT).
These two forms of encryption can be combined together. To identify sender in secure
mail, encrypt first with your private key, then with receiver's public key. The
encryption/decryption functions to send from B to A are:
36
Encryption appears to be a great way to thwart listeners. It does not help with Trojan
Horses, though.
Old dederal Data Encryption Standard (DES). Is not public-key based, but as
implemented efficiently and appeared to be relatively safe.
More recently, there is the Advanced Encryption Standard (AES), called Ryndal
(pronounced "rine doll"). ***more on AES here****
Summary of Protection: very hard, but is increasingly important as things like electronic
funds transfer become more and more prevalent
37
Scheduling
Until now we have talked about processes, from now on we will talk about resources, the
things operated upon by processes. Resources range from cpu time to disk space to
channel I/O time.
Preemptible: processor or I/O channel. Can take resource away, use it for
something else, and then give it back later. Non-preemptible: once given, it
cannot be reused until process gives it back. Examples are file space, terminal,
and maybe memory.
Allocation: who gets what. Given a set of requests for resources, which processes
should be given which resources in order to make most efficient use of the
resources? Implication is that resources are not easily preemptible.
Scheduling: how long can they keep it. When more resources are requested than
can be granted immediately, in which order should they be serviced? Examples
are processor scheduling (one processor, many processes), memory scheduling in
virtual memory systems. Implication is that resource is preemptible.
CPU Scheduling
38
Minimize overhead (context swaps).
Minimize response time. (Define response time.)
Distribute cycles equitably. What does this mean?
Solution: limit maximum amount of time that a process can run without a context switch.
This time is called a time slice.
Round Robin: run process for one time slice, then move to back of queue. Each process
gets equal share of the CPU. Most systems use some variant of this. What happens if the
time slice is not chosen carefully?
39
Originally, Unix had 1 sec. time slices. Too long. Most timesharing systems today use
time slices of 10,000 - 100,000 instructions.
Implementation of priorities: run highest priority processes first, use round-robin among
processes of equal priority. Re-insert process in run queue behind all processes of greater
or equal priority.
Even round-robin can produce bad results occasionally. Go through example of ten
processes each requiring 100 time slices.
STCF: shortest time to completion first with preemption. This minimizes the average
response time.
Unfortunately, STCF requires knowledge of the future. Instead, we can use past
performance to predict future performance.
Exponential Queue (also called "multi-level feedback queues"): attacks both efficiency
and response time problems.
40
Give newly runnable process a high priority and a very short time slice. If process
uses up the time slice without blocking then decrease priority by 1 and double
time slice for next time.
Go through the above example, where the initial values are 1ms and priority 100.
Techniques like this one are called adaptive. They are common in interactive
systems.
The CTSS system (MIT, early 1960's) was the first to use exponential queues.
Linux's new scheduler (version 2.6) makes this all very complex:
Two queues: one with active (eligible to run) processes and with expired (not
eligible to run) processes.
140 priority levels, but the top 100 are reserved for "real time" processes.
Always choose a process from the highest non-empty priority level.
Priority level is the sum of its static priority and its dynamic priority bonus, which
the scheduler assigns as an estimate of its interactivity. Niceness, the value that
Static priorities range from 0-39 (number of queues) and dynamic priority
bonuses range from -5 to +5.
Time slices assigned based on static priority, giving higher-priority tasks larger
time slices and lower-priority tasks shorter time slices.
41
A task might not use all of its time slice at once, since it could block or be
preempted before it finishes, but eventually it consumes the entire amount. When
that happens, the task is usually placed on the expired array with a new time slice
and a recalculated priority.
An interactive task receives the same time slice as others at the same static
priority, but the slice is divided into smaller pieces. When it finishes a piece, the
task will round robin with other tasks at the same priority level. Execution rotates
more frequently among interactive tasks of the same priority, but higher-priority
tasks will run for longer before expiring
Summary:
There are some curious interactions between scheduling and synchronization. A classic
problem caused by this interaction was first observed in 1979 but Butler Lampson and
David Redell at Xerox.
S: mutex.P()
...
...
mutex.V()
42
1. P3 enters S, locking the critical section.
2. P3 is preempted by the scheduler and P2 starts running.
3. P2 is preempted by the scheduler and P1 starts running.
4. P1 tries to enter S and is blocked at the P operation.
5. P2 starts running again, preventing P1 from running.
As a result, P2 running (at medium priority) is blocking P 1 (at highest priority) from
running. This example is not an academic one. Many designers of real-time systems,
where priority can be crucial, have stumbled over issue. You can read the original paper
by Lampson and Redell to see their suggestion for handling the situation. Also, do a Web
search for priority inversion.
Person A Person B
3:00 Look in fridge. Out of milk.
3:05 Leave for store.
43
3:10 Arrive at store. Look in fridge. Out of milk.
3:15 Leave store. Leave for store.
3:20 Arrive home, put milk away. Arrive at store.
3:25 Leave store.
3:30 Arrive home. OH NO!
What does correct mean? One of the most important things in synchronization is to figure
out what you want to achieve.
Mutual exclusion: Mechanisms that ensure that only one person or process is doing
certain things at one time (others are excluded). E.g. only one person goes shopping at a
time.
Critical section: A section of code, or collection of operations, in which only one process
may be executing at a given time. E.g. shopping. It is a large operation that we want to
make "sort of" atomic.
There are many ways to achieve mutual exclusion, which we will be discussing all of this
week. Most involve some sort of locking mechanism: prevent someone from doing
something. For example, before shopping, leave a note on the refrigerator.
What happens if we leave the note at the very beginning: does this make everything
work?
44
3 Buy Milk; Buy Milk;
4 } }
5 Leave Note; Remove Note;
6 } }
Does this work?
How can we tell?
When dealing with complex parallel programs, we cannot rely on our intuitions or
informal reasoning. We need to prove that the programs behave correctly. What
can we say about the above solution?
Suppose B goes on vacation. A will buy milk once and will not buy any more until B
returns. Thus this really does not really do what we want; it is unfair, and leads to
starvation.
Solution is almost correct. We just need a way to decide who will buy milk when both
leave notes (somebody has to hang around to make sure that the job gets done).
Process A
1 Leave NoteA;
2 if (NoNoteB) {
3 if (NoMilk) {
4 Buy Milk;
5 }
6 } else {
7 while (NoteB) {
8 DoNothing;
9 }
10 if (NoMilk) {
11 Buy Milk;
45
12 }
13 }
14 Remove NoteA;
Mutual Exclusion
When one thread reads data that another thread is writing, or when one thread writes data
that another thread is also writing, indeterminate results can occur. We can solve this
problem by granting each thread exclusive access to the shared variable i.e. while one
thread increments the shared variable, all other threads desiring to do so will be made to
wait. When the executing thread finishes accessing the shared variable, the system will
allow one of the waiting processes to proceed. This is called serializing access to the
shared variable. Mutual Exclusion refers to the requirement of ensuring that no two
concurrent processes are in their critical section at the same time. In this manner,
threads will not be able to access shared data simultaneously.
Mutual exclusion needs to be enforced only when threads access shared modifiable data
—when threads are performing operations that do not conflict with one another (i.e.,
46
reading data), the system should allow the threads to proceed concurrently. When a
thread is accessing shared modifiable data, the thread is said to be in its critical section
(or critical region). To prevent the kinds of errors we encountered earlier, the system
should ensure that only one thread can execute the instructions in its critical section at a
time. If one thread attempts to enter its critical section while another thread executes its
critical section, the first thread should wait until the executing thread exits its critical
section. Once a thread has exited its critical section, a waiting thread (or one of the
waiting threads, if there are several), may enter and execute its critical section. If a thread
in its critical section terminates, either voluntarily or involuntarily, then the operating
system, in performing its termination housekeeping, must release mutual exclusion so
that other threads may enter their critical sections.
Critical Sections
A critical section is a piece of code that accesses a shared resource (data structure or
device) that must not be concurrently accessed by more than one thread of execution. A
critical section will usually terminate in fixed time, and a thread, task, or process will
have to wait for a fixed time to enter it (bounded waiting). Only one thread can be in its
critical section at once. We must be careful to avoid infinite loops and blocking inside a
critical section.
47
A thread that is executing instructions outside its critical section cannot
prevent other threads from entering their critical sections;
A thread cannot be indefinitely postponed from entering its critical
section.
Dekker’s Algorithm
Dekker's algorithm is the first known correct solution to the mutual exclusion problem
in concurrent programming. The solution is attributed to Dutch Mathematician Th. J.
Dekker. It allows two threads to share a single-use resource without conflict, using only
shared memory for communication.
It avoids the strict alternation of a naïve turn-taking algorithm, and was one of the first
mutual exclusion algorithms to be invented.
48
It uses the notion of favored threads to determine entry into critical sections.
It resolves the conflict over which thread should execute first.
Each thread temporarily unsets critical section request flag
It also favored status alternates between threads.
It guarantees mutual exclusion.
It also avoids previous problems of deadlock, indefinite postponement
49
•Both threads could set flags to same values at same time
• Would require both threads to execute in tandem (unlikely but possible)
- Unacceptable in mission- or business-critical systems
Pseudocode
//flag[] is boolean array; and turn is an integer
flag[0] = false
flag[1] = false
turn = 0 // or 1
P0:
flag[0] = true;
while (flag[1] == true) {
if (turn ≠ 0) {
flag[0] = false;
while (turn ≠ 0) { // busy wait
}
flag[0] = true;
}
}
// critical section
...
turn = 1;
flag[0] = false;
// remainder section
P1:
flag[1] = true;
while (flag[0] == true) {
if (turn ≠ 1) {
flag[1] = false;
while (turn ≠ 1) {
// busy wait
}
flag[1] = true;
}
}
// critical section
...
turn = 0;
flag[1] = false; // remainder section
Peterson’s Algorithm
50
Peterson's algorithm was published in 1981, after more than a decade of experience and
hindsight about Dekker's algorithm. Peterson wanted a much simpler algorithm than
Dekker so that the proof of correctness is much easier.
Peterson’s Algorithm had the following characteristics:
– It still uses busy waiting, favored threads
– It requires fewer steps to perform mutual exclusion primitives
– It is easier to demonstrate its correctness
– It does not exhibit indefinite postponement or deadlock
Pseudocode
bool flag[0] = false;
bool flag[1] = false;
int turn;
P0: flag[0] = true;
P0_gate: turn = 1;
while (flag[1] && turn == 1)
{
// busy wait
}
// critical section
...
// end of critical section
flag[0] = false;
P1: flag[1] = true;
P1_gate: turn = 0;
while (flag[0] && turn == 0)
{
// busy wait
}
// critical section
...
// end of critical section
flag[1] = false;
51
- It gives a little bit of history about the definition of the mutual exclusion
problem and attempts to solve it up to 1974.
- The Bakery algorithm demonstrates that no hardware atomicity is
required to solve the mutual exclusion problem. Reads that overlap writes
to the same location can return any value and the algorithm still works.
52
20. }
21. }
22. }
23. public void unlock(int pid) {
24. [Link](pid, 0);
25.
Disabling Interrupts
Works only on uniprocessor systems
Prevents the currently executing thread from being preempted
Could result in deadlock
• For example, thread waiting for I/O event in critical section
Test-and-Set Instruction
This uses a machine-language instruction to ensure that mutual exclusion primitives are
performed indivisibly.
– Such instructions are called atomic
– Machine-language instructions do not ensure mutual exclusionalone—the
software must properly use them. For example, programmers must
incorporate favored threads to avoid indefinite postponement
– Used to simplify software algorithms rather than replace them
Example of an atomic read-modify-write (RMW) cycle
testAndSet(a, b)
copies the value of
b
to
53
a
, then sets
b
to
true
Swap Instruction
This is similar in functionality to test-and-set, swap is more commonly implemented on
multiple architectures.
swap(a, b)
exchanges the values of
a
and
b
atomically
Semaphores
These are Software construct that can be used to enforce mutual exclusion.
They contain protected variable which can be accessed only via wait and signal
commands also called P and V operations, respectively.
54
easy-to-implement solution to this problem. This is described below:
Producer enters its critical section to produce value
Consumer is blocked until producer finishes
Consumer enters its critical section to read value
Producer cannot update value until it is consumed
Counting Semaphores
Initialized with values greater than one
Can be used to control access toa pool of identical resources
Decrement the semaphore’s counter when taking resource from pool
Increment the semaphore’s counter when returning it to pool
If no resources are available, thread is blocked until a resource becomes
available
Implementing Semaphores
Semaphores can be implemented at application or kernel level.
Application level: typically implemented by busy waiting inefficient
Kernel implementations can avoid busy waiting
Block waiting threads until they are ready
Summary
In Asynchronous execution, threads generally operate independently of one another, but
must occasionally communicate and synchronize to perform cooperative tasks. This
communication or synchronization is usually complex and difficult to manage.
55
Mutual Exclusion refers to the requirement of ensuring that no two concurrent processes
are in their critical section at the same time. A mutual exclusion (mutex) is a program
object that prevents simultaneous access to a shared resource. This means:
Only one thread allowed access at one time
Others must wait until resource is unlocked
Serialized access
Must be managed such that wait time is not unreasonable
Critical section is a piece of code that accesses a shared resource (data structure or
device) that must not be concurrently accessed by more than one thread of
execution. Mutual exclusion primitives can be implemented using software approach
(Dekker's algorithm, Peterson's algorithm, Lamport's bakery algorithm),
hardware approach(Disabling Interrupts, Test-and Set Instruction, Swap Instructions) and
Semaphores (software construct that can be used to enforce mutual exclusion).
8.0 SCHEDULING
The practice uses the word “scheduling” because it assigns specific percentage of time
machines as well as to share CPU capacity with users connecting to a computer through
remote desktop.
When a system has a choice of processes to execute, it must have a strategy called a
processor scheduling policy (or discipline) for deciding which process to run at a given
time. A scheduling policy should attempt to satisfy certain performance criteria, such as
maximizing the number of processes that complete per unit time (i.e. throughput),
minimizing the time each process waits before executing (i.e. latency), preventing
56
indefinite postponement of processes, ensuring that each process completes before its
maximizing processor utilization and throughput, are complementary; others conflict with
one another a system that ensures that processes will complete before their deadlines may
SCHEDULING LEVELS
term scheduling. It determines which jobs the system allows to compete actively
because it determines which jobs gain admission to the system. Once admitted,
jobs are initiated and become processes or groups of processes. The high-level
processes in a system at a given time. Entry of too many processes into the system
can saturate the system's resources, leading to poor performance. In this case, the
high-level scheduling policy may decide to temporarily prohibit new jobs from
admitted a job (which may contain one or more processes) to the system, the
57
to compete for processors. This policy responds to short-term fluctuations in
system operation and to help realize certain system wide performance goals. The
system and the assignment of processors to the processes representing these jobs.
determines which active process the system will assign to a processor when one
next becomes available. In many of today's systems, the low- and intermediate-
once the system has assigned a processor to a process; the system cannot remove that
processor from that process. Under a non - preemptive scheduling discipline, each
process, once given a processor, runs to completion or until it voluntarily releases its
processor. In non - preemptive systems, short processes can experience lengthy service
delays while longer processes complete, but turnaround times are more predictable,
non - preemptive system cannot remove a process from a processor until it completes,
errant programs that never complete (e.g., by entering an infinite loop) may never release
processes can make important processes wait. Non - preemptive scheduling provides
predictable turnaround times, which is important for batch processing systems that must
58
Preemptive Scheduling disciplines: A scheduling discipline is preemptive if the system
can remove the processor from the process it is running. Under a preemptive scheduling
discipline, the processor may execute a portion of a process's code and then perform a
context switch. Preemptive scheduling helps guarantee acceptable user response times.
To make preemption effective, the system must maintain many processes in main
memory, so that the next process is ready when a processor becomes available, a
preemptive system can take the processor away from a process. To prevent users from
interrupting clock or interval timer that periodically generates an interrupt, which allows
the operating system to execute. Once a processor is assigned to a process, the process
executes until it voluntarily releases its processor, or until the clock interrupt or some
other interrupt occurs. The operating system may then decide whether the running
PRIORITIES
Priority Schedulers often use priorities to determine how to schedule and dispatch
implement and incur relatively low overhead. Such mechanisms are not, however,
responsive to changes in environment, even those that could increase throughput and
reduce latency.
example, the system may want to increase the priority of a process that holds a key
59
resource needed by a higher-priority process. After the first process relinquishes the
resource, the system lowers the priority, so that the higher-priority process may execute.
Dynamic priority schemes are more complex to implement and have greater over- head
than static schemes. Hopefully, the overhead is justified by the increased responsiveness
of the system. In multiuser systems, an operating system must provide reasonable service
to a large community of users but should also provide for situations in which a member
of the user community needs special treatment. A user with an important job may be
willing to pay a premium, i.e., to purchase priority, for a higher level of service. This
extra charge is merited because resources may need to be withdrawn from other paying
customers. If there were no extra charge, then all users would request the higher level of
service.
Scheduling Objectives
discipline, such as the type of system and the users' needs. For example, the scheduling
discipline for a real-time system should differ from that for an interactive desktop system;
users expect different results from these kinds of systems. Depending on the system, the
times.
60
4. Avoid indefinite postponement: A process should not experience an unbounded
the most important objectives. Overhead often results in wasted resources. But a
times, a system can guarantee that processes will receive predictable service
levels. A system can accomplish these goals in several ways. In some cases, the
Eventually, its priority becomes high enough that the scheduler selects that
processes to run. One such strategy favors processes holding key resources. For
should give the low-priority process more execution time than it ordinarily would
receive, so that it will release the key resource sooner. This technique is called
priority inversion, because the relative priorities of the two processes are reversed
so that the high-priority one will obtain the resource it requires to continue
61
execution. Similarly, the scheduler may choose to favor a process that requests
underutilized resources, because the system will be more likely to satisfy this
process's requests in a shorter period of time. Many of these goals conflict with
one another, making scheduling a complex problem. For example, the best way to
are needed. The price for this strategy is that overall resource utilization will be
poor. In real-time systems, fast, predictable responses are crucial, and resource
utilization is less important. In other types of systems, the economics often makes
8. Fairness: A scheduling discipline is fair if all similar processes are treated the
same, and no process can suffer indefinite postponement due to scheduling issues.
9. Predictability: A given process always should run in about the same amount of
10. Scalability: System performance should degrade gracefully (i.e., it should not
Scheduling Criteria
behavior. A processor-bound process tends to use all the processor time that the system
allocates for it. An I /O-bound process tends to use the processor only briefly before
generating an I/O request and relinquishing it. Processor-bound processes spend most of
their time using the processor; I/O-bound processes spend most of their time waiting for
external resources (e.g., printers, disk drives, network connections, etc.) to service their
62
requests, and only nominal time using processors. A scheduling discipline might also
consider whether a process is batch or interactive. A batch process contains work for the
system to perform without interacting with the user. An interactive process requires
frequent inputs from the user. The system should provide good response times to an
interactive process, whereas a batch process generally can suffer reasonable delays.
process. In a system that employs priorities, the scheduler should favor processes with
higher priorities. Schedulers can base their decisions on how frequently a higher priority
process has preempted a lower-priority one. Also, a process that has received much
execution time could be near completion and should be favored to help it reach
completion, free its resources for other processes to use and exit the system as soon as
possible. Similarly, a scheduler may maintain an estimate of how much time remains
before a process completes. It is easy to prove that average waiting times can be
minimized by running those processes first that require the minimum runtime until
completion. Unfortunately, a system rarely knows exactly how much more time each
SCHEDULING ALGORITHMS
Scheduling algorithms determine at runtime which process runs next. These algorithms
decide when and for how long each process runs; they make choices about preemptibility,
63
1. First-In-First-Out (FIFO) Scheduling: Perhaps the simplest scheduling
Processes are dispatched according to their arrival time at the ready queue. FIFO
is non- preemptive once a process has a processor, the process runs to completion.
FIFO is fair in that it schedules processes according to their arrival times, so all
processes are treated equally, but somewhat unfair because long processes make
short processes wait, and unimportant processes make important processes wait.
dispatched FIFO but are given a limited amount of processor time called a time
slice or a quantum. If a process does not complete before its quantum expires, the
system preempts it and gives the processor to the next waiting process. The
system then places the preempted process at the back of the ready queue. The
process priorities over time. In this scheme, as each process enters the system, it
first resides in a holding queue, where it ages until its priority reaches the level of
processes in the active queue. At this point, it is placed in the active queue and
dispatches only processes in the active queue, meaning that older processes are
favored over those that have just entered the system. In SRR, a process's priority
the active queue. When b < a, processes in the holding queue age at a higher rate
64
than those in the active queue, so they will eventually enter the active queue and
algorithm in which the scheduler selects the waiting process with the smallest
The waiting times, however, have a larger variance (i.e., are more unpredictable)
than FIFO, especially for large processes. SPF favors short processes at the
expense of longer ones. As a result, SPF can minimize the average waiting time of
processes as they pass through the system. A key problem with SPF is that it
requires precise knowledge of how long a process will run, and this information
weaknesses in SPF, particularly the excessive bias against longer processes and
scheduling discipline in which each process's priority is a function not only of its
service time but also of its time spent waiting for service. Once a process obtains
it, the process runs to completion. HRRN calculates dynamic priorities according
to the formula:
Because the service time appears in the denominator, shorter processes receive
preference. However, because the waiting time appears in the numerator, longer
processes that have been waiting will also be given favorable treatment. This
65
technique is similar to aging and prevents the scheduler from indefinitely
postponing processes.
with a shorter estimated run-time preempts a running process with a longer run-
time-to-completion.
7. Multilevel feedback queues: A new process enters the queuing network at the tail
of the highest queue. The process progresses through that queue in FIFO order
until the process obtains a processor. If the process completes its execution, or if it
releases the processor to wait for I/O completion or the completion of some other
event, exits the queuing network. If a process's quantum expires before the
process voluntarily releases the processor, the system places the process at the tail
of the next lower-level queue. As long as the process uses the full quantum
provided at each level, it continues to move to the tail of the next lower queue.
process in a lower queue can suffer indefinite postponement, if a higher queue always
contains at least one process. This can occur in systems that have a high rate of incoming
their quanta.
DEADLINE SCHEDULING
66
In deadline scheduling, certain processes are scheduled to be completed by a specific
time or deadline. These processes may have high value if delivered on time and little or
no value otherwise. Deadline scheduling is complex. First, the user must supply the
precise resource requirements in advance to ensure that the process is completed by its
deadline. Such information is rarely available. Second, the system should execute the
deadline process without severely degrading service to other users. Also, the system must
carefully plan its resource requirements through to the deadline. This may be difficult,
because new processes may arrive, making unpredictable demands. Finally, if many
deadline processes are active at once, scheduling could become extremely complex. The
algorithms of which it is required that they can guarantee a process will be done before its
deadline. The only way these algorithms can work if they at least know when the
deadline for a process is, and how much the process takes of the system.
CONCLUSION
When a system has a choice of processes to execute, it must have a strategy called a
processor scheduling policy (or discipline) for deciding which process to run at a given
determines which jobs the system allows to compete actively for system resources. The
high- level scheduling policy dictates the degree of multiprogramming the total number
of processes in a system at a given time. After the high-level scheduling policy has
admitted a job (which may contain one or more processes) to the system, the
67
intermediate-level scheduling policy determines which processes shall be allowed to
compete for a processor. This policy responds to short-term fluctuations in system load.
A system's low-level scheduling policy determines which ready process the system will
assign to a processor when one next becomes available. Low-level scheduling policies
often assign a priority to each process, reflecting its importance—the more important a
process, the more likely the scheduling policy is to select it to execute next.
68
In computing, a context switch is the process of storing and restoring the state (context)
of a process or thread so that execution can be resumed from the same point at a later
time. This enables multiple processes to share a single CPU and is an essential feature of
a multitasking operating system. What constitutes the context is determined by the
processor and the operating system.
Context switches are usually computationally intensive, and much of the design of
operating systems is to optimize the use of context switches. Switching from one process
to another requires a certain amount of time for doing the administration – saving and
loading registers and memory maps, updating various tables and lists etc.
A context switch can mean a register context switch, a task context switch, a stack
frame switch, a thread context switch, or a process context switch.
When to switch?
Most commonly, within some scheduling scheme, one process needs to be switched out
of the CPU so another process can run. This context switch can be triggered by the
process making itself unrunnable, such as by waiting for
an I/O or synchronization operation to complete. On a pre-emptive multitasking system,
the scheduler may also switch out processes which are still runnable. To prevent other
processes from being starved of CPU time, preemptive schedulers often configure a timer
interrupt to fire when a process exceeds its time slice. This interrupt ensures that the
scheduler will gain control to perform a context switch.
Interrupt handling
Modern architectures are interrupt driven. This means that if the CPU requests data from
a disk, for example, it does not need to busy-wait until the read is over; it can issue the
request and continue with some other execution. When the read is over, the CPU can
be interrupted and presented with the read. For interrupts, a program called an interrupt
handler is installed, and it is the interrupt handler that handles the interrupt from the disk.
When an interrupt occurs, the hardware automatically switches a part of the context (at
least enough to allow the handler to return to the interrupted code). The handler may save
additional context, depending on details of the particular hardware and software designs.
Often only a minimal part of the context is changed in order to minimize the amount of
69
time spent handling the interrupt. The kernel does not spawn or schedule a special
process to handle interrupts, but instead the handler executes in the (often partial) context
established at the beginning of interrupt handling. Once interrupt servicing is complete,
the context in effect before the interrupt occurred is restored so that the interrupted
process can resume execution in its proper state.
User and kernel mode switching
When a transition between user mode and kernel mode is required in an operating
system, a context switch is not necessary; a mode transition is not by itself a context
switch. However, depending on the operating system, a context switch may also take
place at this time.
Steps
In a switch, the state of the first process (assuming that the first process is the process in
execution and is to be switched) must be saved somehow, so that, when the scheduler
gets back to the execution of the first process, it can restore this state and continue.
The state of the process includes all the registers that the process may be using, especially
the program counter, plus any other operating system specific data that may be necessary.
This data is usually stored in a data structure called a process control block (PCB), or
switch frame.
In order to switch processes, the PCB for the first process must be created and saved. The
PCBs are sometimes stored upon a per-process stack in kernel memory (as opposed to the
user-mode call stack), or there may be some specific operating system defined data
structure for this information.
Since the operating system has effectively suspended the execution of the first process, it
can now load the PCB and context of the second process. In doing so, the program
counter from the PCB is loaded, and thus execution can continue in the new process.
New processes are chosen from a queue or queues (often referred as ready queue).
Process and thread priority can influence which process continues execution, with
processes of the highest priority checked first for ready threads to execute.
Performance
Context switching itself has a cost in performance, due to running the task
scheduler, TLB flushes, and indirectly due to sharing the CPU cache between multiple
tasks.[2] Switching between threads of a single process can be faster than between two
70
separate processes, because threads share the same virtual memory maps, so a TLB flush
is not necessary.[3]
Hardware vs. software
As with other tasks performed in hardware, one would expect this to be rather fast;
however, mainstream operating systems, including Windows and Linux,[5] do not use this
feature. This is mainly due to two reasons:
Hardware context switching does not save all the registers (only general purpose
registers, not floating point registers — although the TS bit is automatically turned on
in the CR0 control register, resulting in a fault when executing floating point
instructions and giving the OS the opportunity to save and restore the floating point
state as needed).
Associated performance issues, e.g., software context switching can be selective
and store only those registers that need storing, whereas hardware context switching
stores nearly all registers whether they are required or not.
A context switch is a procedure that a computer's CPU (central processing unit) follows
to change from one task (or process) to another while ensuring that the tasks do not
conflict. Effective context switching is critical if a computer is to provide user-
friendly multitasking.
In a CPU, the term "context" refers to the data in the registers and program counter at a
specific moment in time. A register holds the current CPU instruction. A program
counter, also known as an instruction address register, is a small amount of
fast memory that holds the address of the instruction to be executed immediately after the
current one.
A context switch can be performed entirely in hardware (physical media). Older CPUs,
such as those in the x86 series, do it that way. However, most modern CPUs perform
71
context switches by means of software (programming). A modern CPU can perform
hundreds of context switches per second. Therefore, the user gets the impression that the
computer is performing multiple tasks in a parallel fashion, when the CPU actually
alternates or rotates between or among the tasks at a high rate of speed.
72
If a context switch also entails a change in IO port permissions, a different TSS may be
loaded for each Process. When running virtual 8086 tasks, the IO permission map in the
TSS isn't checked to provide I/O port protection. IO protection can be implemented by
setting the IO Permission Level to 0. This will generate a General Protection Fault when
a process in ring 3 attempts to write to or read from an IO port. The GP fault handler can
then check permissions and carry out the port IO on behalf of the user-mode code.
Other Possibilities
During a context switch the operating system can do additional work that isn't strictly
part of the context switch. One common thing is calculating the amount of time the last
thread/task/process used so that software (and the end user) can determine where all the
CPU time is going. Another possibility would be dynamically changing
thread/task/process priorities.
Performance Considerations
Translating a virtual address to a physical address is expensive. The processor must
access the pages table structures, which usually have 3-4 levels. Thus, a single memory
access actually requires 4-5 memory accesses.
To mitigate this issue, most modern processors cache virtual-to-physical translations in a
translation look aside buffer (TLB). The TLB is part of the MMU and is (mostly)
transparent to the system developer and users.
When virtual memory is updated -- for instance, when one process's address space is
replaced with another's during a software context switch -- the TLB suddenly contains
"stale" translations that are no longer valid. These translations must be flushed for correct
behaviour. Writing to CR3 will flush the TLB. However, by writing to CR3, you also
eliminate all translations for the kernel, in addition to the last user process. This is less
than ideal, as the next few operations must wait for the slow virtual-to-physical
translations.
Recent Intel and AMD processors sport a tagged TLB, which allow you to tag a given
translation with a certain address space configuration. In this scheme TLB entries never
get "stale", and thus there is no need to flush the TLB.
Hardware Context Switching
Some CPU's have a special mechanism to perform context switches in hardware. The
following information gives details on 80x86 CPU's only.
The hardware context switching mechanism (called Hardware Task Switching in the
CPU manuals) can be used to change all of the CPU's state except for the FPU/MMX and
SSE state. To use the hardware mechanism you need to tell the CPU where to save the
existing CPU state, and where to load the new CPU state. The CPU state is always stored
in a special data structure called a TSS (Task State Segment).
To trigger a context switch and tell the CPU where to load it's new state from the far
version of CALL and JMP instructions are used. The offset given is ignored, and the
73
segment is used to refer to a "TSS Descriptor" in the GDT. The TSS descriptor is used to
specify the base address and limit of the TSS to be used to load the new CPU state from.
The CPU has a register called the "TR" (or Task Register) which tells which TSS will
receive the old CPU state. When the TR register is loaded with an "LDTR" instruction
the CPU looks at the GDT entry (specified with LDTR) and loads the visible part of TR
with the GDT entry, and the hidden part with the base and limit of the GDT entry. When
the CPU state is saved the hidden part of TR is used.
74
the hardware overhead in a context switch on a modern P4 processor dwarfs the overhead
involved in saving/loading registers (995ns of HW overhead vs 67ns to save/load
registers). From this, it would appear that any performance gains from switching to
software task switching would be minimal, amounting to no more than a few percentage
points. However, Brendan points out in this post that this is horrendously wrong and
explains why.
In your average, memory-protected environment, a "context" is a virtual address space,
the executable contained in it, its data etc.
A "context switch" occurs for a variety of reasons - because a kernel function has been
called, the application has been preempted, or because it had yielded its time slice.
A context switch involves storing the old state and retrieving the new state. The actual
information stored and retrieved may include EIP, the general registers, the segment
registers, CR3 (and the paging structures), FPU/MMX registers, SSE registers and other
things. Because a context switch can involve changing a large amount data it can be the
one most costly operation in an operating system.
There are many ways of performing a context switch. The x86 CPU provides a way of
doing it completely in hardware, but for performance and portability reasons most
modern OS's do context switches in software.
REFERENCES
Harvey M. Deitel, Paul J. Deitel, David R. Choffnes, “Operating Systems,”
Asynchronous Concurrent Execution (3rd Edition), Chapter 5, pp. 185-244.
Leslie Lamport, "A Fast Mutual Exclusion Algorithm," ACM Transactions on Computer
Systems (TOCS), Vol. 5, No. 1, pp.l-11,Feb. 1987.
Atwood, J. W., "Concurrency in Operating Systems," Computer, Vol. 9, No. fO, October
1976, pp. 18-26.
Peterson, G L., "Myths about the Mutual Exclusion Problem," Information Processing
Letters, Vol. 12, No. 3, June 1981, pp. 115-
116.
[Link]
75
concurrent
The description of a process or thread that exists in a system simultaneously
with other processes and/or threads.
asynchronous
Pertaining to events that are not synchronized in time or do not occur in
regular or predictable time intervals.
synchronous
Occurring with a regular or predictable time relationship.
Mutual exclusion
mutual exclusion
A situation in which at most one process can be engaged in a specified
activity at a time.
race condition
A situation where the (uncontrolled) ordering of events can affect the
outcome of the situation.
serialize
To control access to a variable so that only one thread can access the variable
at a time.
producer
A process or thread that creates data and places it into a shared object.
consumer
A process or thread that removes data from a shared object and processes it.
critical section
A section of code which performs operations on a shared resources.
mutual exclusion primitive
A fundamental operation which is needed to implement mutual exclusion.
indefinite postponement
A situation in which a process or thread is waiting for an event which may
never occur.
deadlock
A situation in which two or more processes are prevented from continuing
while each waits for resources to be freed by the continuation of the other.
busy wait
A situation in which a process, while not blocked, continuously checks for a
condition which will allow it to proceed.
atomic operation
An operation which cannot be interrupted.
Semaphores
Semaphore
semaphore
A synchronization variable accessable only through wait and signal
procedures.
binary semaphore
A semaphore that can only have the values 0 and 1.
76
counting semaphore
A semaphore that maintains a count between zero and some maximum value.
Asynchronism
asynchronism, asynchronous, asynchrony means: 1. Operating at a rate determined by
the system rather than at a regular rate of chronological time; without a fixed time
pattern. 2. Describing the relationship of two or more systems that run at their own rates
and interact at unpredictable time
A remote procedure call (RPC) is an inter-process communication that allows
a computer program to cause a subroutine or procedure to execute in another address
space (commonly on another computer on a shared network) without the programmer
explicitly coding the details for this remote interaction.
Time-sharing is the sharing of a computing resource among many users by means
of multiprogramming and multi-tasking.
Protected variables are variables that are visible only to the class to which they belong,
and any subclasses.
A semaphore is a protected variable or abstract data type that provides a simple but
useful abstraction for controlling access by multiple processes to a common resource in
a parallel programming environment.s
Tutorial Questions
Describe the two general roles of an operating system, and elaborate why these roles are
important.
Multi-programming enables more than a single process to apparently execute
simultaneously. How is this achieved on a uni-processor?
Describe the difference between external and internal fragmentation. Indicate which of
the two are most likely to be issues on (i) a simple memory management machine
using base limit registers and static partitioning, and (ii) a similar machine using
dynamic partitioning.
77
What are the five major activities of an operating system with regard to process
management?
What are the three major activities of an operating system with regard to memory
management?
What are the three major activities of an operating system with regard to secondary-
storage management?
What are the five major activities of an operating system with regard to file management?
Give four reasons why the study of concurrency is appropriate and important for students
of Operating System?
When does indeterminate result occur in concurrent processes?
What is Mutual Exclusion?
What is CPU scheduling? (ii) State the basic assumptions behind most scheduling
algorithms.
Give four reasons why the study of concurrency is appropriate and important for students
of Operating System?
When does indeterminate result occur in concurrent processes?
How are these problems solved?
Give an example of a semaphore operation.
78
What are the attributes of a process? (ii) How does the OS implement the process
abstraction?
What is the relationship between threads and processes?
Describe how a multi-threaded application can be supported by a user-level threads
package.
Name some advantages and disadvantages of user-level threads
79
What are three requirements of any solution to the critical sections problem? Why are the
requirements needed?
Why is turn passing a poor solution to the critical sections problem?
Interrupt disabling and enabling is a common approach to implementing mutual
exclusion, what are its advantages and disadvantages?
What is a test-and-set instruction? How can it be used to implement mutual exclusion?
Consider using a fragment of psuedo-assembly language aid you explanation.
What is the producer consumer problem? Give an example of its occurrence in operating
systems.
A semaphore is a blocking synchronisation primitive. Describe how they work with the
aid of pseudo-code. You can assume the existence of a thread_block() and a
thread_wakeup() function.
Describe how to implement a lock using semaphores.
What is deadlock? What is starvation? How do they differ from each other?
What are the four conditions required for deadlock to occur?
Describe four general strategies for dealing with deadlocks.
For single unit resources, we can model resource allocation and requests as a directed
graph connecting processes and resources. Given such a graph, what is involved
in deadlock detection.
What must the banker's algorithm know a priori in order to prevent deadlock?
Assuming the operating system detects the system is deadlocked, what can the operating
system do to recover from deadlock?
Describe the general strategy behind deadlock prevention, and give an example of a
practical deadlock prevention method.
Give an example of a scenario that might benefit from a file system supporting an
append-only access write.
Give a scenario where choosing a large file system block size might be a benefit; give
an example where it might be a hindrance.
What file access pattern is particularly suited to chained file allocation on disk?
80