コード例 #1
0
        /// <summary>
        /// This function runs the scheduler in shortest job first
        /// <param name="life"> the lifetime of the current process</param>
        /// </summary>
        private async void ExecuteShortestJobFirst(long life)
        {
            // TODO Shortest job first uses the number of instructions to calculate how long the job is, which may not be correct
            lifetime       = new Stopwatch();
            readyQueue     = new Queue <SimulatorProcess>(readyQueue.OrderBy(x => x.Program.Instructions.Count));
            runningProcess = readyQueue.Dequeue();
            await CallFromMainThread(UpdateInterface);
            await CallFromMainThread(UpdateMainWindowInterface);

            lifetime.Reset();
            lifetime.Start();
            while (runningProcess != null && !runningProcess.Unit.Stop && !runningProcess.Unit.Done &&
                   !runningProcess.Unit.Process.Terminated && !runningProcess.Unit.TimedOut && !executionWorker.CancellationPending)
            {
                if (lifetime.ElapsedMilliseconds > life)
                {
                    runningProcess.Unit.Done = true;
                }
                runningProcess.Unit.ExecuteInstruction();
                await CallFromMainThread(UpdateInterface);
                await CallFromMainThread(UpdateMainWindowInterface);
            }
            if (runningProcess.Unit.TimedOut)
            {
                runningProcess.CurrentState = EnumProcessState.READY;
                readyQueue.Enqueue(runningProcess);
                PCBFlags?flags = CreatePCBFlags(ref runningProcess);
                if (flags != null)
                {
                    runningProcess.ControlBlock = new ProcessControlBlock(flags.Value);
                }
                else
                {
                    MessageBox.Show("There was an error while creating process control block flags");
                    return;
                }
                runningProcess = readyQueue.Dequeue();
            }
            if (runningProcess.Unit.Stop)
            {
                runningProcess.CurrentState = EnumProcessState.WAITING;
                waitingQueue.Enqueue(runningProcess);
                PCBFlags?flags = CreatePCBFlags(ref runningProcess);
                if (flags != null)
                {
                    runningProcess.ControlBlock = new ProcessControlBlock(flags.Value);
                }
                else
                {
                    MessageBox.Show("There was an error while creating process control block flags");
                    return;
                }
                DeallocateProcessMemory(runningProcess);
                runningProcess = readyQueue.Dequeue();
            }
            if (executionWorker.CancellationPending)
            {
                return;
            }
        }
コード例 #2
0
        /// <summary>
        /// This function creates a simulator process
        /// </summary>
        /// <param name="flags"> the flags to use to create the simulator process</param>
        /// <returns> the created simulator process</returns>
        public SimulatorProcess CreateProcess(ProcessFlags flags)
        {
            SimulatorProcess proc = new SimulatorProcess(flags);

            AllocateProcessMemory(ref proc);
            return(proc);
        }
コード例 #3
0
        /// <summary>
        /// This function calculates the lifetime of the current process
        /// </summary>
        /// <returns> the lifetime of the current process in milliseconds </returns>
        private long CalculateLifetime()
        {
            long procLifetime = 0;

            runningProcess = readyQueue.Peek();
            if (runningProcess.ProcessLifetime == 0 || runningProcess.ProcessLifetime == int.MaxValue)
            {
                procLifetime = ((long)int.MaxValue * 1000);
            }
            else
            {
                if (runningProcess.ProcessLifetimeTimeUnit == EnumTimeUnit.TICKS)
                {
                    procLifetime = (long)(runningProcess.ProcessLifetime * runningProcess.ClockSpeed);
                }
                else if (runningProcess.ProcessLifetimeTimeUnit == EnumTimeUnit.SECONDS)
                {
                    procLifetime = (long)(runningProcess.ProcessLifetime * 1000);
                }
                else
                {
                    procLifetime = long.MaxValue;
                    MessageBox.Show("Unknown Time Unit supplied for process lifetime");
                }
            }
            return(procLifetime);
        }
