Esempio n. 1
0
        // 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);
        }
Esempio n. 2
0
        /// <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();
        }
Esempio n. 3
0
        /// <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++;
        }
Esempio n. 4
0
        /// <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);
                }
            }
        }
Esempio n. 5
0
        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}");
        }
Esempio n. 6
0
 string EffectiveAddress()
 {
     return(MMU.ReadWord(addr, this.activeProgram).Value);
 }