Lab 3 Demand Paging I mplement the following syscalls xmmap xmunmap vcreate vgetmem vfreemem srpolicy Deadline March 22 2015 1000 PM Demand Paging OS From the OS perspective ID: 794244
Download The PPT/PDF document "Lecture 11 PA2 , lock, and CV" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
Lecture 11PA2, lock, and CV
Slide2Lab 3: Demand Paging
I
mplement
the following
syscalls
xmmap
,
xmunmap
,
vcreate
,
vgetmem
/
vfreemem
,
srpolicy
Deadline: March 22 2015, 10:00 PM
Slide3Demand Paging – OS
From the OS perspective:
Evict pages to disk (
backing store
) when memory is full
Pages loaded from disk when referenced again
References to evicted pages cause a TLB miss
Page table entry (PTE) was invalid, causes fault
OS allocates a page frame, reads page from disk
When I/O completes, the OS fills in PTE, marks it valid, and restarts faulting process
Dirty vs. clean pages
O
nly
dirty pages need to be written to disk
Clean
pages do not – but you need to know where
on disk
to read them from again
Slide4Demand Paging – process
From the process perspective:
Demand paging is also used when it first starts up
When a process is created, it has
A brand new page table with all valid bits off
No pages in memory
When the process starts executing
Instructions fault on code and data pages
Faulting stops when necessary code/data pages are in memory
Only code and data needed by a process needs to be loaded, which will change over time …
When the process terminates
All related pages reclaimed back to OS
Slide5Physical Memory Layout
---------------------------------
Virtual
Heap
(pages
4096 and beyond
) (8M-4G)
---------------------------------
16 Backing
stores (pages
2048 - 4095
) (8M)
---------------------------------
1024 Free
F
rames (pages
1024 - 2047
) (4M)
---------------------------------
Kernel Memory (pages 406 - 1023
)
---------------------------------
Kernel Memory, HOLE (pages 160 - 405)
---------------------------------
Kernel Memory (pages 25 - 159)
---------------------------------
Xinu
text, data,
bss
(pages 0 - 24)
----------------------------------
Slide6Backing StoresThere are 16 backing stores in total:
APIs:
get_bs
/
release_bs
,
read_bs
/
write_bs
Emulated by physical memory
Skeleton already given
You may want to add some sanity check!
Slide7Other IssuesThe NULL process
No
private heap
Global
page table entries
The
entire 16M physical memory
Identity
mapping
Page
fault ISR
p
aging/
pfintr.S
,
paging/
pfint.c
Support
data structures
Inverted
page table
Help
functions
E.g
., finding a backing store from a virtual address
Slide8Intel System ProgrammingOuter Page Table (Page Directory) = 1024 page directory entries in a page directory
Page Table = 1024 page table entries in a page table
Page - 4-KB
PDBR = Page Directory Base Register (CR3): points to the start address of Page Directory (Outer Page Table)
TLB - lookup in page tables in memory are performed only when the TLBs do not contain the translation information for a requested page.
invalidate - automatically invalidated any time the CR3 register is loaded.
Slide9From Boot
Initialize (zero out the values)
backing store - (create data structures)
frames - (create data structures)
install page fault handler
Create new page table for null process:
create page directory (outer page table)
initialize 1:1 mapping for the first 4096 pages
allocate 4 page tables (4x1024 pages)
assign each page table entry to the address starting from page number 0 to 1023
this page tables should be shared between processes
Slide10From Boot - 2
Enable
paging
set bit 31st of the CR0
register
take care that PDBR is set, because subsequent
memory address
access will be virtual memory addresses
Creating new process (
eg
. main
):
create page directory (same as with null process
)
share the first 4096 pages with null
process
Context
switch
every process has separate page directory
before
ctxsw
() load CR3 with the process's PDBR
Slide11Using Virtual Memory
Allocate pages in backing store
Map it to virtual page using
xmmap
()
for example if you do
xmmap
(A,
backingstore
, 10)
then the mapping would be made to consecutive locations in
backingstore
for
virtual pages: A, A+1, A+2, ..., A+9
Then try accessing the virtual address
If the page is not present a Page Fault is generated
Slide12Page Fault
Address that caused page
fault
content of CR2
register
Search for the page table entry. Two cases
:
a
).
second
level page table does not
exist
b
). second
level page table exists but the
page table
entry does not
exist
How
do we know? Use the P flag for
page directory/table
entry
Slide13Page Fault - 2Case a)
allocate
a frame -> initialize (zero out the page table frame)
update
the page directory entry with base address of the
page table
frame
Now
this case becomes Case (b)
Slide14Page Fault - 3
Case b)
Locate backing store id of the faulted page, the page number in the backing store.
Find a free frame to store the page from backing store
if found: use the free frame
if not found: evict a page frame (Page Replacement Algorithm)
Update the page table entry for the page and possibly for evicted page frame
Slide15Using Virtual Memory
Allocate pages in backing store
Map it to virtual page using
xmmap
()
for example if you do
xmmap
(A,
backingstore
, 10)
then the mapping would be made to consecutive locations in
backingstore
for
virtual pages: A, A+1, A+2, ..., A+9
Then try accessing the virtual address
If the page is not present a Page Fault is generated
Finally: Flush TLB content, by reloading CR3 with page directory address
Slide16Virtual address has page table offset as well as page directory offset.
PageTableNumber
(31-22)
PageNumber
(21-12) Offset(11-0
)
Page Directory/Table Entry Format
31-12
PFA page
frame address
11- 9
Avail
available
to OS
8 0 must
be 0
7 L PTE
-- Must be 0.
Dir
Entry -- 4MB page
6 D dirty
(PTE only -- documented as
undefined
in directory entry)
5 A accessed
4 PCD page
cache
disable
(can't
cache data on this page)
3
PWT page
write transparent (tell
external cache
to use
write-through strategy
for this page)
2 U
user accessible
1
W
writeable
0
P
present
Slide17Last lectureControlling interrupts
Test
and set (atomic exchange)
Compare and swap
Load linked
and
store conditional
Fetch and add
and
ticket locks
Slide18typedef
struct
__
lock_t
{
int
ticket;
int
turn;
}
lock_t
;
void
lock_init
(
lock_t
*lock) {
lock->ticket = 0
; lock-
>turn = 0;
}
void
lock(
lock_t
*lock) {
int
myturn
=
FetchAndAdd
(&lock->ticket);
while (lock->turn !=
myturn
)
; // spin
}
void
unlock(
lock_t
*lock) {
FetchAndAdd
(&lock->turn
);
}
Slide19Slide20Sleeping Instead Of SpinningOn Solaris, OS provides two calls:
park
()
to put a calling thread to
sleep
unpark
(
threadID
)
to wake a particular thread as designated by
threadID
Slide21typedef
struct
__
lock_t
{
int
flag;
int
guard;
queue_t
*q;
}
lock_t
;
void
lock_init
(
lock_t
*m) {
m->flag = 0;
m->guard = 0;
queue_init
(m->q);
}
Slide22void
lock(
lock_t
*m) {
while (
TestAndSet
(&m->guard, 1) == 1)
; //acquire guard lock by spinning
if (m->flag == 0) {
m->flag = 1; // lock is acquired
m-
>guard = 0;
}
else {
queue_add
(m-
>q,
gettid
());
setpark
();
m-
>guard = 0;
park
();
}
}
Slide23void
unlock(
lock_t
*m) {
while
(
TestAndSet
(&m->guard, 1) == 1)
; //acquire guard lock by spinning
if (
queue_empty
(m->q))
m->flag = 0; // let go of
lock; no
one wants it
else
// hold lock (for next thread!)
unpark
(
queue_remove
(m-
>q
));
m-
>guard = 0;
}
Slide24Different Support on LinuxOn
Linux
,
OS provides two calls:
f
utex_wait
(address
,
expected)
puts
the calling thread to sleep, assuming the value at address is equal to expected. If it is not equal, the call returns
immediately.
f
utex_wake
(address
)
wakes one thread that is waiting on the queue.
Slide25void
lock(
lock_t
*m) {
int
v;
/*
Bit 31 was clear, we got the
mutex
(
fastpath
) */
if
(
atomic_bit_test_set
(
m
,
31) ==
0) return
;
atomic_increment
(
m
);
while (1) {
if (
atomic_bit_test_set
(m,
31) == 0) {
atomic_decrement
(m); return
;
}
/*
We have to wait now. First make sure the
futex
value
we are monitoring is truly negative (i.e. locked). */
v
=
*m;
if
(v >= 0
)
continue;
futex_wait
(m,
v);
}
}
Slide26void
unlock(
lock_t
*m) {
/*
Adding 0x80000000 to the counter results in
0 if
& only if there
are not other interested threads */
if
(
atomic_add_zero
(
mutex
, 0x80000000))
return;
/* There are other threads waiting for this
mutex
,
wake one of them up. */
futex_wake
(
mutex
);
}
Slide27Lock Usage ExamplesConcurrent
Counters
Concurrent Linked
Lists
Concurrent Queues
Concurrent Hash Table
Slide28Concurrency ObjectivesMutual exclusion (e.g., A and B don’t run at same time)
solved
with locks
Ordering (e.g., B runs after A)
solved
with condition variables
Slide29Condition VariablesCV’s are more like channels than variables.
B waits for a signal on channel before running.
A sends signal when it is time for B to run
.
A CV also has a queue of waiting threads
.
A CV is usually PAIRED with some kind state
variable
。
Slide30Broken CV’swait(cond_t
*cv)
puts
caller to sleep (and on queue)
signal(
cond_t
*cv)
wake
a single waiting thread (if >= 1 thread is waiting)
if
there is no waiting thread, just return w/o doing anything
Slide31When to Call wait
if (!ready)
wait
(&cv);
lock(&
mutex
);
// critical section
unlock(&
mutex
);
lock
(&
mutex
);
//
critical section
if (!ready)
wait(&cv);
unlock(&
mutex
);
Slide32Correct CV’swait(
cond_t
*cv,
mutex_t
*lock)
assumes
the lock is held when wait() is called
puts
caller to sleep + releases the lock (atomically)
when
awoken, reacquires lock before returning
signal(
cond_t
*cv)
wake
a single waiting thread (if >= 1 thread is waiting)
if
there is no waiting thread, just return w/o doing anything
Slide33Ordering Example: Join
pthread_t
p1, p2;
printf
("main: begin [balance = %d]\n", balance);
Pthread_create
(&p1, NULL,
mythread
, "A");
Pthread_create
(&p2, NULL,
mythread
, "B");
// join waits for the threads to finish
Pthread_join
(p1, NULL);
Pthread_join
(p2, NULL);
printf
("main: done\n [balance: %d]\n [should: %d]\n",
balance, max*2);
return 0;
Slide34Implementing Join with CV’s (attempt 1)
void
thread_exit
() {
Mutex_lock
(&m);
//
a
Cond_signal
(&c);
//
b
Mutex_unlock
(&m);
//
c
}
void
thread_join
() {
Mutex_lock
(&m);
//
x
Cond_wait
(&c, &m); // y
Mutex_unlock
(&m
);
// z
}
Slide35Implementing Join with CV’s (attempt 2)
void
thread_exit
() {
done = 1
; //
a
Cond_signal
(&c);
//
b
}
void
thread_join
() {
Mutex_lock
(&m);
//
w
if (done == 0)
//
x
Cond_wait
(&c, &m); // y
Mutex_unlock
(&m);
//
z
}
Slide36Good Rule of ThumbKeep state in addition to CV’s!
CV’s are used to nudge threads when state changes.
If state is already as needed, don’t wait for a nudge
!
Always do wait and signal while holding the lock
!