예제 #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);
        }
예제 #2
0
 public static void DeallocateMemory(PCB pcb)
 {
     for (int i = 0; i < RAM.RAM_SIZE; i++)
     {
         if (used[i] == pcb.ProcessID)
         {
             used[i] = -1;
         }
     }
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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;
                }
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
 public static void Stop(PCB pcb)
 {
     pcb.Timer.Stop();
 }
예제 #8
0
 public static void Start(PCB pcb)
 {
     pcb.Timer.Start();
 }
예제 #9
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);
                }
            }
        }
예제 #10
0
 public static void WriteWord(int address, PCB program, Word value)
 {
     RAM.Write(program.JobStartAddress + address, value);
 }
예제 #11
0
 public static Word ReadWord(int address, PCB program)
 {
     return(RAM.Read(program.JobStartAddress + address));
 }
예제 #12
0
 // Sets the active to program to notify it is waiting for a program
 public CPU(int id = 0)
 {
     this.id       = id;
     activeProgram = null;
 }