Suppose the following actions occur:
|
E requests 300: E is allocated in 400-700
A requests 400 more: cannot fit because the entire process is
allocated in a single continuous chunk of memory in a segmented memory
system. Need to compact memory: move B to 1100-1900, move E to
2400-2800, give A
additional addresses 400-800
B exits: there is a hole between 800-1900
F requests 800: F is allocated in 800-1600
C exits: there is a hole between 1600-2400
G requests 900: no hole that is big enough. Compact memory: move
E to 2800-3100, G is allocated in 1600-2500
E requests 300: E is allocated in 1600-1900
A requests 400 more: this 400 is allocated in 400-800
B exits: there is a hole between 800-1600
F requests 800: F is allocated in 800-1600
C exits: there is a hole between 1900-3100
G requests 900: G is allocated in 1900-2800
E requests 300: E is allocated in 2400-2700
A requests 400 more: this additional 400 is allocated in 400-800
B exits: there is a hole between 800-1900
F requests 800: F is allocated in 800-16000
C exits: there is a hole between 1600-2400
G requests 900: no hole big enough. Need to compact: move E to
2800-3100, give 1600-2500 to G.
For this example, best-fit is best.
Address translation will now map the virtual address to the new copy of the page and the write operation will now succeed.
When forking a process, it would be best to mark all pages as copy-on-write and allow the original and forked processes to share pages until one of them attempts to modify the page. This would be much more efficient than actually copying the address space on the fork operation.
Virtual address bits: log2(8x512) = 12 bits.
Physical address bits: log2(16x512) = 13 bits.
Virtual | Page |
---|---|
Page | Frame |
0 | 0 |
1 | 8 |
2 | 11 |
3 | 6 |
4 | 3 |
5 | 1 |
6 | 7 |
7 | 10 |
binary physical address = 0 0110 1111 0001 so, physical address = 1777
It is easier for processes to share code pages in a system combining
segments and paging because the offset within the segment will be the
same for each process that shares the segment.
Whole segments can be shared by sharing
the segment table.
Without segmentation, we need to be sure that each chunk of shared
pages (like the code) and each chunk of
non-shared pages (like the stack) begins on a page boundary, since we
cannot share just part of a page. Mapping virtual memory onto pages
is done simply by dividing the virtual address space into units that
are the size of the hardware page frames. To place page boundaries at
the right places, the compiler would need to be know the size of the
hardware page frames when generating the virtual addresses used in
object code. This is obviously more difficult than generating
separate segments for each chunk.
2*150=300 ns
Let p=percent of page table references need to hit in the TLB, then
155 = p*150 + (1-p)*300
so, p=96.6%