Unit-I: Fundamentals of Computers and Operating Systems
Unit-I: Fundamentals of Computers and Operating Systems
Evolution of Computers –The growth of computer industry started with the need for performing fast calculations.
The manual method of computing was slow and prone to errors. So attempts were made to develop faster calculating
devices. The journey that started from the first calculating device i.e. Abacus has led us today to extremely high
speed calculating devices. Let us first have a look at some early calculating devices and then we will explore various
generations of computer.
Abacus: Abacus was discovered by the The Chinese further improved on the abacus so that
Mesopotamia’s in around 3000 BC. An abacus calculations could be done more easily. Even today
consisted of beads on movable rods divided into two abacus is considered as an apt tool for young children
parts. (Fig-1) Addition and multiplication of numbers to do calculations. In an abacus, each row is thought
was done by using the place value of digits of the of as a ten’s place. From right to left ,row no-1
numbers and position of beads in an abacus. represents the one’s column and the second column
represents ten’s place.The third column represents the
hundred’s place and so on. The starting position of
the top beads (representing the value of five) is
always towards the top wall of the abacus while the
lower beads (representing the value of one) will
always be pushed towards the lower wall as a starting
position.
Fig. Abacus
Jacquard’s Loom: In order to make the cotton weaving process automatic, Joseph Jacquard devised punch cards
and used them to control looms in 1801. The entire operation was under a program’s control. Through this historic
invention, the concept of storing and retrieving information started.
The First Generation (1942-1955): The first generation computers used the concept of ‘stored program’ and were
characterized by vacuum tubes. A vacuum tube is a delicate glass device that can control and amplify electronic
signals. The first generation computers were made using thousands of vacuum tubes and were the fastest calculating
devices of their time.
Salient features of First generation computers:
The Second Generation (1955–1964): In 2nd generation computers, Vacuum tubes were replaced by Transistors.
They required only 1/10 of power required by Vacuum tubes. This generation computers generated less heat & were
reliable. The first operating system developed in this generation.
The Third Generation (1964-1975): The 3rd generation computers replaced transistors with Integrated circuit
known as chip. From small scale integrated circuits which had 10 transistors per chip, technology developed to MSI
circuits with 100 transistors per chip. These computers were smaller, faster & more reliable. High level languages
invented in this generation.
Fifth Generation Computers (Present & Beyond): Fifth generation computing devices, based on artificial
intelligence, are still in development, though there are some applications, such as voice recognition, that are being
used today. The use of parallel processing and superconductors is helping to make artificial intelligence a reality.
Quantum computation and molecular and nanotechnology will radically change the face of computers in years to
come.
Parallel Processing
Superconductivity
Artificial Intelligence
Classification of Computers: The computers can be classified based on the technology being used as: Digital,
Analog and Hybrid.
Digital Computers: A computer that performs calculations and logical operations with quantities represented as
digits, usually in the binary number system. Binary digits are easily expressed in a digital computer by the presence
(1) or absence (0) of current or voltage. It computes by counting and adding operations. The digital computers are
used in industrial, business and scientific applications. They are quite suitable for large volume data processing.
Digital Computers can be classified on the basis of size and capability as under.
Super Computer -> The fastest type of computer. Supercomputers are very expensive and are employed for
specialized applications that require immense amounts of mathematical calculations. For example, weather
forecasting requires a supercomputer. Other uses of supercomputers include animated graphics, fluid dynamic
calculations, nuclear energy research, and petroleum exploration. PARAM & Pace are the supercomputer made in
India.
Mainframe Computer -> A very large and expensive computer capable of supporting hundreds, or even thousands,
of users simultaneously. In the hierarchy that starts with a simple microprocessor (in watches, for example) at the
bottom and moves to supercomputers at the top, mainframes are just below In some ways, mainframes are more
powerful than supercomputers because they support more simultaneous programs. But supercomputers can execute
a single program faster than a mainframe.
Mini Computer -> A mid-sized computer. In size and power, minicomputers lie between workstations and
mainframes. In the past decade, the distinction between large minicomputers and small mainframes has blurred,
however, as has the distinction between small minicomputers and workstations. But in general, a minicomputer is a
multiprocessing system capable of supporting from 4 to about 200 users simultaneously. Generally, servers are
comes in this category.
Micro Computers -> These are also known as Personal Computers. These type of digital computer uses a
microprocessor (a CPU on a single chip) and include both desktops and laptops. These computers can work on small
volume of data, are very versatile and can handle variety of applications.
Analog Computers: An Analog computer is a form of computer that uses continuous physical phenomena such as
electrical, mechanical, or hydraulic quantities to model the problem being solved. These computers measure changes
in continuous physical quantities say current and voltage. These computers are used to process data generated by
ongoing physical processes. Example: Thermometer, Speedometer, Petrol pump indicator etc.
Hybrid Computers (Analog + Digital): These use both analog and digital technology. It has the speed of analog
computer and the accuracy of a digital computer. It may accept digital or analog signals but an extensive conversion
of data from digital to analog and analog to digital has to be done. Generally the analog components provide
efficient processing of differential equations while the digital part deals with logical operations of the system. Hence
benefits of both analog and digital computing are readily available. Hybrid Computers are used as a cost effective
means for complex simulations.
Von Neumann Component 1 - The CPU : The CPU, or Central Processing Unit, is the name given to the
component that controls the computer and works on the data. It can be split up into four sub-components:
We know a few things from before about the Von Neumann CPU.
1) The ALU, or Arithmetic Logic Unit: A Von Neumann CPU has an ALU. This is the part of the CPU that
performs arithmetic and logic operations on data and acts as the revolving for the CPU, letting data enter and
leave the CPU. We also know that CPUs have a ‘word size’. This is the number of bits that can be added, for
example, in one go. The bigger a CPU’s word size, the more bits it can work on in one clock cycle and the
more work you can get done.
2) The Control Unit: A Von Neumann CPU has a control unit. The control unit is in charge of ‘fetching’ each
instruction that needs to be executed in a program by issuing control signals to the hardware. It then decodes
the instruction and finally issues more control signals to the hardware to actually execute it.
3) Registers: A Von Neumann CPU has registers. These are very fast memory circuits. They hold information
such as the address of the next instruction (Program Counter), the current instruction being executed (Current
Instruction Register), the data being worked on and the results of arithmetic and logical operations
(Accumulators), information about the last operation (Status Register) and whether an interrupt has happened
(Interrupt Register).
Types and functions of Computer Registers.
There are various types of computer registers… Such as,
Data Register.
Accumulator Register.
Memory Address Register.
Memory Data Register
Memory Buffer Register.
Program Counter.
Instruction Register.
Stack Control Register.
Flag Register.
I/O Address Register.
I/O Buffer Register.
1. Data Register:
A register used in microcomputers to temporarily store data being transmitted to or from a peripheral.
2. Accumulator Register: This Register is used for storing the Results those are produced by the System. When the
CPU will generate Some Results after the Processing then all the Results will be Stored into the AC Register.
This Register is used for storing the Results those are produced by the System. When the CPU will generate
Some Results after the Processing then all the Results will be Stored into the AC Register. The accumulator register
is located inside the accumulator register, It is used during arithmetic & logical operations of the accumulator
register.
3. Memory Address Register: This register holds the memory addresses of data and instructions. This register is
used to access data and instructions from memory during the execution phase of an instruction. Suppose CPU wants
to store some data in the memory or to read the data from the memory. It places the address of the-required memory
location in the MAR. It stores the address of memory where CPU wants to read or write data.
4. Memory Data Register: MDR is the register of a computer's control unit that contains the data to be stored in the
computer storage (e.g. RAM), or the data after a fetch from the computer storage. It acts like a buffer and holds
anything that is copied from the memory ready for the processor to use it. MDR hold the information before it goes
to the decoder.
MDR which contains the data to be written into or readout of the addressed location. For example, to retrieve
the contents of cell 123, we would load the value 123 (in binary, of course) into the MAR and perform a fetch
operation. When the operation is done, a copy of the contents of cell 123 would be in the MDR. To store the value
98 into cell 4, we load a 4 into the MAR and a 98 into the MDR and perform a store. When the operation is
completed the contents of cell 4 will have been set to 98, by discarding whatever was there previously.
The MDR is a two-way register. When data is fetched from memory and placed into the MDR, it is written to
in one direction. When there is a write instruction, the data to be written is placed into the MDR from another CPU
register, which then puts the data into memory.
The Memory Data Register is half of a minimal interface between a micro program and computer storage, the
other half is a memory address register.
5. Memory Buffer Register: This register holds the contents of data or instruction read from, or written in memory.
It means that this register is used to store data/instruction coming from the memory or going to the memory.
6. Program Counter: The program counter (PC), commonly called the instruction pointer (IP) in Intel x86
microprocessors, and sometimes called the instruction address register, or just part of the instruction sequencer in
some computers, is a processor register
It is a 16 bit special function register in the 8085 microprocessor. It keeps track of the the next memory
address of the instruction that is to be executed once the execution of the current instruction is completed. In other
words, it holds the address of the memory location of the next instruction when the current instruction is executed by
the microprocessor. This register always points or holds the address of next instruction to be fetched for execution.
7. Instruction Register:
Once an instruction is fetched from main memory, it is stored in the Instruction Register. The control unit takes
instruction from this register, decodes and executes it.
8. Stack Control Register:
The Stack Control Register is used to manage the stacks in memory.
9. Flag Register:
The Flag register is used to indicate the occurrence of a certain condition during an operation of the CPU. It is a
special purpose register with size one byte or two bytes.
10. I/O Address Register:
I/O Address register is used to specify the address of a particular I/O device.
11. I/O Buffer Register:
I/O Buffer Register is used for exchanging data between the I/O module and the processor.
12. Index Register: A hardware element which holds a number that can be added to (or, in some cases, subtracted
from) the address portion of a computer instruction to form an effective address. Also known as base register. An
index register in a computer's CPU is a processor register used for modifying operand addresses during the run of a
program.
4) The clock : Instructions are carried out to the beat of the clock! Some instructions take one beat and others more
than one beat. Very roughly speaking, the faster the clock, the more clock beats you have per second so the more
instructions per section you can do and the faster your computer will go.
Von Neumann Component 2 – IAS: We also know that the Von Neumann computer has an IAS, or Immediate
Access Store, where it puts both programs and data. We often commonly refer to this memory as RAM. RAM is
made up of lots of boxes that can store a bit pattern. Each box has a unique address. A memory address might store
an instruction (which is made up of an operator and an operand) or it might store just a piece of data. A Von
Neumann computer can’t tell the difference between the bit patterns as such, but ‘knows’ indirectly because
of where the bit pattern is stored in RAM. Pre-Von Neumann computers used to split up memory into program
memory and data memory and this made computers relatively complex. Von Neumann was the first to realise that
there was actually no difference between the nature of an instruction and the nature of a piece of data. One important
function of an operating system is to manage memory and to keep track of the RAM addresses of applications as
well as any data.
We also know that computers have an address bus, so that the CPU can address each individual memory location in
the IAS, for example, when it wants to store a piece of data or retrieve a piece of data. The data itself is moved about
between devices on a data bus. There is also a control bus, to generate signals to manage the whole process.
Von Neumann Component 3 - I/O: A computer needs peripherals for inputting and outputting data. It needs to be
able to read data into itself and send data out. It reads data in and sends data out through its I/O ports. A port is
simply a gateway, like a port used for shipping. Just like every port used for ships needs its own harbour master, so
every I/O port needs to be managed. An I/O controller is the term used to describe the I/O port along with the
circuits that manage data into and out of the port. It allows you to connect up any I/O device to the PC and transfer
data in to or out of the computer. You wouldn’t want to connect an I/O device directly to a CPU because you would
have to redesign the CPU every time a new type of device came along. Besides, a new type of device might need
different voltages and control signals from the CPU, again necessitating a CPU redesign. The I/O controller acts as
an interface to overcome these problems. Refining the diagram we saw in the previous chapter on CPUs, we now
have:
A computer system showing the I/O controllers.: Of course, there are a whole range of other I/O controllers we
could have included. We could have shown ones for devices such as a mouse, a MIDI device, a printer, a DVD
player, a SCSI device as used with many scanners or a network card, to name just a few.
Von Neumann bottleneck: Whatever you do to improve performance, you cannot get away from the fact that
instructions can only be done one at a time and can only be carried out sequentially. Both of these factors hold back
the efficiency of the CPU. This is commonly referred to as the 'Von Neumann bottleneck'. You can provide a Von
Neumann processor with more RAM, more cache or faster components but if real gains are to be made in CPU
performance then a major review needs to take place of CPU design.
Functional units –Digital computer systems consist of three distinct units. These units are as follows:
Input unit
Central Processing unit
Output unit
These units are interconnected by electrical cables to permit communication between them. This allows the
computer to function as a system. Input Unit A computer must receive both data and program statements to function
properly and be able to solve problems. The method of feeding data and programs to a computer is accomplished by
an input device. Computer input devices read data from a source, such as magnetic disks, and translate that data
into electronic impulses for transfer into the CPU. Some typical input devices are a keyboard, a mouse, or a scanner.
Central Processing Unit The brain of a computer system is the central processing unit (CPU). The CPU processes
data transferred to it from one of the various input devices. It then transfers either an intermediate or final result of
the CPU to one or more output devices. A central control section and work areas are required to perform
calculations or manipulate data. The CPU is the computing center of the system. It consists of a control section, an
arithmetic-logic section (fig. 3-1), and an internal storage section (main memory). Each section within the CPU
serves a specific function and has a particular relationship with the other sections within the CPU.
CONTROL SECTION.—The control section directs the flow of traffic (operations) and data. It also maintains
order within the computer. The flow of control is indicated by dotted arrows in figure 3-1. The control section
selects one program statement at a time from the program storage area, interprets the statement, and sends the
appropriate electronic impulses to the arithmetic-logic and storage sections so they can carry out the instructions.
The control section does not perform actual processing operations on the data. The control section instructs the input
device on when to start and stop transferring data to the input storage area. It also tells the output device when to
start and stop receiving data from the output storage area.
INTERNAL STORAGE SECTION.—The internal storage section is sometimes called primary storage, main
storage, or main memory, because this section functions similar to our own human memory. The storage section
serves four purposes; three relate to retention (holding) of data during processing. First, as indicated by the solid
arrow (fig. 3-1), data is transferred from an input device to the INPUT STORAGE AREA where it remains until
the computer is ready to process it. Second, a WORKING STORAGE AREA ("scratch pad" memory) within the
storage section holds both the data being processed and the intermediate results of the arithmetic-logic
operations. Third, the storage section retains the
Figure 3-1.—Sections of a CPU
.processing results in the OUTPUT STORAGE AREA .From there the processing results can be transferred to an
output device. The fourth storage section, the PROGRAM STORAGE AREA, contains the program statements
transferred from an input device to process the data. Please note that the four areas (input, working storage, output,
and program storage) are NOT f med in size or location but are determined by individual program requirements.
Output Unit: As program statements and data are received by the CPU from an input device, the results of the
processed data are sent from the CPU to an OUTPUT DEVICE. These results are transferred from the output storage
area onto an output medium, such as a floppy disk, hard drive, video display, printer, and so on .By now, you should
have an idea of the functions performed by a CPU. It is the CPU that executes stored programs and does all of
the processing and manipulating of data. The input and output (I/O)devices simply aid the computer by
sending and receiving data and programs.
Instruction format Typical Architectures:- Computer perform task on the basis of instruction provided. A
instruction in computer comprises of groups called fields. These field contains different information as for
computers everything is in 0 and 1 so each field has different significance on the basis of which a CPU decide what
so perform. The most common fields are:
Operation field which specifies the operation to be performed like addition.
Address field which contain the location of operand, i.e., register or memory location.
Mode field which specifies how operand is to be founded.
A instruction is of various length depending upon the number of addresses it contain. Generally CPU organization
are of three types on the basis of number of address fields:
1. Single Accumulator organization
2. General register organization
3. Stack organization
In first organization operation is done involving a special register called accumulator. In second on multiple registers
are used for the computation purpose. In third organization the work on stack basis operation due to which it does
not contain any address field. It is not necessary that only a single organization is is applied a blend of various
organization is mostly what we see generally.
OR
An instruction format defines the layout of the bits of an instruction, in terms of its constituents parts. An instruction
format must include an opcode and, implicitly or explicitly, zero or more operands. Each explit operand is
referenced using one of the addressing mode that is available for that machine. The format must, implicitly or
explictly, indicate the addressing mode of each operand. For most instruction sets, more than one instruction format
is used. Four common instruction format are shown in the Figure 4.9.
Instruction Length: On some machines, all instructions have the same length; on others there may be many
different lengths. Instructions may be shorter than, the same length as, or more than the word length. Having all the
instructions be the same length is simpler and make decoding easier but often wastes space, since all instructions
then have to be as long as the longest one. Possible relationship between instruction length and word length is shown
in the Figure 4.10.
Figure 4.10: Some Possible relationship between instructions and word length
Generally there is a correlation between memory transfer length and the instruction length. Either the instruction
length should be equal to the memory transfer length or one should be a multiple of the other. Also in most of the
case there is a correlation between memory transfer length and word length of the machine.
Allocation of Bits: For a given instruction length, there is a clearly a trade-off between the number of opcodes and
the power of the addressing capabilities. More opcodes obviously mean more bits in the opcode field. For an
instruction format of a given length, this reduces the number of bits available for addressing.
The following interrelated factors go into determining the use of the addressing bits:
Number of Addressing modes: Sometimes as addressing mode can be indicated implicitly. In other cases, the
addressing mode must be explicit, and one or more bits will be needed.
Number of Operands: Typical instructions on today's machines provide for two operands. Each operand address in
the instruction might require its own mode indicator, or the use of a mode indicator could be limited to just one of
the address field.
Register versus memory: A machine must have registers so that data can be brought into the CPU for processing.
With a single user-visible register (usually called the accumulator), one operand address is implicit and consumes no
instruction bits. Even with multiple registers, only a few bits are needed to specify the register. The more that
registers can be used for operand references, the fewer bits are needed.
Number of register sets:A number of machines have one set of general purpose registers, with typically 8 or 16
registers in the set. These registers can be used to store data and can be used to store addresses for displacement
addressing. The trend recently has been away from one bank of general purpose registers and toward a collection of
two or more specialized sets (such as data and displacement).
Address range: For addresses that reference memory, the range of addresses that can be referenced is related to the
number of address bits. With displacement addressing, the range is opened up to the length of the address register.
Address granularity: In a system with 16- or 32-bit words, an address can reference a word or a byte at the
designer's choice. Byte addressing is convenient for character manipulation but requires, for a fixed size memory,
more address bits.
Variable-Length Instructions:Instead of looking for fixed length instruction format, designer may choose to
provide a variety of instructions formats of different lengths. This tectic makes it easy to provide a large repertoire
of opcodes, with different opcode lengths. Addressing can be more flexible, with various combinations of register
and memory references plus addressing modes. With variable length instructions, many variations can be provided
efficiently and compactly. The principal price to pay for variable length instructions is an increase in the complexity
of the CPU.
Number of addresses : The processor architecture is described in terms of the number of addresses contained in
each instruction. Most of the arithmatic and logic instructions will require more operands. All arithmatic and logic
operations are either unary
(one source operand, e.g. NOT) or binary (two source operands, e.g. ADD).
Thus, we need a maximum of two addresses to reference source operands. The result of an operation must be stored,
suggesting a third reference.
Three address instruction formats are not common because they require a relatively long instruction format to hold
the three address reference.
With two address instructions, and for binary operations, one address must do double duty as both an operand and a
result.
In one address instruction format, a second address must be implicit for a binary operation. For implicit reference, a
processor register is used and it is termed as accumulator(AC). the accumulator contains one of the operands and is
used to store the result.
The evaluation of this expression in three address instruction format, two address instruction format and one address
instruction format is shown in the Figure 4.11, Figure 4.12 and Figure 4.13 respectively.
Figure 4.11: Three address instructions Figure 4.12: Two address instructions
Computers-Operating system and functions: An operating system includes all the programs of a computer system
that control and monitor the operations of the system. Operating systems typically consist of a kernel that manages
the hardware of the computer, as well as basic system programs that are used to boot the operating system and
configure it. We are going to discuss main functions of operating system.
1. Booting: Booting is a process of starting the computer operating system starts the computer to work. It checks the
computer and makes it ready to work.
2. Memory Management: It is also an important function of operating system. The memory cannot be managed
without operating system. Different programs and data execute in memory at one time. if there is no operating
system, the programs may mix with each other. The system will not work properly.
3. Loading and Execution: A program is loaded in the memory before it can be executed. Operating system
provides the facility to load programs in memory easily and then execute it.
4. Data Security:Data is an important part of computer system. The operating system protects the data stored on the
computer from illegal use, modification or deletion.
5. Disk Management: Operating system manages the disk space. It manages the stored files and folders in a proper
way.
6. Process Management: CPU can perform one task at one time. if there are many tasks, operating system decides
which task should get the CPU.
7. Device Controlling: operating system also controls all devices attached to computer. The hardware devices are
controlled with the help of small software called device drivers.
8. Printing Controlling:Operating system also controls printing function. It a user issues two print commands at a
time, it does not mix data of these files and prints them separately.
9. Providing Interface: It is used in order that user interface acts with a computer mutually. User interface controls
how you input data and instruction and how information is displayed on screen. The operating system offers two
types of the interface to the user;
Graphical-line interface: It interacts with of visual environment to communicate with the computer. It uses windows,
icons, menus and other graphical objects to issues commands.
Command-line interface: it provides an interface to communicate with the computer by typing commands.
Without software, a computer is effectively useless. Computer software controls the use of the hardware
(CPU, memory, disks etc.), and makes the computer into a useful tool for its users.
As we saw in the first lecture, the software side of a computer can be divided into programs, libraries and
the operating system.
Each layer hides much of the complexity of the layer below, and provides a set of abstract services and
concepts to the layer above.
For example, the computer's hard disk allows data to be stored on it in a set of fixed-sized blocks. The
operating system hides this complexity, and provides the concept of files to the application software. In
turn, an application program such as a word processor hides the idea of a file, and allows the user to work
with documents instead.
The most fundamental of all system software is the operating system. It has three main tasks to perform.
1. The operating system must shield the details of the hardware from the application programs, and
thus from the user.
2. The operating system has to substitute a set of abstract services to the application programs, to
replace the physical hardware services. When applications use these abstract services, the
operations must be translated into real hardware operations.
3. Finally, the resources in a computer (CPU, memory, disk space) are limited. The operating system
must act as a resource manager, optimising the use of the resources, and protecting them against
misuse and abuse. When a system provides multiuser or multitasking capabilities, resources must
be allocated fairly and equitably amongst a number of competing requests.
Because an operating system must hide the computer's hardware, and manage the hardware resources, it
needs to prevent the application software from accessing the hardware directly. Without this sort of
protection, the operating system would not be able to do its job.
The computer's CPU provides two modes of operation which enforce this protection. The operating system
runs in kernel mode, also known as supervisor mode or privileged mode. In kernel mode, the software has
complete access to all of the computer's hardware, and can control the switching between the CPU modes.
Interrupts are also received in the kernel mode software.
The rest of the software runs in user mode. In this mode, direct access to the hardware is prohibited, and so
is any arbitrary switching to kernel mode. Any attempts to violate these restrictions are reported to the
kernel mode software: in other words, to the operating system itself. Programs running in user mode are
given an address space, visible only to themselves, which contains enough memory for them to do their
job.
By having two modes of operation which are enforced by the computer's own hardware, the operating
system can force application programs to use the operating system's abstract services, instead of
circumventing any resource allocations by direct hardware access.
If the software layers hide complexity and replace it with simpler abstractions, how do programs access
these abstractions?
Each layer provides an API (Application Program Interface), which is the set of functions and commands
that it provides.
At the top of the operating system are the system calls. These are the set of abstract operations that the
operating system provides to the applications programs. This interface is generally constant: users cannot
change what is in the operating system while it is running. When executed, a system call provides a
controlled transition from user mode to kernel mode.
Above the system calls are a set of library routines which come with the operating system. These are
functions and subroutines which are useful for many programs.
Programs do the work for the user. Regardless of their type, all programs can use the library routines and
the system calls that come with an operating system. In fact, the only way to ask the kernel to do anything
is to perform a system call.
A mainframe operating system runs on mainframes, which provide immense I/O and availability. They
may provide a batch environment: jobs are segregated into batches with similar requirements. Each batch
is given to the computer to run. When jobs with similar system requirements are batched together, this
helps to streamline their processing.
Alternatively, the system may provide transaction processing, where hundred or thousands of small
requests must be performed every second.
User interaction is generally lacking in these systems, as the emphasis is on the computer's utilisation. An
example mainframe system is IBM's OS/390.
A server operating system runs on servers. The aim here is to provide services to many users
simultaneously. Services may include applications, file storage, print and other networking operations.
The emphasis here is on user response time as well as computer utilisation. Server systems are usually
more general-purpose than the other types of operating systems. Example multiprogramming systems are
Linux, Solaris and Windows 2K.
A personal computer operating system is designed to provide a good environment to a single user at a
time. User interface elements (desktops, GUIs etc.) are important here. Response time and the user
experience is often more important that efficient computer utilisation. Windows 7 and Mac OS X are
examples. Linux also fits in here, although it can deal with multiple users at the same time.
A real-time system is designed to respond to input within certain time constraints. This input usually
comes from external sensors, and not from humans. Thus, there is usually little or no user interaction. Many
embedded systems are also real-time systems. An example real-time system is the QNX operating system.
An embedded operating system usually has the operating system built into the computer, and is used to
control external hardware. There is little or no application software in an embedded system. Examples here
are the PDAs that everybody seems to have, and of course the computers built into DVDs, microwaves, and
into most cars. Symbian is an example of an embedded operating system.
In this course, we will concentrate on server operating systems: these are much more sophisticated and complex then
the other operating system types, and will give us a lot more to look at. In particular, we will also concentrate
on multi-user systems: these are systems which support multiple users at the same time.
The services provided by an operating system depends on the concepts around which the operating system
was created; this gives each operating system a certain `feel' to the programmers who write programs for it.
We are talking here not about the `look & feel' of the user interface, but the `look & feel' of
the programmer's interface, i.e the services provided by the API (i.e. the set of system calls).
Although each operating system provides its own unique set of services, most operating systems share a
few common concepts. Let's briefly take at look at each now. We will examine most of these concepts in
detail in later topics.
The Process
Most operating systems provide the concept of a process. Here, we need to distinguish between
a program and a process.
A program is a collection of computer instructions plus some data that resides on a storage medium (e.g. a
disk), waiting to be called into action.
A process is a program during execution. It has been loaded into the computer's main memory, and is
taking input, manipulating the input, and producing output.
Specifically, a process is an environment for a program to run in. This includes:
o An address space, which is a set of memory locations which stores the machine-code instructions
required by process, and the process' variables. The address space is protected, so that other
processes cannot interfere.
o A set of CPU registers, so that the process can perform some operations quickly (e.g additions,
subtractions) without having to access memory, which can be slow.
o The ability to invoke system calls, so that the process can obtain services from the operating
system.
This environment is often known as a process' context.
Memory
Part of every computer's hardware is its main memory. This is a set of temporary storage locations which
can hold machine code instructions and data. Memory is volatile: when the power is turned off, the contents
of main memory are lost.
In current computers, there are usually several gigabytes of memory (i.e billions of 8-bit storage areas).
Memory contents can be accessed by reading or writing a memory location, which has an integeraddress,
just like the numbers on the letter boxes in a street.
Memory locations often have a hardware protection, allowing or preventing read and writes. Usually, a
process can only read or write to a specific set of locations that have been given to it by the operating
system: its address space.
The operating system allocates memory to processes as they are created, and reclaims the memory once
they finish. As well, processes can usually request more memory, and also relinquish this extra memory if
they no longer require it. The operating system must allocate memory on a fair and equitable basis to all the
processes on the system.
Files
Files are storage areas for programs, source code, data, documents etc. They can be accessed by processes,
but don't disappear when processes die, or when the machine is turned off. They are thus persistent objects.
Operating systems provide mechanisms for file manipulation, such as open, close, create, read and write.
As part of the job of hiding the hardware and providing abstract services, the operating system must map
files onto areas on disks, USB and flash devices, and tapes. The operating system must also deal with files
that grow or shrink in size.
Some operating systems don't enforce any structure to files, or enforce particular file types types. Others
distinguish between file types and structures, e.g. Java source files, text documents, executable files, data
files etc.
Most operating systems allow files to have permissions, allowing certain types of file access to authorised
users only.
Directories (i.e folders) may exist to allow related files to be collected. The main reason for the existence
of directories is to make file organisation easier and more flexible for the user.
Windows
Nearly all operating systems these days provide some form of graphical user interface, although in many
cases a command-line interface is also available.
In these operating systems, there are services available to allow processes to do graphical work. Although
there are primitive services such as line and rectangle drawing, most GUI interfaces provide an abstract
concept known as the window.
The window is a logical, rectangular, drawing area. Processes can create one or more windows, of any size.
The operating system may decorate each window with borders, and these may include iconswhich allow
the window to be destroyed, resized, or hidden.
The operating system must map these logical windows onto the physical display area provided by the video
card and computer monitor. As well, the operating system must direct the input from the user (in the form
of keyboard input, and mouse operations) to the appropriate window: this is known as changing the
input focus.
From a programmer's point of view, an operating system is defined mainly by the Application Program
Interface (API) that it provides, and to a lesser extent what library routines are available.
It follows, therefore, that a number of different operating system products may provide exactly the same
Application Program Interface, and thus appear to be the same operating system to the programmer. The
most obvious example of this is Unix.
Unix is really not a single operating system, but rather a collection of operating systems that share a
common API. This API has now been standardised, and is known as the POSIX standard. Solaris, Linux,
Minix, Mac OS X and FreeBSD are all examples of Unix operating systems.
What this means is that a program written to run on one Unix platform can be recompiled and will run on
another Unix system. As long as the set of systems calls are the same on both systems, the program will run
on both systems.
Another group of operating systems which share a common API are the Windows systems from Microsoft:
Windows CE, Windows 2K, Windows XP and Windows 7. Although each one is structurally different, a
program can be written to run on all three.
The operating system must hide the actual computer from the users and their programs, and present an
abstract interface to the user instead. The operating system must also ensure fair resource allocation to users
and programs. The operating system must shield each user and her programs from all other users and
programs.
Therefore, the operating system must prevent all access to devices by user programs. It must also limit each
program's access to main memory, to only that program's memory locations.
These restrictions are typically built into the CPU (i.e into unchangeable hardware) as two operating
modes: user and kernel mode. In kernel mode, all memory is visible, all devices are visible, all instructions
can be executed. The operating system must run in kernel mode, why? In user mode, all devices are
hidden, and most of main memory is hidden. This is performed by the Memory Management Unit, of which
we will learn more later. Instructions relating to device access, interrupt handling and mode changing
cannot be executed either.
When a user program run as a process, the operating system forces the process to run in user mode. Any
attempt to violate the user mode will cause an exception, which is caught by the operating system. Thus, the
operating system can thus determine when user mode violations have been attempted.
Note: Every interrupt or exception causes the CPU to switch from its current mode into kernel mode. Why?
This ensures that the operating system, and never a user process, will catch the event. This ensures that user
processes cannot hijack the operation of the system.
Finally, because a process runs in user mode and can only see its own memory, it cannot see the operating
system's instructions or data. This prevents nosy user programs from subverting the working of the
operating system.
If the operating system is protected, how does a process ask for services from the OS? User programs can't
call functions within the operating system's memory, because it can't see those areas of memory.
Even worse, the operating system executes in kernel mode, which the user mode process cannot reach.
To solve the problem, all computers with a user mode/kernel mode split have a special user-mode machine
instruction, known as a TRAP instruction.
When the TRAP instruction is executed in user mode, an exception occurs. The CPU switches to kernel
mode, and sets the Program Counter to a specific location. The CPU continues executing instructions
starting at this specific location, which is always somewhere in the operating system.
The TRAP instruction merely provides the mechanism to get to the operating system from user mode.
However, the operating system has to be told exactly what services a user mode process wants.
Consider the following C command to read nbytes of data from the file fd into the buffer. This requires the
services of the operating system to get the data from the disk and place it into the buffer.
To perform the read() operation, the process first pushes the arguments to the operation onto the stack
(steps 1-3 below). The process then calls the read() system call, which is normally written in assembly code
(step 4 below).
The system call places a number identifying the read() operation into a register (step 5), and then executes
the TRAP instruction (step 6). The CPU jumps to a fixed location within the kernel. Once in the kernel,
the dispatch handler uses the register value as an index into a table of system calls (step 7), and calls the
correct kernel function (step 8).
The kernel is now able to perform the read() request, and as it is running in kernel mode, it can look at the
arguments to read() which are on the stack, and it can also command the hard drive to fetch the appropriate
data.
When the data has been read in and copied into the buffer, the kernel needs to return to user mode, and
resume the execution of the process. A new machine instruction called ReTurn from Interrupt (RTI) does
this (step 9). Back in user mode, the CPU is now executing the next instruction after the TRAP, but is still
inside the read() system call. Any return value from the kernel is collected, and the system call returns to
the original calling function (step 10).
Remember, the TRAP instruction ensures that the only access to the privileged operating system is via a
single, well-protected entry point. It is up to the kernel to inspect the arguments provided by the user
process, and to ensure that they are valid.
The implementation of an operating system is completely up to its designers, and throughout the course we
will look at some of the design decisions that must be made when creating an operating system.
In general, none of the implementation details of an operating system are visible to the programmer or user:
these details are hidden behind the operating system's Application Program Interface. The API fixes the
"look" of the operating system, as seen by the programmer.
This API, however, can be implemented by very different operating system designs. So, for example,
Solaris, Linux and FreeBSD all provide a POSIX API, but all three systems have a very different operating
system architecture.
We will examine the two most common operating system designs, the monolithic model and the client-
server model.
In the monolithic model, the operating system is written as a collection of routines, each of which can call
any of the other routines as required. At build-time, each routine is compiled, and then they are all linked
together to create a single program called the operating system kernel.
When the operating system is started, this kernel is loaded into the computer's memory, and runs in kernel
mode. Most versions of Unix, including Linux, use the monolithic design model.
The monolithic design model suffers from the fact that every part of the operating system can see all the
other parts; thus, a bug in one part may destroy the data that another part is using. Recompilation of the
operating system can also be slow and painful.
To reduce this shortcoming, most designers place some overriding structure on their operating system
design. Many of the routines and data structures are `hidden' in some way, and are visible only to the other
routines that need them.
An abstract map of Unix's architecture is shown in the diagram below. As you can see, the functionality
provided by the kernel is broken up into a number of sections. Each section provides a small number of
interface routines, and it is these routines which can be used by the other sections.
Because Unix is monolithic, nothing stops one section of the operating system from calling another
with function calls, or using another section's data. Each box is a set of C source files.
The upper-half of the kernel is the portion that runs in kernel mode but which is invoked by a system call.
The lower-half of the kernel is the portion that reacts to exceptions and interrupts.
This is an important distinction which we will return to.
An alternative method of operating system design, called the client-server model, tries to minimise the
chance of a bug in one part of the operating system from corrupting another part.
In this model, most of the operating system services are implemented as privileged processes
called servers. Remember, each process is protected against interference by other processes. These servers
have some ability to access the computer's hardware, which ordinary processes cannot.
Ordinary processes are known as clients. These send requests in the form of messages to the servers, which
do the work on their behalf and return a reply.
The set of services that the servers provide to the user processes thus form the operating system's
Application Program Interface.
The messages sent between the clients and servers are well-defined `lumps' of data. These must be copied
between the client and the server. This copying can slow the overall system down, when compared to a
monolithic system where no such copying is required. The servers themselves also may need to
intercommunicate.
There must be a layer in the operating system that does message passing. This model can be implemented
on top of a single machine, where messages are copied from a client's memory are into the server's memory
area. The client-server model can also be adapted to work over a network or distributed system where the
processes run on several machines.
Windows 2K uses the client-server model, as shown in the diagram below. Most of the subsystems are
privileged processes. Other client-server based operating systems are Minix and Plan 9.
2.11 Microkernels
You will have noticed that most, if not all, of an operating system appears to run in kernel mode.
This is not exactly necessary. The only code which has to run in kernel mode is that which:
o has to deal with hardware directly: I/O, interrupts, exceptions, syscall catching, memory
permissions.
o enforces security restrictions at the hardware level.
There is a lot of operating system software which deals with the OS abstractions, e.g. files, directories,
windows, and which does not really need to run in kernel mode.
Where a kernel does little more than process scheduling, basic memory management, interrupt handling
and message passing, it is called a microkernel.
The code which deals with higher-level abstractions such as files, virtual memory, windows etc. can run in
user mode. Message passing is used to pass requests from the user-mode programs to the user-mode parts
of the operating system.
Minix and QNX are examples of microkernels.
FUNCTIONS: Operating System supports the basic functions of the computer and is a low-level software. The
functions of operating systems are as described below:
i) I/O Management:
OS manages I/O devices and makes the I/O process effective. OS accepts the input from the input device, stores it in
the main memory, ask the CPU to process it and finally provides the result to the output devices for output.
v) Time Sharing:
OS manages the time of CPU. The kernel OS checks frequency for other processes requesting CPU time. Time-
sharing checks for CPU request from higher priority processes that are made every 10 milliseconds. When two or
more processes at the same priority level are competing for the CPU time, CPU time is sliced into segments, defined
by time slice and passed from process to process in a round robin fashion, preventing a single process from
monopolizing the CPU until it blocks or terminates.
vi) Security:
OS makes sure that only authorized users get access to the computer and its data and the users only do things they
are authorized to do.
a) Pre-empetive multitasking: In the pre-empetive multitasking, the OS allows CPU times slice to each program.
After each time slice, CPU executes another task. Example: Windows XP
b) Co-operative multitasking: In co-operative multitasking a task can control CPU as long as it requires . However,
it will free CPU to execute another program if it doesn’t require CPU. Exaample: windows 3.x, multifinder,etc.
v) Multithreading:
A program in execution is known as process. A process can be further divided into multiple sub-processers. These
sub-processers are known as threads. A multi-threading OS can divide process into threads and execute those
threads. This increases operating speed but also increases the complexity. For example: Unix, Server edition of
Linux and windows.
Batch O.S.:- By the early 1950's, the General Motors Research Laboratories implemented the first Single-Stream
batch processing systems. It ran a single job at a time and data were submitted in the form of groups or batches.
Batch operating system overcomes the problem of setup time.
The First operating system of the second-generation computer is the batch operating system. Batch operating system
took the input on the punch card. Each punch card had the different form of data. System executed the jobs one by
one in batch. When one job from the batch executed, then the second job has taken from it and so on. The process of
placing the jobs in queue for execution is known as spooling.
How its work: OS keeps the number of jobs in memory and executes them one by one. Jobs processed in first come
first served order. Each set of a job considered as a batch. When a job completes its execution, its memory is
released, and the output for the job gets copied into an output spool for later printing or processing. User interaction
in the batch processing system is minimal. One’s system accepts the jobs from users, and then the user is free. That
is why we can use batch processing system in large organizations in these days.
The batch processing system used where we want to update the data related to any transactions or any record.
Transactions can be related to any customer orders, receipts, invoices, payments, online transactions, data entry,
payroll system, banks etc.
Advantages:
Disadvantages:
1) Difficult to debug.
2) If a job gets to enter in an infinite loop, other jobs wait for unknown time.
3) Batch systems are costly.
Interactive:- An interactive operating system is one that allows the user to directly interact with the operating
system whilst one or more programs are running.
There will be an user interface in place to allow this to happen. It could be a command line style of interface or it
could be a graphical interface.
Time sharing:- Time sharing (or multitasking) OS is a logical extension of multiprogramming. It provides extra
facilities such as:
Faster switching between multiple jobs to make processing faster.
Allows multiple users to share computer system simultaneously.
The users can interact with each job while it is running. These systems use a concept of virtual memory for
effective utilization of memory space. Hence, in this OS, no jobs are discarded. Each one is executed using virtual
memory concept. It uses CPU scheduling, memory management, disc management and security management.
Examples: CTSS, MULTICS, CAL, UNIX etc.
Real Time System:- Real-time operating system (RTOS) - Real-time operating systems are used to
control machinery, scientific instruments and industrial systems. An RTOS typically has very little user-
interface capability, and no end-user utilities, since the system will be a "sealed box" when delivered for
use. A very important part of an RTOS is managing the resources of the computer so that a particular
operation executes in precisely the same amount of time, every time it occurs. In a complex machine,
having a part move more quickly just because system resources are available may be just as catastrophic as
having it not move at all because the system is busy.
Single-user, single task - As the name implies, this operating system is designed to manage the computer
so that one user can effectively do one thing at a time. The Palm OS for Palm handheld computers is a good
example of a modern single-user, single-task operating system.
Single-user, multi-tasking - This is the type of operating system most people use on their desktop and
laptop computers today. Microsoft's Windows and Apple's MacOS platforms are both examples of
operating systems that will let a single user have several programs in operation at the same time. For
example, it's entirely possible for a Windows user to be writing a note in a word processor while
downloading a file from the Internet while printing the text of an e-mail message.
Multi-user - A multi-user operating system allows many different users to take advantage of the
computer's resources simultaneously. The operating system must make sure that the requirements of the
various users are balanced, and that each of the programs they are using has sufficient and separate
resources so that a problem with one user doesn't affect the entire community of users. Unix, VMS and
mainframe operating systems, such as MVS, are examples of multi-user operating systems.
Multiprocessor Systems:- Multiprocessor operating systems are also known as parallel OS or tightly coupled OS.
Such operating systems have more than one processor in close communication that sharing the computer bus, the
clock and sometimes memory and peripheral devices. It executes multiple jobs at same time and makes the
processing faster. Multiprocessor systems have three main advantages:
Increased throughput: By increasing the number of processors, the system performs more work in less time. The
speed-up ratio with N processors is less than N.
Economy of scale: Multiprocessor systems can save more money than multiple single-processor systems, because
they can share peripherals, mass storage, and power supplies.
Increased reliability: If one processor fails to done its task, then each of the remaining processors must pick up a
share of the work of the failed processor. The failure of one processor will not halt the system, only slow it down.
The ability to continue providing service proportional to the level of surviving hardware is called graceful
degradation. Systems designed for graceful degradation are called fault tolerant.
Multiuser Systems:- A Multi-user operating system is a computer operating system which allows multiple users to
access the single system with one operating system on it. It is generally used on large mainframe computers.
Example: Linux, Unix, Windows 2000, Ubuntu, Mac OS etc.,
In the multi-user operating system, different users connected at different terminals and we can access, these users
through the network as shown in the diagram.
Features of the Multi-user Operating System
• Multi-tasking- Using multi-user operating system we can perform multiple tasks at a time, i.e. we can run more
than one program at a time.
Example: we can edit a word document while browsing the internet.
• Resource sharing- we can share different peripherals like printers, hard drives or we can share a file or data. For
this, each user is given a small time slice of CPU time.
• Background processing- It means that when commands are not processed firstly, then they are executed in the
background while another programs are interacting with the system in the real time.
Firstly, it must be loaded enough in structure to reflect the actual relationships of the data with the real world
object.
Secondly, the formation should be simple enough so that anyone can efficiently process the data each time it is
necessary.
The first way is to provide the linear relationships among all the elements represented using linear memory
location. These linear structures are termed as arrays.
The second technique is to provide a linear relationship among all the elements represented by using the concept
of pointers or links. These linear structures are termed as linked lists.
The common examples of the linear data structure are:
Arrays
Queues
Stacks
Linked lists
Graphs
the family of trees and
table of contents
Tree: In this case, data often contain a hierarchical relationship among various elements. The data structure that
reflects this relationship is termed as a rooted tree graph or a tree.
Graph: In this case, data sometimes hold a relationship between the pairs of elements which is not necessarily
following the hierarchical structure. Such a data structure is termed as a Graph.
Basic Operations of Data Structures: Some specific operations process all data in the data structures. The specific
data structure that has been chosen mostly depends on the number of time of the occurrence of the operation which
needs to be carried out on the data structure. Names of such operations are listed below:
Traversing Deletion
Searching Sorting
Insertion Merging
Basic Terminology:
Applications of Stack
1. Conversion of polish notations
There are three types of notations:
> Infix notation - Operator is between the operands : x + y
> Prefix notation - Operator is before the operands : + xy
> Postfix notation - Operator is after the operands : xy +
2. To reverse a string
A string can be reversed by using stack. The characters of string pushed on to the stack till the end of the string. The
characters are popped and displays. Since the end character of string is pushed at the last, it will be printed first.
Algorithms
In stack related algorithms TOP initially point 0, index of elements in stack is start from 1, and index of last element
is MAX.
INIT_STACK (STACK, TOP)
Algorithm to initialize a stack using array.
TOP points to the top-most element of stack.
TOP: = 0;
Exit
Pop operation is used to remove an item from stack, first get the element and then decrease TOP pointer.
POP_STACK(STACK,TOP,ITEM)
Algorithm to pop an element from stack.
IF TOP = 0 then
Print “Stack is empty”;
Exit;
Otherwise
ITEM: =STACK (TOP);
TOP:=TOP – 1;
End of IF
Exit
IS_FULL(STACK,TOP,MAX,STATUS)
Algorithm to check stack is full or not.
STATUS contains the result status.
IF TOP = MAX then
STATUS:=true;
Otherwise
STATUS:=false;
End of IF
Exit
IS_EMPTY(STACK,TOP,MAX,STATUS)
Algorithm to check stack is empty or not.
STATUS contains the result status.
IF TOP = 0 then
STATUS:=true;
Otherwise
STATUS:=false;
End of IF
Exit
2. QUEUE:
Array Implementation of Queue: In Array implementation FRONT pointer initialized with 0 and REAR
initialized with -1.
Note: In case of empty queue, front is one position ahead of rear : FRONT = REAR + 1;
Drawback of Linear Queue/ Queue: The linear queue suffers from serious drawback that performing some
operations, we cannot insert items into queue, even if there is space in the queue. Suppose we have queue of 5
elements and we insert 5 items into queue, and then delete some items, then queue has space, but at that condition
we cannot insert items into queue.
1. Initialize operation
2. Addition or insertion operation.
3. Deletion operation.
4. Is_full check.
5. Is_empty check.
Algorithms: In algorithm implementation first item of queue starts from 1, and in program implementation first
item will be start from 0.
1. INIT(QUEUE,FRONT,REAR)
2. INSERT-ITEM(QUEUE,FRONT,REAR,MAX,ITEM)
3. REMOVE-ITEM(QUEUE,FRONT,REAR,ITEM)
4. FULL-CHECK(QUEUE,FRONT,REAR,MAX,FULL)
5. EMPTY-CHECK(QUEUE,FRONT,REAR,EMPTY)
INIT(QUEUE,FRONT,REAR)
This algorithm is used to initialize a QUEUE, FRONT, and REAR.
1. FRONT := 1;
2. REAR := 0;
3. Return;
INSERT-ITEM(QUEUE,FRONT,REAR,MAX,ITEM)
This algorithm is used to add or insert item to QUEUE.
1. If (REAR = MAX) then
a. Display “Queue overflow”;
b. Return;
2. Otherwise
a. REAR := REAR + 1;
b. QUEUE(REAR) := ITEM;
3. Return;
REMOVE-ITEM(QUEUE,FRONT,REAR,ITEM)
This algorithm is used to delete an item from QUEUE.
1. If (FRONT = REAR + 1) then
a. Display “Queue underflow”;
b. Return;
2. Otherwise
a. ITEM := QUEUE(FRONT);
b. FRONT := FRONT + 1;
3. Return;
EMPTY-CHECK(QUEUE,FRONT,REAR,EMPTY)
This algorithm is used to check whether
a QUEUE is EMPTY or not.
1. If (FRONT = REAR + 1) then
a. EMPTY := true;
2. Otherwise
a. EMPTY := false;
3. Return;
FULL-CHECK(QUEUE,FRONT,REAR,MAX,FULL)
This algorithm is used to check whether
a QUEUE is full or not.
1. If ( REAR = MAX ) then
a. FULL := true;
2. Otherwise
a. FULL := false;
3. Return;
Circular Queue
The queue is considered as a circular queue when the positions 0 and MAX-1 are adjacent. Any position before front
is also after rear.
Note: that the container of items is an array. Array is stored in main memory. Main memory is linear. So this
circularity is only logical. There cannot be physical circularity in main memory.
See the logical circularity of the queue. Addition causes the increment in REAR. It means that when REAR
reaches MAX-1 position then Increment in REAR causes REAR to reach at first position that is 0.
As we know that, Deletion causes the increment in FRONT. It means that when FRONT reaches the MAX-1
position, then increment in FRONT, causes FRONT to reach at first position that is 0.
if( front == MAX -1 )
front = 0;
else
front = front + 1;
Algorithms
INIT(QUEUE,FRONT,REAR,COUNT)
INSERT-ITEM(QUEUE, FRONT, REAR, MAX, COUNT, ITEM)
REMOVE-ITEM(QUEUE, FRONT, REAR, COUNT, ITEM)
FULL-CHECK(QUEUE,FRONT,REAR,MAX,COUNT,FULL)
EMPTY-CHECK(QUEUE,FRONT,REAR,MAX,COUNT,EMPTY)
INIT(QUEUE,FORNT,REAR,COUNT)
This algorithm is used to initialize circular queue.
1. FRONT := 1;
2. REAR := 0;
3. COUNT := 0;
4. Return;
INSERT-ITEM( QUEUE, FRONT, REAR, MAX, COUNT, ITEM)
This algorithm is used to insert or add item
into circular queue.
1. If ( COUNT = MAX ) then
a. Display “Queue overflow”;
b. Return;
2. Otherwise
a. If ( REAR = MAX ) then
i. REAR := 1;
b. Otherwise
i. REAR := REAR + 1;
c. QUEUE(REAR) := ITEM;
d. COUNT := COUNT + 1;
3. Return;
EMPTY-CHECK(QUEUE,FRONT,REAR,MAX,COUNT,EMPTY)
This is used to check queue is empty or not.
1. If( COUNT = 0 ) then
a. EMPTY := true;
2. Otherwise
a. EMPTY := false;
3. Return ;
FULL-CHECK(QUEUE,FRONT,REAR,MAX,COUNT,FULL)
This algorithm is used to check queue is full or not.
1. If ( COUNT = MAX ) then
a. FULL := true;
2. Otherwise
a. FULL := false;
3. Return ;
LINKED LIST: A linked list is a data structure used for storing data. A linked list has the following properties:
Before discussing link list it’s necessary to differentiate link list and array. Both are used for same purpose, but we
need to differentiate their usage, their operations. That means where using array is suitable and where linked list.
Disadvantage of Arrays:
The main disadvantage is that the access time for any single element in a link list is not constant like an
array.
Link list somehow needs additional code to be implemented.
Types of Linked List – There are three common types of Linked List.
Singly Linked List
Doubly Linked List
Circular Linked List
Singly Linked List: It is the most common. Each node has data and a pointer to the next node.
singly linked list
struct node {
int data;
struct node *next;
}
A three member singly linked list can be created as:
/* Initialize nodes */
struct node *head;
struct node *one = NULL;
struct node *two = NULL;
struct node *three = NULL;
/* Allocate memory */
one = malloc(sizeof(struct node));
two = malloc(sizeof(struct node));
three = malloc(sizeof(struct node));
/* Assign data values */
one->data = 1;
two->data = 2;
three->data = 3;
/* Connect nodes */
one->next = two;
two->next = three;
three->next = NULL;
/* Save address of first node in head */
head = one;
Doubly Linked List
We add a pointer to the previous node in a doubly linked list. Thus, we can go in either direction: forward or
backward.
A node is represented as
struct node {
int data;
struct node *next;
struct node *prev;
}
A three member doubly linked list can be created as
/* Initialize nodes */
struct node *head;
struct node *one = NULL;
struct node *two = NULL;
struct node *three = NULL;
/* Allocate memory */
one = malloc(sizeof(struct node));
two = malloc(sizeof(struct node));
three = malloc(sizeof(struct node));
/* Assign data values */
one->data = 1;
two->data = 2;
three->data = 3;
/* Connect nodes */
one->next = two;
one->prev = NULL;
two->next = three;
two->prev = one;
three->next = NULL;
three->prev = two;
/* Save address of first node in head */
head = one;
Circular Linked List
A circular linked list is a variation of linked list in which the last element is linked to the first element. This forms a
circular loop.
for singly linked list, next pointer of last item points to the first item
In doubly linked list, prev pointer of first item points to last item as well.
A three member circular singly linked list can be created as:
/* Initialize nodes */
struct node *head;
struct node *one = NULL;
struct node *two = NULL;
struct node *three = NULL;
/* Allocate memory */
one = malloc(sizeof(struct node));
two = malloc(sizeof(struct node));
three = malloc(sizeof(struct node));
/* Assign data values */
one->data = 1;
two->data = 2;
three->data = 3;
/* Connect nodes */
one->next = two;
two->next = three;
three->next = one;
/* Save address of first node in head */
head = one;
In all of the examples, we will assume that the linked list has three nodes 1 --->2 --->3 with node structure as below:
struct node
{
int data;
struct node *next;
};
How to traverse a linked list
Displaying the contents of a linked list is very simple. We keep moving the temp node to the next one and display its
contents.
When temp is NULL, we know that we have reached the end of linked list so we get out of the while loop.
You can add elements to either beginning, middle or end of linked list.
Add to beginning
Allocate memory for new node
Store data
Change next of new node to point to head
Change head to point to recently created node
struct node *newNode;
newNode = malloc(sizeof(struct node));
newNode->data = 4;
newNode->next = head;
head = newNode;
Add to end
Allocate memory for new node
Store data
Traverse to last node
Change next of last node to recently created node
struct node *newNode;
newNode = malloc(sizeof(struct node));
newNode->data = 4;
newNode->next = NULL;
struct node *temp = head;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = newNode;
Add to middle
Allocate memory and store data for new node
Traverse to node just before the required position of new node
Change next pointers to include new node in between
struct node *newNode;
newNode = malloc(sizeof(struct node));
newNode->data = 4;
struct node *temp = head;
for(int i=2; i < position; i++) {
if(temp->next != NULL) {
temp = temp->next;
}
}
newNode->next = temp->next;
temp->next = newNode;
How to delete from a linked list
You can delete either from beginning, end or from a particular position.
1. Elementary Data Items: These data items can’t be further sub-divided. For e.g. ROLL
NUMBER.
2. Group Data Items: These data items can be further sub-divided into elementary data items. For
example: DATE may be divided into Days, Months and Years.
3. Record: Record is a collection of related data items. E.g. a student record for a student’s contains data fields such
as name, age, sex, class etc.
4. File (Data File): File is collection of logically related records. E.g. a payroll file might consist of the employee
pay records for a company.
5. Entity: An entity is a person, place, thing, event or concept about which information recorded.
7. Data Value: A data value is the actual data or information contained in each attribute.
Example:
Entity : Employee
Attributes: Id, Name, Age
Value: 1, ABC, 18
8. Entity Set: Entities with similar attributes form an entity set. For example, All the employees in an organization
form an entity set.
Introduction to Algorithm –
Introduction: Algorithms, It is a combination of a sequence of finite steps to solve a particular problem. or, It is a
well-defined procedure which takes zero or more input and must produce at least one output to solve a particular
problem.
Properties/Characteristics of Algorithms
Input: It may take zero or more input.
Output: It must produce at least one output.
Definiteness (Unambiguous): Every step in algorithm should be well defined, unique, precise.
Finiteness (Limited): Every algorithm should contain a finite number of steps and should produce a result
infinite amount of time.
Effectiveness: Operations used in algorithm must be simple and easy to understand.
Language independent.
Note:
An algorithm is a step by step procedure to solve a particular problem whereas a program is an algorithm
that is encoded in any programming language.
Program is language dependent and algorithm is language independent.
Notation of an Algorithm
1. Name of the algorithm: It should specify the problem to be solved.
2. Step no.: It is an identification tag ( step numbering ) that specify the numbering of steps/statements. It is a
positive integer.
3. Explanatory comments: It is used to specify the meaning of instruction that is used in the algorithm. It is
used to understand the logic of operations by the use of [ ] for comments in the algorithm.
4. Termination: Generally it is a STOP statement and the last statement of an algorithm that denoted ending
of the algorithm.
Example
Algorithm for addition of two numbers:
ADD( A , B )
Analysis of Algorithms: Why Analyze an Algorithm? The most straightforward reason for analyzing an algorithm
is to discover its characteristics in order to evaluate its suitability for various applications or compare it with other
algorithms for the same application. Moreover, the analysis of an algorithm can help us understand it better, and can
suggest informed improvements. Algorithms tend to become shorter, simpler, and more elegant during the analysis
process.
Computational Complexity. The branch of theoretical computer science where the goal is to classify algorithms
according to their efficiency and computational problems according to their inherent difficulty is known as
computational complexity. Paradoxically, such classifications are typically not useful for predicting performance or
for comparing algorithms in practical applications because they focus on order-of-growth worst-case performance.
In this book, we focus on analyses that can be used to predict performance and compare algorithms.
Analysis of Algorithms. A complete analysis of the running time of an algorithm involves the following steps:
Implement the algorithm completely.
Determine the time required for each basic operation.
Identify unknown quantities that can be used to describe the frequency of execution of the basic operations.
Develop a realistic model for the input to the program.
Analyze the unknown quantities, assuming the modelled input.
Calculate the total running time by multiplying the time by the frequency for each operation, then adding
all the products.
Classical algorithm analysis on early computers could result in exact predictions of running times. Modern systems
and algorithms are much more complex, but modern analyses are informed by the idea that exact analysis of this sort
could be performed in principle.
Analysis of algorithms can be defined as a theoretical study of computer-program performance and
resource usage.
So, I’ve written word performance in above definition in bold words. Simply because our main focus throughout this
article would be about computer program performance.
But, before we start talking about it, can you think of any other thing more important than the performance in
programming?
Um, like the program maybe super-duper fast, but gives wrong output?
Will this work? No!
There are many things like correctness, simplicity, maintainability, robustness, security, functionality and most
important user-friendliness which is way more important than the performance of the program.
Example: Whatsapp chat of two friends is regular thing to calculate performance of friendship.
The Whatsapp works as it is supposed to be, but still, Developers plans to redesign it. Because based on feedback,
they found out the app was a little hard to understand and they plan to improve it by making it easier to use. Here,
user-friendliness clearly outweighs algorithms.
So, clearly, performance lies at the bottom of the heap as compared to above -mentioned features. Then, why am I
writing a post about performance then?
Armed with this knowledge, let’s try to analyze a simple problem of sorting:
Now, we are going to use an algorithm called Bubble Sort. I’ll write this algorithm in pseudo-code(kind of
programming language written in English)
Here, the input will have a sequence of numbers and output will give a sorted list of numbers. The function
Bubblesort accepts an array of data as input and will generate a sorted list of numbers.
Here our input to our BubbleSort function is {6, 5,3}. We want our algorithm to give us our desired output, sorted list
like this {3,5,6}
Round 1:
# Our aim to to sort our list from smallest to largest. If we find numbers out of order, we swap them.# Start with first
element and compare it with next.
{**6, 5**, 3}
# Compare 6 and 5. Since 6 > 5 -> Perform swap
{5, 6, 3}
# Now,look at second and third element and compare.
{5, **6, 3**}
# Compare 6 and 3. Since 6 > 3 -> Perform swap
{5, 3, 6}
# Round 1 output:{5, 3, 6}
# The list is still not sorted.
Here, we start off by comparing first and second number, 6 and 5 in our case and swap them as they are out of order.
We proceed with comparing 2nd and 3rd element,6 and 3 and swap them too as 3 is a smaller number than 6. We
continue this till we reach the last element and we get a list {5,3,6} like this.
The list is still not sorted and we continue with the similar approach till the entire list gets sorted.
Round 2:
# First round gave us list {5, 3, 6}. We continue with our steps of comparing and swapping if we find elements out of order
# Start with first element and compare it with next.
{**5, 3**, 6}
# Compare 5 and 3. Since 5 > 3-> Perform swap
{3, 5, 6}
# Now,look at second and third element and compare.
{3, **5, 6**}
# Compare 5 and 6. Since 5 < 6 -> NO SWAPPING
{3, 5, 6}
# The list is sorted now. We got our desired output.
Our List is finally sorted.
Simple, right? (In case, you are finding it difficult to understand Bubble Sort or want to know more about it, I’ve
covered all its nitty-gritty in this post.)
1. Depends on Input :
Now let’s say the input list({3, 5, 6})given to our Bubble sort was already sorted. In this case, Bubble sort doesn’t
have much to do. But, what if the input list(6,5,3) is reverse sorted. Bubble sort will have to do a lot of work to give
us a sorted list as each element needs to be swapped.
Design of Algorithms: Before designing an algorithm it is important to first understand what the problem is.
Algorithms can be designed using pseudocode or a flowchart, and the standard notations of each should be known.
Pseudocode: Most programs are developed using programming languages. These languages have
specific syntax that must be used so that the program will run properly. Pseudocode is not a programming language,
it is a simple way of describing a set of instructions that does not have to use specific syntax.
There is no strict set of standard notations for pseudocode, but some of the most widely recognised are:
INPUT – indicates a user will be inputting something
OUTPUT – indicates that an output will appear on the screen
WHILE – a loop (iteration that has a condition at the beginning)
FOR – a counting loop (iteration)
REPEAT – UNTIL – a loop (iteration) that has a condition at the end
IF – THEN – ELSE – a decision (selection) in which a choice is made
any instructions that occur inside a selection or iteration are usually indented
Using pseudocode
Pseudocode can be used to plan out programs. Planning a program that asks people what the best subject they take
is, would look like this in pseudocode:
REPEAT
OUTPUT 'What is the best subject you take?'
INPUT user inputs the best subject they take
STORE the user's input in the answer variable
IF answer = 'Computer Science' THEN
OUTPUT 'Of course it is!'
ELSE
OUTPUT 'Try again!'
UNTIL answer = 'Computer Science'
Complexity of Algorithms: The complexity of an algorithm computes the amount of time and spaces required by
an algorithm for an input of size nn. The complexity of an algorithm can be divided into two types. The time
complexity and the space complexity.
Lets start with a simple example. Suppose you are given an array A and an integer x and you have to find if xexists
in array A.
Simple solution to this problem is traverse the whole array A and check if the any element is equal to x.
for i : 1 to length of A
if A[i] is equal to x
return TRUE
return FALSE
Each of the operation in computer take approximately constant time. Let each operation takes c time. The number of
lines of code executed is actually depends on the value of x. During analyses of algorithm, mostly we will consider
worst case scenario, i.e., when x is not present in the array A. In the worst case, the if condition will run N times
where N is the length of the array A. So in the worst case, total execution time will be (N∗c+c). N∗c for
the if condition and c for the return statement ( ignoring some operations like assignment of i ).
As we can see that the total time depends on the length of the array A. If the length of the array will increase the
time of execution will also increase.
Order of growth is how the time of execution depends on the length of the input. In the above example, we can
clearly see that the time of execution is linearly depends on the length of the array. Order of growth will help us to
compute the running time with ease. We will ignore the lower order terms, since the lower order terms are relatively
insignificant for large input. We use different notation to describe limiting behavior of a function.
O-notation:
To denote asymptotic upper bound, we use O-notation. For a given function g(n), we denote by O(g(n))(pronounced
“big-oh of g of n”) the set of functions:
O(g(n))= { f(n) : there exist positive constants c and n0 such that 0≤f(n)≤c∗g(n) for all n≥n0 }
Ω-notation:
To denote asymptotic lower bound, we use Ω-notation. For a given function g(n), we denote by Ω(g(n))(pronounced
“big-omega of g of n”) the set of functions:
Ω(g(n))= { f(n) : there exist positive constants c and n0 such that 0≤c∗g(n)≤f(n) for all n≥n0 }
Θ-notation:
To denote asymptotic tight bound, we use Θ-notation. For a given function g(n), we denote by Θ(g(n))(pronounced
“big-theta of g of n”) the set of functions:
Θ(g(n))= { f(n) : there exist positive constants c1,c2 and n0 such that 0≤c1∗g(n)≤f(n)≤c2∗g(n) for all n>n0 }
While analysing an algorithm, we mostly consider O-notation because it will give us an upper limit of the execution
time i.e. the execution time in the worst case.
To compute O-notation we will ignore the lower order terms, since the lower order terms are relatively insignificant
for large input.
Let f(N)=2∗N2+3∗N+5
O(f(N))=O(2∗N2+3∗N+5)=O(N2)
int count = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < i; j++)
count++;
Total number of times count++ will run is 0+1+2+...+(N−1)=N∗(N−1)2. So the time complexity will be O(N2).
2.
int count = 0;
for (int i = N; i > 0; i /= 2)
for (int j = 0; j < i; j++)
count++;
This is a tricky case. In the first look, it seems like the complexity is O(N∗logN). N for the j′s loop
and logNfor i′s loop. But its wrong. Lets see why.
Total number of times count++ will run is N+N/2+N/4+...+1=2∗N. So the time complexity will be O(N).
The table below is to help you understand the growth of several common time complexities, and thus help you judge
if your algorithm is fast enough to get an Accepted ( assuming the algorithm is correct ).
Length of Input (N) Worst Accepted Algorithm
≤[10..11] O(N!),O(N6)
≤[15..18] O(2N∗N2)
≤[18..22] O(2N∗N)
≤100 O(N4)
≤400 O(N3)
≤2K O(N2∗logN)
≤10K O(N2)
≤1M O(N∗logN)
≤100M O(N),O(logN),O(1)
Asymptotic Notations: The main idea of asymptotic analysis is to have a measure of efficiency of algorithms that
doesn’t depend on machine specific constants, and doesn’t require algorithms to be implemented and time taken by
programs to be compared. Asymptotic notations are mathematical tools to represent time complexity of algorithms
for asymptotic analysis. The following 3 asymptotic notations are mostly used to represent time complexity of
algorithms.
Theta Notation
1) Θ Notation: The theta notation bounds a function from above and below, so it defines exact asymptotic behavior.
A simple way to get Theta notation of an expression is to drop low order terms and ignore leading constants. For
example, consider the following expression.
3n3 + 6n2 + 6000 = Θ(n3)
Dropping lower order terms is always fine because there will always be a n0 after which Θ(n3) has higher values
than Θn2) irrespective of the constants involved.
For a given function g(n), we denote Θ(g(n)) is following set of functions.
The above definition means, if f(n) is theta of g(n), then the value f(n) is always between c1*g(n) and c2*g(n) for
large values of n (n >= n0). The definition of theta also requires that f(n) must be non-negative for values of n
greater than n0.
2) Big O Notation: The Big O notation defines an upper bound of an algorithm, it bounds a function only from
above. For example, consider the case of Insertion Sort. It takes linear time in best case and quadratic time in worst
case. We can safely say that the time complexity of Insertion sort is O(n^2).
Note that O(n^2) also covers linear time.
If we use Θ notation to represent time complexity of Insertion sort, we have to use two statements for best and worst
cases:
1. The worst case time complexity of Insertion Sort is Θ(n^2).
2. The best case time complexity of Insertion Sort is Θ(n).
The Big O notation is useful when we only have upper bound on time complexity of an algorithm. Many times we
easily find an upper bound by simply looking at the algorithm.
BigOmega
3) Ω Notation: Just as Big O notation provides an asymptotic upper bound on a function, Ω notation provides an
asymptotic lower bound.
Ω Notation can be useful when we have lower bound on time complexity of an algorithm. As discussed in the
previous post, the best case performance of an algorithm is generally not useful, the Omega notation is the least used
notation among all three.
In mathematical relation,
f(n) = o(g(n)) means
lim f(n)/g(n) = 0
n→∞
Examples:
Is 7n + 8 ∈ o(n2)?
In order for that to be true, for any c, we have to be able to find an n0 that makes
f(n) < c * g(n) asymptotically true.
lets took some example,
If c = 100,we check the inequality is clearly true. If c = 1/100 , we’ll have to use
a little more imagination, but we’ll be able to find an n0. (Try n0 = 1000.) From
these examples, the conjecture appears to be correct.
then check limits,
lim f(n)/g(n) = lim (7n + 8)/(n2) = lim 7/2n = 0 (l’hospital)
n→∞ n→∞ n→∞
hence 7n + 8 ∈ o(n2)
Little ω asymptotic notation
Definition : Let f(n) and g(n) be functions that map positive integers to positive real numbers. We say that f(n) is
ω(g(n)) (or f(n) ∈ ω(g(n))) if for any real constant c > 0, there exists an integer constant n0 ≥ 1 such that f(n) > c *
g(n) ≥ 0 for every integer n ≥ n0.
f(n) has a higher growth rate than g(n) so main difference between Big Omega (Ω) and little omega (ω) lies in their
definitions.In the case of Big Omega f(n)=Ω(g(n)) and the bound is 0<=cg(n)<=f(n), but in case of little omega, it is
true for 0<=c*g(n)<f(n).
In mathematical relation,
if f(n) ∈ ω(g(n)) then,
lim f(n)/g(n) = ∞
n→∞
Example:
Prove that 4n + 6 ∈ ω(1);
the little omega(ο) running time can be proven by applying limit formula given below.
if lim f(n)/g(n) = ∞ then functions f(n) is ω(g(n))
n→∞
here,we have functions f(n)=4n+6 and g(n)=1
lim (4n+6)/(1) = ∞
n→∞
and,also for any c we can get n0 for this inequality 0 <= c*g(n) < f(n), 0 <= c*1 < 4n+6
Hence proved.
Growth of function:
The growth of a function is determined by the highest order term: if you add a bunch of terms, the function grows
about as fast as the largest term (for large enough input values).
For example, f(x)=x2+1f(x)=x2+1 grows as fast as g(x)=x2+2g(x)=x2+2 and h(x)=x2+x+1h(x)=x2+x+1, because
for large xx, x2x2 is much bigger than 11, 22, or x+1x+1.
Similarly, constant multiples don't matter that much: f(x)=x2f(x)=x2 grows as fast
as g(x)=2x2g(x)=2x2 and h(x)=100x2h(x)=100x2, because for large xx, multiplying x2x2 by a constant does not
change it "too much" (at least not as much as increasing xx).
Essentially, we are concerned with the shape of the curve:
All three of these functions are lines; their exact slope/y-intercept does not matter.
Only caring about the highest order term (without constant multiples) corresponds to ignoring differences in
hardware/operating system/etc. If the CPU is twice as fast, for example, the algorithm still behaves the same way,
even if it executes faster.