-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemory.h
More file actions
247 lines (198 loc) · 6.97 KB
/
memory.h
File metadata and controls
247 lines (198 loc) · 6.97 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
//
// Created by selman.ozleyen2017 on 3.07.2020.
//
#ifndef OSFINAL_MEMORY_H
#define OSFINAL_MEMORY_H
#include <vector>
#include <fstream>
#include <chrono>
#include <thread>
#include <mutex>
#include <atomic>
#include <functional>
#include <condition_variable>
#include <map>
#include <sstream>
#include <queue>
#include <list>
#define INT_PERIOD 20
#define TAU 40
#define WSStep 100
enum ReplacementPolicy{
nru,fifo,sc,lru,wsclock
};
enum AllocPolicy{
local,global
};
class ProcessStats{
public:
uint64_t noReads = 0;
uint64_t noWrites = 0;
uint64_t noPageMisses = 0;
uint64_t noPageReplacement = 0;
uint64_t noDiskWrites = 0;
uint64_t noDiskReads = 0;
ProcessStats operator+(const ProcessStats& ps) const;
ProcessStats operator/(int div) const;
};
/* Class For An Entry Of Page Table*/
struct PageTableEntry{
public:
unsigned long int counter = 0;
struct timespec timer{0,0};
bool present = false;
bool modified = false;
bool referenced = false;
/* First numPhysical bits will be used in pageFrameNo */
unsigned int pageFrameNo = 0;
};
/*
* Is the abstraction for memory
* when there is a get/set request
* this class will abstract away the
* cache and will act as if there is only
* one memory (in the layout of vm) we
* need to access.
*/
class Memory {
public:
Memory(int frameSize, int numPhysical, int numVirtual, int pageTablePrintInt,
ReplacementPolicy replacementPolicy, AllocPolicy allocPol, const char * diskFileName);
~Memory();
Memory(const Memory& mem) = delete ;
Memory& operator=(const Memory& other) = delete;
void set(unsigned int index, int value, char * tName);
int get(unsigned int index, char * tName);
void addProcess(const std::function<void(Memory *)> &func, const char *tName);
void startProcesses();
void waitProcesses();
void writeDisk(unsigned int destPageNo,unsigned int srcFrameNo);
void readDisk(unsigned int srcPageNo,unsigned int destFrameNo);
void printPageTable();
int getSimulationPid(const char * tName) const;
std::string getThreadNameFromPid(int pid) const;
unsigned long getIntCount() const;
void printStats() const;
ProcessStats getTotalStats() const;
class ContPartition;
class NRUPart;
class LRUPart;
class FIFOPart;
class SCPart;
class WSClockPart;
/* RECORDING STATS FOR THE BONUS PARTS */
std::map<std::string,std::vector<std::vector<bool>>> processWs{};
std::map<std::string,ProcessStats> stats;
private:
/* Class to Contain Frames In Memory */
class FrameCont{
public:
explicit FrameCont(Memory *parent);
~FrameCont();
FrameCont();
FrameCont(const FrameCont& fc) = delete;
FrameCont& operator=(const FrameCont& fc) = delete;
unsigned int updatePT(unsigned int va, int pid, bool modified, bool referenced);
void clear();
void set(int processCount, const std::vector<unsigned int> &freeFrames);
private:
void loadToMem(unsigned int pageNo, int pid, ProcessStats &pStats);
Memory* parent;
std::vector<Memory::ContPartition*> partitions;
};
/* Function that will return if it is a hit or not*/
bool checkHit(unsigned int index) const;
unsigned int getPhyAddr(unsigned int va) const;
void resetRBits();
const int frameSize;
const int numPhysical;
const int numVirtual;
const int pageTablePrintInt;
const ReplacementPolicy replacementPol;
const AllocPolicy allocPol;
const char * diskFileName;
uint64_t PC = 0;
/* Physical Memory*/
std::vector<int> pMem;
const long unsigned int pMemSize;
const long unsigned int vMemSize;
const long unsigned int pageIntCount; // how many int a page hold
const long unsigned int pageSizeByte; // page size in bytes
std::vector<PageTableEntry> pageTable; // Has same elements as the pageCount of VM
long unsigned int refCount = 0;
std::fstream diskStream; // file representing the disk
// for the interrupt thread
const int interruptPeriod = INT_PERIOD;
std::mutex memMutex; // for saving the memory from the race conditions
/* Thread to reset R bits periodically*/
std::thread intThread;
std::atomic_bool stopSysThread{false};
static std::chrono::nanoseconds convertTs(struct timespec t);
/* PROCESS MANAGEMENT START */
/* The size of the process management variables won't change between;
* startProcesses()
* ...
* endProcesses()
*
* calls
* */
FrameCont cont;
std::vector<std::function<void(Memory*)>> processFuncs;
std::map<std::string,int> processNames;
std::vector<std::thread> processThreads;
/* PROCESS MANAGEMENT END */
};
class Memory::ContPartition{
public:
ContPartition(Memory *mem, std::vector<unsigned int> freeFrames);
virtual ~ContPartition() = default;
ContPartition() = delete;
/*
* Returns the replaced/free Frame and the replaced frame pageNo if the frame was free
* replacedFramePageNo will be -1
*/
virtual unsigned int getFrame(unsigned int pageNo, long *replacedFramePageNo) = 0;
/* Free frame no's in the physical memory*/
Memory * parent = nullptr;
std::vector<unsigned int> freeFrames;
};
class Memory::NRUPart: public Memory::ContPartition{
public:
NRUPart(Memory *mem, const std::vector<unsigned int> &freeFrames);
unsigned int getFrame(unsigned int pageNo, long *replacedFramePageNo) override;
private:
std::vector<unsigned int> phyLoadedPages;
};
class Memory::LRUPart: public Memory::ContPartition{
public:
LRUPart(Memory *mem, const std::vector<unsigned int> &freeFrames);
unsigned int getFrame(unsigned int pageNo, long *replacedFramePageNo) override;
std::vector<bool> ws;
private:
std::vector<unsigned int> phyLoadedPages;
};
class Memory::FIFOPart: public Memory::ContPartition{
public:
FIFOPart(Memory *mem, const std::vector<unsigned int> &freeFrames);
unsigned int getFrame(unsigned int pageNo, long *replacedFramePageNo) override;
private:
std::queue<unsigned int> phyLoadedPages;
};
class Memory::SCPart: public Memory::ContPartition{
public:
SCPart(Memory *mem, const std::vector<unsigned int> &freeFrames);
unsigned int getFrame(unsigned int pageNo, long *replacedFramePageNo) override;
private:
std::queue<unsigned int> phyLoadedPages;
};
class Memory::WSClockPart: public Memory::ContPartition{
public:
WSClockPart(Memory *mem, const std::vector<unsigned int> &freeFrames);
unsigned int getFrame(unsigned int pageNo, long *replacedFramePageNo) override;
private:
void incHand();
std::list<unsigned int> phyLoadedPages;
std::list<unsigned int>::iterator hand;
std::chrono::nanoseconds tau{};
};
#endif //OSFINAL_MEMORY_H