コード例 #4
0
 /// <summary>
 /// Constructor for execution unit that starts executing from a specified location in the process
 /// </summary>
 /// <param name="program"> the process to execute </param>
 /// <param name="currentIndex"> the index to start executing from</param>
 /// <param name="clockSpeed"> the clock speed of the CPU </param>
 public ProcessExecutionUnit(SimulatorProcess program, int clockSpeed, int currentIndex) : base(program.Program, clockSpeed, currentIndex)
 {
     this.process      = program;
     this.program      = process.Program;
     this.ClockSpeed   = clockSpeed;
     this.CurrentIndex = currentIndex;
 }
コード例 #5
0
 /// <summary>
 /// Constructor for lottery ticket
 /// </summary>
 /// <param name="id"> the unique identifier of the ticket</param>
 /// <param name="owner"> the process that owns this ticket</param>
 /// <param name="currencyValue"> the currency value of this ticket (how likely it is to get chosen) </param>
 public LotteryTicket(int id, SimulatorProcess owner, int currencyValue)
 {
     this.id            = id;
     this.owner         = owner;
     this.currencyValue = currencyValue;
     this.selected      = false;
 }
コード例 #6
0
 /// <summary>
 /// This function runs the scheduler in first come first served mode
 /// <param name="life">the lifetime of the current process</param>
 /// </summary>
 private async void ExecuteFirstComeFirstServed(long life)
 {
     lifetime       = new Stopwatch();
     runningProcess = readyQueue.Dequeue();
     //ProcessExecutionUnit unit = runningProcess.Unit;
     lifetime.Reset();
     lifetime.Start();
     while (runningProcess != null && !runningProcess.Unit.Stop && !runningProcess.Unit.Done &&
            !runningProcess.Unit.Process.Terminated && !runningProcess.Unit.TimedOut && !executionWorker.CancellationPending)
     {
         if (lifetime.ElapsedMilliseconds > life)
         {
             runningProcess.Unit.Done = true;
         }
         runningProcess.Unit.ExecuteInstruction();
         await CallFromMainThread(UpdateInterface);
         await CallFromMainThread(UpdateMainWindowInterface);
     }
     if (runningProcess.Unit.TimedOut)
     {
         runningProcess.CurrentState = EnumProcessState.READY;
         readyQueue.Enqueue(runningProcess);
         PCBFlags?flags = CreatePCBFlags(ref runningProcess);
         if (flags != null)
         {
             runningProcess.ControlBlock = new ProcessControlBlock(flags.Value);
         }
         else
         {
             MessageBox.Show("There was an error while creating process control block flags");
             return;
         }
         runningProcess = readyQueue.Dequeue();
     }
     if (runningProcess.Unit.Stop)
     {
         runningProcess.CurrentState = EnumProcessState.WAITING;
         waitingQueue.Enqueue(runningProcess);
         PCBFlags?flags = CreatePCBFlags(ref runningProcess);
         if (flags != null)
         {
             runningProcess.ControlBlock = new ProcessControlBlock(flags.Value);
         }
         else
         {
             MessageBox.Show("There was an error while creating process control block flags");
             return;
         }
         DeallocateProcessMemory(runningProcess);
         runningProcess = readyQueue.Dequeue();
     }
     if (executionWorker.CancellationPending)
     {
         return;
     }
 }
コード例 #7
0
        public void DeallocateProcessMemory(SimulatorProcess proc)
        {
            if (proc == null)
            {
                MessageBox.Show("Can't de-allocate memory for a null process");
                return;
            }
            dynamic        wind = GetMainWindowInstance();
            PhysicalMemory mem  = wind.Memory;

            mem.Pages.RemoveAll(x => x.ProcessId == proc.ProcessID);
        }
コード例 #8
0
        /// <summary>
        /// This function allocates memory for processes
        /// </summary>
        /// <param name="proc">reference to the process to allocate memory too</param>
        public void AllocateProcessMemory(ref SimulatorProcess proc)
        {
            if (proc == null)
            {
                MessageBox.Show("Can't allocate memory for a null process");
                return;
            }
            dynamic        wind = GetMainWindowInstance();
            PhysicalMemory mem  = wind.Memory;

            for (int i = 0; i < proc.ProcessMemory; i++)
            {
                MemoryPage m = new MemoryPage(i, i * MemoryPage.PAGE_SIZE, proc.Program.Name, proc.ProcessID);
                mem.AddPage(m, i);
            }
        }
