-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemorySimulatorBase.java
More file actions
264 lines (229 loc) · 6.93 KB
/
MemorySimulatorBase.java
File metadata and controls
264 lines (229 loc) · 6.93 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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Starter code for a memory simulator.
* Simulator strategies extend this abstract class.
*/
public abstract class MemorySimulatorBase {
protected static final int MEM_SIZE = 560;
protected static final char FREE_MEMORY = '.';
protected static final char RESERVED_MEMORY = '#';
protected int CURRENT_TIME = -1;
protected char[] main_memory;
protected ArrayList<Process> processes;
protected static final boolean MEMSIM_DEBUG = true;
private int timeAdded;
/**
* Default constructor that takes an input file
* @param fileName
*/
public MemorySimulatorBase(String fileName) {
main_memory = new char[ MEM_SIZE ];
processes = InputFileParser.parseInputFile( fileName );
initializeMainMemory();
for (Process p : processes) {
debugPrintln("Process " + p.getPid() + " (size " + p.getSize() + ")");
debugPrintln(" Start Time: " + p.getStartTime());
debugPrintln(" End Time: " + p.getEndTime());
}
}
/**
* Return the index of the first position of the next available slot
* in memory
*
* Different memory strategy classes must override this abstract method.
* @param slotSize The size of the requested slot
* @return The index of the first position of an available requested block
*/
protected abstract int getNextSlot(int slotSize);
/**
* Move the simulator one virtual time step into the future,
* handling processes leaving and entering the system.
* NOTE: Not used now that the project specifications have changed.
*/
public void timeStep() {
CURRENT_TIME++;
while (!eventOccursAt(CURRENT_TIME)) {
debugPrintln("Fast-forwarding past boring time " + CURRENT_TIME);
CURRENT_TIME++;
}
debugPrintln("=========== TIME IS NOW " + CURRENT_TIME + " ============");
//Processes exit the system
ArrayList<Process> toRemove = new ArrayList<Process>();
for (Process p : processes) {
if (p.getEndTime() == CURRENT_TIME) {
debugPrintln("Removing process " + p.getPid());
removeFromMemory(p);
toRemove.add(p);
}
}
for (Process p : toRemove) {
processes.remove(p);
}
//Processes enter the system
for (Process p : processes) {
if (p.getStartTime() == CURRENT_TIME) {
debugPrintln("Adding process " + p.getPid());
putInMemory(p);
}
}
}
/**
* Move the simulator into the future
* @param t The time to which to move the simulator
*/
public void timeStepUntil(int t) {
while (CURRENT_TIME < t) {
CURRENT_TIME++;
while (!eventOccursAt(CURRENT_TIME) && CURRENT_TIME < t) {
debugPrintln("Fast-forwarding past boring time " + CURRENT_TIME);
CURRENT_TIME++;
}
debugPrintln("=========== TIME IS NOW " + CURRENT_TIME + " ============");
//Processes exit the system
ArrayList<Process> toRemove = new ArrayList<Process>();
for (Process p : processes) {
if (p.getEndTime() == CURRENT_TIME) {
debugPrintln("Removing process " + p.getPid());
removeFromMemory(p);
toRemove.add(p);
}
}
for (Process p : toRemove) {
processes.remove(p);
}
//Processes enter the system
for (Process p : processes) {
if (p.getStartTime() == CURRENT_TIME) {
debugPrintln("Adding process " + p.getPid());
putInMemory(p);
}
}
if(eventOccursAt(CURRENT_TIME))
printMemory();
}
}
/**
* Find whether an event occurs at a specific time
* Useful for ascertaining if we can skip a time in the simulator
* @param time The time we should check to see if an event occurs
* @return True if an event occurs at time, else false
*/
private boolean eventOccursAt(int time) {
for (Process p : processes) {
if (p.getStartTime() == time || p.getEndTime() == time) {
return true;
}
}
return false;
}
/**
* Put a process into memory
* @param p The process to put into memory
*/
protected void putInMemory(Process p) {
int targetSlot = getNextSlot(p.getSize());
if (targetSlot == -1) {
defragment();
targetSlot = getNextSlot(p.getSize());
if (targetSlot == -1) {
Externals.outOfMemoryExit();
}
}
debugPrintln("Got a target slot of " + targetSlot + " for pid " + p.getPid());
//If we get here, we know that there's an open chunk
for (int i = 0; i < p.getSize(); i++) {
main_memory[i+targetSlot] = p.getPid();
}
}
/**
* Take a process out of memory
* @param p The process to remove from memory
*/
protected void removeFromMemory(Process p) {
for (int i = 0; i < main_memory.length; i++) {
if (main_memory[i] == p.getPid()) {
main_memory[i] = FREE_MEMORY;
}
}
}
/**
* Initialize our main memory with the predetermined amount of reserved and
* free memory
*/
private void initializeMainMemory() {
for (int i = 0; i < 80 && i < main_memory.length; i++) {
main_memory[i] = RESERVED_MEMORY;
}
for (int i = 80; i < main_memory.length; i++) {
main_memory[i] = FREE_MEMORY;
}
}
/**
* Print the current contents of memory
*/
public void printMemory() {
System.out.print("Memory at time " + CURRENT_TIME + ":");
for (int i = 0; i < main_memory.length; i++) {
if (i % 80 == 0) {
System.out.println("");
}
System.out.print( main_memory[i] + "" );
}
System.out.println("");
}
/**
* Attempt to defragment main memory
*/
private void defragment() {
HashMap<Character, Integer> processesMoved = new HashMap<Character, Integer>();
DecimalFormat f = new DecimalFormat("##.00");
System.out.println("Performing defragmentation...");
int destination = 80;
for (int i = 0; i < main_memory.length; i++) {
if (main_memory[i] != FREE_MEMORY
&& main_memory[i] != RESERVED_MEMORY
&& i != destination ) {
main_memory[destination] = main_memory[i];
main_memory[i] = FREE_MEMORY;
destination++;
processesMoved.put(main_memory[i], null);
}
}
int numMoved = processesMoved.size();
int freeBlockSize = main_memory.length - destination;
double percentage = (double)freeBlockSize / (double)main_memory.length;
System.out.println("Defragmentation completed.");
System.out.println("Relocated " + numMoved + " processes " +
"to create a free memory block of " + freeBlockSize + " units " +
"(" + f.format(percentage * 100) + "% of total memory).");
}
/**
* Print a string if a debug flag is set.
* Do not include a newline.
* @param toPrint The string to print
*/
private static void debugPrint(String toPrint) {
if (MEMSIM_DEBUG == true) {
System.out.print(toPrint);
}
}
/**
* Print a string if a debug flag is set.
* Include a newline.
* @param toPrint The string to print
*/
private static void debugPrintln(String toPrint) {
if (MEMSIM_DEBUG == true) {
System.out.println(toPrint);
}
}
/**
* Get the number of processes with events remaining in the simulator
* @return The number of processes with events remaining in the simulator
*/
public int processesRemaining() {
return processes.size();
}
}