-
Notifications
You must be signed in to change notification settings - Fork 0
/
Table.cs
67 lines (59 loc) · 2.35 KB
/
Table.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using ConcurrencyUtilities;
using ThreadSupport = TestConcurrencyUtilities.TestSupport;
namespace CigaretteSmokers
{
/// <summary>
/// The table is the 'agent'. It keeps two of the three resources in stock at any one time.
/// </summary>
public class Table
{
List<SmokerResource> _resources;
Semaphore _startIteration; // Permission to start the next resource restocking iteration
Random _rnd; // The random number generator to use to decide which resource should not be restocked
/// <summary>
/// Initializes a new instance of the <see cref="CigaretteSmokers.Table"/> class.
/// </summary>
/// <param name="resources">The list containing the smoker resources which should be restocked.</param>
public Table(List<SmokerResource> resources) {
_startIteration = new Semaphore(0);
_resources = resources;
_rnd = new Random();
ReadyToStartNewIteration();
}
/// <summary>
/// Runs the table thread. Restocks when allowed to.
/// </summary>
public void Run() {
while (true) {
// Wait for a new iteration to begin before continuing (signalled by constructor / successful smoker)
_startIteration.Acquire();
// Start a new iteration. If using the iteration checking method, the IterationID has already been
// updated by the successful smoker -- avoiding modifying the 'agent' (table) from the original problem
RestockTwoResources();
}
}
/// <summary>
/// Gives the table permission to restock the resources (from having been waiting in the run method for the
/// existing resouces to be taken).
/// </summary>
public void ReadyToStartNewIteration() {
_startIteration.Release();
}
/// <summary>
/// Randomly restocks two of the three resources.
/// </summary>
void RestockTwoResources() {
List<SmokerResource> resourcesToRestock = new List<SmokerResource>(_resources); // Clone the resource list
int indexOfResourceToWithhold = _rnd.Next(0, 3);
ThreadSupport.DebugThread("{yellow}Not restocking: " + resourcesToRestock[indexOfResourceToWithhold].Name +
" (" + (indexOfResourceToWithhold+1) + ")");
resourcesToRestock.RemoveAt(indexOfResourceToWithhold);
foreach (SmokerResource resource in resourcesToRestock) {
ThreadSupport.DebugThread("{black}Restocked: " + resource.Name);
resource.Restock();
}
}
}
}