コード例 #9
0
        /// <summary>
        ///  This function runs the scheduler in round robin mode
        /// </summary>
        /// <param name="timeSlice"> the timeslice allocated to each process</param>
        /// <param name="life"> the lifetime of the current process</param>
        /// <param name="preEmptive"> whether the scheduler should be preEmptive
        /// i.e if a higher priority process enters the ready queue
        /// it will immediately start running</param>
        private async void ExecuteRoundRobin(int timeSlice, long life, bool preEmptive)
        {
            timeout  = new Stopwatch();
            lifetime = new Stopwatch();

            while (readyQueue.Count > 0 && readyQueue.Peek() != null && !executionWorker.CancellationPending)
            {
                runningProcess = readyQueue.Dequeue();
                LoadPCB();
                life = runningProcess.ProcessLifetime;
                runningProcess.Unit.TimedOut = false;
                runningProcess.CurrentState  = EnumProcessState.RUNNING;
                lifetime.Reset();
                lifetime.Start();

                if (preEmptive)
                {
                    readyQueue = new Queue <SimulatorProcess>(readyQueue.OrderBy(x => x.ProcessPriority));
                    //Thread.Sleep(50);
                    await CallFromMainThread(UpdateInterface);
                    await CallFromMainThread(UpdateMainWindowInterface);
                }

                while (runningProcess != null && !runningProcess.Unit.Done && !runningProcess.Unit.Stop && !runningProcess.Unit.TimedOut)
                {
                    timeout.Start();
                    if (this.timeout.ElapsedMilliseconds >= timeSlice)
                    {
                        TimeOutProcess(preEmptive);
                        break;
                    }
                    if (lifetime.ElapsedMilliseconds > life)
                    {
                        runningProcess.Unit.Done = true;
                    }
                    runningProcess.Unit.ExecuteInstruction();
                    await CallFromMainThread(UpdateInterface);
                    await CallFromMainThread(UpdateMainWindowInterface);
                }
                if (runningProcess.Unit.Done)
                {
                    DeallocateProcessMemory(runningProcess);
                }
                runningProcess = null;
            }
        }
コード例 #10
0
        /// <summary>
        /// This function creates the flags required to construct a PCB (Process Control Block)
        /// </summary>
        /// <param name="currentProcess"> a reference to the process that the PCB will belong to</param>
        /// <returns> a struct containing the flags to create a PCB or null if an error occurred</returns>
        private PCBFlags?CreatePCBFlags(ref SimulatorProcess currentProcess)
        {
            //SimulatorProcess currentProcess = waitingQueue.Peek();
            PCBFlags flags = new PCBFlags();

            flags.CPUID = currentProcess.CPUID;
            flags.OSID  = currentProcess.OSID;
            flags.allocatedResources = currentProcess.AllocatedResources;
            flags.avgBurstTime       = 0;
            flags.avgWaitingTime     = 0; //TODO calculate correct values
            flags.baseAddress        = currentProcess.Program.BaseAddress;
            flags.proceessMemory     = currentProcess.ProcessMemory;
            flags.processID          = currentProcess.ProcessID;
            flags.processName        = currentProcess.ProcessName;
            flags.processPriority    = currentProcess.ProcessPriority;
            flags.CPUID              = 0; //TODO Change this once multiple CPU's are implemented
            flags.processState       = currentProcess.CurrentState;
            flags.programName        = currentProcess.ProgramName;
            flags.requestedResources = currentProcess.RequestedResources;
            flags.resourceStarved    = currentProcess.ResourceStarved;
            flags.startAddress       = currentProcess.Program.BaseAddress; // TODO Implement program start address
            flags.lifetimeMills      = (int)(currentProcess.ProcessLifetime - lifetime.ElapsedMilliseconds);
            flags.registers          = new Register[21];
            for (int i = 0; i < flags.registers.Length; i++)
            {
                string registerName = String.Empty;
                if (i < 10)
                {
                    registerName = "R0" + i;
                }
                else
                {
                    registerName = "R" + i;
                }
                flags.registers[i] = Register.FindRegister(registerName);
            }
            flags.specialRegisters    = new SpecialRegister[7];
            flags.specialRegisters[0] = SpecialRegister.PC;
            flags.specialRegisters[1] = SpecialRegister.BR;
            flags.specialRegisters[2] = SpecialRegister.SP;
            flags.specialRegisters[3] = SpecialRegister.IR;
            flags.specialRegisters[4] = SpecialRegister.SR;
            flags.specialRegisters[5] = SpecialRegister.MAR;
            flags.specialRegisters[6] = SpecialRegister.MDR;
            return(flags);
        }
