\chapter{Overview of Functions of an Operating System:  Processes}
\label{chap:osprocs} 

\section{Introduction}

\subsection{It's Just a Program!}

\fbox{\parbox{\textwidth}{\bf Throughout this chapter, we are assuming a
single-core machine except when otherwise stated. And we continue to
assume a 32-bit word size for convenience, again except when otherwise
stated.}}

First and foremost, it is vital to understand that an \textbf{operating
system} (OS) is just a program---a very large, very complex program, but
still just a program.  Someone---or more typically, a group of
``someones''---wrote it, probably using the C language.

The OS provides support for the loading and execution of other programs
(which we will refer to below as {}``application programs{}''), and the
OS will set things up so that it has some special privileges which user
programs don't have, but in the end, the OS is simply a program.  

Consider Linux.\footnote{The material in this paragraph is based on the
article ``75\% of Linux Code Now Written by Paid Developers,'' {\it
APC}, January 20, 2010.}  It consists of 2.8 millions lines of code,
mostly C but with some assembly language.  In the early years, almost
all the code was written by volunteers, but today some corporations (the
new volunteers) write most of it.

Another way to see that an OS is just a program is that you can actually
see the binary program file on Linux systems, typically under the name
{\bf vmlinuz}.  Look for it in your Linux machine, say in the directory
{\bf /boot}.

Note carefully that when your program, say \textbf{a.out},\footnote{ Or
it could be a program which you didn't write yourself, say \textbf{gcc}.
} is running, the OS is \textit{not} running, Thus the OS has no power
to suspend your program while your program is running---since the OS
isn't running!\footnote{This is not the case on a multicore system, but
in this chapter we assume a single core.} This is a key concept, so
let's first make sure what the statement even means.

What does it mean for a program to be {}``running{}'' anyway? Recall
that the CPU is constantly performing its fetch/execute/fetch/execute/... 
cycle.  For each fetch, it fetches whatever instruction the Program
Counter (PC) is pointing to. If the PC is currently pointing to an
instruction in your program, then your program is running! Each time an
instruction of your program executes, the circuitry in the CPU will
update the PC, having it point to either the next instruction (the usual
case) or an instruction located elsewhere in your program (in the case
of jumps), but in any case that means your program is still running.

The point is that the only way your program can stop running is if the
PC is changed to point to another program, say the OS. How might this
happen?  There are only two ways this can occur:

\begin{itemize}

\item Your program can \textit{voluntarily} relinquish the CPU to the
OS. It does this via a \textbf{system call}.which is a call to some
function in the operating system which provides some useful service. \\
For example, suppose the C source file from which \textbf{a.out} was
compiled had a call to \textbf{scanf()}. The \textbf{scanf()} function
is a C library function, which was linked into \textbf{a.out}.  But
\textbf{scanf()} itself calls \textbf{read()}, a function within the OS.
So, when \textbf{a.out} reaches the \textbf{scanf()} call, that will
result in a call to the OS.  After the OS does the read from the
keyboard, the OS will return to \textbf{a.out} via a RET or IRET
instruction, and your program will resume running.

\item The other possibility is that a hardware interrupt occurs.  This
is a signal---a physical pulse of current along an interrupt-request
line in the bus---from some input/output (I/O) device such as the
keyboard to the CPU. The circuitry in the CPU is designed to then jump
to a place in memory which we designated upon bootup of the machine.
This will be a place in the OS, so the OS will now run. The OS will
attend to the I/O device, e.g. record the keystroke in the case of the
keyboard, and then return to the interrupted program via an IRET
instruction.

Note in our keystroke example that the keystroke may not have been made
by you.  While your program is running, some other user of the machine
may hit a key.  The interrupt will cause your program to be suspended;
the OS will run the device driver for whichever device caused the
interrupt---the keyboard, if the person was sitting at the console of
the machine, or the network interface card, if the person was logged in
remotely, say via \textbf{ssh}---which will record the keystroke in
the buffer belonging to that other user; and the OS will execute an 
IRET to return from the interrupt, causing your program to resume.

A hardware interrupt can also be generated by the CPU itself, e.g. if
your program attempts to divide by 0, or tries to access memory which
the hardware finds is off limits to your program.  (The latter case
describes a seg fault; more on this later.)

\end{itemize}

\checkpoint

So, when your program is running, it is king. The OS has no power to
stop it, since it is NOT running.  The only ways your program can stop
running is if it voluntarily does so or is forced to stop by action
occuring at an I/O device.

\subsection{What Is an OS for, Anyway?}

A computer might not even have an OS, say in embedded applications.  A
computer embedded in a washing machine will just run one program (in
ROM).  So, there are no files to worry about, no issues of timesharing,
etc., and thus no need for an OS.

But on a general-purpose machine, we need an OS to do:

\begin{itemize}

\item Input/output device management:

If you recall the example in Chapter \ref{chap:io}, we saw that at the machine
level it takes about a dozen lines of code just to read one character
from the keyboard.  We certainly would not want to have to deal with
that in our own programs, but fortunately the OS provides this service
for us.  Let's see what that means in the case of the keyboard. 

First, the OS includes the keyboard device driver, so that we do not
need to write our own.  Second, the OS provides the {\bf read()}
function for us to call in order to pick up the characters the keyboard
driver has collected for us.  Suppose for instance that you have a {\bf
scanf()} call or a {\bf cin} statement in your program.  When the user
types some characters, each keystroke will cause an
interrupt.\footnote{Actually two interrupts, one for key press and one
for release, but let's say one here, for simplicity.}  When the
interrupt occurs, the keyboard driver will add the character to an
array, typically referred to as a {\bf buffer}.  Your program's {\bf
scanf()} call or {\bf cin} statement will include to a call to {\bf
read()}, a function in the OS.  That function will then pick up the
characters in the keyboard buffer, parse them according to whatever kind
of read format you asked for, and return the result to your program.

Again, the central point here is that the OS is doing a big service for
you, in that it is alleviating you of the burden of writing all this
code.

