Operating System Notes.
Operating System Notes.
Level 200
COLTECH - UBa
Introduction
To understand an operating system (OS) is to understand the workings of the whole computer system,
since the OS manages each and every piece of hardware plus software. This course will explore what
OSs concepts are, how they work, what they do and why. In order words, you are going to visualise
how the various components work cordially to keep a computer system working smoothly.
A modem computer comprises of one or more processors, some main memory, disks, printers, a
keyboard, a mouse, a display, network interfaces, and various other input/output devices. All in all, a
complex system. If every application programmer had to understand how all these things work in detail,
no code would ever get written. Moreover, managing all these components and using them optimally is
an extremely challenging job. For this reason, computers are equipped with a layer of software called
the operating system, whose job is to provide user programs with a better, simpler, cleaner, model of
the computer and to handle managing all the resources just stated. These systems are the focus of this
course.
Most students will have had some experience with an operating system such as Windows, Linux,
FreeBSD, or Max OS X, but appearances can be misleading. The program that users interact with,
usually called the shell when it is text based and the GUI (Graphical User Interface) - when it uses
icons, is actually not part of the operating system although it uses the operating system to get its work
done.
A simple overview of the main components under discussion here is given in Figure 1-1 (Tanenbaum,
2007).
Here we see the hardware at the bottom. The hardware consists of chips, boards, disks, a keyboard, a
monitor, and related physical objects. On top of the hardware is the software. Most computers have
two modes of operation: kernel mode and user mode. The operating system is the most fundamental
1
piece of software and runs in kernel mode (also called supervisor mode). In this mode it has full
access to all the hardware and can execute any instruction the machine is capable of executing. The rest
of the software runs in user mode, in which only a subset of the machine instructions is available. In
particular, those instructions that affect control of the machine or do 1/0 (Input/Output) are prohibited
to user-mode programs.
The user interface program, shell or GUI, is the lowest level of user-mode software, and allows the user
to start other programs, such as a Web browser, email reader, or music player. These programs, too,
make heavy use of the operating system. The placement of the operating system is depicted in Figure 1-
1. It runs on the bare hardware and provides the base for all the other software.
An important distinction between the operating system and normal (user-mode) software is that if a
user does not like a particular e-mail reader, he/she is free to get another one or writes his/her own if
he/she so chooses; he is not free to write his own clock interrupt handler, which is part of the operating
system and is protected by hardware against attempts by users to modify it.
This distinction, on the other hand, is sometimes blurred in embedded systems (which may not have
kernel mode) or interpreted systems (such as Java-based operating systems that use interpretation, not
hardware, to separate the components).
Also, in many systems there are programs that run in user mode but which help the operating system or
perform privileged functions. For example, there is often a program that allows users to change their
passwords. This program is not part of the operating system and does not run in kernel mode, but it
clearly carries out a sensitive function and has to be protected in a special way. In some systems, this
idea is carried to an extreme form, and pieces of what is traditionally considered to be the operating
system (such as the file system) run in user space.
In such systems, it is difficult to draw a clear boundary. Everything running in kernel mode is clearly
part of the operating system, but some programs running outside it are arguably also part of it, or at
least closely associated with it. Operating systems differ from user (i.e., application) programs in ways
other than where they reside. In particular, they are huge, complex, and long-lived. The source code of
an operating system like Linux or Windows is on the order of five million lines of code. To conceive of
what this means, think of printing out five million lines in book form, with 50 lines per page and 1000
pages per volume (larger than a standard book). It would take 100 volumes to list an operating system
of this size - essentially an entire bookcase. Can you imagine getting a job maintaining an operating
system and on the first day having your boss bring you to a book case with the code and say: "Go learn
that." And this is only for the part that runs in the kernel. User programs like the GUI, libraries, and
basic application software (things like Windows Explorer) can easily run to 10 or 20 times that amount.
It should be clear now why operating systems live a long time - they are very hard to write, and having
written one, the owner is unwilling to throw it out and start again. Instead, they evolve over long
periods of time. Windows 95/98/Me was basically one operating system and Windows
NT/2000/XP/Vista is a different one as well as Windows 7/8 and 10. They look similar to the users
because Microsoft made very sure that the user interface of Windows 2000/XP was quite similar to the
2
system it was replacing, mostly Windows 98. Nevertheless, there were very good reasons why
Microsoft got rid of Windows 98.
There are other major operating systems (besides Windows) for instance UNIX and its variants and
clones. It, too, has evolved over the years, with versions like System V, Solaris, and FreeBSD being
derived from the original system, whereas Linux is a fresh code base, although very closely modelled
on UNIX and highly compatible with it. In this course, we will touch on a number of key aspects of
operating systems, briefly, including what they are, what kinds are around, their functions, some of the
basic concepts, and their structure.
A computer system comprises of software (programs) and hardware (the physical machine and its
electronic components). The OS software is the main piece of software, the part of the computing
system that manages all the hardware plus all of the other software. To be more precise, it controls
every file, every device, every section of the main memory and every nanosecond of processing time.
The OS controls who can use the system and how.
Thus, an OS is the software that controls or coordinates the overall operation of a computer. It offers
the means through which a user can store and retrieve files. It provides the interface by which a user
can request execution of programs as well as the environment required to execute the programs
requested.
Arguably, the best known example of an OS is Windows which is provided in several versions by
Microsoft and widely used in the PC arena. UNIX is another well-established example and it is a
popular choice in larger computer systems as well as PC. UNIX is the core of two other popular OSs:
Mac OS – is the operating system provided by Apple for its range of machines
Solaris which was developed by Sun Microsystems (now owned by Oracle)
Linux is still another example of an OS that is found on both large and small machines. It was
originally developed by computer enthusiasts for non commercial purpose although it is now available
through many commercial sources including IBM.
The differences between OSs are largely cosmetic for casual users. But for computing professionals,
different OSs can signify major changes in the tools they work with or the approach they follow in
disseminating and maintaining their work. However, at their centre, all conventional OSs address the
same kinds of problems that computing experts have encountered for more than half a century.
Operating systems for computers large and small fall into five categories, differentiated by response
time and how data is entered into the system: batch, interactive, real-time, hybrid, and embedded
systems.
3
Batch Systems
They date from the earliest computer when they relied on stacks of punched cards or reels of magnetic
type for input. Jobs were entered by assembling the cards into a deck and then running the entire deck
of cards through a card reader as a group – a batch. The efficiency of a batch system is measured in
throughput: that is the number of jobs completed in a given amount of time e.g. 700 jobs per hour.
Interactive Systems
Interactive systems offer a faster turnaround than batch systems but they are slower than the real-time
systems. They were introduced to address the demands of users who required fast turnaround when
debugging their programs. The OS needed the development of time-sharing software which would
permit each user to interact directly with the computer system via commands entered from a typewriter-
like terminal. The OS gives immediate feedback to the user and response time can be measured in
fractions of a second.
Real-time Systems
Real-time systems are deployed in time-critical environments where reliability is key and data must be
processed within strict time limit. The time limit does not need to be ultra-fast. But system response
time must meet deadline or risk significant consequences. These systems equally have to put into place
contingencies to fail gracefully .i.e. maintain as much of the system’s capabilities and data as possible
in order to facilitate recovery.
Real-time systems are deployed for space flights, airport traffic control, critical industrial processes,
certain medical equipment and telephone switching etc. There are two types of real-time systems
depending on the missing deadline outcome:
Hard real-time systems risk total failure if predicted deadline is missed
Soft real-time systems suffer performance degradation but not total system failure as a result of
a missed deadline.
Hybrid Systems
Hybrid systems are a combination of batch and interactive systems. They tend to be interactive since
individual users can access the system and get fast response. But such a system normally accepts and
runs batch programs in the background if the interactive load is light.
A hybrid system takes advantage of the free time between high-demand usage of the system and low-
demand times. Several large computer systems are hybrids.
4
Embedded Systems
Embedded systems are computers placed inside other products to add features and capabilities. For
example, you can find embedded computers in household appliances, automobiles, digital music
players, elevators, and pacemakers. In the case of automobiles, embedded computers can help with
engine performance, braking and navigation. So several projects are underway to implement “smart
roads” that would alert motorists in cars equipped with embedded computers to choose alternate routes
when traffic becomes congested.
Operating systems for embedded computers are very different from those for general computer systems.
Each one is designed to carry out a set of specific programs, which are not interchangeable among
systems. This allows the designer to make the OS more efficient plus take advantage of computer’s
limited resources such as memory, to its upper limit.
5
Chapter 2 – OS
Each computer system includes a basic set of programs called the operating system. The most
important program in the set is referred to as the kernel. It is loaded into RAM when the system boots
and contains many critical procedures that are required for the system to operate. The other programs
are less crucial utilities; they can provide a wide variety of interactive experiences for the user - as well
as doing all the jobs the user bought the computer for; but the essential shape and capabilities of the
system are determined by the kernel. The kernel provides key facilities to everything else on the system
and determines many of the characteristics of higher software. Therefore, we often use the term
“operating system” as a synonym for “kernel.”
Interact with the hardware components, servicing all low-level programmable elements
included in the hardware platform.
Provide an execution environment to the applications that run on the computer system (the so-
called user programs).
Some operating systems permit all user programs to directly play with the hardware components (a
typical example is MS-DOS). In contrast, a Unix-like operating system hides all low-level details
concerning the physical organization of the computer from applications run by the user. When a
program wants to use a hardware resource, it must issue a request to the operating system. The kernel
evaluates the request and, if it chooses to grant the resource, interacts with the proper hardware
components on behalf of the user program.
So in order to enforce this mechanism, modern operating systems rely on the availability of specific
hardware features that prohibit user programs to directly interact with low-level hardware components
or to access arbitrary memory locations. In particular, the hardware introduces at least two different
execution modes for the CPU: a nonprivileged mode for user programs and a privileged mode for the
kernel. Unix calls these User Mode and Kernel Mode, respectively. This is also applicable to other
modern operating systems.
Multiuser Systems
A multiuser system is a computer that is able to concurrently and independently execute several
applications belonging to two or more users. Concurrently means that applications can be active at the
same time and contend for the various resources such as CPU, memory, hard disks, and so on.
Independently means that each application can perform its task with no concern for what the
applications of the other users are doing. Switching from one application to another, of course, slows
down each of them and affects the response time seen by the users. Many of the complexities of
modern operating system kernels, are present to minimize the delays enforced on each program and to
provide the user with responses that are as fast as possible.
6
Multiuser operating systems must include several features such as:
To ensure safe protection mechanisms, operating systems must use the hardware protection associated
with the CPU privileged mode. Otherwise, a user program would be able to directly access the system
circuitry and overcome the imposed bounds. Unix/windows/linux etc are a multiuser system that
enforces the hardware protection of system resources.
In a multiuser system, each user has a private space on the machine; usually, he/she owns some quota
of the disk space to store files, receives private mail messages, and so on. The operating system must
ensure that the private portion of a user space is visible only to its owner. In particular, it must ensure
that no user can exploit a system application for the purpose of violating the private space of another
user.
All users are identified by a unique number called the User ID, or UID. Usually only a restricted
number of persons are allowed to make use of a computer system. When one of these users starts a
working session, the system asks for a login name and a password. If the user does not input a valid
pair, the system denies access. Because the password is assumed to be secret, the user’s privacy is
ensured.
To selectively share material with other users, each user is a member of one or more user groups,
which are identified by a unique number called a user group ID. Each file is associated with exactly
one group. For instance, access can be set so the user owning the file has read and write privileges, the
group has read-only privileges, and other users on the system are denied access to the file.
Any Unix-like operating system has a special user called root or superuser. The system administrator
must log in as root to handle user accounts, perform maintenance tasks such as system backups and
program upgrades, and so on. The root user can do almost everything, because the operating system
does not apply the usual protection mechanisms to her. In particular, the root user can access every file
on the system and can manipulate every running user program.
Processes
All operating systems use one fundamental abstraction: the process. A process can be defined either as
“an instance of a program in execution” or as the “execution context” of a running program. In
traditional operating systems, a process executes a single sequence of instructions in an address space;
the address space is the set of memory addresses that the process is allowed to reference. Modern
7
operating systems allow processes with multiple execution flows - that is, multiple sequences of
instructions executed in the same address space.
Multiuser systems must enforce an execution environment in which several processes can be active
concurrently and contend for system resources, mainly the CPU. Systems that allow concurrent active
processes are said to be multiprogramming or multiprocessing. It is important to distinguish programs
from processes; several processes can execute the same program concurrently, while the same process
can execute several programs sequentially.
On uniprocessor systems, just one process can hold the CPU, and hence just one execution flow can
progress at a time. Generally, the number of CPUs is always restricted, and therefore only a few
processes can progress at once. An operating system component called the scheduler chooses the
process that can progress. Some operating systems allow only nonpreemptable processes, which means
that the scheduler is invoked only when a process voluntarily relinquishes the CPU. But processes of a
multiuser system must be preemptable; the operating system tracks how long each process holds the
CPU and periodically activates the scheduler.
Unix is a multiprocessing operating system with preemptable processes. Although when no user is
logged in and no application is running, several system processes monitor the peripheral devices. In
particular, several processes listen at the system terminals waiting for user logins. When a user inputs a
login name, the listening process runs a program that validates the user password. If the user identity is
acknowledged, the process creates another process that runs a shell into which commands are entered.
When a graphical display is activated, one process runs the window manager, and each window on the
display is usually run by a separate process. When a user creates a graphics shell, one process runs the
graphics windows and a second process runs the shell into which the user can enter the commands. For
each user command, the shell process creates another process that executes the corresponding program.
Unix-like operating systems/windows/Linux adopt a process/kernel model. Each process has the
illusion that it’s the only process on the machine, and it has exclusive access to the operating system
services. Whenever a process makes a system call (i.e., a request to the kernel), the hardware changes
the privilege mode from User Mode to Kernel Mode, and the process starts the execution of a kernel
procedure with a strictly limited purpose. In this way, the operating system acts within the execution
context of the process in order to satisfy its request. Whenever the request is fully satisfied, the kernel
procedure forces the hardware to return to User Mode and the process continues its execution from the
instruction following the system call.
Kernel Architecture
As stated before, most Unix kernels are monolithic: each kernel layer is integrated into the whole
kernel program and runs in Kernel Mode on behalf of the current process. In contrast, microkernel
operating systems demand a very small set of functions from the kernel, generally including a few
synchronization primitives, a simple scheduler, and an interprocess communication mechanism.
Several system processes that run on top of the microkernel implement other operating system-layer
functions, like memory allocators, device drivers, and system call handlers.
8
Although academic research on operating systems is oriented toward microkernels , such operating
systems are generally slower than monolithic ones, because the explicit message passing between the
different layers of the operating system has a cost. However, microkernel operating systems might
have some theoretical advantages over monolithic ones. Microkernels force the system programmers to
adopt a modularized approach, because each operating system layer is a relatively independent
program that must interact with the other layers through well-defined and clean software interfaces.
Moreover, an existing microkernel operating system can be easily ported to other architectures fairly
easily, because all hardware-dependent components are generally encapsulated in the microkernel
code. Finally, microkernel operating systems tend to make better use of random access memory
(RAM) than monolithic ones, because system processes that aren’t implementing needed
functionalities might be swapped out or destroyed.
modularized approach
Because any module can be linked and unlinked at runtime, system programmers must introduce well-
defined software interfaces to access the data structures handled by modules. This makes it easy to
develop new modules.
Platform independence
Even if it may rely on some specific hardware features, a module doesn’t depend on a fixed hardware
platform. For example, a disk driver module that relies on the SCSI standard works as well on an IBM-
compatible PC as it does on Hewlett-Packard’s Alpha.
A module can be linked to the running kernel when its functionality is required and unlinked when it is
no longer useful; this is quite useful for small embedded systems.
No performance penalty
Once linked in, the object code of a module is equivalent to the object code of the statically linked
kernel. Therefore, no explicit message passing is required when the functions of the module are
invoked.
9
Computer-System Organization/model
A modern general-purpose computer system comprises of one or more CPUs and a number of device
controllers connected through a common bus that provides access between components and shared
memory as depicted in Figure 1.2 (Silberschatz, Gagne & Galvin, 2018).
Each device controller is in charge of a specific type of device (for example, a disk drive, audio device,
or graphics display). Depending on the controller, more than one device may be attached. For instance,
one system USB port can connect to a USB hub, to which several devices can connect. A device
controller maintains some local buffer storage and a set of special-purpose registers. The device
controller is responsible for moving the data between the peripheral devices that it controls and its
local buffer storage.
Typically, operating systems have a device driver for each device controller. This device driver
understands the device controller and provides the rest of the operating system with a uniform interface
to the device. The CPU and the device controllers can execute in parallel, competing for memory
cycles. To ensure orderly access to the shared memory, a memory controller synchronizes
access to the memory.
Interrupts
Consider a typical computer operation: a program performing I/O. To start an I/O operation, the device
driver loads the appropriate registers in the device controller. The device controller, in turn, examines
the contents of these registers to determine what action to take (such as “read a character from the
10
keyboard”). The controller starts the transfer of data from the device to its local buffer. Once the
transfer of data is complete, the device controller informs the device driver that it has finished its
operation.
The device driver then gives control to other parts of the operating system, possibly returning the data
or a pointer to the data if the operation was a read. For other operations, the device driver returns status
information such as “write completed successfully” or “device busy”. But how does the controller
inform the device driver that it has finished its operation? This is accomplished via an interrupt.
Therefore, programmed I/O is sometimes known as polled I/O. Once the CPU detects a “data ready”
condition, it acts according to instructions programmed for that particular register.
The advantage of using this approach is that we have programmatic control over the behaviour of each
device. Program changes can adjust to the number and type of devices in the system as well as their
polling priorities plus intervals. However, constant register polling is a problem. The CPU is in
continual “busy wait” loop until it starts receiving an I/O request. So it won’t be able to do any useful
work until there is I/O to process. With respect to these limitations, programmed I/O is best suited for
special-purpose systems such as automated teller machines and systems that control or monitor
environmental events.
Interrupt-Driven I/O
Interrupt-driven I/O can be regarded as the opposite of the programmed I/O. Instead of the CPU
continually asking its attached devices whether they have any inputs, the devices notify the CPU when
they have data to send. The CPU proceeds with other tasks until a device requesting service interrupts
it. Interrupts are usually signalled with a bit in the CPU flags register called an interrupt flag.
Once the interrupt flag is set, the OS interrupts whatever program is currently executing plus saves that
program’s state and variable information. System then fetches the address of the I/O service routine.
After the CPU has finished servicing the I/O, it then restores the information which it saved from the
program that was running when the interrupt occurred, and the program execution resumes.
Interrupt-driven I/O is similar to programmed I/O in that the service routine can be modified to
accommodate hardware changes. Since vectors for various types of hardware are usually kept in the
same locations in systems running the same type and level of OS, these vectors can easily be changed
to point to vector-specific code. For instance, if someone invents a new type of hard drive that is not
yet supported by a popular OS, the manufacturer of that disk drive may update the disk I/O vector to
point to a code particular to that disk drive. Sadly, some of the early DOS-based virus writers also
deployed the same idea. They would replace the DOS I/O vectors with pointers to their own
disreputable code, destroying many systems in the process. Fortunately, these Oss have mechanisms in
place to safeguard against this kind of vector manipulation.
11
Storage hierarchy (Memory hierarchy)
The design constraints of a computer’s memory can be summed up by three questions: How much?
How fast? How expensive? The question of how much is rather open ended. Suppose the capacity is
there, applications will likely be developed to use it. However, the question of how fast is in a way,
easier to answer. So in order to attain the best performance, memory must be capable of keeping up
with the processor, i.e. as instruction one being executed by processor; we would not want it to pause
while waiting for instructions or operand.
For a practical system, the cost of memory must be realistic in relationship to other components. So
there is the need for a trade-off to be made among the three key characteristics which are: capacity,
access time, and cost. Thus, a mixture of technologies is deployed to implement memory systems, and
across this spectrum of technologies, the following relationships hold:
The problem facing the designer is obvious since he/she would like to use memory technologies that
provide for large capacity memory. This is due to the fact that the capacity is required and the cost per
bit is low.
However, to meet performance requirements, the designer has to use expensive, relatively lower
capacity memories with short access time. The method of resolving this problem is not to rely on a
single memory component or technology, but to deploy a memory hierarchy as depicted below
As one goes down the hierarchy, it could be seen that there is:
The smaller, more expensive, faster memories are supplemented by larger, cheaper and slower
memories. The key to the success of this organisation is item (d); decreasing frequency of access. The
use of two levels of memory to reduce access time works in theory, but only if condition (a) through (d)
are applicable. By using a variety of technologies, a wide range of memory system exists that addresses
conditions (a) through (c) but condition (d) fortunately is also valid.
Windows has a highly modular architecture. Each system function is managed by just one component
of the OS. The rest of the OS and all applications access that function through the responsible
component using standard interfaces. Key system data can only be accessed through the appropriate
function. In principle, any module can be removed, upgraded, or replaced without rewriting the entire
system or its standard application program interface (APIs).
Executive: Contains the base OS services, such as memory management, process and thread
management, security, I/O, and interprocess communication.
Kernel: Controls execution of the processor(s). The Kernel manages thread scheduling,
process switching, exception and interrupt handling, and multiprocessor synchronization.
Unlike the rest of the Executive and the user level, the Kernel’s own code does not run in
threads.
Hardware abstraction layer (HAL): Maps between generic hardware commands and
responses and those unique to a specific platform. It isolates the OS from platform-specific
hardware differences. The HAL makes each computer’s system bus, direct memory access
(DMA) controller, interrupt controller, system timers, and memory module look the same to
the Executive and Kernel components. It also delivers the support needed for symmetric
multiprocessing (SMP), explained subsequently.
Device drivers: Dynamic libraries that extend the functionality of the Executive. These
include hardware device drivers that translate user I/O function calls into specific hardware
device I/O requests and software components for implementing file systems, network
protocols, and any other system extensions that need to run in kernel mode.
Windowing and graphics system: Implements the graphical user interface (GUI) functions,
such as dealing with windows, user interface controls, and drawing.
The Windows Executive includes components for specific system functions and provides an
API for user-mode software. Following is a brief description of each of the Executive modules:
I/O manager: Provides a framework through which I/O devices are accessible to applications,
and is responsible for dispatching to the appropriate device drivers for further processing. The
I/O manager implements all the Windows I/O APIs and enforces security and naming for
devices, network protocols, and file systems (using the object manager).
13
Cache manager: Improves the performance of file-based I/O by causing recently referenced
file data to reside in main memory for quick access, and by deferring disk writes by holding
the updates in memory for a short time before sending them to the disk.
Object manager: Creates, manages, and deletes Windows Executive objects and abstract data
types that are used to represent resources such as processes, threads, and synchronization
objects. It enforces uniform rules for retaining, naming, and setting the security of objects. The
object manager also creates
object handles, which consist of access control information and a pointer to the object.
Plug-and-play manager: Determines which drivers are required to support a particular device
and loads those drivers.
Power manager: Coordinates power management among various devices and can be
configured to reduce power consumption by shutting down idle devices, putting the processor
to sleep, and even writing all of memory to disk and shutting off power to the entire system.
Security reference monitor: Enforces access-validation and audit-generation rules. The
Windows object-oriented model allows for a consistent and uniform view of security, right
down to the fundamental entities that make up the Executive. Thus, Windows uses the same
routines for access validation and for audit checks for all protected objects, including files,
processes, address spaces,
and I/O devices.
Virtual memory manager: Manages virtual addresses, physical memory, and the paging files
on disk. Controls the memory management hardware and data structures which map virtual
addresses in the process’s address space to physical pages in the computer’s memory.
Process/thread manager: Creates, manages, and deletes process and thread objects.
Configuration manager: Responsible for implementing and managing the system registry,
which is the repository for both system wide and per-user settings of various parameters.
Advanced local procedure call (ALPC) facility: Implements an efficient cross-process
procedure call mechanism for communication between local processes implementing services
and subsystems. Similar to the remote procedure call (RPC) facility used for distributed
processing.
14
Chapter 3 – OS: Functions of an Operating System
An OS is a very large and complex piece of software that has several responsibilities within a computer
system. An OS as we have seen earlier in this course, is a program that controls the execution of
application programs and acts as an interface between applications and the computer hardware. It can
be thought of as having three objectives:
We are now going to look at some of the most important tasks that it carries out.
An OS is executing whenever no other piece of user software or system software is utilising the
processor. Its most essential task is to wait for a user command given through input devices such as
mouse, keyboard etc. The OS then activates plus schedules the appropriate software package to process
the request if it’s a permissible command. As such, the OS operates as the computer receptionist as well
as dispatcher.
OS commands generally request access to hardware resources i.e. printers, processors, communication
lines. Software services i.e. translators, loaders, text editors, application program or information i.e.
data files, time, date. Some examples of typical OS commands are: delete a file/rename a file, save
information in a file and let user set or change a password.
Modern OSs can execute dozens or even hundreds of different commands. An OS determines which
software package requires to be loaded plus scheduled for execution after receiving a user command.
The control is returned to the OS after the package completes its execution while waiting for a user to
enter the next command. The user interfaces on OSs of the 1950, 1960s and 1970s were text oriented.
This implies that a prompt character was displayed by system on the screen to indicate that it was
waiting for input while waiting for something to happen. The user entered commands in a special and
sometimes quite complicated command language. But commands were not always easy to comprehend
and so learning these OS command language was a major stumbling block for new users. But without
learning first some basic commands, no useful work could be carried out.
Thus, almost all modern OSs now incorporate a graphical user interface (GUI) since users found text-
oriented command language very cumbersome. So to communicate with a user, a GUI supports visual
aids and point-and-click operations instead of textual commands. This interface deploys icons, pull-
down/up menus, scrolling windows, and other visual components and graphical symbols that facilitate
the process of creating requests for the user. GUIs are a perfect example of a high-level virtual machine
produced by the OS. GUI hides/conceals a great deal of the underlying hardware and software, thereby
making the computer appears very easy to manipulate.
15
System Security and Protection
In addition to being a receptionist, the OS also provides the duties of a security guard, managing access
to the computer and its resources. It prevents unauthorised users from accessing the system as well as
preventing authorised ones from doing unauthorised things. At least, the OS must not permit people to
access the computer if they have not been granted permission. In the early days of computing (i.e.
1950s and 1960s), security was provided by physical means – i.e. walls and locked doors around the
computer plus security guard at the doors to avoid unauthorised access.
However, the introduction of telecommunications networks in the late 1960s and 1970s through which
access to computers over phone lines became possible from virtually anywhere in the world and the job
of access control migrated from the guard at the door to the OS inside the machine. With most OS
today, access control implies that a user is required to enter a legal username and a password before any
other requests are accepted e.g. below is what a user encounters when logging onto a network server
while attempting to gain access into a university resource base:
Please enter your User Name and Password in the appropriate boxes in order to access our electronic
database for journals
So if an incorrect user name or password is entered, the OS would not allow any access to the computer.
It is equally the duty of the OS to safeguard the password file that stores all valid user name/password
combinations. This file must be restricted from being accessed by unauthorised users since that would
compromise the entire system security. This can be likened to putting a lock on your door but also
ensuring that you do not lose the key. However, there are some privileged users called supper users
who are usually computer centre employees or system administrators who must be able to access and
maintain this file. The OS may choose to encrypt the password file in order to provide security
deploying an encoded algorithm that is extremely difficult to crack. Operating systems deploy
encryption algorithms whenever they must offer a high degree of security to sensitive information.
Even when valid users gain access to the system, there are certain things that they should not be
allowed to do. The most obvious being that they should be able to access only their personal
information and should not be able to look at files or records of other users.
It must determine who is the owner of this file i.e. who created it and if the individual accessing the file
is not the owner, the request is definitely rejected. But most OSs allow file owner to provide a list of
additional authorised users or a general class of authorised users such as all students/all faculty. These
authorised lists are highly sensitive files so the OS normally stores them in an encrypted format.
Most modern OS not only determine whether one is permitted to access a file. They also verify what
operations you are allowed to do on that file. The following hierarchically ordered list shows the
different types of operations that users may be permitted to do on a file:
For instance, the CA marks file MARKS of a student called Sam could have the authorisation list as
portrayed below:
File: MARKS
So from the authorisation list, Sam being a student whose marks are in the file has the right to access
his own marks but simply to read the information. Mercy, who is a clerical officer in the administration
centre can read plus append new marks to the file at completion of the semester.
John, who is university registrar can read, append information plus is also allowed to change student’s
marks in case of errors. Jane – who is director of computer centre, can carry out all of these operations
plus delete the file and all its content from the system.
17
Efficient Allocation of Resources
It is equally the duty of the OS to ensure that the resources of a computer system are used efficiently as
well as correctly. To ensure that a processor does not idle if there is useful work to do, the OS
maintains a queue (a waiting line) of programs/activities that are ready to run. Each time the processor
is idle, the OS picks one of these jobs and assigns it to the processor. This ensures that the processor
always has something to do
To observe how this algorithm might work, let us define the following three classes of programs:
Now, here is how these three lists might look at some point in time
N M
O
P
In the memory, there are 4 programs called M, N, O, and P. As we can see, program M is executing on
the processor while programs N, O and P are ready to run and in line waiting for their turn. Let us
suppose that program M carries out the I/O operation “read a sector from a disk.” Normally, the
processing speed to this operation takes a long time about 10msec or so. So while waiting for this disk
I/O operation to finish, the processor has nothing to do, thus the system efficiency drops. To resolve
this problem, the OS can do some shuffling. It first moves program M to the waiting list since it must
wait for its I/O operation to complete before it can continue.
As such, it then selects one of the ready programs (say N) and assigns it to the processor which begins
executing it. This results in the following scenario depicted below:
M O N
P
Instead of still idling while M waits for I/O, the processor works upon N and gets something useful
done. This is analogous to working on another project while waiting for your secretary to obtain a
document rather than waiting and doing nothing. Maybe N also does an I/O operation and if this is the
case, then the OS respects the same steps. It takes N to the waiting list, picks up any ready program
e.g. O and begins executing it creating the following scenario:
18
Waiting Ready Running
M P O
N
So long as there is at least one program that is ready to run, the processor will always have something
useful to do. At a certain point, the I/O operation that M started completes and the “I/O completed
interrupt signal” is generated. The emergence of that signal portrays that program M is now ready to
run. But it could not do so immediately since processor is currently assigned to O. Rather, the OS
takes M to the ready list creating the following scenario:
N P O
M
Programs cycle from running to waiting to ready and back to running, each one using only a portion of
the processor's resources. We have seen that the execution of a program is an unbroken repetition of
the fetch/decode/execute from the first instruction line of the program to the HALT.
Now it seems that this view may not be entirely accurate. So for efficiency reasons, the running history
of a program may be a sequence of starts and stops i.e. a cycle of execution, waits for I/O operation,
waits for the processor, followed again by execution. By having many programs loaded in memory,
and sharing the processor, the OS can use the processor to its maximum capacity and run the overall
system more efficiently.
In addition to resources being used efficiently, they must be used safely too. The duty of the OS is to
prevent programs or users from attempting operations that cause a computer system to enter a state
where it’s unable to carry further work - a “frozen” state in which all useful work come to a grinding
halt.
To visualise how this can take place, imagine a computer system that has a single laser printer, one
data file M, and two programs X and Y. Program X wants to load data file M plus print it on a laser
printer. Program Y also wants to do the same thing. Thus, the following results are made by each of
them to the OS:
Program X Program Y
If the OS fulfills the request of each program, then X “posses” data file M and Y has the laser printer.
When X demands ownership of the laser printer, it is told that the printer is being used by Y. In a
19
similar manner, Y is told that it would have to wait for the data file until X is done with it. Each
program is waiting for a resource to become available that will never be free. This scenario is called
deadlock. Program X and Y are in a permanent waiting state and if there is no other ready to run, all
useful work on the system comes to an end. More formally, deadlock implies that there is a set of
programs in which each is waiting for an event to occur before it could proceed.
Program A Program B
Message >>>>
<<<< Acknowledge
Message >>>>
<<<< Acknowledge
Message >>>>
Program A will stop and wait for the receipt of an acknowledgement from B. Program B stops and is
waiting for the next message from A. Deadlock!! Neither side can proceed and unless something is
done. All communication between the two will stop.
There are two essential approaches known as deadlock prevention and deadlock recovery. With
deadlock prevention, the OS uses resource allocation algorithms that prevent deadlock from taking
place in the first instance. In the example of the two programs concurrently requesting laser printer and
data file, the problem is caused by the fact that each program has a portion of the resources to solve its
problem but without any of them having all that is requested. To prevent this, the OS can deploy the
following algorithm:
If a program cannot get all the resources that it needs, it must give up all the resources it
currently owns and issues a completely new request
This resource allocation algorithm basically states that, if you cannot get everything that you need, you
get nothing. If we had used this algorithm, then after program X had gotten hold of the data file but not
the laser printer, it would have to give up the ownership of the data file. Now Y could get everything it
required to execute and no deadlock would take place. It could equally work in the reverse direction
with Y giving up ownership of the laser printer while X gets the required resources. Whatever scenario
unfolds depends on the exact order in which requests are made.
In the telecommunications example, one deadlock prevention algorithm is to stipulate that messages
and acknowledgement never get lost or missing. This is practically impossible. Real-world
20
communication systems (telephone, satellite) do make errors. So we are incapable to guarantee that
deadlock will never take place. Rather, we must detect them and recover from them when they take
place. This is accomplished through the methods of deadlock recovery algorithms. For instance, here is
a possible algorithmic solution to the telecom problem:
Sender: Number your messages with nonnegative integers 0, 1, 2, ….and send them in numerical order.
If you send message number i and have not received an acknowledgement for 30 seconds, send
message i again.
Receiver: when you send an acknowledgement include the number of the message you received. If you
get a duplicate copy of message i, send another acknowledgement and discard the duplicate.
Program A Program B
At this juncture we have exactly the same deadlock condition described earlier. Nonetheless, this time
we are able to recover in pretty short period. For 30 seconds, nothing happens. However, after 30
seconds, A sends message (2) a second time. B acknowledges it and discards it (since it already has a
copy) and communication continues:
(wait 30 seconds)
Irrespective of whether we prevent deadlocks from taking place or recover from those that do occur it
is the duty of the OS to create a virtual machine in which a user never notices deadlocks plus not worry
about them. The OS should create the illusion of a smoothly functioning, highly efficient, error-free
environment even though as we know from our glance behind the scene, this is not always the case.
21
Chapter 4 – OS
PROCESS MANAGEMENT
We are going to embark on an in-depth study of how the operating systems are designed and
constructed. The central concept in any OS is the process: That is an abstraction of a running program.
Everything else centres on this concept and it is crucial that the OS designer (and the student) have a
thorough understanding of what a process is as early as possible.
Thus, the fundamental task of any modern OS is process management. Processes are one of the oldest
and most important abstractions that operating systems provide. They support the capability to have
(pseudo) concurrent operation even when there is only one CPU available. They convert a single CPU
into multiple CPUs. Without the process abstraction, modern computing could not exist. After this
brief introduction, it is imperative that we now delve into the central concept of processes plus an
introduction to the concept of threads.
Processes
All modern computers time and again do many things at the same time. Individuals used to working
with personal computers may not be fully aware of this fact. So providing a few examples could make
this point clearer. Let us consider the case of a web server with requests coming in from all over
demanding for web pages. When a request comes in, the server checks to see if the page required is in
the cache. If it is, it is sent back but if it is not, a disk request is initiated to fetch it. Nevertheless, this
disk requests take eternity from the CPU’s perspective. So while waiting for the disk request to
complete, many more requests may come in. If there are multiple disks present, some or all of them
may be fired off to other disks long before the first request is dealt with. Clearly, some approach is
required to model and control this concurrency.
Thus, processes (and especially threads) can help here. Now take the case of a PC user and when the
system is booted, several processes are secretly started, often unknown to the user. For example, a
process could be started up to wait for incoming emails but another may run on behalf of the antivirus
program to check periodically if any new virus definitions are available.
Additionally, explicit user processes may be running such as printing files and scanning documents, all
while user is surfing the web. All these activities have to be managed and so a multiprogramming
system comes in very handy here. In any multiprogramming system, the CPU switches from process
to process quickly, running each for tens or hundreds of milliseconds. While in reality, the CPU at any
instant of time is running only one process and in course of one second, it may work on many of them
giving the illusion of parallelism. Quite often, people talk of pseudoparallelism in this context, to
contrast it with true hardware parallelism of multiprocessor systems (which involve two or more CPUs
sharing the same memory). Keeping track of multiple parallel activities is difficult for people to do.
Thus, OS designers over the years have evolved a conceptual model (sequential processes) that makes
parallelism easier to deal with. Within this model, all runnable software on the computer, sometimes
including the OS is arranged into a number of sequential processes or just processes for short.
22
A process is just an instance of an executing program including current values of the program counter
(PC), registers, and variables.
Theoretically, each process has its own virtual CPU. But in reality, the real CPU switches back and
forth from process to process and to understand the systems, it is much easier to think about a
collection of processes running in (pseudo) parrallelism than trying to keep track of how the CPU
switches from program to program. This rapid switching back and forth is known as
multiprogramming. Figure 2.1 (a) shows a computer multiprogramming four programs in memory.
Figure 2.1 (b) depicts four processes, each with its own flow of control (i.e. its own logical program
counter) and each running independently of other ones. There is only one physical program counter, so
when each process runs, its logical program counter is loaded into the real program counter. So when it
is finished (for the time being), the physical program counter is the saved in the process’ stored logical
program counter in memory.
In figure 2.1 (c), we note that viewed over a long enough time interval, all processes have made
progress but at any given instant, only one process is actually running. In this module, we will assume
that there is only one CPU although this assumption is increasingly untrue, since new chips are often
multicore, with two, four or more CPUs. It is simpler just to think of one CPU at a time.
Thus, we can say that a CPU can run only one process at a time but if there are two cores (or CPUs),
each one of them can run only one process at a time. With the CPU switching rapidly back & forth
among the processes, the rate at which a process carries out its computation will not be uniform and
probably not even reproducible if the same processes are run again.
23
Therefore, processes should not be programmed with built-in assumptions about timing. Consider, for
example an I/O process that starts a streamer tape to restore backed-up files executes an idle loop
10,000 times to allow it to get up to speed plus gives a command to read the first record. If the CPU
chooses to switch to another process during the idle loop, the tape process might not run again until
after the first record was already past the read head. When a process has critical real-time requirements
like this, particular events must take place within specified number of milliseconds. Special measures
must be taken to make sure that they do not take place. Usually, most processes are not affected by the
underlying multiprogramming of the CPU or the relative speeds of different processes.
The difference between a process and a program is subtle but crucial. Let us take the case of a
computer scientist who is baking a birthday cake for his daughter. He has the birthday cake recipe and
a kitchen well stocked with all the input: flour, eggs, sugar, extract of vanilla, and so on. In this
analogy, the recipe is the program (i.e. an algorithm expressed in some suitable notation), the computer
scientist is the processor (CPU) and cake ingredients are input data. The process is the recipe, fetching
the ingredients and baking the cake.
Now imagine that the computer scientist’s son comes running in screaming with his head off shouting
that he has been stung by a bee. The computer scientist records where he was in the recipe i.e. the state
of the current process is saved, gets out his first aid book and starts following directions in it. Here we
see the processor being switched from one process (baking) to a higher-priority process (i.e.
administering medical care), each having a different program (recipe vs first aid book). So when the
bee sting has been taken care of, the computer scientist goes back to his cake continuing at the point
where he left off. The main idea here is that a process is an activity of some kind. It has a program,
input, output and a state. A single processor may be shared among several processes, with scheduling
algorithm being used to establish when to stop work on one process and service a different or another
process.
It is worth noting that if a program is running twice, it counts as two processes e.g. it is often possible
to start a word processor twice or print two files at the same time if two printers are available. The fact
that two running processes happen to be running the same program does not matter: They are distinct
processes. The operating system may be able to share the code between them, so only one copy is in
memory but that is a technical detail that does not change the conceptual situation of two processes
running.
Threads
Multi-core technology helps the operating system handle threads, multiple actions that can be executed
at the same time. First, an explanation: The Processor Manager is responsible for processing each job
submitted by a user. Jobs are made up of processes (sometimes called tasks in other textbooks), and
processes consist of multiple threads.
It requires space in main memory where it resides during its execution; even though, from time
to time, it requires other resources such as data files or I/O devices.
24
It passes through several states (such as running, waiting, ready) from its initial arrival into the
computer system to its completion.
Multiprogramming and virtual memory dictate that processes be swapped between main memory and
secondary storage during their execution. With conventional processes (also known as heavyweight
processes), this swapping results in a lot of overhead. That is because each time a swap takes place, all
process information must be saved to preserve the process’s integrity.
A thread (or lightweight process) can be defined as a unit smaller than a process, which can be
scheduled and executed. Using this technique, the heavyweight process, which owns the resources,
becomes a more passive element, while a thread becomes the element that uses the CPU and is
scheduled for execution. Manipulating threads is less time consuming than manipulating processes,
which are more complex. Some operating systems support multiple processes with a single thread,
while others support multiple processes with multiple threads.
Multithreading allows applications to manage a separate process with several threads of control. Web
browsers use multithreading routinely. For instance, one thread can retrieve images while another
sends and retrieves e-mail. Multithreading is also used to increase responsiveness in a time-sharing
system to increase resource sharing and decrease overhead.
Process Creation
Operating systems require some means to create processes. In very simple systems or in those
designed for running only a single application (e.g. the controller in a microwave oven), it might be
possible to have all the processes that will ever be needed and be present when the system comes up.
With general-purpose systems, some mechanism is required to create as well as to terminate processes
as required during operation. We will now take a look at some of the problems. There are four
principal events that cause processes to be created:
System initialization
Execution of a process creation
A user requested to create a new process
Initiation of a batch job
When an OS is booted, usually several processes are created. Some of these are foreground processes
that interact with (human) users and carry out work for them. And on the other hand, others are
background processes that are not associated with particular users, but instead have some specific
function. For example, one background process may be designed to accept incoming e-mail sleeping
most of the day but suddenly bouncing back to life when incoming e-mails arrive. Another
25
background process may be designed to accept incoming requests for web pages hosted on that
machine waking up when a request arrives to service that request.
Processes that reside in the background to handle some activities such as e-mail, web pages, news,
printing and so on are called daemons. Large systems commonly have dozens of them. In UNIX, the
PS program can be used to list the running processes while in Windows, the task manager can be used.
In addition to these processes created at boot time, new processes can be created afterward as well.
Frequently, a running process could issue system calls to create one or more processes to help it carry
out its job.
Creating new processes is mostly useful when the work to be done can easily be formulated in terms of
many created but otherwise independent interacting processes. For example, if a large amount of data
is being fetched over a network for subsequent processing, it may be convenient to create one process
to fetch the data and put in a shared buffer while a second process removes data items plus processes
them.
So on a multiprocessor, allowing each process to run on a different CPU may also make the job go
faster. With interactive systems, users can start a program by typing a command or (double) clicking
an icon. Taking either of these actions starts a new process and then runs the selected program in it. In
command-based UNIX systems running X, the new process takes over the window in which it was
started. But in Microsoft Windows, when a process is started, it does not have a window but when it
can create one (or more), it must do. So in both systems, users could have multiple windows open at
once with each running some process. Using a mouse, the user can select a window and interact with
the process. For example, providing input when needed, the last scenario in which processes are
created is applicable only to the batch systems found on large mainframes.
Here users can submit batch jobs to the system (possibly remotely). When the OS decides that it has
the resources to run another job, it creates a new process and runs the next job from the input queue in
it. Technically, in all these cases, a new process is created by having an existing one execute a process
creation system call that process may be running a user process. A system process invoked from
keyboard or mouse or a batch manager process. What that process does is – execute a system call to
create the new process. This system call instructs the OS to create a new process plus indicates directly
or indirectly which program to run in it.
In UNIX, there is only a single system call to create a new process – fork. This call creates an exact
clone of the calling process. After the fork, the two processes –parent and child have the same memory
image, the same environment strings, and the same open files.
Generally, the child process executes the execve or similar system call to change its memory image
and run a new program. For instance, when a user types a command say, sort to the shell, the shell
forks off a child process and the child executes sort. The reason for this two-step process is to allow
the child to manipulate its file descriptor after the fork before the execve in order to accomplish
redirection of standard input, standard output, and standard error.
26
In windows, in contrast, a single Win32 function call, CreateProcess handles both process creation and
loading the correct program into the new process. This call has 10 parameters to feed that program;
various security attributes, bits that control whether open files are inherited, priority information,
specification of window to be created for the process (if any), and a pointer to a structure in which
information about the newly created process is returned to the caller. In addition to CreateProcess,
Win32 has about 100 other functions for managing and synchronizing processes and related topics
In both UNIX and Windows, after a process is created, the parent and child have their own distinct
address spaces. If either process changes a word in its address space, change is not visible to the other
process. In UNIX, the child’s initial address space is a copy of the parent’s but there are definitely two
distinct address spaces involved; no writable memory is shared (some UNIX implementations share
program text between the two since that cannot be modified). It is nonetheless, possible to share some
of the creator’s other resources such as open files. In windows, the parent’s and child’s address spaces
are different from the start
Process Termination
After a process has been created, it starts to run plus executes whatever job it has to do. Nevertheless,
nothing lasts forever, not even the process. Sooner or later the new process will terminate usually as a
result of the following conditions:
Another reason for termination is that the process discovers a fatal error. Also, termination may occur
when an error is caused by the process, often due to a program bug e.g. executing an illegal instruction
With UNIX, a process plus all of its children and further descendants together make up a process
group. When a user sends a signal from a keyboard, that signal is sent to all members of the process
group. A process might also terminate if the process executes a system call telling the OS to kill some
other process. In UNIX this call is kill while corresponding Win32 function is TerminateProcess. But
in both cases, they require the necessary authorization
27
Process Hierarchies
In some systems, when a process creates another process, the parent process and child process continue
to be associated in some way. The child process can itself create more processes forming a process
hierarchy. Note that unlike plants and animals that use sexual reproduction, a process has only one
parent (but zero, one, two or more children). With UNIX, a process plus all of its children and further
descendants together make up a process group. When a user sends a signal from a keyboard, that signal
is sent to all members of the process group currently associated with the keyboard (usually all active
processes that were created in the current window).
Individually, each process catches the signal, ignore the signal, or take the default action which is to be
killed by the signal. On the contrary, Windows has no concept of a process hierarchy. All processes are
equal. The only indication of a process hierarchy is that when a process is created, the parent is given a
special token (called a handle) that it can use to control the child. However, it is free to pass this token
to some other process therefore, invalidating the hierarchy. UNIX cannot disinherit their children.
As a recap, there are several definitions of the term process and they include:
A program in execution
A process can be construed as an entity that comprises of a number of elements. Two essential
elements of a process are program code (which may be shared with other processes that are executing
the same program) and a set of data associated with code.
Let us suppose that the processor begins to execute this program code and we refer to this executing
entity as a process. At any given point in time while the program is executing, this process can be
distinctively characterised by a number of elements, including the following:
Identifier: A unique identifier associated with this process, to differentiate it from all other processes.
Program counter: the address of the next instruction in the program to be executed.
Memory Pointers: Includes pointers to the program code and data associated with this process plus
any memory blocks shared with other processes.
28
Context data: These are data that are present in registers in the processor while the process is
executing.
I/O status information: Includes outstanding I/O requests, I/O devices (e.g., tape drives) assigned to
this process a list of files in use by the process and so on.
Accounting information: May include the amount of processor time and clock time used, time limits,
account numbers, etc.
The information in the preceding list is stored in a data structure usually called process control block
(as depicted in Figure 3.1 below), that is created and managed by the OS.
The important point about the process control block is that it contains enough information such that it
is possible to interrupt a running process and later resume execution as if the interruption had not
occurred. The process control block is the key tool that enables the OS to support multiple processes
plus to provide for multiprogramming. When a process is interrupted, the current values of the
program counter and the processor registers (context data) are saved in appropriate fields of the
corresponding process control block while the state of the process is changed to some other value such
as block or ready.
The OS is now free to put some other process in the running state. The program counter and context
data for this process are loaded into the processor registers and this process can now begin to execute.
Thus, we can say that a process consists of program code and associated data plus a process control
block. So for a single-processor computer, at any given time, at most one process is executing and that
process is in the running state
29