// 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); }
public static void DeallocateMemory(PCB pcb) { for (int i = 0; i < RAM.RAM_SIZE; i++) { if (used[i] == pcb.ProcessID) { used[i] = -1; } } }
/// <summary> /// Please kill me /// </summary> /// <param name="pcb"></param> /// <returns>the start address of the program</returns> public static int AllocateMemory(PCB pcb) { int startIndex = findHole(pcb); if (startIndex != -1) { for (int i = startIndex; i < startIndex + pcb.ProgramSize; i++) { used[i] = pcb.ProcessID; } } return(startIndex); }
/// <summary> /// finds the first big enough hole and returns it /// </summary> /// <param name="pcb"></param> /// <returns></returns> static int findHole(PCB pcb) { bool inHole = false; int holeIndex = -1; for (int i = 0; i < RAM.RAM_SIZE; i++) { //in hole if (inHole) { //allocated if (used[i] != -1) { //reset hole stats inHole = false; holeIndex = -1; } ///not allocated else { //hole is big enough if ((i - holeIndex) + 1 == pcb.ProgramSize) { //return hole index return(holeIndex); } //hole isn't big enough } } //not in hole else { //not allocated if (used[i] == -1) { //start hole holeIndex = i; inHole = true; } } } return(-1); }
/// <summary> /// Acquires the queue lock for the new queue and validates the new queue is not empty /// --> Make async if Queue lock /// </summary> static void __init() { // For single core priority since the MMU only gets loaded one program at a time, need to select based on priority if (degree == 0 && ShortTermScheduler.POLICY == SchedulerPolicy.Priority) { Driver._QueueLock.Wait(); var toSort = Queue.New; Queue.New = ShortTermScheduler.InsertSort(toSort); Driver._QueueLock.Release(); degree = 1; } if (Driver._QueueLock.CurrentCount != 0) { if (Queue.New.First != null) { currentPointer = Queue.New.First.Value; } } }
/// <summary> /// Sorts the queue based on priority from min to max values by insertion /// - O(n^2) complexity /// </summary> public static LinkedList <PCB> InsertSort(LinkedList <PCB> sortee) { //Jess, if you're looking at this, I apolgize for what you're about to see. //It's not pretty. I'm not proud. var returnValue = new LinkedList <PCB>(); var runCount = sortee.Count; for (int run = 0; run < runCount; run++) { //incrementing index for the foreach int currentIndex = 0; //index of highest priority int HPindex = 0; //Also known as the HP Reverb G2 gotemm //shitty highest priority tracker //I'm so sorry for your eyes PCB highestPriority = new PCB(0, 0, 9999, 0, 0, 0, 0); //find the highest priority PCB foreach (PCB pcb in sortee) { if (pcb.Priority < highestPriority.Priority) { HPindex = currentIndex; highestPriority = pcb; } currentIndex++; } //add it to the new queue and kill it from the old queue returnValue.AddLast(highestPriority); sortee.Remove(highestPriority); } return(returnValue); }
public static void Stop(PCB pcb) { pcb.Timer.Stop(); }
public static void Start(PCB pcb) { pcb.Timer.Start(); }
/// <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); } } }
public static void WriteWord(int address, PCB program, Word value) { RAM.Write(program.JobStartAddress + address, value); }
public static Word ReadWord(int address, PCB program) { return(RAM.Read(program.JobStartAddress + address)); }
// Sets the active to program to notify it is waiting for a program public CPU(int id = 0) { this.id = id; activeProgram = null; }