You are on page 1of 21

Lecture 2

Chapter 2 of Robbins Book

Programs, Processors and Threads

BIL 244 – System Programming


Program ??

• A program is a prepared sequence of instructions to accomplish a


predefined task.
• We will be using C instructions to create a program
– Traditionally, C source files have .c extension and header files have .h
extension
– Header files contains (only!!) macro and type definitions, defined constants
and function declarations.
– Use #include preprocessor command to insert the contents of a header
file
• C Compilier translates each source to an object file (Step1). The
compiler then links the object files with necessary libraries to
produce an executable module (Step 2).
• When a program is executed, the O/S copies the executable
module into a program image in main memory

BIL 244 – System Programming


How does a Program Becomes a Process?

• A process is an instance of a program that is executing. Each


instance has its own address space and execution state.
• The O/S reads the program into the memory, assigns an ID
(process ID) so that it can distinguish amoung individual
processes, process state indicates the execution states of the
process
• The O/S keeps tracks of the process Id and the corresponding
process state and uses the information to allocate and manage
resources for the system
• When the O/S has added the appropriate information into the
kernel data structures and has allocated the necessary resources to
run the program code, the program becomes a process.
process
• The process has an address space and at least one flow of control
called a thread

BIL 244 – System Programming


Threads and Thread of Execution

• When a program executes, the value of the process program


counter determines which process instructions is executed next.
The resulting stream of instructions, called a thread of execution,
can be represented by the squence of instruction addresses assigned
to the program counter during the execution of the program’s code
• The sequence of instructions in a thread of execution appears the
process as an unintrerrupted stream of addresses. From the point of
the processor, however, the stream of execution from different
processes are intermixed. The point at which execution switches
from one process to another is called a context switch
• A thread is an abstract data type that represents a thread of
execution within a process. A thread has its own execution stack
program counter value, register set and state
• By declaring many threads within a process one can write
programs that achieve parallelism with low overhead.
BIL 244 – System Programming
Layout of a Program Image

• When loaded the program executable appears to occupy a contigunous blosck of


memory called a program image, which has several distinct sections (as shown in
the figure)
high command line arguments
address and environment variables
argc, argv, environments

stack activation records for function calls


.
(return address, parameters,
.
. saved registors, automatic variables)
.
.
.
heap Allocations from malloc family
uninitialize static data

initialize static data

low program text


address

BIL 244 – System Programming


Layout of a Program Image (cont.)

• An activation record is a block in the memory allocated on top of the process


stack to hold the execution context of a function call (each function call creates
a new activation record on the stack and removed from the stack when the
function returns)
• The activaiton record contains the return address, parameters, status
information and a copy of some CPU registor values at the time of the call.
The process restores the registor values on return from the call represented by
the record
• The activation record also contains automatic variables allocated within the
function during its execution. The particular format for an activation record
depends on the hardware and the programming language used.
• The malloc family of functions allocated storage from a free memory poll
called the heap. Storage allocated on the heap persists until it is freed or until
the program ends.

BIL 244 – System Programming


Layout of a Program Image (Static Variables)

• Static variables that are not explicitly initialiazed in their decleration are
initialized to zero (0) at run time (notice that the initialized static variables
and uninitializes static variables occupy different sections in the program
image)
• Static variables can make a program unsafe for threaded executions (they are
not thread-safe)
• External static variables also make code harder to debug as succesive
invocation of a function that references a static variable may behave in an
unexpected way (!! Avoid using static variables except for under controlled
circumstances!!)

BIL 244 – System Programming


Function Return Values and Errors

• Error handling is a key issue in system programming. Here are


some key issues to handle errors
• Make use of return values to communicate information and make error
trapping easy for the calling program
• Do not exit from a function. Instead return an error value to allow the
calling program flexibility in handling the error
• Make functions general but usable
• Do not make unnecessary assumptions about the sizes of buffers
• When it is necessary to use limits use standard system-defined limits
rather than arbitrary constants
• Use standard library functions when possible

BIL 244 – System Programming


Function Return Values and Errors (cont.)

• Do not modify input parameter values unless it makes sense to do so


• Analyze all calls to the malloc family to make sure the program
frees the memory allocated (to avoid memory leaks)
• Consider when a function is ever called recursively or from a signal
handler or from a thread. Functions with variables of static storage
class may not behave as expected.
• Analyze the sequence of interreptions by signals
• Carefully consider how the entire program terminates !!!

BIL 244 – System Programming


Argument Arrays

• A command line consists of tokens that are separeted by white


spaces: blanks tabs or a backslash (\) at the end of each line.
Each token is a string of characters contaning no white space
(unless quatation marks are used to groups tokens)
• An argument array is an array of pointers terminated by a
NULL pointer.
• Each element of the array is of type char * and represents a
string.

