forked from nykez/memory-simulator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPageFaultHandler.cpp
72 lines (66 loc) · 2.9 KB
/
PageFaultHandler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Project: GroupProject
// File Name: PageFaultHandler.cpp
// Description: Implemenation of PageFaultHandler.h
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "PageFaultHandler.h"
/// <summary>
/// Handle a page fault. Get a PFN for our page.
/// </summary>
/// <param name="PT">pointer to page table</param>
/// <param name="DTLB">pointer to related data TLB</param>
/// <param name="DC">pointer to related data cache</param>
/// <param name="VPNindex">VPN of faulted page.</param>
/// <returns>PFN for new page.</returns>
int PageFaultHandler::HandleFault(PageTable* PT, TLB* DTLB, Cache* DC, int VPNindex) {
int PFN = PageFaultHandler::FindFreeFrame(PT); // Find free frame to use.
if(PFN == -1) { // Is there a free frame?
PFN = PageFaultHandler::LRUReplacePage(PT, DTLB, DC); // If not, swap out a frame.
}
PT->SetEntryPFN(VPNindex, PFN); // Update entry's PFN.
PT->SetEntryValidity(VPNindex,true);// Set as now valid.
return PFN; // Return PFN.
}
/// <summary>
/// Returns PFN of free frame (If any).
/// </summary>
/// <param name="PT">pointer to page table</param>
/// <returns>PFN of free frame. -1 if no free frames.</returns>
int PageFaultHandler::FindFreeFrame(PageTable* PT) {
return PT->AllocateFrame();
}
/// <summary>
/// Runs LRU replacement for pages.
/// </summary>
/// <param name="PT">pointer to page table</param>
/// <returns>PFN of victim entry.</returns>
int PageFaultHandler::LRUReplacePage(PageTable* PT, TLB* DTLB, Cache* DC) {
int LRU = PT->GetAccessOrdinal();
int victimPFN = -1;
int victimVPN = 0;
// Find Least-Recently-Used entry in PT.
for(int i = 0; i < PT->GetTableSize(); i++) {
// If invalid, skip. (It doesn't have a frame).
if(PT->GetEntryValidity(i) == false) continue;
// If least recent so far...
if(PT->GetEntryAccessOrdinal(i) < LRU) {
LRU = PT->GetEntryAccessOrdinal(i); // Update comparer,
victimPFN = PT->GetEntryPFN(i); // update PFN,
victimVPN = i; // and update VPN
}
}
// Update victim entry
PT->SetEntryValidity(victimVPN, false);
if(DTLB != nullptr) {
DTLB->SetEntryValidity(victimVPN, false);
}
// Update DC
int dirtyCount = DC->Invalidate(victimPFN);
if (DC->GetPolicy() == 1) // write-back policy; update mem references
{
memoryReferences++;
}
return victimPFN;
}