\item File management:

For example, suppose you are writing a program to write a new file.  You
wouldn't want to have to deal with the details of knowing where the
empty space is on the disk, choosing some of it for the file, etc.
Again, the OS does this for you.

\item Process management:

When you want to run a program, the OS loads it into memory for you and
starts its execution. 

The OS enables \textbf{timesharing}, in which many application programs
seem to be running simultaneously but are actually {}``taking turns,{}''
\textit{by coordinating with hardware operations}.

\item Memory management:

The OS must keep track of which parts of memory are currently in use, so
that it knows what areas it can load a program to when the program is
requested for execution.

The OS also enables \textbf{virtual memory} operations for application
programs, which both allows flexible use of memory and enforces
security, again by \textit{by coordinating with hardware operations}.

\end{itemize}

How the OS does these things is explained in the following sections. We
will model the discussion after a Linux system, but the description here
applies to most modern OSs. It is assumed here that the reader is
familiar with basic Linux commands; a Linux tutorial is available at
\url{http://heather.cs.ucdavis.edu/~matloff/unix.html}

\section{Application Program Loading}

\subsection{Basic Operations}

Suppose you have just compiled a program, producing, say for a Linux system,
an executable file \textbf{a.out}.  (And the following would apply
equally well to {\bf gcc} or any other program.)  To run it, you type

\begin{Verbatim}[fontsize=\relsize{-2}]
% a.out
\end{Verbatim}

For the time being, assume a very simple machine/OS combination, with no
\textbf{virtual memory}. Here is what will occur:

\begin{itemize}

\item During your typing of the command, the shell is running, say
\textbf{tcsh} or \textbf{bash}. Again, the shell is just a program (one
which could be assigned as a homework problem in a course).  It prints
out the `\%' prompt using {\bf printf()},\footnote{Most shells are
written in C.} and enters a loop in which it reads the command you type
using {\bf scanf()}.\footnote{Note that there will be an interrupt each
time you type a character.  The OS will store these characters until you
hit Enter, in which case the OS will finally ``wake'' the shell program,
whose {\bf scanf()} will now finally execute.  See also Sleep and Run
states later in this chapter.}

\item The shell will then make a system call, {\bf execve()},\footnote{It
will also call another system call, {\bf fork()}, but we will not go into that
here.} asking the OS to run \textbf{a.out}. The OS is now running. 

\item The OS will look in its disk directory, to determine where on disk
the file \textbf{a.out} is. It will read the {\bf header}, i.e.
beginning section of \textbf{a.out}, which contains information on the
size of the program, a list of the data sections used by the program,
and so on.\footnote{You can read that information yourself, using the
{\bf readelf} command in Linux.}

\item The OS will check its memory-allocation table (this is just an
array in the OS) to find an unused region or regions of memory large
enough for \textbf{a.out}.  (Note that the OS has loaded all
currently-active programs in memory up to now, just like it is loading
\textbf{a.out} now, so it knows exactly which parts of memory are in use
and which are free.) We need space both for \textbf{a.out}'s
instructions, in the {\bf .text} section, its static data (in the {\bf
.data} section for uninitialized variables, and in the {\bf .bss} section
for initialized variables), as well as for stack space and the
\textbf{heap}.  

The heap is used for calls to {\bf malloc()} or for invocations of the
C++ operator {\bf new}.  With the GCC compiler, these are one and the
same, since the internal implementation of {\bf new} calls {\bf
malloc()}.  There will be a data structure there which keeps track of
which parts of the heap are in use and which are free.  Of course, they
are initially all free.  Each time we need new memory, we use parts of
the heap, and they will be marked as in use.  Calling {\bf free()} or
invoking {\bf delete} will result in the space being marked as free
again.  All the marking is done by {\bf malloc()}.

\item The OS will then load \textbf{a.out} (including text and data)
into those regions of memory, and will update its memory-allocation
table accordingly. 

\item The OS will check a certain section of the \textbf{a.out} file, in
which the linker previously recorded \textbf{a.out}'s \textbf{entry
point}, i.e. the instruction in \textbf{a.out} at which execution is to
begin.   (This for example is {\bf \_start} in our previous assembly language
examples.)

\item The OS is now ready to initiate execution of \textbf{a.out}. It
will set the stack pointer to point to the place it had chosen earlier
for \textbf{a.out}'s stack. (The OS will save its own register values,
including stack pointer value, beforehand.) Then it will place any
command-line arguments on {\bf a.out}'s stack, and then actually start
\textbf{a.out}, say by executing a JMP instruction (or equivalent) to
jump to \textbf{a.out}'s entry point. 

\item The \textbf{a.out} program is now running! 

\end{itemize}

\checkpoint

\subsection{Chains of Programs Calling Programs}

Note that \textbf{a.out} itself may call {\bf execve()} and start other
programs running.  We mentioned above that the shell does this, and so
for example does \textbf{gcc}.\footnote{Remember, a compiler is just a
program too. It is a very large and complex program, but in principle no
different from the programs you write.} It first runs the \textbf{cpp} C
preprocessor (which translates {\bf \#include}, {\bf \#define} etc. from
your C source file). Then it runs \textbf{cc1}, which is the
{}``real{}'' compiler (\textbf{gcc} itself is just a manager that runs
the various components, as you can see now); this produces an assembly
language file.\footnote{You can view this file by running \textbf{gcc}
with its {\bf -S} option. This is often handy if you are going to write an
assembly-language subroutine to be called by your C code, so that you
can see how the compiler will deal with the parameters in the call to
the subroutine.  } Then \textbf{gcc} runs \textbf{as}, the assembler, to
produce a {\bf .o} machine code file. The latter must be linked with
some code, e.g. {\bf /usr/lib/crt1.o} and other files which set up the
{\bf main()} structure, e.g. access to the {\bf argv} command-line
arguments, and also linked to the C library, {\bf /lib/libc.so.6} or
some such file; so, \textbf{gcc} runs the linker, \textbf{ld}. In all
these cases, \textbf{gcc} starts these programs by calling {\bf
execve()}.

\subsection{Static Versus Dynaming Linking}

Say your C code includes a call to {\bf printf()}.  Even though someone
else wrote {\bf printf()}, when you link it in to your program (which
GCC does for you when it calls LD), it becomes part of your program.
The question is when this occurs.

With {\bf static} linking, LD will put {\bf printf()}'s machine code
into your {\bf a.out} executable.  However, since most programs make use
of the C library, they would collectively take up a lot of disk space if
static linking were used.  

So, the default is that GCC and LD would set up {\bf dynamic} linking
for {\bf printf()} in your program.  In your {\bf a.out} file, there
will be a message saying that your code calls {\bf printf()}, and that
when your program is loaded into memory and is run, {\bf printf()}
should be linked in to it at that time.

\subsection{Making These Concepts Concrete: Commands You Can Try Yourself}

\subsubsection{Mini-Example}

Below is a simple illustration of {\bf execve()} in action.  The program
{\bf run.c} makes this system call to get the program {\bf greeting.c}
running.  Assume the executable files are named {\bf greeting} and {\bf
run}.

\begin{Verbatim}[fontsize=\relsize{-2},numbers=left]
// greeting.c

main()
{  printf("hello\n");  }
\end{Verbatim}

\begin{Verbatim}[fontsize=\relsize{-2},numbers=left]
// run.c

main()
{  char **a[2],  // arguments to "greeting" (none here; see man page)
        **p[2];  // environment for "greeting" (none here)

   a[0] = ""; a[1] = 0;
   p[0] = ""; p[1] = 0;
   execve("./greeting",a,p);  }
\end{Verbatim}

\begin{Verbatim}[fontsize=\relsize{-2},numbers=left]
% run
hello
\end{Verbatim}

\checkpoint

Note that the shell will do something like this too, when you request
that your program {\bf a.out} be run. 

\subsubsection{The strace Command}

The Linux \textbf{strace} command will report which system calls your
program makes. Place it before your program name on the command line, 
e.g.

\begin{Verbatim}[fontsize=\relsize{-2}]
% strace a.out
\end{Verbatim}

The output will be rather overwhelming, but if you sift through
it\footnote{I recommend running the Linux {\bf script} command before you
run {\bf strace}.  It will keep a record of everything that appears on
your screen.  After you are done running {\bf strace}, type {\tt exit}
to leave the shell created by {\bf script}.  Then the record of your
session is in a file named {\bf typescript}.  You can then browse
through it using your favorite text editor.} You will see that a call
{\bf execve()} is made by the shell to launch {\bf a.out}, as well as
the various systems call made by {\bf a.out}.

\section{OS Bootup}

As was explained earlier, when we wish to run an application program,
the OS loads the program into memory. But wait!  The OS is a program
too, so how does {\it it} get loaded into memory and begin execution?
The answer is that another program, the {\bf boot loader}, will load the
OS into memory.  But then how does the boot loader get loaded in
memory?!  It sounds like we have an endless, ``chicken and egg''
problem.  The resolution is that the boot loader is permanently in
memory, in ROM, so it doesn't have to be loaded.

The process by which the OS is loaded into memory is called
\textbf{bootup}.  We will explain this using the Intel Pentium
architecture for illustration.\footnote{An overview of that architecture
is presented in Section \ref{pentium}.}

The circuitry in the CPU hardware will be designed so that upon powerup
the Program Counter (PC) is initialized to some specific value,
0xfffffff0 in the case of Intel CPUs.  And those who \textbf{fabricate}
the computer (i.e. who put together the CPU, memory, bus, etc. to form a
complete system) will include a small ROM at that same address, again
0xfffffff0 in the Intel case. The contents of the ROM include the boot
loader program.  So, immediately after powerup, the boot loader program
is running!

The goal of the boot loader is to load in the OS from disk to memory. In
the simple form, the boot loader reads a specified area of the disk,
copies the contents there---which will be part of the OS---to some
section of memory, and then finally executes a JMP instruction (or
equivalent) to that section of memory---so that now the OS is running.
The OS then reads the rest of itself into memory.

For the sake of concreteness, let's look more closely at the Intel case.
The program in ROM here is the BIOS, the Basic I/O System. It contains
parts of the device drivers for that machine,\footnote{These may or may
not be used, depending on the OS. Windows uses them, but Linux doesn't.}
and also contains the first-stage boot loader program.

The boot loader program in the BIOS has been written to read some
information, to be described now, from the first physical sector of the
disk.\footnote{The boot device could be something else instead of a hard
drive, such as a floppy or a CD-ROM.  This is set in the BIOS, with a
priority ordering of which device to try to boot from first.} That
sector is called the Master Boot Record (MBR).

There will be one or more {\bf partitions} for the disk.  If, say, the
disk has 1,000 cylinders, then for example we may have the first 200 as
one partition and the remaining 800 as the second
partition.\footnote{You should review the material on disks in Chapter
\ref{chap:io}.} These simply divide up parts of the disk for different
purposes.  A typical example would be that there are two partitions, one
for Windows and the other for Linux.  Your machine was probably shipped
with the entire disk consisting of just one partition, but you can split
it into several partitions to accommodate different OSs.  

These partitions are defined in the {\bf partition table} in the MBR.
Note that there is no physical separation from one partition to the
next; the boundary between one partition and the next is only defined by
the partition table.  Exactly one of the primary partitions will be
marked in the table as {\bf active}, meaning bootable.

The MBR also contains the second-stage boot loader program.  The boot
loader program in the BIOS will read this second-stage code into memory
and then jump to it, so that that program is now running.  That program
reads the partition table, to determine which partition is the active
one.  It then goes to the first sector in that partition, reads in the
third-stage boot loader program into memory from there, and then jumps
to that program.

% The first-stage boot loader in ROM will copy the second-stage code to
% memory, starting at memory location 0x00007c00. It then does a jump to
% that address, so that that code is now running.

Now if the machine had originally been shipped with Windows installed,
the second-stage code in the MBR had been written to then load into
memory the third-stage code from the Windows partition.  If on the other
hand the machine had been shipped with Linux or some other OS installed,
there would be a partition for that OS; the code in the MBR would have
been written accordingly, and that OS would now be loaded into memory.

Many people who use Linux retain both Windows and Linux on their hard
drives, and have a \textbf{dual-boot} setup. They start with a Windows
machine, but then install Linux as well, so both OSs are on the machine.
As part of the process of installing Linux, the old MBR is copied
elsewhere, and a program named LILO (Linux Loader) is written into the
MBR.\footnote{A newer, now more popular alternative to LILO is GRUB.
But the principle is the same for both, so we will just refer to LILO
here for simplicity.}  In other words, LILO will be the second-stage
boot loader.  LILO will ask the user whether he/she wants to boot Linux
or Windows, and then go to the corresponding partition to load and
execute the third-stage boot loader which is there.\footnote{The
partition does not have to be the active one.  The term {\it active}
applies only from the point of view of the Windows second-stage boot
loader which had originally been installed in the MBR.}

In any case, after the OS is loaded into memory by the third-stage code,
that code will perform a jump to the OS, so the OS is running. 

\checkpoint

\section{Timesharing}

\subsection{Many Processes, Taking Turns}

Suppose you and someone else are both using the computer {\bf pc12} in
our lab, one of you at the console and the other logged in remotely.
Suppose further that the other person's program will run for five hours!
You don't want to wait five hours for the other person's program to end.
So, the OS arranges things so that the two programs will take turns
running.  It won't be visible to you, but that is what happens.

\textbf{Timesharing} involves having several programs running in what
\underbar{appears} to be a simultaneous manner.\footnote{These programs
could be from different users or the same user; it doesn't matter.} If
the system has only one CPU (for simplicity, we will exclude the case of
multiprocessor systems in this discussion), this simultaneity is of
course only an illusion, since only one program can run at any given
time, but it is a worthwhile illusion, as we will see.

First of all, how is this illusion attained? The answer is that we have
the programs all take turns running, with each turn---called a
\textbf{quantum} or \textbf{timeslice}---being of very short duration,
for example 50 milliseconds.  Say we have four programs, {\bf u}, {\bf
v}, {\bf x} and {\bf y}, running currently. What will happen is that
first {\bf u} runs for 50 milliseconds, then {\bf u} is suspended and
{\bf v} runs for 50 milliseconds, then {\bf v}  is suspended and {\bf x}
runs for 50 milliseconds, and so on.  After {\bf y} gets its turn, then
{\bf u} gets a second turn, etc.  Since the turn-switching, formally
known as \textbf{context-switching},\footnote{We are switching from the
``context'' of one program to another.} is happening so fast (every 50
milliseconds), it appears to us humans that each program is running
continuously (though at one-fourth speed), rather than on and off, on
and off, etc.\footnote{Think of a light bulb turning on and off
extremely rapidly, with half the time on and half off.  If it is
blinking rapidly enough, you won't see it go on and off.  You'll simply
see it as shining steadily at half brightness.}

But how can the OS enforce these quanta? For example, how can the OS
force the program {\bf u} above to stop after 50 milliseconds? As
discussed earlier, the answer is, {}``It can't! The OS is dead while
{\bf u} is running.{}'' Instead, the turns are implemented via a timing
device, which emits a hardware interrupt at the proper time. For
example, we could set the timer to emit an interrupt every 50
milliseconds. We would write a timer device driver, and incorporate it
into the OS.

We will make such an assumption here. However, what is more common is to
have the timer interrupt more frequently than the desired quantum size.
On a PC, the 8253 timer interrupts 100 times per second.  Every sixth
interrupt, the Linux OS will perform a context switch.  That results in
a quantum size of 60 milliseconds.  But this can be changed, simply by
changing the count of interrupts needed to trigger a context switch.

The timer device driver saves all {\bf u}'s current register values,
including its PC value and the value in its EFLAGS register. Later, when
{\bf u}'s next turn comes, those values will be restored, and {\bf u}
will resume execution as if nothing ever happened. For now, though, the
OS routine will restore {\bf v}'s's previously-saved register values,
making sure to restore the PC value last of all. That last action forces
a jump from the OS to {\bf v}, right at the spot in {\bf v}  where {\bf
v} was suspended at the end of its last quantum. (Again, the CPU just
{}``minds its own business,{}'' and does not {}``know{}'' that one
program, the OS, has handed over control to another, {\bf v}; the CPU
just keeps performing its fetch/execute cycle, fetching whatever the PC
points to, oblivious to which process is running.)

\checkpoint

At any given time, there are many different \textbf{processes} in
memory. These are instances of executions of programs. If for instance
there are three users running the \textbf{gcc} C compiler right now on a
given machine, here one program corresponds to three processes.

\subsection{Example of OS Code: Linux for Intel CPUs}

Here is a bit about how the context switch is done in Linux, in the
version for Intel machines.\footnote{This was as of Linux kernel version
2.3.  I have slightly modified some of this section for the sake
of simplicity.}

The OS maintains a {\bf process table}, which is simply an array of {\bf
struct}s, one for each process.  The {\bf struct} for a process is
called the Task State Segment (TSS) for that process, and stores various
pieces of information about that process, such as the register values
which the program had at the time its last turn ended.  Remember, these
need to be stored somewhere so that we can restore them at the program's
next turn; here's where we store them.

As an example of the operations performed, and to show you concretely
that the OS is indeed really a program with real code, here is a typical
excerpt of Linux internal code:\footnote{Linux is constantly evolving.
This code existed in Linux at the time it was included in this book, but
could have changed subsequently.}

\begin{Verbatim}[fontsize=\relsize{-2},numbers=left]
pushl %esi
pushl %edi
pushl %ebp 
movl %esp, 532(%ebx) 
...
movl 532(%ecx), %esp
...
popl %ebp
popl %edi
popl %esi
...
iret
\end{Verbatim}

This code is the ISR for the timer.  Upon entry, {\bf u}'s turn has just
ended, having been interrupted by the timer.  In code not shown here,
the OS has pointed the registers EBX and ECX to the TSSs of the process
whose turn just ended, {\bf u}, and the process to which we will give
the next turn, say {\bf v}.

By the way, how does the OS know that the process whose turn just ended
was {\bf u}'s?  The answer is that whenever the OS gives a process a
turn, it records which process it was.  In Linux this is information is
stored at address 0xffffe000, and the macro {\bf GET\_CURRENT()} is used
to fetch it and place it into a register specified by the programmer; in
our situation here, the register would be EBX.  So the OS knows where to
point EBX.  The OS will make a decision as to which process to next give
a turn to, and point ECX to it.

Here is what that code does.  The source code for Linux includes a
variable {\bf tss}, which is the TSS {\bf struct} for the current
process.  In that struct is a field named {\bf esp}.  So, {\bf tss.esp}
contains the previously-stored value of ESP, the stack pointer, for this
process; this field happens to be located 532 bytes past the beginning
of the TSS.\footnote{In the C source code, this field is referred to as
{\bf tss.esp}, but in assembly language we can only use the 532, as
field names of {\bf struct}s are not shown.}

Now, upon entry to the above OS code, ESP is still pointing to {\bf u}'s
stack, so the three PUSH instructions save {\bf u}'s values of the ESI,
EDI and EBP registers on {\bf u}'s own stack.\footnote{ Note the need to
write this in assembly language instead of C, since C would not give us
direct access to the registers or the stack. Most of Linux is written in
C, but machine-dependent operations like the one here must be done in
assembly language.  } The other register values of {\bf u} must be saved
too, including its value of ESP.  The latter is done by the MOV, which
copies the current ESP value, i.e. {\bf u}'s ESP value, to {\bf tss.esp}
in {\bf u}'s TSS. Other register saving is similar, though not shown
here.

Now the OS must prepare to start {\bf v}'s next turn. Thus {\bf v}'s
previously-saved register values must be restored to the registers. To
understand how that is done, you must keep in mind that that same code
we see above had been executed when {\bf v}'s last turn ended. Thus {\bf
v}'s value of ESP is in {\bf tss.esp} of its TSS, and the second MOV we
see above copies that value to ESP. So, now we are using {\bf v}'s
stack.

Next, note similarly that at the end of {\bf v}'s last turn, its values
of ESI, EDI and EBP were pushed onto its stack, and of course they are
still there. So, we just pop them off, and back into the registers,
which is what those three POP instructions do.

Finally, what actually get's {\bf v}'s new turn running?  To answer
this, note that the mechanism which made {\bf v}'s last turn end was a
hardware interrupt from the timer. At that time, the values of the Flags
Register, CS and PC were pushed onto the stack. Now, the IRET
instruction you see here pops all that stuff back into the corresponding
registers.  Note only does that restore registers, but since {\bf v}'s
old PC value is restored to the PC register, {\bf v} is now running!

\checkpoint

\subsection{Process States}

The OS maintains a \textbf{process table} which shows the state of each
process in memory, mainly Run state versus Sleep state. A process which
is in Run state means that it is ready to run but simply waiting for its
next turn. The OS will repeatedly cycle through the process table,
starting turns for processes which are in Run state but skipping over
those in Sleep state. The processes in Sleep state are waiting for
something, typically an I/O operation, and thus currently ineligible for
turns. So, each time a turn ends, the OS will browse through its process
table, looking for a process in Run state, and then choosing one for its
next turn.

Say our application program {\bf u} above contains a call to {\bf scanf()} to
read from the keyboard. Recall that {\bf scanf()} calls the OS function
{\bf read()}. The latter is in the OS, so now the OS is running, and
this function will check to see whether there are any characters
ready in the keyboard buffer.  Typically there won't be any characters
there yet, because the user has not started typing yet. In this case the
OS will place this process in Sleep state, and then start a turn for
another process.

How does a process get switched to Run state from Sleep state? Say our
application program {\bf u} was in Sleep state because it was waiting
for user input from the keyboard, waiting for just a single character,
in {\bf raw} mode.\footnote{Recall from Chapter \ref{chap:io} that in
this mode, a character is made available to a program as input the
minute the user strikes the key.  In ordinary, {\bf cooked}, mode, the
program doesn't see the input until the user hits the Enter key.} 

As explained earlier, when the user hits a key, that causes
a hardware interrupt from the keyboard, which forces a jump to the OS.
Suppose at that time program {\bf v}  happened to be in the midst of a
quantum. The CPU would temporarily suspend {\bf v}  and jump to the
keyboard driver in the OS. The latter would notice that the program {\bf
u} had been in Sleep state, waiting for keyboard input, and would now
move {\bf u} to Run state.

Note, though, that that does not mean that the OS now starts {\bf u}'s
next turn; {\bf u} simply becomes eligible to run. Recall that each time
one process' turn ends, the OS will select another process to run, from
the set of all processes currently in Run state, and {\bf u} will now be
in that set.  Eventually it will get a turn. 

\checkpoint

To make all this concrete, say {\bf u} is running the {\bf vi} text
editor, {\bf v} is running a long computational program, and user
{\bf w} is also running some long computational program.  Remember,
{\bf vi} \underline{is} a program; its source code might have a section
like this:

\begin{Verbatim}[fontsize=\relsize{-2}]
while (1)  {
   KeyStroke = getch();
   if (KeyStroke == 'x') DeleteChar();
   else if (KeyStroke = 'j') CursorDown();
   else if ...
}
\end{Verbatim}

Here you see how {\bf vi} would read in a command from the user, such as
{\bf x} (delete a character), {\bf j} (move the cursor down one line)
and so on.  Of course, {\bf DeleteChar()} etc. are functions, whose code is
not shown here.

When during a turn for {\bf u}, {\bf vi} hits the {\bf getch()} line,
the latter calls {\bf read()}, which is in the OS, so now the OS is
running.  Assuming {\bf u} has not hit a key yet (almost certainly the
case, since the CPU is a lot faster than {\bf u}'s hand, not to mention
the fact that {\bf u} might have gone for a lunch break), the OS will
mark {\bf u}'s process as being in Sleep state in the OS's Process Table.

Then the OS will look for a process in Run state to give the next turn
to.  This might be, say, {\bf v}.  It will run until the timer interrupt
comes.  That pulse of current will cause the CPU to jump to the OS, so
the OS is running again.  This time, say, {\bf w} will be run.

Say during {\bf w}'s turn, {\bf u} finally hits a key.  The resulting
interrupt from the keyboard again forces the CPU to jump to the OS.  The
OS read the character that {\bf u} typed, notices in its Process Table
that {\bf u}'s process was in Sleep state pending keyboard input, and
thus changes {\bf u}'s entry in the Process Table to Run state.  The OS
then does IRET, which makes {\bf w}'s process resume execution, but when
the next timer interrupt comes, the OS will likely give {\bf u} a turn
again.

\subsection{Roles of the Hardware and Software}

It is crucial to understand the relative roles of the hardware and
software here.

The CPU hardware provides interrupt capability, and the timer hardware
sends the interrupts.  {\bf Without these, we could not have timesharing.}
The OS could not arrange the suspension of another program by itself.

For instance, suppose we have a dual core machine.  Even if the OS is
running on one core, how could it stop a program that is running on the
other core?  The most the OS could do is overwrite the program---which
would destroy it, not suspend it.

\subsection{What About Background Jobs?}

For example, you could run the Firefox Web browser by typing

\begin{Verbatim}[fontsize=\relsize{-2}]
% firefox 
\end{Verbatim}

at the command line.  But that would tie up the window you typed it
into; you wouldn't be able to run any other commands until you quit
Firefox, which might be a very long time.  To solve this problem, you
can run it {\it in the background}, as follows.

You could type

\begin{Verbatim}[fontsize=\relsize{-2}]
% firefox &
\end{Verbatim}

with the ampersand meaning, ``Run this job in the background.''  The
shell would start Firefox, and then print out a prompt, inviting you to
run other commands.  What is really happening here?

The first point to be made here is that it really means nothing to the
OS.  The entry for the Firefox process in the OS' process table
will not state whether this program is background or foreground; the OS
doesn't know.

The only meaning of that ampersand was for the shell.  We used it to
tell the shell, ``Go ahead and launch {\bf a.out} for me, but don't wait
for it to finish before giving me your `\%' prompt again.  Give me the
prompt right away, because I want to run some other programs
too.''\footnote{To do this, the shell must first create a new process,
by calling the {\bf fork()} system call, and then calling {\bf execve()}
from the child process.  That way, the parent process---the shell--can
keep running and give you the prompt.}

\subsection{Threads:  ``Lightweight Processes''}
\label{threadsintro}

A very important type of application programming is that of {\bf
threads}.  Thread libraries are offered by any modern OS.  On
Unix-family systems such as Linux, for instance, a popular thread
package is {\bf pthreads}, which we will assume for concreteness here.  

Threading is pervasive in computing today.  Most Web servers are
threaded, for instance.  Also many GUI (``graphical user interface'')
programs are threaded too.  

Threading is also the standard way of programming on multiprocessor
systems.  Since such systems are now common even at the household
level---the term {\bf dual core} means two CPUs---you can see how
important threaded programming has become.  We'll pursue this in more
detail in Chapter \ref{chap:multcore}.

\subsubsection{The Mechanics}

Threads, of the ``system'' type discussed here, are
processes.\footnote{What we are describing here are {\bf system-level}
threads, i.e. those provided by the OS, which is the case for {\bf
pthreads}.  There are also {\bf user-level} threads.  These, exemplified
by the GNU {\bf pth} library, are handled internally to the application
program.  Basically, the library runs its own private processes, with
its own private process table!} If your program creates three threads on
a Unix-family system such as Linux, for example, you may (depending on
the OS)  see three entries for them in the output of the {\bf ps}
command which displays processes.  (For Linux, type {\bf ps axms}.)
These will correspond to three entries in the process table.  Thus the
threads take turns running, in the usual timesharing manner.  The turn
taking includes the other processes too, of course.  

From the programmer's point of view, the main difference between threads
and processes is that in threaded programs all global variables of the
program are shared.\footnote{It is actually possible to have different
processes share memory too, using the system call {\bf shmget()}.
However, this is unwieldy and involves a lot of system overhead, and is
not commonly done.}  This is the way the different threads communicate
with each other, by reading and writing these shared variables.

(This may come as a shock to readers who were taught that shared
variables are ``evil.''  In my opinion, shared variables are fine for
general programming (within reason), but whether one agrees with that
notion or not, {\bf the fact is that in threaded programming one
\underline{must} use global variables.})

Each thread does have its own local variables, though.  So, the various
threads of a program will share the same {\bf .data} and {\bf .comm}
sections, but each will have its own separate stack.

One creates a thread by calling {\bf pthread\_create()}.  One of its
arguments must be a pointer to a function in the application program.
For instance, in a GUI program, we might have one thread for the mouse,
one thread for the keyboard, etc.  The function which handles mouse
events (movement and clicks) would be specified as an argument to {\bf
pthread\_create()}, and basically the thread would consist of executing
that function.  There would also be a function for the keyboard, etc.

Key to threaded programming is {\bf locks}.  Suppose for instance that
an airline reservation system is threaded, and that there is one seat
left for a particular flight.  We want to make sure to avoid a situation
in which two clerks both sell that last seat.  (Ignore the issue of
overbooking.)  So, the two threads running for the two clerks must
cooperate, and not try to access that flight's record at the same time.
In other words, we want access to that record to be {\bf atomic}.  

This is achieved by using lock variables, of type {\bf
pthread\_mutex\_t}, which are locked and unlocked via calls to {\bf
pthread\_mutex\_lock()} and {\bf pthread\_mutex\_unlock()}.  The portion
of the code which needs to accessed atomically, called a {\bf critical
section}, must be surrounded by lock/unlock code.

Threads are often called {\bf lightweight processes}.  The term {\it
lightweight} here refers to the fact that creating a thread involves
much less overhead than creating a process.  In {\bf pthreads}, for
instance, calling {\bf pthread\_create()} has a lot less work to do than
would be involved in calling {\bf execve()} to make a new process.
Among other things, the latter requires finding memory for the new
process, whereas a new thread would simply use the same memory.

\subsubsection{Threads Example}
\label{pthreadsexample}

Examples of threaded programming tend to be rather elaborate, so I've
written the following simple (if a bit contrived) example:\footnote{Note
that this example uses only a few of the many functions in the {\bf
pthreads} library.}

\begin{Verbatim}[fontsize=\relsize{-2},numbers=left]
// HelloWorld.c, a baby-level first example of threaded programming

// doesn't actually print out "hello world." :-), but it's of that level
// of simplicity, so I gave it that name anyway

// reads from each of several keyboard input sources, in different
// windows on the same console; records the inputs, making sure not to
// mix them

// for simplicity, the program has no mechanism for stopping

// Linux compilation:  gcc -g -o hw HelloWorld.c -lpthread 

// usage:  hw first_keybd_input_filename second_keybd_input_filename ...
// e.g. hw /dev/pts/4 /dev/pts/6

#define MAX_THREADS 20

#include <stdio.h>
#include <pthread.h>  // required for threads usage

int nthreads;  // number of threads to be run

pthread_mutex_t numlock = PTHREAD_MUTEX_INITIALIZER;
// ID structs for the threads
pthread_t id[MAX_THREADS];

// each thread runs this routine
void *worker(char *fname)  // fname is file name
{  FILE *kb;  // note separate stacks, so separate kb's
   int num;  // separate num's too
   kb = fopen(fname,"r");  // open this keyboard input, read only
   while(1)  {
      fscanf(kb,"%d",&num);  // wait for user to type in this window
      pthread_mutex_lock(&numlock);
      printf("read %d from %s\n",num,fname);
      pthread_mutex_unlock(&numlock);
   } 
}

main(int argc, char **argv)
{  int i; 
   nthreads = argc - 1;
   // get threads started
   for (i = 0; i < nthreads; i++)  {
      // this next call says to create a thread, record its ID in the array
      // id, and get the thread started executing the function worker(), 
      // passing the argument argv[i+1] to that function
      pthread_create(&id[i],NULL,worker,argv[i+1]);
   }
   while(1) ;  // dummy loop, to keep main() from exiting, killing
               // the other threads
}
\end{Verbatim}

The program reads keyboard input from two different windows on the same
console on the same machine.  This is the contrived part.  A typical
example would have input coming from keyboards on other machines, with
the characters being sent across a network.  But I wanted to avoid
bringing in network programming.

As you can see, {\bf main()} starts up the threads.  Once they are
started, they take turns running, since they are processes.  Note that
{\bf main()} is considered a thread too, the parent of those created by
it.  So, all three threads take turns running.\footnote{Since {\bf
main()} is doing nothing useful, it would be better not to give it turns.
There are other functions in the {\bf pthreads} library that would
set this up.}

I ran the program on the windows {\bf /dev/pts/4} and {\bf /dev/pts/6}
on my Linux machine at home.  In each window I typed

\begin{Verbatim}[fontsize=\relsize{-2}]
% sleep 10000
\end{Verbatim}

to put the shell to sleep, ensuring that the input I type in those
windows would go to my program rather than to the shells.

In a third window, I ran the program.  In window 6 I then typed 5 and
12, and then 13 in window 5, then 168 in window 6 again.  The output in
the third window was

\begin{Verbatim}[fontsize=\relsize{-2}]
% a.out /dev/pts/4 /dev/pts/6
read 5 from /dev/pts/6
read 12 from /dev/pts/6
read 13 from /dev/pts/4
read 168 from /dev/pts/6
\end{Verbatim}

Here's how it works:

The issue here is that we don't know which keyboard input will have some
activity next.  If we simply call {\bf scanf()} in nonthreaded fashion
(and don't resort to something called {\bf nonblocking I/O}), our
program would wait forever for input from one nonactive window when
there is input waiting at another window.  The solution is to use
threads, with one thread for each window.

Each source of keyboard input is considered a different file.  (In
Unix-family systems such as Linux, I/O devices are considered "files.")
We determine the file name by running the {\bf who am i} command in the
given window.  If for instance the answer is {\bf pts/6}, the keyboard
input there is {\bf /dev/pts/6}.

Each time there is keyboard input from somewhere, the program will
report what number was typed.

Just to make sure that some {\bf printf()} output doesn't get mixed with
another, we treat that line as a critical section, surrounding it with
lock/unlock operations.  When a thread reaches the lock call, one of two
things will occur:

\begin{itemize}

\item If the lock is not locked, the thread will be allowed to
immediately enter the critical section.

\item If the lock is locked, the thread will be suspended---put in Sleep
state, given no more turns---until the thread currently in the section
executes the unlock.  Then the waiting thread will be resumed, i.e.
placed in Run state.

\end{itemize}

Of course, in that second scenario, if multiple threads are waiting when
an unlock occurs, the OS must choose one to reactivate.

Note that, as in all of this chapter, we are assuming only a single CPU.
Thus only one thread can run at a time.  In Chapter \ref{chap:multcore} our
context will be that of multiple processors, allowing multiple threads
to run simultaneously.

{\bf REMINDER TO THE READER:}  Don't become overly obsessed with how to
do {\bf pthreads} programming.  Learn how to write such code, yes, but
also focus on the concepts relevant to our course.  Think especially of
the role of interrupts here.  Threads take turns running, with a turn
ending either from a timer interrupt or from a thread voluntarily
relinquishing its turn via a system call, in this case {\bf read()}
being called by {\bf fscanf()}.  In the latter situation, an interrupt
from the keyboard will change a thread from Sleep to Run state. 

\subsubsection{Debugging Threads Programs}
\label{debugthreads}

Most debugging tools include facilities for threads.  Here's an overview
of how it works in GDB.

First, as you run a program under GDB, the creation of new threads will
be announced, e.g.

\begin{Verbatim}[fontsize=\relsize{-2}]
(gdb) r 100 2
Starting program: /debug/primes 100 2
[New Thread 16384 (LWP 28653)]
[New Thread 32769 (LWP 28676)]
[New Thread 16386 (LWP 28677)]
[New Thread 32771 (LWP 28678)]
\end{Verbatim}

You can do backtrace ({\bf bt}) etc. as usual.  Here are some
threads-related commands:

\begin{itemize}

\item {\tt info threads} (gives information on all current threads)

\item {\tt thread 3} (change to thread 3)

\item {\tt break 88 thread 3} (stop execution when thread 3 reaches
source line 88)

tem {\tt break 88 thread 3 if x==y} (stop execution when thread 3
reaches
source line 88 and the variables x and y are equal)

\end{itemize}

Of course, many GUI IDEs use GDB internally, and thus provide the above
facilities with a GUI wrapper.  Examples are DDD, Eclipse and NetBeans.

\subsection{Making These Concepts Concrete: Commands You Can Try Yourself}

First, try the \textbf{ps} command. On Linux systems, much information on current
processes is given by the \textbf{ps} command, including:

\begin{itemize}

\item state (Run, Sleep, etc.) 

\item page usage (how many pages, number of page faults, etc.; see
material on virtual memory below) 

\item ancestry (which process is the {}``parent{}'' of the given
process, via a call to {\bf execve()}) 

\end{itemize}

\textbf{The reader is urged to try this out. You will understand the
concepts presented here much better after seeing some concrete
information which the {\bf ps} command can give you.} The format of this
command's options varies somewhat from machine to machine (on Linux, I
recommend {\bf ps axms}), so check the {\bf man} page for details, but run
it with enough options that you get the fullest output possible.

Another command to try is \textbf{w.} One of the pieces of information given
by the \textbf{w} command is the average number of processes in Run state in
the last few minutes. The larger this number is, the slower will be the response
time of the machine as perceived by a user, as his program is now taking turns
together with more programs run by other people.

On Linux (and some other Unix) systems, you can also try the \textbf{pstree}
command, which graphically shows the {}``family tree{}'' (ancestry relations)
of each process. For example, here is the output I got by running it on one
of our CSIF PCs:\footnote{Some lines omitted, for brevity.}

\begin{Verbatim}[fontsize=\relsize{-2}]
% pstree
init─┬─NetworkManager─┬─dhclient
     │                └─2*[{NetworkManager}]
     ├─acpid
     ├─atd
     ├─avahi-daemon───avahi-daemon
     ├─bamfdaemon
     ├─bonobo-activati───2*[{bonobo-activat}]
     ├─console-kit-dae───64*[{console-kit-da}]
     ├─cron
     ├─cupsd
     ├─2*[dbus-daemon]
     ├─dbus-launch
     ├─dconf-service───{dconf-service}
     ├─dropbox───14*[{dropbox}]
     ├─e-addressbook-f───{e-addressbook-}
     ├─e-calendar-fact───{e-calendar-fac}
     ├─firefox─┬─plugin-containe───8*[{plugin-contain}]
     │         └─26*[{firefox}]
     ├─gconfd-2
     ├─gdm-binary─┬─gdm-simple-slav─┬─Xorg
     │            │                 ├─gdm-session-wor─┬─gnome-session─┬─applet.+
...
     ├─gnome-terminal─┬─gnome-pty-helpe
     │                ├─tcsh───ssh
     │                ├─tcsh───opera───5*[{opera}]
     │                ├─tcsh─┬─pstree
     │                │      └─xpdf───xpdf.real
     │                └─2*[{gnome-terminal}]
...
     ├─gvim
...
     ├─sshd
...
\end{Verbatim}

On Linux systems, the first thing the OS does after bootup is to start a
process named \textbf{init}, which will be the parent (or grandparent,
great-grandparent, etc.) of all processes.  That {\bf init} process then
starts several OS {\bf daemons}.  A {\bf daemon} in Linux parlance means
a kind of server program.  In Linux, the custom is to name such programs
with a `d' at the end, standing for ``daemon.''

For example, you can see above that {\bf init} started {\bf lpd} (``line
printer daemon''), which is the print server.\footnote{Another common
print server daemon is {\bf cupsd}.} When users issue {\bf lpr} and
other print commands, the OS refers them to {\bf lpd}, which arranges
for the actual printing to be done.

Often daemons spawn further processes.  For example, look at the line

\begin{Verbatim}[fontsize=\relsize{-2}]
     |-inetd---in.rlogind---tcsh---pstree
\end{Verbatim}

The {\bf inetd} is an Internet request server.  The system administrator
can optionally run this daemon in lieu of some other network daemons
which are assumed to run only rarely.  Here the user (me) had done {\bf
rlogin}, a login program like {\bf ssh}\footnote{But no longer allowed
on CSIF.}, to remotely login to this machine.  The system administrators
had guessed that {\bf rlogin} would be used only rarely, so they did not
have {\bf init} start the corresponding daemon, {\bf in.rlogind}, upon
bootup.  Instead, any network daemon not started at bootup will be
launched by {\bf inetd} when the need arises, which as you can see
occurred here for {\bf in.rlogind}.  The latter then started a shell for
the user who logged in (me), who then ran {\bf pstree}.  Note again that
the shell is the entity which got {\bf pstree} started.


