예제 #1
0
        /// <summary>
        /// Helper function that adjusts the ready list based upon recent changes
        /// </summary>
        private void Scheduler(ProcessControlBlock process)
        {
            ProcessControlBlock p = null;

            for (var i = 2; i >= 0; i--)
            {
                if (ReadyList[i].Count > 0)
                {
                    p = ReadyList[i][0];
                    break;
                }
            }

            if (p == null)
            {
                throw new Exception("No processes running: EXTREME FAILURE!");
            }

            if (process == null ||
                process.Priority < p.Priority ||
                process.StatusType != ProcessStates.Running)
            {
                p.StatusType   = ProcessStates.Running;
                RunningProcess = p;
            }
        }
예제 #2
0
        /// <summary>
        /// Creates a new new process <name> at the priority level <priority>;
        /// <name> is a single character; <priority> can be a 1 or 2 (0 is reserved for Init process).
        /// </summary>
        /// <param name="name">The process name.</param>
        /// <param name="priority">The process priority.</param>
        public void Create(char name, int priority)
        {
            // Error if priority is not 1 or 2
            if (priority != 1 && priority != 2)
            {
                throw new Exception("Priority must be 1 or 2");
            }

            // Recursively search children tree of the init process to see if process id already exists
            if (FindProcessById(name.ToString(), ReadyList[0][0]) != null)
            {
                throw new Exception(String.Format("duplicate process name: {0}", name));
            }

            // Create new Process
            var process = new ProcessControlBlock(name.ToString(), (Priorities)priority);

            // Initialize process
            process.StatusList = ReadyList;
            process.Parent     = RunningProcess;

            // Update parent process
            RunningProcess.Children.Add(process);

            // Add process to ready list
            ReadyList[priority].Add(process);

            Scheduler(process);
        }
예제 #3
0
        /// <summary>
        /// Initializes the Process and Resource manager state back to the original
        /// state.
        /// </summary>
        public void Initialize()
        {
            // Initialize the ready list
            ReadyList = new List <ProcessControlBlock>[3]
            {
                new List <ProcessControlBlock>(),
                new List <ProcessControlBlock>(),
                new List <ProcessControlBlock>()
            };

            // Create new Process
            var process = new ProcessControlBlock("init", Priorities.Init);

            // Initialize process
            process.StatusList = ReadyList;

            // Add process to ready list
            ReadyList[0].Add(process);

            // Create resources
            Resources = new List <ResourceControlBlock>()
            {
                new ResourceControlBlock("R1", 1),
                new ResourceControlBlock("R2", 2),
                new ResourceControlBlock("R3", 3),
                new ResourceControlBlock("R4", 4),
            };

            Scheduler(process);
        }
예제 #4
0
        /// <summary>
        /// Helper method used to release the resource. This function is the core of the "Release"
        /// function, but is used because "Kill Tree" also recursively releases resources on delete.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="units">The units.</param>
        /// <exception cref="Exception">
        /// </exception>
        private void ReleaseResource(ProcessControlBlock process, ResourceControlBlock resource, int units)
        {
            // Validate that the process has units from the resource
            if (!process.OtherResources.Where(x => x.Key == resource).Select(y => y).Any())
            {
                throw new Exception(String.Format("not holding resource: {0}", resource.Rid));
            }

            // Is the release attempting to release too many units
            if (resource.CurUnits + units > resource.MaxUnits)
            {
                throw new Exception(String.Format("release too many units: {0}/{1}:{2}", units, resource.Rid, resource.MaxUnits - resource.CurUnits));
            }


            // Reduce the allocated units from resource units pair
            var resourceUnits = process.OtherResources.First(x => x.Key == resource);
            var newPair       = new KeyValuePair <ResourceControlBlock, int>(resourceUnits.Key,
                                                                             resourceUnits.Value - units);

            // process is no longer using resource
            if (newPair.Value == 0)
            {
                process.OtherResources.Remove(process.OtherResources.First(x => x.Key.Equals(resource)));
            }
            else
            {
                process.OtherResources.Remove(
                    RunningProcess.OtherResources.First(x => x.Key == resourceUnits.Key));
                RunningProcess.OtherResources.Add(newPair);
            }


            resource.CurUnits += units;


            // loop through all waiting processes to get access to resource
            while (resource.WaitingList.Count != 0 && resource.WaitingList[0].Value <= resource.CurUnits)
            {
                // Get process from waiting list
                process = resource.WaitingList[0].Key;

                // Get requested amount of resource
                var u = resource.WaitingList.First(x => x.Key.Equals(process)).Value;

                // Remove units from resource
                resource.CurUnits -= u;

                // Remove process from waiting list
                resource.WaitingList.RemoveAt(0);

                // Add resource to process list
                process.StatusType = ProcessStates.Ready;
                process.StatusList = ReadyList;
                process.OtherResources.Add(new KeyValuePair <ResourceControlBlock, int>(resource, u));

                // Insert process into ready list
                ReadyList[(int)process.Priority].Add(process);
            }
        }
예제 #5
0
        /// <summary>
        /// Recursive function that searches for the process by identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="process">The current process.</param>
        /// <returns></returns>
        private static ProcessControlBlock FindProcessById(string id, ProcessControlBlock process)
        {
            if ((process == null) || process.Pid == id)
            {
                return(process);
            }

            // recursively navigate through tree to find process, otherwise return null
            foreach (var proc in process.Children)
            {
                var p = FindProcessById(id, proc);
                if (p != null)
                {
                    return(p);
                }
            }

            return(null);
        }
예제 #6
0
        /// <summary>
        /// Timesouts the manager and shifts the current running process to the back of it's queue,
        /// and sets the current running process to the next in line.
        /// </summary>
        public void Timeout()
        {
            ProcessControlBlock process = null;

            for (var i = 2; i >= 0; i--)
            {
                if (ReadyList[i].Count > 0)
                {
                    process = ReadyList[i][0];
                    break;
                }
            }

            ReadyList[(int)process.Priority].Remove(process);
            process.StatusType = ProcessStates.Ready;
            ReadyList[(int)process.Priority].Add(process);

            Scheduler(process);
        }
예제 #7
0
        /// <summary>
        /// Releases resources from all children nodes and from process.
        /// </summary>
        /// <param name="process">The process.</param>
        private void KillTree(ProcessControlBlock process)
        {
            if (process == null)
            {
                return;
            }

            foreach (var proc in process.Children)
            {
                KillTree(proc);
            }

            // remove all children
            process.Children = null;

            // if process is blocked by resource, remove process from waiting list
            if (process.StatusType == ProcessStates.Blocked)
            {
                var resource = (ResourceControlBlock)process.StatusList;
                resource.WaitingList.Remove(resource.WaitingList.First(x => x.Key.Equals(process)));
                process.StatusList = null;
            }
            // else remove process from ready list
            else
            {
                ReadyList[(int)process.Priority].Remove(process);
            }

            // Release resources
            foreach (var resourceRequest in process.OtherResources.ToList())
            {
                var units    = resourceRequest.Value;
                var resource = resourceRequest.Key;

                ReleaseResource(process, resource, units);
            }
        }