コード例 #11
0
        private async Task <int> DrawLottery(int ticketNumber)
        {
            LotteryTicket ticket = issuedLotteryTickets.Where(x => x.Id == ticketNumber).FirstOrDefault();

            if (ticket == null)
            {
                return(0);
            }
            while (runningProcess != ticket.Owner)
            {
                if (runningProcess != null && !runningProcess.Unit.Done)
                {
                    readyQueue.Enqueue(runningProcess);
                    runningProcess = null;
                }
                System.Console.WriteLine("Items in Queue: " + readyQueue.Count);
                runningProcess = readyQueue.Dequeue();
            }
            return(0);
        }
コード例 #12
0
        /// <summary>
        /// This function calculates the length of the timeslice when running in round robin mode
        /// </summary>
        /// <returns> the length of the timeslice in milliseconds </returns>
        private int CalculateTimeSlice()
        {
            int timeOutMills = 0;

            runningProcess = readyQueue.Peek();

            if (timeSliceUnit == EnumTimeUnit.SECONDS)
            {
                timeOutMills = (int)(RR_TimeSlice * 1000);
            }
            else if (timeSliceUnit == EnumTimeUnit.TICKS)
            {
                timeOutMills = (int)(RR_TimeSlice * runningProcess.Unit.ClockSpeed);
            }
            else
            {
                MessageBox.Show("Unknown time slice unit specified " + timeSliceUnit.ToString());
                return(int.MaxValue);
            }
            return(timeOutMills);
        }
コード例 #13
0
 /// <summary>
 /// Constructor for a process
 /// </summary>
 /// <param name="flags"> the flags to create this process with</param>
 public SimulatorProcess(ProcessFlags flags)
 {
     this.program               = flags.program;
     this.programName           = flags.programName;
     this.processName           = flags.processName;
     this.processPriority       = flags.processPriority;
     this.processMemory         = flags.processMemory;
     this.processLifetime       = flags.processLifetime;
     this.processID             = flags.processID;
     this.CPUID                 = flags.CPUid;
     this.burstTime             = flags.burstTime;
     this.displayProfile        = flags.displayProfile;
     this.parentDiesChildrenDie = flags.parentDiesChildrenDie;
     this.delayedProcess        = flags.delayedProcess;
     this.delayedProcessTime    = flags.delayedProcessTime;
     this.delayTimeUnit         = flags.delayTimeUnit;
     this.parentProcess         = flags.parentProcess;
     if (parentProcess != null)
     {
         parentProcessID = parentProcess.processID;
     }
     else
     {
         parentProcessID = -1;
     }
     this.childProcesses      = flags.childProcesses;
     this.processSwapped      = flags.processSwapped;
     this.currentState        = flags.processState;
     this.previousState       = flags.previousState;
     this.resourceStarved     = flags.resourceStarved;
     this.allocatedResources  = flags.allocatedResources;
     this.requestedResources  = flags.requestedResources;
     this.processControlBlock = flags.processControlBlock;
     this.OSid                = flags.OSid;
     this.clockSpeed          = flags.clockSpeed;
     this.unit                = new ProcessExecutionUnit(this, clockSpeed);
     this.lotteryTickets      = flags.lotteryTickets;
     this.ownsSemaphore       = flags.ownsSemaphore;
     this.waitingForSemaphore = flags.waitingForSemaphore;
 }
