Example #1
0
        /// <summary>
        /// Get an individual pcb from the scheduler by id
        /// </summary>
        /// <param name="id">Id of the pcb</param>
        /// <returns></returns>
        public ProcessControlBlock GetPcb(int id)
        {
            foreach (KeyValuePair <string, ExecutionQueue> item in _ioDictionary)
            {
                foreach (ProcessControlBlock pcb in item.Value.Pcbs)
                {
                    if (pcb.PId == id)
                    {
                        //copy the pcb and remove it from the queue
                        ProcessControlBlock p = pcb;
                        item.Value.Pcbs.Remove(pcb);

                        //remove the queue from the list if it is empty
                        if (item.Value.IsEmpty())
                        {
                            _ioDictionary.Remove(item.Key);
                        }

                        return(p);
                    }
                }
            }

            return(null);
        }
Example #2
0
        /// <summary>
        /// Add a pcb to the queue. The order will depend on which scheduling algorithm is selected
        /// </summary>
        /// <param name="pcb">Pcb to be inserted</param>
        public void EnQueue(ProcessControlBlock pcb)
        {
            this.Pcbs.Add(pcb);

            if (IsShortestJobFirst)
            {
                this.Pcbs = this.Pcbs.OrderBy(p => p.TotalCyclesNeeded).ToList(); //OrderBy(o => o.OrderDate).ToList();
            }
        }
Example #3
0
        /// <summary>
        /// Remove and return the pcb on the top of the queue
        /// </summary>
        /// <returns>Pcb next in line</returns>
        public ProcessControlBlock DeQueue()
        {
            ProcessControlBlock process = this.Pcbs[0];

            this.Pcbs.RemoveAt(0);

            if (IsShortestJobFirst)
            {
                this.Pcbs = this.Pcbs.OrderBy(p => p.TotalCyclesNeeded).ToList();
            }

            return(process);
        }
Example #4
0
        /// <summary>
        /// Add a new pcb to the os. Scheduler decides where to put it based on the currernt scheduling algorithm
        /// </summary>
        /// <param name="pcb"></param>
        public void AddNewPCB(ProcessControlBlock pcb)
        {
            JobCount++;
            this._os.Gui.UpdateTotalJobs(JobCount);

            if (this._os.Settings.SchedulingAlgorithm == SchedulingAlgorithm.RoundRobin || this._os.Settings.SchedulingAlgorithm == SchedulingAlgorithm.FirstComeFirstServe)
            {
                this.AddPcbRoundRobin(pcb);
            }
            else if (this._os.Settings.SchedulingAlgorithm == SchedulingAlgorithm.ShortestJobFirst)
            {
                this.AddPcbShortestJobFirst(pcb);
            }
        }
