diff --git a/os-simulator/src/main/java/com/com1032/assignment/CPUSimulator.java b/os-simulator/src/main/java/com/com1032/assignment/CPUSimulator.java new file mode 100644 index 0000000000000000000000000000000000000000..42cbcedde65dd980bee2606e4a679a725348faea --- /dev/null +++ b/os-simulator/src/main/java/com/com1032/assignment/CPUSimulator.java @@ -0,0 +1,194 @@ +/** + * + */ +package com.com1032.assignment; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author felipedabrantes + * + */ +public class CPUSimulator extends Thread{ + /**Processes running on CPU.*/ + private List<PCB> cpuQueue = new ArrayList<PCB> (); + + /**The global time of the system.*/ + private Clock globalTime = null; + + /**The hardware to use.*/ + private Hardware hardware = null; + + + /** + * Constructor. Initialises fields. + * + * @param os + * @param cpuQueue + */ + public CPUSimulator(Clock globalTime, List<PCB> cpuQueue, Hardware hardware) { + this.cpuQueue = cpuQueue; + this.globalTime = globalTime; + this.hardware = hardware; + } + + + @Override + public void run() { + while(true) { + + //Temporarily stop executing for however milliseconds. + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //Runs process in queue. + this.runCode(); + } + } + + public void runCode() { + if(!this.cpuQueue.isEmpty()) { + + if(this.cpuQueue.get(0).getState() == ProcessState.RUNNING) { + //The process the CPU runs. + PCB processRunning = this.cpuQueue.get(0); + + //Split code string into lines. + String[] codeLines = processRunning.getCode().split("\\r\\n|\\r|\\n"); + + //Increase program counter by one to run next line. + processRunning.increaseProgramCounter(); + + //Compile and run the program counter line. + this.compileLine(processRunning, codeLines[processRunning.getProgramCounter()]); + + //If not blocked, then decrease remaining time and global time by one. + if(processRunning.getState() != ProcessState.BLOCKED) { + processRunning.increaseConsecutiveTimeOnCPU(); + processRunning.decreaseRemainingTime(1); + + //Instruction takes 4 ticks. Each core in processor decreases it by 1. + this.globalTime.increaseTime(5 - this.hardware.getCoresPerProcessor()); + + //If all code finished, then terminate process. + if(processRunning.getProgramCounter() == codeLines.length - 1) { + processRunning.setState(ProcessState.TERMINATED); + } + } + } + } + } + + + public void compileLine(PCB processRunning, String line) { + + try { + + Map<String, Integer> variables = processRunning.getVariables(); + + if(line.equals("")) { + return; + } + + String command = line.split(" ")[0]; + + //STORE NAME VALUE + if(command.toLowerCase().equals("store")) { + String newVariableName = line.split(" ")[1]; + Integer newVariableValue = 0; + + if(line.split(" ")[2].startsWith("#")) { + newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1)); + } + else { + Integer storedVariableValue = variables.get(line.split(" ")[2]); + newVariableValue = storedVariableValue; + } + + //Store result to new variable. + variables.put(newVariableName, newVariableValue); + + } + + //ADD NAME VALUE1 VALUE2 + else if(command.toLowerCase().equals("add")) { + String newVariableName = line.split(" ")[1]; + Integer newVariableValue = 0; + + //Find VALUE1. + if(line.split(" ")[2].startsWith("#")) { + newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1)); + } + else { + Integer storedVariableValue = variables.get(line.split(" ")[2]); + newVariableValue = storedVariableValue; + } + + //Add VALUE2 to VALUE1. + if(line.split(" ")[3].startsWith("#")) { + newVariableValue += Integer.valueOf(line.split(" ")[3].substring(1)); + } + else { + Integer storedVariableValue = variables.get(line.split(" ")[3]); + newVariableValue += storedVariableValue; + } + + //Store result to new variable. + variables.put(newVariableName, newVariableValue); + } + + + //SUB NAME VALUE1 VALUE2 + else if(command.toLowerCase().equals("sub")) { + String newVariableName = line.split(" ")[1]; + Integer newVariableValue = 0; + + //Find VALUE1. + if(line.split(" ")[2].startsWith("#")) { + newVariableValue = Integer.valueOf(line.split(" ")[2].substring(1)); + } + else { + Integer storedVariableValue = variables.get(line.split(" ")[2]); + newVariableValue = storedVariableValue; + } + + //Subtract VALUE1 from VALUE2. + if(line.split(" ")[3].startsWith("#")) { + newVariableValue -= Integer.valueOf(line.split(" ")[3].substring(1)); + } + else { + Integer storedVariableValue = variables.get(line.split(" ")[3]); + newVariableValue -= storedVariableValue; + } + + //Store result to new variable. + variables.put(newVariableName, newVariableValue); + } + + + //PRINT VALUE + else if(command.toLowerCase().equals("print")) { + processRunning.setState(ProcessState.BLOCKED); + } + } + + catch(IndexOutOfBoundsException e) { + StringBuffer errorMessage = new StringBuffer(); + errorMessage.append("Error in Line "); + errorMessage.append(processRunning.getProgramCounter()); + errorMessage.append(": "); + errorMessage.append(processRunning); + processRunning.setFailed(true); + processRunning.setState(ProcessState.TERMINATED); + + System.out.println(errorMessage); + } + + } + +} diff --git a/os-simulator/src/main/java/com/com1032/assignment/Hardware.java b/os-simulator/src/main/java/com/com1032/assignment/Hardware.java new file mode 100644 index 0000000000000000000000000000000000000000..ed11cdb69c8d151bc7f08fd4846daad5a0c35b39 --- /dev/null +++ b/os-simulator/src/main/java/com/com1032/assignment/Hardware.java @@ -0,0 +1,94 @@ +/** + * + */ +package com.com1032.assignment; + +import java.io.File; +import java.util.Scanner; + +/** + * @author felipedabrantes + * + */ +public class Hardware { + + private int processorNum = 0; + private int coresPerProcessor = 0; + private int RAMSize = 0; + private int diskSize = 0; + + + /** + * Constructor. Initialises fields. + * + * @param processorNum + * @param coresPerProcessor + * @param RAMSize + * @param diskSize + */ + public Hardware(int processorNum, int coresPerProcessor, int RAMSize, int diskSize) { + this.processorNum = processorNum; + this.coresPerProcessor = coresPerProcessor; + this.RAMSize = RAMSize; + this.diskSize = diskSize; + } + + + /** + * Constructor. Initialises fields using a text file. + * + * @param fileName + */ + public Hardware() { + try { + + File file = new File("hardware.txt"); + Scanner fileReader = new Scanner(file); + + this.processorNum = Integer.valueOf(fileReader.nextLine()); + this.coresPerProcessor = Integer.valueOf(fileReader.nextLine()); + this.RAMSize = Integer.valueOf(fileReader.nextLine()); + this.diskSize = Integer.valueOf(fileReader.nextLine()); + + //Closes file. + fileReader.close(); + } + + catch(Exception e) { + System.out.println("Error with Hardware file."); + } + + } + + + /** + * @return the processorNum + */ + public int getProcessorNum() { + return this.processorNum; + } + + /** + * @return the coresPerProcessor + */ + public int getCoresPerProcessor() { + return this.coresPerProcessor; + } + + /** + * @return the rAMSize + */ + public int getRAMSize() { + return this.RAMSize; + } + + /** + * @return the diskSize + */ + public int getDiskSize() { + return this.diskSize; + } + + + +} diff --git a/os-simulator/src/main/java/com/com1032/assignment/IOManager.java b/os-simulator/src/main/java/com/com1032/assignment/IOManager.java new file mode 100644 index 0000000000000000000000000000000000000000..b2dd8884e343a67f536550feb662d30a9f14b7c4 --- /dev/null +++ b/os-simulator/src/main/java/com/com1032/assignment/IOManager.java @@ -0,0 +1,123 @@ +/** + * + */ +package com.com1032.assignment; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author felipedabrantes + * + */ +public class IOManager extends Thread { + + /**Processes waiting for I/O.*/ + private List<PCB> blockedQueue = new ArrayList<PCB> (); + + + /** + * Constructor. Initialises fields. + * + * @param globalTime + * @param cores + * @param readyQueue + * @param blockedQueue + * @param terminatedQueue + */ + public IOManager(List<PCB> blockedQueue) { + this.blockedQueue = blockedQueue; + } + + + @Override + public void run() { + + while(true) { + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + this.runBlockedProcess(); + } + } + + + public void runBlockedProcess() { +// System.out.println("IO B: " + this.blockedQueue); +// System.out.println("CP" + this.blockedQueue.size()); + if(!this.blockedQueue.isEmpty()) { + + if(this.blockedQueue.get(0).getState() == ProcessState.BLOCKED) { + //The process the CPU runs. + PCB processRunning = this.blockedQueue.get(0); + + //Split code string into lines. + String[] codeLines = processRunning.getCode().split("\\r\\n|\\r|\\n"); + + //Compile and run the program counter line. + this.compileLine(processRunning, codeLines[processRunning.getProgramCounter()]); + //Decrease expected remaining time. + processRunning.decreaseRemainingTime(1); + + //Reset time used on CPU. + processRunning.resetConsecutiveTimeOnCPU(); + + //If all code finished, then terminate process. + if(processRunning.getProgramCounter() == codeLines.length - 1) { + processRunning.setState(ProcessState.TERMINATED); + } + else { + processRunning.increaseProgramCounter(); + processRunning.setState(ProcessState.READY); + } + } + } + } + + + public void compileLine(PCB processRunning, String line) { + + try { + Map<String, Integer> variables = processRunning.getVariables(); + + String command = line.split(" ")[0]; + + //PRINT VALUE + if(command.toLowerCase().equals("print")) { + Integer variableValue = null; + + if(line.split(" ")[1].startsWith("#")) { + variableValue = Integer.valueOf(line.split(" ")[1].substring(1)); + } + else { + Integer storedVariableValue = variables.get(line.split(" ")[1]); + variableValue = storedVariableValue; + } + + this.print(variableValue); + } + } + + catch(Exception e) { + StringBuffer errorMessage = new StringBuffer(); + errorMessage.append("Error in Line "); + errorMessage.append(processRunning.getProgramCounter()); + errorMessage.append(": "); + errorMessage.append(processRunning); + processRunning.setFailed(true); + processRunning.setState(ProcessState.TERMINATED); + + System.out.println(errorMessage); + } + } + + + public void print(int value) { + System.out.println(value); + } + +} diff --git a/os-simulator/src/main/java/com/com1032/pss/OSSim.java b/os-simulator/src/main/java/com/com1032/pss/OSSim.java new file mode 100644 index 0000000000000000000000000000000000000000..9f0b70740141938a9e6f6dac2ed8a1eefceca25f --- /dev/null +++ b/os-simulator/src/main/java/com/com1032/pss/OSSim.java @@ -0,0 +1,108 @@ +package com.com1032.pss; +/** + * OS.java + */ + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import com.com1032.assignment.Clock; +import com.com1032.assignment.SchedulingAlgorithm; +import com.com1032.pss.Process; +import com.com1032.pss.ProcessSchedulerSimulator; + +/** + * @author felipedabrantes + * + */ +public class OSSim { + + /**The global time of the OS.*/ + private Clock globalTime = new Clock(); + /**The class the handles the process scheduling.*/ + private ProcessSchedulerSimulator pss = null; + /**A list of processes of the OS.*/ + private List<Process> processes = new ArrayList<Process>(); + + + /** + * Constructor. Initialises fields. + */ + public OSSim() { + + this.pss = new ProcessSchedulerSimulator(this.globalTime); + } + + /** + * @param args + * @throws FileNotFoundException + * @throws IOException + */ + public static void main(String[] args) throws FileNotFoundException { + OSSim os = new OSSim(); + + os.addProcess("OSInput.txt"); + os.runProcessScheduling(); + + } + + + /** + * Used to a single process to OS. + * @param process + */ + public void addProcess(Process process) { + this.processes.add(process); + } + + + /** + * Used to add processes from a file to the OS. + * + * @param fileName of the processes file. + * + * @throws FileNotFoundException if no file is found. + */ + public void addProcess(String fileName){ + //Tries to open file. + try { + File file = new File(fileName); + Scanner fileReader = new Scanner(file); + + //Reads file line by line. + while (fileReader.hasNextLine()) { + //Splits process info to make a process object. + String[] data = fileReader.nextLine().split(", "); + this.processes.add(new Process( + Integer.valueOf(data[0]), + data[1], + Integer.valueOf(data[4]), + Integer.valueOf(data[3]), + Integer.valueOf(data[2]))); + } + + //Closes file. + fileReader.close(); + } + //Ran if no file is found. + catch(FileNotFoundException e) { + System.out.println("File not found."); + } + + } + + + /** + * Runs process scheduling simulation with processes in OS. + */ + public void runProcessScheduling() { + pss.addProcessToJob(this.processes); + pss.run(SchedulingAlgorithm.SPF, 3); + System.out.println(pss.getReport()); + } + +} \ No newline at end of file