BIL 244 – System Programming


Argument Arrays

• The following command line has 4 tokens


mine –c 10 2.0
• The program mine might start with the following line
int main (int argc, char *argv[])
which means

BIL 244 – System Programming


makeargv Implementations

• Sometimes it is necessary to create a structure like this yourself from a


string.
The shell must do this when you execute a command.
• argv[] is an array of pointers to chars
In C, this is the same as a pointer to a pointer to a char.
• One way to write a function to do this is:
char **makeargv(char *s)

• If you want to return the number of tokens, you can pass a pointer to
the arg array as in:
int makeargv(char *s, char ***argvp)

• The version we will use has an additional parameter that specifies a


string of delimiters:
int makeargv(const char *s, const char *delimiters,
char ***argvp)
The const for the first two parameters indicates that the strings should
not be modified by the function.
The rest is left to the Student (Go and play with the code...)

BIL 244 – System Programming


Storage Classes

static and automatic


• static storage class refers to variables that, once allocated, persist
throughout the execution of a program.
• automatic storage class refers to variables which come into
existence when the block in which they are declared is entered
and are discarded when the defining block is exited.
• Variables declared inside a function have automatic storage class
unless they are declared to be static.
These are usually allocated on the program stack.
• Variables defined outside any functions have static storage class.
• The word static has two meanings is C.
One is related to storage class and the other to linkage class.

BIL 244 – System Programming


Linkage Classes

• Linkage class determines whether variables can be accessed in


files other than the one in which they are declared.
• Internal linkage class means they can only be accessed in the file
in which they are declared.
• External linkage class means they can be accessed in other files.
• variables declared outside any function and function name
identifiers have external linkage by default.
They can be given internal linkage with the key word static.
• Variables declared inside a function are only known inside that
function and are said to have no linkage.

BIL 244 – System Programming


Static Variables and Structures of Static Objects

• While care must be taken in using static variables with multiple


threads, do not forget that sometimes static variables are useful,
for example a static variable can hold the internal state
information between calls to a function. (i.e. Check the
bubblesort.c example in the book)
• Static variables are commonly used in the C implementations
of data structure as an object. The data structure and all the
functions accessing it are placed in a single source file and the
data structure is defined outside anny function.
• The data structure has static attribute giving it internal linkage
(it is private to that file)

BIL 244 – System Programming


Process Environment

• An environment list consists of an array of pointers to strings of


the form name = value where the name sapecifies an
environment variable and the value specifies a string value
associated with the environment variable. The last entry of the
array is NULL
• The external variable environ points to the process
environment list when the process starts execution.
external char **environ

• If the process is initialized by execl, execlp, execv or


execvp, then the process inherents the environment list of the
process just before execution of exec (more on this later..)

BIL 244 – System Programming


The following sample program outputs the contents of the environment list and exits

#include <stdio.h>

extern char ** environ;

int main (void) {


int i;

printf (“The environment list is as follows : \n”);


for (i=0; environ[i]!=NULL; i++ )
printf (environ[%d]: %s\n, i, environ[i]);

return 0;
}
Process Environment (cont.)

• Environment variables provide a mechanism for using system


specific or user specific information in setting the defaults
within a program (like the program may need to find an
executable file or the directory it has been installed)
• Use getenv to determine whether a specific variable has a value
in the process environment. Pass the name of the environment
variable as a string
#include <stdlib.h>

char *getenv(const char *name);


• Be carefull when calling getenv more than once without
copying the first return string to a buffer (some implemetation of
getenv might use static buffer and overwrite the buffer on each
call)
BIL 244 – System Programming
Process Termination

• When a process terminates, the O/S deallocates the process


resources, updates the appropriate statistics and notifies the other
processes of the demise.
• The activities performed during the process termination include
cancelling pending timers and signals, releasing virtual memory
resources, releasing other process-held system resources (such
as locks), and closing opened files
• The operation systems records the process status and resource
usage, notifying the parent in responce to a wait function
• In UNIX a process does not completely release resources after
its termiantion until the parent waits for it (if parent is not
waiting when the process terminates, the process becomes a
zombie )
BIL 244 – System Programming
Process Termination (cont.)

• A zombie process is an inactive process whose


resources are deleted later when its parent waits
for it
• When a process terminates its orphaned children
and zombies are adopted by a special system
process called the init process (a process with
the process ID value 1 that periodically waits for
childeren)

BIL 244 – System Programming


Process Termination (cont.)

• The termination can either be normal or abnormal


• A normal termination occurs when
• return form a main
• Implicit return from main (the main falls off the end)
• Call to an exit, _Exit or _exit
• User defined exit handles can also be installed
using the atexit funciton

#include <stdlib.h>

İnt atexit(void (*func)(void));

BIL 244 – System Programming

You might also like