ECE 329 Section 01 Spring 2006 Exam 2--Solution
Name:________KEY___________
Grade:______________________
1.) Term matching: Write the BEST term for each definition. Not all terms will be used. Some
may be used twice. (14 points)
hierarchical paging
process
round-robin
monitor
multi-programmed sys. PCB
shortest remaining time first
critical region
internal fragmentation
aging
critical section
external fragmentation EAT
starvation
hold-and-wait
paging
ready queue
deadlock
no preemption
swapping
inverted page table
multilevel queue scheduling
circular wait
compaction
thrashing
queueing-network analysis
deadlock prevention
best-fit
working set
simulation
deadlock avoidance
first-fit
page fault
race condition
deadlock detection
worst-fit
degree of
multiprogramming
page table
deadlock recovery
a page
process mix
segment table
bounded buffer
a frame
medium-term scheduler bakery algorithm
user mode
TLB
context switch
banker's algorithm
supervisor mode
segmentation
thread
atomicity
main memory
virtual memory
user-level threads
fetch and add
hard disk drive
pager
kernel-level threads
semaphore
sigsetjmp
swapper
first come first serve
spinlock
siglongjmp
locality
shortest job first
readers writers
setitimer
COW
__segment table _______: Stores base and limit values.
__virtual memory_______: Makes programming easier because the programmer does not have to worry
about the amount of physical memory that will be available.
__main memory_______: Is partitioned into frames and is the destination of pages returning from the
backing store.
_______EAT ______: Is a metric that addresses the additional overhead in memory access due to the
paging subsystem.
______worst-fit_______: Results in the largest leftover hole.
_____compaction__________: Helps correct external fragmentation.
degree of multiprogramming: If this becomes too high, thrashing may ensue.
2.) Short Answer: Briefly explain the DIFFERENCE between the two terms: (12 points)
a) logical address space and physical address space
The logical address space is the set of all logical addresses generated by the program. An address
generated by the CPU is commonly referred to as a logical address. This address is then mapped to a
physical memory address by the MMU. In this sense, the logical address is a virtual address in that it
differs from the physical location where that data actually resides.
b) page fault and a TLB miss
In a paging system where both a TLB and a page table are being used, when a logical address is
generated, the TLB is first consulted to determine if the mapping has been cached, and if not, this is
referred to as a TLB miss (i.e. the entry is not in the TLB). Then the page table is consulted to
determine what the physical memory address is for the logical address originally generated. If the
associated page in not yet in memory, a page fault is generated, and the page is brought from the
backing store to MM. The instruction that generated the page fault is then restarted.
c) paging and swapping
Both refer to moving data to and from the backing store to MM. Generally, in the case of swapping, the
entire process is moved to and from MM from the backing store, while swapping refers to the scenario
where the process is broken into fixed sized blocks, called pages, and the data can be moved in units of
pages, rather than the entire process as a whole. This allows for considerable more flexibility, including
the possibility of non-contiguous memory allocation, as well as not needing to have the entire process
in memory to execute. It also make using overlays a thing of the past.
d) frame allocation and page replacement
Frame allocation refers to: how to divide up the total number of frames among the competing
processes. There is a minimum number of frames that a process will require given the architectural
features. Additionally, one might choose to use an equal or proportional strategy to assign a number of
frames to a process. Page replacement refers to the scenario where a page-fault has occurred, and must
be paged in, but there are no free frames. In this case, an existing page, must be selected as a victim,
and sent back to the backing store. The process of selecting a victim frame is page replacement. The
page replacement strategy can also affect the frame allocation goals as well, as is the case in global
replacement.
3.) Discussion: Write a brief paragraph to answer the following questions: (48 points)
a) Explain the concept of working set and how it relates to memory management, performance,
and the degree of multiprogramming.
Due to locality, programs tend to move through phases of execution that require certain actively used
sets of pages to satisfy memory requests. During a given phase, this set of actively required pages is
referred to as the working set. This set it typically identified as the set of pages that have been
referenced during the last certain amount of time or number of instructions. If a process does not have
access to its working set, the number of page faults will be higher. The page fault rate will ultimately be
tied to the disparity between the number of pages it needs in its working set, and how many it actually
has; as the disparity increases, so does the page-fault rate. The higher the PFR, the worse the
performance. The higher the MPL, the less space in MM there will be per process, thus the less space
there will be to accommodate the working set of each process. As the MPL increases beyond a certain
point, more processes will encounter the situation where their number of frames will not be sufficient to
support their entire working set, and the page-fault rate will worse for all affected processes. This
condition leads to thrashing.
b) What is the difference between internal and external fragmentation, and how do these relate to
both paging and segmentation?
Fragmentation refers to the situation where there is “free” (unused) memory locations that cannot be
used. The internal type is when a block of memory has been assigned to a process, but that process does
not need the entire block. In this case, the leftover memory cannot be used by another process, and it
not being used by the assigned process. This typically occurs when memory is partitioned into fixed
size blocks, as with paging. The external type happens when there are “holes” in physical memory that
are spread out, such that no single hole can satisfy the requirement of a given process, but that
collectively there is still enough “free” memory to satisfy the process; or at the very least, the dynamic
allocation problem is introduced in which a combination has to be found that will allow the memory
needed to fit among the holes. This happens when memory is partitioned into variable-sized blocks, and
as process enter and leave, “holes” in the physical address space begin to form, as is the case with pure
segmentation.
c) What is the rationale behind using a TLB in conjunction with a page table, and what are some
of the governing factors in the performance obtained through the use of a TLB?
Since page table may require thousands to millions of entries, the use of registers to hold the entire
page-table is not feasible. In this case, there may be some hardware real-estate that can be dedicated to
holding a portion of the page-table in high-speed registers, or TLB. The TLB is essentially a hardware
cache for storing portions of the page-table. The reason this is important is to reduce the EAT, since if
the page-table was consulted each time from MM itself, two memory references would be necessary
each time an address was generated, once for the page-table, and once for the memory itself. Having a
cache, helps improve the situation; however the extent to which it does depends on a number of factors.
Once of the biggest is the locality behavior of the program. If it is completely random, the TLB is not
likely to help. Another factor is the relative size of the TLB versus the page-table. Of course, the size of
the page-table is governed by the size of a page versus the size of physical memory (or even virtual
memory for that matter). The TLB miss/hit rate/ratio is also important.
d) Explain the difference between local and global page replacement, and describe the arguments
for and against each strategy.
Local replacement refers to the situation where a process experiences a page-fault, and the only pages
that can be selected as victims for replacement are the pages already possessed by the process.
Alternatively, global replacement is when the victim can be selected from the pages belonging to any
process. There are several arguments, including that local replacement keeps the page fault-rate a
function of just the behavior of the process itself; because global interferes with the pages of other
processes. However, local also keeps the number of frames belonging to a given process fixed,
implying that while a process may have frames that would be good candidates for replacement, because
they are not actively being used by the process, these frames cannot be used by other processes that
have more actively used frames.
e) What is the optimal page replacement strategy, and why is it important for analyzing the
performance of other replacement strategies?
OPT results in the lowest number of page-faults by replacing pages that will be referenced farthest in
the future. This requires having a priori knowledge of the memory reference sequence, which is not
known for the majority of actual running programs. It is however still important, because it allows us to
establish an upper bound on the performance that can be obtained from sub-optimal replacement
strategies, and thus gives something to shoot for.
f) Explain what happens during thrashing, why it is bad, and what can reasonably be done to
prevent it.
Thrashing is essentially when the page-fault rate is so high, that the system spends most of its time
paging in and out, rather than actually doing computation. This leads to low CPU utilization. As
explained in part (a), if the MPL is too high that the working set or sets can not be satisfied by the
number of available frames, thrashing can ensue. One way to keep it from happening is the keep track
of the working sets, and do not increase the MPL too high. If the working sets grow too large, a process
may been to be temporarily halted, and its frames divided among the remaining processes to help stop
thrashing (and low CPU utilization as a consequence). A more straight-forward approach might include
trying to keep the page-fault rate to an acceptable level like this: If the rate it to high, suspend a process
if necessary and redistribute released frames, if it is too low, process loses frame(s) and are added back
to the pool, so that if another process can be started, the MPL can be increased. This is beneficial in that
it does not require the explicit tracking of the working set of each process.
4.) C Prog.: Given the following program package (prog.c, foo.c, bar.c, foo.h, bar.h) (26 points)
foo.c:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
struct fooStruct {
int fooSize;
foo fp;
};
foo fooInit(void) {
foo temp = (foo) malloc(sizeof(struct fooStruct));
temp>fooSize = 1;
temp>fp = temp;
return temp;
}
bar.c:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
#include "bar.h"
prog.c:
#include<stdio.h>
#include<stdlib.h>
#include "foo.h"
#include "bar.h"
int main(void) {
int tmp;
foo foo1 = fooInit();
bar bar1 = barInit(foo1);
tmp = foo1>fooSize;
printf("size of foo is: %d \n", tmp);
return 0;
}
foo.h:
#ifndef _FOO
#define _FOO
typedef struct fooStruct* foo;
foo fooInit(void);
#endif
struct barStruct {
int barNum;
foo fp;
};
bar barInit(foo arg) {
bar temp = (bar) malloc(sizeof(bar));
temp>barNum = 2;
temp>fp = arg;
return temp;
}
bar.h:
#ifndef _BAR
#define _BAR
#include "foo.h"
typedef struct barStruct* bar;
bar barInit(foo);
#endif
a) What is the function and purpose of the #ifndef's in the header files? (10 points)
These are used to control having a header file included more than once for a given compilation. This
allows the programmer to include the associated header for a given compilation, and not to worry in the
header is included in some other dependency. It also, allows a more organized structure, because the
programmer only has to include headers associated with functions, etc that are directly used in the
program his is currently compiling. (I explained this in class one day)
b) What is (are) the problem(s) with this code, and why? (read the next question before answering)
tmp = foo1>fooSize; // This is problem since it is dereferencing a pointer to an incomplete type.
bar temp = (bar) malloc(sizeof(bar)); // this is a problem because it is mallocing the space only for a pointer (4 bytes) rather than for the entire structure.
c) What would be the BEST and most modular way to fix any problem(s) you identified above
Illustrate how to fix to the code below, by changing / adding to the code itself, in the open spaces.
foo.c:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
struct fooStruct {
int fooSize;
foo fp;
};
foo fooInit(void) {
foo temp = (foo) malloc(sizeof(struct fooStruct));
temp>fooSize = 1;
temp>fp = temp;
return temp;
}
// Add this here
int fooSize(foo fp) {
return fp>fooSize;
}
prog.c:
#include<stdio.h>
#include<stdlib.h>
#include "foo.h"
#include "bar.h"
int main(void) {
int tmp;
foo foo1 = fooInit();
bar bar1 = barInit(foo1);
// remove this
tmp = foo1>fooSize;
// add this
tmp = fooSize(foo1); printf("size of foo is: %d \n", tmp);
return 0;
}
bar.c:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
#include "bar.h"
struct barStruct {
int barNum;
foo fp;
};
bar barInit(foo arg) {
// remove this
bar temp = (bar) malloc(sizeof(bar));
// replace with
bar temp = (bar) malloc(sizeof(struct barStruct));
temp>barNum = 2;
temp>fp = arg;
return temp;
}
foo.h:
#ifndef _FOO
#define _FOO
typedef struct fooStruct* foo;
foo fooInit(void);
// Add this here
int fooSize(foo);
#endif
bar.h:
#ifndef _BAR
#define _BAR
#include "foo.h"
typedef struct barStruct* bar;
bar barInit(foo);
#endif
© Copyright 2026 Paperzz