コード例 #14
0
        /// <summary>
        /// this method creates flags for the operating system scheduler based on selected UI options
        /// </summary>
        /// <returns> a struct containing the selected options or null if an error occurred</returns>
        private SchedulerFlags?CreateSchedulerFlags()
        {
            SchedulerFlags temp = new SchedulerFlags();

            temp.schedulingPolicies = schedulingPolicy;
            if (temp.schedulingPolicies == EnumSchedulingPolicies.ROUND_ROBIN) // if the user selected round robin scheduling
            {
                temp.RR_Priority_Policy = priorityPolicy;
                temp.RR_TimeSlice       = RR_Time_Slice;
                temp.RR_Type            = roundRobinType;
                temp.TimeSliceUnit      = RR_Time_Slice_Unit;
            }
            temp.allowCPUAffinity       = allowCPUAffinity;
            temp.defaultScheduler       = useDefaultScheduler;
            temp.runningWithNoProcesses = runWithNoProcesses;
            temp.usingSingleCPU         = true; //TODO Change this when multiple CPU's are Implemented
            if (!temp.runningWithNoProcesses)   // if the user selected to run the scheduler no processes
            {
                temp.readyQueue   = readyQueue;
                temp.waitingQueue = waitingQueue;
                SimulatorProcess proc = readyQueue.Dequeue();
                if (proc != null)
                {
                    proc.CurrentState = EnumProcessState.RUNNING;
                }
                temp.runningProcess = proc; // populate the queues and set the first processes state to running
            }
            else  // otherwise create a blank queue and set the running process to null
            {
                readyQueue          = new Queue <SimulatorProcess>();
                waitingQueue        = new Queue <SimulatorProcess>();
                temp.runningProcess = null;
            }
            temp.cpuClockSpeed        = CPUClockSpeed;
            temp.issuedLotteryTickets = new List <LotteryTicket>();
            temp.drawnLotteryTickets  = new List <LotteryTicket>();
            temp.core = this;
            return(temp);
        }
コード例 #15
0
 /// <summary>
 /// Constructor for process Scheduler
 /// </summary>
 /// <param name="flags"> the flags to use to create this scheduler</param>
 public Scheduler(SchedulerFlags flags)
 {
     readyQueue             = flags.readyQueue ?? new Queue <SimulatorProcess>();
     waitingQueue           = flags.waitingQueue ?? new Queue <SimulatorProcess>();
     runningProcess         = flags.runningProcess;
     schedulingPolicy       = flags.schedulingPolicies;
     RR_TimeSlice           = flags.RR_TimeSlice;
     timeSliceUnit          = flags.TimeSliceUnit;
     defaultScheduler       = flags.defaultScheduler;
     RR_Priority_Policy     = flags.RR_Priority_Policy;
     RR_Type                = flags.RR_Type;
     usingSingleCPU         = flags.usingSingleCPU;
     allowCPUAffinity       = flags.allowCPUAffinity;
     runningWithNoProcesses = flags.runningWithNoProcesses;
     cpuClockSpeed          = flags.cpuClockSpeed;
     suspended              = false;
     issuedLotteryTickets   = flags.issuedLotteryTickets;
     drawnLotteryTickets    = flags.drawnLotteryTickets;
     core = flags.core;
     CollectionChanged += OnCollectionChanged;
     CreateBackgroundWorker();
     //BindingOperations.EnableCollectionSynchronization(readyQueue,thisLock);
 }
