// Ends the process private void EndProcess() { // Deallocate the memory MMU.DeallocateMemory(activeProgram); // Adds the pcb to the terminated queue activeProgram.Core_Used = ID; // Remove the program from the running queue Driver._QueueLock.Wait(); var pcb = activeProgram; Queue.Running.Remove(pcb); Queue.Terminated.AddLast(pcb); Driver._QueueLock.Release(); // Clears the CPU & PCB attributes this.registers = null; this.activeProgram = null; this.PC = 0; this.OPCODE = -1; this.isWaiting = false; // Clear the cache this.cache = null; // Stop the running time Metrics.Stop(pcb); }
/// <summary> /// Acquires the lock for the MMU then executes its write to functionality /// --> Make async if MMU lock /// </summary> /// <returns>True if the memory was written</returns> static void WriteToMemory(int allocationStartAddress) { Driver._MMULock.Wait(); var allProgramData = ReadFromDisk; for (int i = 0; i < allProgramData.Length; i++) { MMU.WriteWord(allocationStartAddress + i, currentPointer, allProgramData[i]); } Driver._MMULock.Release(); }
/// <summary> /// Does an IO instruction through the DMA /// </summary> /// <param name="readOrWrite">True for read, false for write</param> /// <param name="callingCPU">The CPU that's calling the DMA</param> /// <param name="reg1">Reg1 in the instructions</param> /// <param name="secondLocation">The second location to be called, whether it be register or address</param> /// <param name="reg2ORAddress">True for reg2, false for address as second location</param> /// <returns></returns> public static async Task IOExecution(bool readOrWrite, CPU callingCPU, int reg1, int secondLocation, bool reg2ORAddress) { /* * Start the timer */ // Metrics.Stop(callingCPU.ActiveProgram); if (readOrWrite) // ==> Read { Task thread = Task.Factory.StartNew(() => { blocker().GetAwaiter().GetResult(); if (reg2ORAddress) { callingCPU.Registers[reg1] = callingCPU.Registers[secondLocation]; } else { callingCPU.Registers[reg1] = MMU.ReadWord(secondLocation, callingCPU.ActiveProgram); } unlocker().GetAwaiter().GetResult(); }); thread.Wait(); } else // ==> Write { Task thread = Task.Factory.StartNew(() => { blocker().GetAwaiter().GetResult(); if (reg2ORAddress) { callingCPU.Registers[secondLocation] = callingCPU.Registers[reg1]; } else { MMU.WriteWord(secondLocation, callingCPU.ActiveProgram, callingCPU.Registers[reg1]); } unlocker().GetAwaiter().GetResult(); }); thread.Wait(); } /* * Stop the waiting timer */ // Metrics.Stop(callingCPU.ActiveProgram); // Increment the IO count for the pcb callingCPU.ActiveProgram.IOOperationCount++; }
/// <summary> /// Loads the memory as long as the LT_Scheduler has the queue lock and memory has enough space /// --> Make async /// </summary> public static void Execute() { // Acquires the lock for the new queue __init(); // Multi core cpu configuration if (Driver.IsMultiCPU) { // Sets the memory switch false to check if allocation is possible bool isMemFullSwitch = false; bool programsLoaded = false; // While the memory is not full continue loading program data from disk to RAM with the MMU while (!isMemFullSwitch && !programsLoaded) { // Allocate memory for the program disk instructions and buffer sizes if available var allocationStartAddress = MMU.AllocateMemory(currentPointer); // Validate if the MMU allocated memory in RAM for the program's instructions break if so if (allocationStartAddress == -1) { isMemFullSwitch = true; } else { // Write the disk instructions and buffers to the allocated RAM for the PCB.ProgramSize count WriteToMemory(allocationStartAddress); SetPCBStartEndAddresses(allocationStartAddress); // Move the pcb to the ready queue if it was loaded properly to memory Queue.New.Remove(currentPointer); Queue.Ready.AddLast(currentPointer); if (Queue.New.First != null) { currentPointer = Queue.New.First.Value; } else { programsLoaded = true; } } } } // Single core cpu configuration else { // Allocate memory for the program disk instructions and buffer sizes if available var allocationStartAddress = MMU.AllocateMemory(currentPointer); // Validate if the MMU allocated memory in RAM for the program's instructions break if so if (allocationStartAddress == -1) { throw new Exception("Long term scheduler could not load from disk to memory on single core configuration"); } else { // Write the disk instructions and buffers to the allocated RAM for the PCB.ProgramSize count WriteToMemory(allocationStartAddress); SetPCBStartEndAddresses(allocationStartAddress); // Move the pcb to the ready queue if it was loaded properly to memory Queue.New.Remove(currentPointer); Queue.Ready.AddLast(currentPointer); } } }
private void ExecuteCondi() { string second; int preAddr = addr; addr /= 4; if (dReg == 0) { second = Utilities.WordFill(Utilities.DecToHex(preAddr)); } else { second = MMU.ReadWord(addr, activeProgram).Value; } switch (OPCODE) { case 2: // 02: ST Driver._MMULock.Wait(); DMA.IOExecution(false, this, bReg, addr, false).GetAwaiter().GetResult(); Driver._MMULock.Release(); break; case 3: // 03: LW Driver._MMULock.Wait(); DMA.IOExecution(true, this, dReg, addr, false).GetAwaiter().GetResult(); Driver._MMULock.Release(); break; case 11: // 0B: MOVI registers[dReg].Value = Utilities.WordFill(second); break; case 12: // 0C: ADDI registers[dReg] = registers[dReg] + MMU.ReadWord(addr, activeProgram); break; case 13: // 0D: MULI registers[dReg] = registers[dReg] * MMU.ReadWord(addr, activeProgram); break; case 14: // 0E: DIVI registers[dReg] = registers[dReg] / MMU.ReadWord(addr, activeProgram); break; case 15: // 0F: LDI registers[dReg] = new Word(second); break; case 17: // 11: SLTI registers[dReg].Value = Utilities.DecToHexFullAddr(registers[sReg0].ValueAsInt < addr ? 1 : 0); break; case 21: // 15: BEQ PC = registers[bReg] == registers[dReg] ? preAddr : PC; break; case 22: // 16: BNE PC = registers[bReg] != registers[dReg] ? preAddr : PC; break; case 23: // 17: BEZ PC = registers[bReg].ValueAsInt == 0 ? preAddr : PC; break; case 24: // 18: BNZ PC = registers[bReg].ValueAsInt != 0 ? preAddr : PC; break; case 25: // 19: BGZ PC = registers[bReg].ValueAsInt > 0 ? preAddr : PC; break; case 26: // 1A: BLZ PC = registers[bReg].ValueAsInt < 0 ? preAddr : PC; break; default: throw new Exception("OPCode invalid, check the hex to dec conversion: " + OPCODE); } // Console.WriteLine($"CONDI: OPCODE {OPCODE} | B = {bReg} | D = {dReg} | ADDR = {addr} | SECOND = {second}"); }
string EffectiveAddress() { return(MMU.ReadWord(addr, this.activeProgram).Value); }