-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMMU.cpp
147 lines (126 loc) · 3.59 KB
/
MMU.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//
// Created by conrad on 11/9/17.
//
#include "MMU.h"
#include <tuple>
#include "Hex_Util.h"
// Constructor / Deconstructor
MMU::MMU() {
disk = new Disk();
ram = new Ram();
disk_frame_map = new std::map<int, bool>();
ram_frame_map = new std::map<int, bool>();
free_ram_frames = new M_queue<int*>();
for(int i = 0; i < 512; i++)
{
(*disk_frame_map)[i] = false;
int *num = new int(i);
if(i < 256) {
free_ram_frames->push(num);
}
}
ram_pages_used = 0;
}
MMU::~MMU(){}
// Memory Access ons
std::string MMU::disk_memory(int address, std::string s) {
disk_mutex.lock();
std::string a;
if(s == "NULL"){
a = disk->read(address);
disk_mutex.unlock();
return a;
}
else {
disk->write(address, s);
disk_mutex.unlock();
return s;
}
}
std::string MMU::ram_memory(int address, std::string s) {
std::string a;
ram_mutex.lock();
if(s == "NULL") {
a = ram->read(address);
ram_mutex.unlock();
return a;
}
else {
ram->write(address, s);
ram_mutex.unlock();
return s;
}
}
// Page memory access functions
bool MMU::add_page_to_disk(std::vector<std::string> page, int frame_num) {
// Check if map location is free
// If it is then add the word there, and set the location
// in the map to be not free and return true
disk_mutex.lock();
if((*disk_frame_map).at(frame_num) == false)
{
(*disk_frame_map).at(frame_num) = true;
for(int i = frame_num * 4; i < frame_num*4 + 4; i++)
disk->write(i, page[i%4]);
disk_mutex.unlock();
return true;
}
else{
disk_mutex.unlock();
return false;
}
}
int* MMU::add_page_to_ram(std::vector<std::string> page, int frame) {
// Check if map location is free
// If it is then add the word there, and set the location
// in the map to be not free and return true
int *a;
ram_mutex.lock();
if(frame==-1) a = free_ram_frames->pop();
else a = &frame;
if (a == nullptr) {
std::cout << "Nullptr! in add_page_to_ram" << std::endl;
} else {
for(int i = 0; i < 4; i++) {
ram->write((*a) * 4 + i, page[i]);
}
ram_pages_used++;
std::cout << "Ram pages used " << ram_pages_used << std::endl;
}
ram_mutex.unlock();
return a;
}
std::vector<std::string> MMU::read_page_from_ram(int frame_num) {
std::vector<std::string> output = std::vector<std::string>(4);
ram_mutex.lock();
for (int i = 0; i < 4; i++) {
output[i] = ram->read(frame_num * 4 + i);
}
ram_mutex.unlock();
return output;
}
std::vector<std::string> MMU::read_page_from_disk(int frame_num) {
disk_mutex.lock();
std::vector<std::string> output = std::vector<std::string>(4);
if(frame_num < 0)
throw std::invalid_argument("read_page_from_disk in MMU.cpp " + std::to_string(frame_num));
for (int i = 0; i < 4; i++) {
output[i] = disk->read(frame_num * 4 + i);
}
disk_mutex.unlock();
return output;
}
int MMU::get_ram_frame(int page_num, const PCB *p) {
return std::get<1>(p->page_table.at(page_num));
}
int MMU::get_disk_frame(int page_num, const PCB *p) {
return std::get<0>(p->page_table.at(page_num));
}
void MMU::print_disk_map(bool page_mode) {
for(int i = 0; i < disk_frame_map->size(); i++) {
if (page_mode)
std::cout << "PAGE #" << i << " " << Hex_Util::bool_to_string(disk_frame_map->at(i)) << "\n";
else
std::cout << disk_memory(i) << "\n";
}
}