Example #5
0
        /// <summary>
        /// Checks if an individual pc is in the scheduler
        /// </summary>
        /// <param name="pcb"></param>
        /// <returns></returns>
        public bool IsInIoScheduler(ProcessControlBlock pcb)
        {
            foreach (KeyValuePair <string, ExecutionQueue> item in _ioDictionary)
            {
                foreach (ProcessControlBlock p in item.Value.Pcbs)
                {
                    if (p.PId == pcb.PId)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #6
0
        /// <summary>
        /// Adds a pcb to the system when using round robin scheduling
        /// </summary>
        /// <param name="pcb"></param>
        public void AddPcbRoundRobin(ProcessControlBlock pcb)
        {
            var canAdd = this.Memory.CanAllocate(pcb.MemoryRequirement);

            //add PCB to ready queue
            if (canAdd)
            {
                pcb.State = State.NEW;
                this.ReadyQueue.EnQueue(pcb);
                this.Memory.AssignMemory(pcb.MemoryRequirement);
            }
            else
            { // add PCB to waiting queue
                pcb.State = State.NEW;
                WaitingQueue.EnQueue(pcb);
                this._os.Gui.UpdateWaitingQueueLog();
            }
        }
        /// <summary>
        /// Handles events and makes takes the corresponding actions
        /// </summary>
        /// <param name="ecb"></param>
        public void HandleEvent(EventControlBlock ecb)
        {
            switch (ecb.Type)
            {
            case EventType.ReleaseIO:
                //get the pcb from the ioscheduler
                ProcessControlBlock pcb = this.IoScheduler.GetPcb(ecb.PcbId);
                //move it back to the ready queue
                this.Scheduler.ReadyQueue.EnQueue(pcb);
                this.Gui.UpdateIoQueueLog();
                this.Gui.UpdateReadyQueueLog();
                //updateUI = true;
                break;

            case EventType.ContextSwitch:
                this.Scheduler.ContextSwitch();
                this.Scheduler.UpdateReadyQueue();
                //this.gui.UpdateCurrentPCBTable(this.cpu.currentPcb.ToString());
                this.Gui.UpdateReadyQueueLog();
                this.Gui.UpdateAllocatedMemoryLabel(this.AllocatedMemory);
                this.Gui.UpdateAvgWaitTime(this.GetAvgWaitTimes(), this.Scheduler.FinishedPcbs.Count);
                break;

            case EventType.NewShortestFirstPCB:
                //check if anything in the waiting queue should be moved into the ready queue
                if (this.Scheduler.WaitingQueue.Size > 0)
                {
                    var toCheck = this.Scheduler.WaitingQueue.DeQueue();

                    while (this.UpdateQueues(toCheck) && this.Scheduler.WaitingQueue.Size > 0)
                    {
                        toCheck = this.Scheduler.WaitingQueue.DeQueue();
                    }
                }

                this.Gui.UpdateWaitingQueueLog();
                break;

            case EventType.Done:
                this.UserInterrupt = true;
                break;
            }
        }
Example #8
0
        /// <summary>
        /// Adds pcb to the appropriate device queue. If a queue doesnt exist for it create one.
        /// </summary>
        /// <param name="ioDevice"></param>
        /// <param name="pcb"></param>
        public void ScheduleIo(string ioDevice, ProcessControlBlock pcb)
        {
            //log the io request
            pcb.IoRequestsPerformed++;

            //add the io to its queue if it exists, else create a new queue and it
            if (_ioDictionary.ContainsKey(ioDevice))
            {
                _ioDictionary[ioDevice].EnQueue(pcb);
            }
            else
            {
                ExecutionQueue newQ = new ExecutionQueue();
                newQ.EnQueue(pcb);
                _ioDictionary.Add(ioDevice, newQ);
            }

            this._os.Gui.UpdateIoQueueLog();
        }
Example #9
0
        /// <summary>
        /// Removes a pcb from the scheduler
        /// </summary>
        /// <param name="pcb"></param>
        /// <returns></returns>
        public ProcessControlBlock RemoveFromIoScheduler(ProcessControlBlock pcb)
        {
            ProcessControlBlock x;

            foreach (KeyValuePair <string, ExecutionQueue> item in _ioDictionary)
            {
                bool found = false;
                for (int i = 0; i < item.Value.Pcbs.Count; i++)
                {
                    if (item.Value.Pcbs[i].PId == pcb.PId)
                    {
                        x = item.Value.Pcbs[i];
                        item.Value.Pcbs.RemoveAt(i);
                        return(x);
                    }
                }
            }

            throw new NullReferenceException();
        }
Example #10
0
        /// <summary>
        /// Load the program in and assign it to whichever queue is appropriate
        /// </summary>
        /// <param name="filename">Name of the file(program) to load</param>
        /// <returns></returns>
        public async Task <ProcessControlBlock> LoadFile(string filename)
        {
            try
            {
                var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///program_files/" + filename));

                using (var inputStream = await file.OpenReadAsync())
                    using (var classicStream = inputStream.AsStreamForRead())
                        using (var streamReader = new StreamReader(classicStream))
                        {
                            var counter                 = 0;
                            int memRequirement          = 0;
                            List <Operation> operations = new List <Operation>();
                            while (streamReader.Peek() >= 0)
                            {
                                if (counter == 0)
                                {
                                    memRequirement = Convert.ToInt32(streamReader.ReadLine());
                                }
                                else
                                {
                                    operations.Add(convertLineToOperation(streamReader.ReadLine()));
                                }

                                counter++;
                            }

                            ProcessControlBlock newProcess = new ProcessControlBlock(State.NEW, memRequirement, operations);
                            newProcess.PId = this._idCount;
                            this._idCount++;

                            return(newProcess);
                        }
            }
            catch (System.IO.FileNotFoundException e)
            {
                Debug.WriteLine(e.Message);
                return(null);
            }
        }
        /// <summary>
        /// Decides which queue a pcb goes in in shortest job first mode
        /// </summary>
        /// <param name="pcb"></param>
        /// <returns></returns>
        public bool UpdateQueues(ProcessControlBlock pcb)
        {
            // get a side list of all pcbs in memory
            List <ProcessControlBlock> allInMemory = new List <ProcessControlBlock>();

            allInMemory.Add(pcb);

            //add anything in cpu to temp list
            if (this.Cpu.CurrentPcb != null)
            {
                allInMemory.Add(this.Cpu.CurrentPcb);
            }

            //add all pcbs in ready queue to temp list
            foreach (ProcessControlBlock p in this.Scheduler.ReadyQueue.Pcbs)
            {
                allInMemory.Add(p);
            }

            //add all io to temp list
            foreach (ProcessControlBlock p in this.IoScheduler.GetAllPcBs())
            {
                allInMemory.Add(p);
            }

            //order everything in the list by number of cc's required
            allInMemory = allInMemory.OrderBy(p => p.TotalCyclesNeeded).ToList();

            //remove everything below the new pcb in the queue and see if it would fit in memory
            List <ProcessControlBlock> removed = new List <ProcessControlBlock>();

            while (pcb.PId != allInMemory[allInMemory.Count - 1].PId && this.Helper(allInMemory) > this.Settings.MemorySize)
            {
                removed.Add(allInMemory[allInMemory.Count - 1]);
                allInMemory.RemoveAt(allInMemory.Count - 1);
            }

            //add up the memory in the temp array
            int memory = 0;

            foreach (ProcessControlBlock block in allInMemory)
            {
                memory += block.MemoryRequirement;
            }

            //if the new pcb will fit in the queue actually do the stuff
            if (memory <= this.Settings.MemorySize && removed.Count > 0)
            {
                foreach (ProcessControlBlock block in removed)
                {
                    //if the pcb to be removed was in the io scheduler move it to the waiting queue
                    if (this.IoScheduler.IsInIoScheduler(block))
                    {
                        ProcessControlBlock pcbFromIo = this.IoScheduler.RemoveFromIoScheduler(block);
                        this.Scheduler.Memory.FreeMemory(pcbFromIo.MemoryRequirement);
                        this.Scheduler.WaitingQueue.EnQueue(pcbFromIo);
                    }
                    //if the pcb to be removed is in the cpu move it to the waiting queue and create an event to switch context
                    else if (this.Cpu.CurrentPcb != null && this.Cpu.CurrentPcb.PId == pcb.PId)
                    {
                        this.Scheduler.WaitingQueue.EnQueue(this.Cpu.CurrentPcb);
                        this.Scheduler.Memory.FreeMemory(this.Cpu.CurrentPcb.MemoryRequirement);
                        this.Cpu.CurrentPcb = null;

                        this.InterruptProcessor.CreateAndAddEvent(EventType.ContextSwitch);
                    }
                    // the pcb has to be in the ready queue so move it to the waiting queue
                    else
                    {
                        for (int j = 0; j < this.Scheduler.ReadyQueue.Pcbs.Count; j++)
                        {
                            if (this.Scheduler.ReadyQueue.Pcbs[j].PId == block.PId)
                            {
                                this.Scheduler.WaitingQueue.EnQueue(block);
                                this.Scheduler.ReadyQueue.Pcbs.RemoveAt(j);
                                this.Scheduler.Memory.FreeMemory(block.MemoryRequirement);
                            }
                        }
                    }
                }

                //space has been freed up for the new pcb to be added
                this.Scheduler.ReadyQueue.EnQueue(pcb);
                this.Scheduler.Memory.AssignMemory(pcb.MemoryRequirement);

                this.Gui.UpdateIoQueueLog();
                this.Gui.UpdateReadyQueueLog();
                this.Gui.UpdateWaitingQueueLog();

                return(true);
            }
            else if (memory <= this.Settings.MemorySize && removed.Count == 0)
            {
                this.Scheduler.ReadyQueue.EnQueue(pcb);
                this.Scheduler.Memory.AssignMemory(pcb.MemoryRequirement);
                this.Gui.UpdateReadyQueueLog();

                return(true);
            }
            else
            {
                this.Scheduler.WaitingQueue.EnQueue(pcb);
                this.Gui.UpdateWaitingQueueLog();

                return(false);
            }
        }
Example #12
0
        /// <summary>
        /// Executes current operation in the current pcb
        /// </summary>
        public void ExecuteOperation()
        {
            if (CurrentPcb == null)
            {
                return;
            }



            //if the program is new flag it as running since its in the cpu and about to be executed
            if (this.CurrentPcb.State == State.NEW)
            {
                this.CurrentPcb.State = State.RUN;
            }

            int remainingCycles = this.CurrentPcb.DecrementOperationClock();

            switch (this.CurrentPcb.CurrentOperation.Type)
            {
            case OperationType.CALCULATE:
                //this.gui.PrintToLog("cpu executing calc");
                //this.gui.PrintToLog(remainingCycles + " cycles remaing for calc");
                if (this.CurrentPcb.CurrentOperation.Cycles == 0)
                {
                    this.CurrentPcb.SetNextCommand();
                }

                break;

            case OperationType.IO:
                if (this.CurrentPcb.State == State.RUN)
                {
                    this.CurrentPcb.State = State.WAIT;
                    this.CurrentPcb.CurrentOperation.Cycles++;     //add the io cycle back since this cycle was wasted moving to io q
                    this._os.IoScheduler.ScheduleIo(this.CurrentPcb.CurrentOperation.IoType, CurrentPcb);
                    this.CurrentPcb = null;
                    this._os.Gui.UpdateCurrentPCBTable("");
                }
                else
                {
                    this.CurrentPcb.SetNextCommand();
                    //put the pcb back in a run state
                    this.CurrentPcb.State = State.RUN;
                }

                break;

            case OperationType.YIELD:
                this.CurrentPcb.SetNextCommand();
                //if the yield is the last command discard it and create a cont switch event
                this._os.InterruptProcessor.CreateAndAddEvent(EventType.ContextSwitch);
                break;

            case OperationType.OUT:
                this._os.Gui.LogMessageToConsole(this.CurrentPcb.ToString());
                this.CurrentPcb.SetNextCommand();
                break;
            }

            //if the process is exiting create a context switch event to notify the scheduler to switch it out
            if (CurrentPcb != null && CurrentPcb.State == State.EXIT)
            {
                //remove from system and free memory
                this._os.Scheduler.Memory.FreeMemory(CurrentPcb.MemoryRequirement);
                this._os.Scheduler.FinishedPcbs.Add(CurrentPcb); //your journey is over little buddy. Live long and prosper...
                this.CurrentPcb = null;                          //discard currentpcb

                this._os.InterruptProcessor.CreateAndAddEvent(EventType.ContextSwitch);
            }
        }
Example #13
0
 /// <summary>
 /// Resets the cpu
 /// </summary>
 public void Reset()
 {
     this.Clock.Reset();
     this.CurrentPcb = null;
 }
Example #14
0
 /// <summary>
 /// Adds a pcb to the system when using sjf scheduling
 /// </summary>
 /// <param name="pcb"></param>
 public void AddPcbShortestJobFirst(ProcessControlBlock pcb)
 {
     //add the pcb to the waiting queue and create an event to check if it should be moved into the ready queue
     this.WaitingQueue.EnQueue(pcb);
     this._os.InterruptProcessor.CreateAndAddEvent(EventType.NewShortestFirstPCB);
 }
Example #15
0
 public void InsertPCB(ProcessControlBlock pcb)
 {
     throw new NotImplementedException();
 }