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 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(); }