コード例 #16
0
        /// <summary>
        /// This function is the main scheduler loop that runs until no processes remain or the OS is suspended
        /// </summary>
        private async void RunScheduler()
        {
            while (readyQueue.Count > 0 && readyQueue.Peek() != null && !suspended && !executionWorker.CancellationPending)
            {
                switch (schedulingPolicy)
                {
                case EnumSchedulingPolicies.FIRST_COME_FIRST_SERVED:
                {
                    long life = CalculateLifetime();
                    ExecuteFirstComeFirstServed(life);
                    if (runningProcess.Unit.Done)
                    {
                        DeallocateProcessMemory(runningProcess);
                    }
                    break;
                }

                case EnumSchedulingPolicies.SHORTEST_JOB_FIRST:
                {
                    long life = CalculateLifetime();
                    ExecuteShortestJobFirst(life);
                    if (runningProcess.Unit.Done)
                    {
                        DeallocateProcessMemory(runningProcess);
                    }
                    break;
                }

                case EnumSchedulingPolicies.ROUND_ROBIN:
                {
                    switch (RR_Priority_Policy)
                    {
                    case EnumPriorityPolicy.NON_PRE_EMPTIVE:
                    {
                        readyQueue = new Queue <SimulatorProcess>(readyQueue.OrderBy(x => x.ProcessPriority));
                        long life    = CalculateLifetime();
                        int  timeout = CalculateTimeSlice();
                        await CallFromMainThread(UpdateInterface);
                        await CallFromMainThread(UpdateMainWindowInterface);

                        ExecuteRoundRobin(timeout, life, false);
                        if (runningProcess.Unit.Done)
                        {
                            DeallocateProcessMemory(runningProcess);
                        }
                        break;
                    }

                    case EnumPriorityPolicy.NO_PRIORITY:
                    {
                        long life    = CalculateLifetime();
                        int  timeout = CalculateTimeSlice();
                        ExecuteRoundRobin(timeout, life, false);
                        if (runningProcess.Unit.Done)
                        {
                            DeallocateProcessMemory(runningProcess);
                        }
                        break;
                    }

                    case EnumPriorityPolicy.PRE_EMPTIVE:
                    {
                        readyQueue = new Queue <SimulatorProcess>(readyQueue.OrderBy(x => x.ProcessPriority));
                        long life    = CalculateLifetime();
                        int  timeout = CalculateTimeSlice();
                        await CallFromMainThread(UpdateInterface);
                        await CallFromMainThread(UpdateMainWindowInterface);

                        ExecuteRoundRobin(timeout, life, true);
                        if (runningProcess.Unit.Done)
                        {
                            DeallocateProcessMemory(runningProcess);
                        }
                        break;
                    }

                    case EnumPriorityPolicy.UNKNOWN:
                    {
                        MessageBox.Show("Unknown priority policy selected");
                        return;
                    }

                    default:
                    {
                        MessageBox.Show("An Internal error occurred in the scheduler the program will now terminate");
                        Environment.Exit(1);
                        return;
                    }
                    }
                    break;
                }

                case EnumSchedulingPolicies.LOTTERY_SCHEDULING:
                {
                    await AllocateLotteryTickets();

                    long life = CalculateLifetime();
                    await CallFromMainThread(UpdateInterface);
                    await CallFromMainThread(UpdateMainWindowInterface);

                    ExecuteLottery(DateTime.Now.Ticks, life);
                    if (runningProcess.Unit.Done)
                    {
                        DeallocateProcessMemory(runningProcess);
                    }
                    break;
                }

                case EnumSchedulingPolicies.FAIR_SHARE_SCEDULING:
                {
                    break;
                }

                case EnumSchedulingPolicies.UNKNOWN:
                {
                    MessageBox.Show("Please select a scheduling policy");
                    return;
                }

                default:
                {
                    MessageBox.Show("Unknown scheduling policy selected");
                    return;
                }
                }
            }
            if (executionWorker.CancellationPending)
            {
                await CallFromMainThread(UpdateInterface);
                await CallFromMainThread(UpdateMainWindowInterface);

                return;
            }
            MessageBox.Show("OS Execution Complete");
            runningProcess = null;
            await CallFromMainThread(UpdateInterface);
            await CallFromMainThread(UpdateMainWindowInterface);

            return;
        }
コード例 #17
0
 /// <summary>
 /// Constructor for execution unit that starts executing from the beginning of the process
 /// </summary>
 /// <param name="program"> the process to execute </param>
 /// <param name="clockSpeed"> the clock speed of the CPU </param>
 public ProcessExecutionUnit(SimulatorProcess program, int clockSpeed) : base(program.Program, clockSpeed)
 {
     this.process    = program;
     this.program    = process.Program;
     this.ClockSpeed = clockSpeed;
 }