Skip to content

Commit 65fe075

Browse files
committed
chore: add things
0 parents  commit 65fe075

25 files changed

+1194
-0
lines changed

.gitignore

Lines changed: 408 additions & 0 deletions
Large diffs are not rendered by default.

BankerAlgorithm/Arguments.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using CommandLine;
2+
using System.Runtime.InteropServices;
3+
4+
namespace BankerAlgorithm
5+
{
6+
public class Arguments
7+
{
8+
[Option("fileName", Required = true, HelpText = "Test File Name")]
9+
public string FileName { get; set; } = "";
10+
}
11+
}

BankerAlgorithm/Banker.cs

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection.Metadata.Ecma335;
6+
using System.Runtime.CompilerServices;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace BankerAlgorithm
11+
{
12+
public enum AllocateStatus
13+
{
14+
Fail = 0,
15+
Success = 1,
16+
Waiting = 2
17+
}
18+
19+
public class Banker
20+
{
21+
private int[] availableResource;
22+
public int[] AvailableResource => availableResource;
23+
24+
private int[,] maxDemand;
25+
public int[,] MaxDemand => maxDemand;
26+
27+
private int[,] allocation;
28+
public int[,] Allocation => allocation;
29+
30+
private int[,] need;
31+
public int[,] Need => need;
32+
33+
public int ProcessNum => maxDemand.GetLength(0);
34+
35+
private Queue<Tuple<int, int[]>> processQueue;
36+
37+
public AllocateStatus AllocateRequest(int processID, int[] requestVec) => AllocateAfterFree(processID, requestVec, true);
38+
39+
private bool TryAllocate(int processID, int[] requestVec)
40+
{
41+
for (int i = 0; i < requestVec.Length; i++)
42+
{
43+
availableResource[i] -= requestVec[i];
44+
allocation[processID, i] += requestVec[i];
45+
need[processID, i] -= requestVec[i];
46+
}
47+
int[] work = new int[availableResource.Length];
48+
Array.Copy(availableResource, work, availableResource.Length);
49+
bool[] finish = Enumerable.Repeat(false, ProcessNum).ToArray();
50+
bool findi;
51+
do
52+
{
53+
findi = false;
54+
for (int i = 0; i < ProcessNum; i++)
55+
{
56+
if (!finish[i])
57+
{
58+
bool flag = true;
59+
for (int j = 0; j < work.Length; j++)
60+
{
61+
if (need[i, j] > work[j])
62+
{
63+
flag = false;
64+
break;
65+
}
66+
}
67+
if (flag)
68+
{
69+
findi = true;
70+
for (int j = 0; j < work.Length; j++)
71+
{
72+
work[j] += allocation[i, j];
73+
}
74+
finish[i] = true;
75+
break;
76+
}
77+
else
78+
{
79+
continue;
80+
}
81+
}
82+
}
83+
}
84+
while (findi);
85+
bool res = finish.All(b => b);
86+
if (!res)
87+
{
88+
for (int i = 0; i < requestVec.Length; i++)
89+
{
90+
availableResource[i] += requestVec[i];
91+
allocation[processID, i] -= requestVec[i];
92+
need[processID, i] += requestVec[i];
93+
}
94+
}
95+
return res;
96+
}
97+
98+
private AllocateStatus AllocateAfterFree(int processID, int[] requestVec, bool joinQueue = false)
99+
{
100+
Console.Write($"Request pid: {processID}; Allocate: ");
101+
foreach (int r in requestVec)
102+
Console.Write($"{r}, ");
103+
Console.WriteLine();
104+
if (requestVec.Length != availableResource.Length)
105+
return AllocateStatus.Fail;
106+
if (processID < 0 || processID >= ProcessNum)
107+
return AllocateStatus.Fail;
108+
for (int i = 0; i < requestVec.Length; i++)
109+
{
110+
if (requestVec[i] > need[processID, i])
111+
return AllocateStatus.Fail;
112+
}
113+
for (int i = 0; i < requestVec.Length; i++)
114+
{
115+
if (requestVec[i] > availableResource[i])
116+
{
117+
if (joinQueue)
118+
processQueue.Enqueue(Tuple.Create(processID, requestVec));
119+
return AllocateStatus.Waiting;
120+
}
121+
}
122+
if (TryAllocate(processID, requestVec))
123+
return AllocateStatus.Success;
124+
else
125+
{
126+
if (joinQueue)
127+
processQueue.Enqueue(Tuple.Create(processID, requestVec));
128+
return AllocateStatus.Waiting;
129+
}
130+
}
131+
132+
public bool FreeRequest(int processID, int[]? requestVec = null)
133+
{
134+
Console.Write($"Request pid: {processID}; Free: ");
135+
if (requestVec != null)
136+
foreach (int r in requestVec)
137+
Console.Write($"{r}, ");
138+
else
139+
Console.Write("all.");
140+
Console.WriteLine();
141+
if (requestVec != null)
142+
{
143+
if (requestVec.Length != availableResource.Length)
144+
return false;
145+
if (processID < 0 || processID >= ProcessNum)
146+
return false;
147+
for (int i = 0; i < requestVec.Length; i++)
148+
{
149+
if (requestVec[i] > allocation[processID, i])
150+
return false;
151+
}
152+
for (int i = 0; i < requestVec.Length; i++)
153+
{
154+
availableResource[i] += allocation[processID, i];
155+
allocation[processID, i] -= requestVec[i];
156+
need[processID, i] += requestVec[i];
157+
}
158+
}
159+
else
160+
{
161+
for (int i = 0; i < availableResource.Length; i++)
162+
{
163+
availableResource[i] += allocation[processID, i];
164+
allocation[processID, i] = 0;
165+
need[processID, i] = maxDemand[processID, i];
166+
}
167+
}
168+
AllocateStatus res;
169+
do
170+
{
171+
res = AllocateStatus.Fail;
172+
processQueue.TryPeek(out var req);
173+
if (req != null)
174+
{
175+
res = AllocateAfterFree(req.Item1, req.Item2);
176+
if (res == AllocateStatus.Success)
177+
processQueue.Dequeue();
178+
}
179+
} while (res == AllocateStatus.Success);
180+
181+
return true;
182+
}
183+
184+
public void PrintStatus()
185+
{
186+
int maxLength = maxDemand.GetLength(1);
187+
Console.Write(" | ");
188+
Console.Write("{0, " + $"{-5 * maxLength}}}", "MaxDemand");
189+
Console.Write("| ");
190+
Console.Write("{0, " + $"{-5 * maxLength}}}", "Allocation");
191+
Console.Write("| ");
192+
Console.Write("{0, " + $"{-5 * maxLength}}}", "Need");
193+
Console.WriteLine();
194+
for (int i = 0; i < maxDemand.GetLength(0); i++)
195+
{
196+
Console.Write("pid: {0, -5}| ", i);
197+
for (int j = 0; j < maxDemand.GetLength(1); j++)
198+
{
199+
Console.Write("{0, -5}", maxDemand[i, j]);
200+
}
201+
Console.Write("| ");
202+
for (int j = 0; j < allocation.GetLength(1); j++)
203+
{
204+
Console.Write("{0, -5}", allocation[i, j]);
205+
}
206+
Console.Write("| ");
207+
for (int j = 0; j < need.GetLength(1); j++)
208+
{
209+
Console.Write("{0, -5}", need[i, j]);
210+
}
211+
Console.WriteLine();
212+
}
213+
214+
Console.WriteLine("Available Resource: ");
215+
for (int j = 0; j < availableResource.GetLength(0); j++)
216+
{
217+
Console.Write($"{availableResource[j]} ");
218+
}
219+
Console.WriteLine();
220+
Console.WriteLine("Waiting Queue: ");
221+
int k = 0;
222+
foreach ((var pid, var reqVec) in processQueue)
223+
{
224+
Console.Write($"(PID {pid}: ");
225+
foreach (var v in reqVec)
226+
{
227+
Console.Write("{0}, ", v);
228+
}
229+
Console.Write(")");
230+
if (++k < processQueue.Count)
231+
Console.Write(" <--- ");
232+
}
233+
Console.WriteLine("\n");
234+
}
235+
236+
public Banker(int[] availableResource, int[,] maxDemand)
237+
{
238+
if (availableResource.Length != maxDemand.GetLength(1))
239+
throw new Exception("Inconsistent number of resources!");
240+
this.availableResource = availableResource;
241+
this.maxDemand = maxDemand;
242+
this.allocation = new int[maxDemand.GetLength(0), maxDemand.GetLength(1)];
243+
this.need = new int[maxDemand.GetLength(0), maxDemand.GetLength(1)];
244+
Array.Copy(maxDemand, need, maxDemand.Length);
245+
this.processQueue = new(ProcessNum);
246+
}
247+
}
248+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="CommandLineParser" Version="2.9.1" />
12+
</ItemGroup>
13+
14+
</Project>

BankerAlgorithm/BankerAlgorithm.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.3.32811.315
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankerAlgorithm", "BankerAlgorithm.csproj", "{398EB3CE-FC89-467B-8F24-0C233FA7D632}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{398EB3CE-FC89-467B-8F24-0C233FA7D632}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{398EB3CE-FC89-467B-8F24-0C233FA7D632}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{398EB3CE-FC89-467B-8F24-0C233FA7D632}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{398EB3CE-FC89-467B-8F24-0C233FA7D632}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {E15F2DFF-EB37-48B4-A599-319E3F8BF471}
24+
EndGlobalSection
25+
EndGlobal

BankerAlgorithm/Program.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using CommandLine;
2+
using System;
3+
4+
namespace BankerAlgorithm
5+
{
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
Arguments? options = null;
11+
_ = Parser.Default.ParseArguments<Arguments>(args).WithParsed(o => { options = o; });
12+
if (options == null)
13+
{
14+
Console.WriteLine("Argument parsing failed!");
15+
return;
16+
}
17+
ReadFromFile(options.FileName, out var availRes, out var maxDemand, out var requsetType ,out var requestProcess, out var requestContent);
18+
Banker banker = new Banker(availRes, maxDemand);
19+
banker.PrintStatus();
20+
for (int i = 0; i < requestProcess.Length; i++)
21+
{
22+
if (requsetType[i] != "-")
23+
banker.AllocateRequest(requestProcess[i], requestContent[i]!);
24+
else
25+
banker.FreeRequest(requestProcess[i], requestContent[i]);
26+
banker.PrintStatus();
27+
}
28+
}
29+
30+
public static void ReadFromFile(string fileName, out int[] availRes, out int[,] maxDemand, out string[] requestType, out int[] requestProcess, out int[]?[] requestContent)
31+
{
32+
string[] lines = File.ReadAllLines(fileName);
33+
34+
int m = lines[0].Split().Length;
35+
int n = lines.Skip(2).TakeWhile(line => line != "").Count();
36+
int l = lines.Skip(n + 3).TakeWhile(line => line != "").Count();
37+
38+
availRes = new int[m];
39+
maxDemand = new int[n, m];
40+
requestType = new string[l];
41+
requestProcess = new int[l];
42+
requestContent = new int[l][];
43+
44+
string[] items = lines[0].Split();
45+
for (int j = 0; j < m; j++)
46+
{
47+
availRes[j] = int.Parse(items[j]);
48+
}
49+
50+
for (int i = 0; i < n; i++)
51+
{
52+
items = lines[i + 2].Split();
53+
for (int j = 0; j < m; j++)
54+
{
55+
maxDemand[i, j] = int.Parse(items[j]);
56+
}
57+
}
58+
59+
for (int i = 0; i < l; i++)
60+
{
61+
items = lines[i + n + 3].Split();
62+
requestContent[i] = new int[m];
63+
for (int j = 0; j < m + 2; j++)
64+
{
65+
if (j == 0)
66+
requestType[i] = items[j];
67+
else if (j == 1)
68+
requestProcess[i] = int.Parse(items[j]);
69+
else
70+
{
71+
if (j < items.Length)
72+
requestContent[i]![j - 2] = int.Parse(items[j]);
73+
else if (requestType[i] == "-")
74+
{
75+
requestContent[i] = null;
76+
break;
77+
}
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"profiles": {
3+
"BankerAlgorithm": {
4+
"commandName": "Project",
5+
"commandLineArgs": "--fileName E:\\清华\\大三春\\操作系统\\作业\\OS_Projects\\BankerAlgorithm\\testFiles\\test3.txt"
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)