public void RequestGetRes(string procName, short resourceId) { var procCtrlScan = (ProcessesController)_processesController.Clone(); procCtrlScan.AddRequestRes(procName, resourceId); try { SafeCheck(_resourcesAllocator, procCtrlScan); } catch (Exception e) { var additionMessage = $"#Error: Impossible to init process [{procName}], because this action goes to deadlock:\n"; throw new Exception(additionMessage + e.Message); } _processesController = procCtrlScan; }
public void ProcGetRes(string procName, short resourceId) { var resAllocScan = (ResourcesAllocator)_resourcesAllocator.Clone(); var procCtrlScan = (ProcessesController)_processesController.Clone(); var proc = procCtrlScan.AddAvailableRes(procName, resourceId); resAllocScan.MakeLink(resourceId, proc.Name); try { SafeCheck(resAllocScan, procCtrlScan); } catch (Exception e) { var additionMessage = $"#Error: Impossible to init process [{procName}], because this action goes to deadlock:\n"; throw new Exception(additionMessage + e.Message); } _resourcesAllocator = resAllocScan; _processesController = procCtrlScan; }
public void InitProcess(string procName, IEnumerable <short> availableRes, IEnumerable <short> requestRes) { var dosntNeedRes = !availableRes.Any() && !requestRes.Any(); if (dosntNeedRes) { var newProcess = new Process(procName, availableRes, requestRes); _processesController.AddProcess(newProcess); } else { foreach (var resourceId in availableRes) { var inSystem = _resourcesAllocator.CkeckRes(resourceId); if (!inSystem) { throw new Exception($"#Error: Impossible to init process [{procName}], because system doesn't constains resource with id [{resourceId}]"); } var isfree = _resourcesAllocator.CheckResToFree(resourceId); if (!isfree) { throw new Exception($"#Error: Impossible to init process [{procName}], because another process already uses resource with id [{resourceId}]"); } } foreach (var resourceId in requestRes) { var inSystem = _resourcesAllocator.CkeckRes(resourceId); if (!inSystem) { throw new Exception($"#Error: Impossible to init process [{procName}], because system doesn't constains resource with id [{resourceId}]"); } } if (IsRepeat(availableRes) || IsRepeat(requestRes)) { throw new Exception($"#Error: One Process [{procName}] can't request (pick up) a single resource twise"); } var newProcess = new Process(procName, availableRes, requestRes); var resAllocScan = (ResourcesAllocator)_resourcesAllocator.Clone(); var procCtrlScan = (ProcessesController)_processesController.Clone(); foreach (var resourceId in availableRes) { resAllocScan.MakeLink(resourceId, newProcess.Name); } procCtrlScan.AddProcess(newProcess); try { SafeCheck(resAllocScan, procCtrlScan); } catch (Exception e) { var additionMessage = $"#Error: Impossible to init process [{procName}], because this action goes to deadlock:\n"; throw new Exception(additionMessage + e.Message); } _resourcesAllocator = resAllocScan; _processesController = procCtrlScan; } }
private static string GetMeassageFromDeadlock(IEnumerable <string> analystic, ProcessesController procCtrl) { var sb = new StringBuilder(); var resInDeadlock = new List <string>(); var procInDeadlock = new List <string>(); var analysticList = analystic.ToList(); var index = analysticList.Count - 1; analysticList.RemoveAt(index); var processes = procCtrl.Processes; foreach (var id in analysticList) { var isProcess = processes.ContainsKey(id); if (isProcess) { procInDeadlock.Add(id); foreach (var res in processes[id].AvailableRes) { resInDeadlock.Add(res.ToString()); } } } sb.Append("{\nProcess in deadlock:\n"); var counter = 1; foreach (var procName in procInDeadlock) { sb.Append("\t" + counter + ") " + procName + "\n"); ++counter; } sb.Append("Resources in deadLock:\n"); counter = 1; foreach (var resName in resInDeadlock) { sb.Append("\t" + counter + ") " + resName + "\n"); ++counter; } sb.Append("}"); return(sb.ToString()); }
private static void SafeCheck(ResourcesAllocator resAlloc, ProcessesController procCtrl) { var processes = procCtrl.Processes; var resources = resAlloc.Resources; var linksDict = new SortedDictionary <string, int>(); foreach (var procPair in processes) { var outLinksCount = procPair.Value.NecessaryRes.Count; linksDict[procPair.Key] = outLinksCount; } foreach (var res in resources) { var resName = res.Key.ToString(); linksDict[resName] = (res.Value != null) ? 1 : 0; } var nodes = linksDict.Keys.ToList(); var analistycStack = new Stack <string>(); foreach (var startingNode in nodes) { var currentNode = startingNode; analistycStack.Push(currentNode); while (linksDict[startingNode] != 0 || analistycStack.Count > 1) { var outLinkNumber = linksDict[currentNode]; if (outLinkNumber != 0) { var isProcess = procCtrl.ProcessInSystem(currentNode); string nextNode; if (isProcess) { nextNode = processes[currentNode].NecessaryRes[outLinkNumber - 1].ToString(); } else { short.TryParse(currentNode, out var resid); nextNode = resources[resid]; } linksDict[currentNode] -= 1; analistycStack.Push(nextNode); currentNode = nextNode; var isCycle = IsRepeat(analistycStack); if (isCycle) { var message = GetMeassageFromDeadlock(analistycStack, procCtrl); throw new Exception(message); } } else { analistycStack.Pop(); currentNode = analistycStack.Peek(); } } analistycStack.Clear(); } }
public MySystem() { _resourcesAllocator = new ResourcesAllocator(); _processesController = new ProcessesController(); }