-
Notifications
You must be signed in to change notification settings - Fork 1
/
protectobj.adb
178 lines (142 loc) · 5.11 KB
/
protectobj.adb
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers; use Ada.Containers;
with Ada.Containers.Vectors;
procedure protectobj is
tick : Float := 0.033;
package IntVec is new Ada.Containers.Vectors
(Index_Type => Natural,
Element_Type => Integer);
use IntVec;
package Integer_IO is new Ada.Text_IO.Integer_IO (Integer);
-- --- RESOURCE OBJECT --- --
-- You will finish implementing allocateLow, allocateHigh, and deallocate.
-- Note: There are no checks that the final execution order is correct. You will have to check this yourself.
-- Hints:
-- - Use `entryName'Count` to get the number of tasks waiting on an entry. This can be used in the guard of another entry.
-- - Equality checks are done with `=`, instead of `==`. Assignment is always done with `:=`.
-----------------------
protected type Resource is
entry allocateHigh(val: out IntVec.Vector);
entry allocateLow(val: out IntVec.Vector);
procedure deallocate(val: IntVec.Vector);
private
value: IntVec.Vector;
busy: Boolean := False;
end Resource;
protected body Resource is
entry allocateLow(val: out IntVec.Vector) when True is
begin
--Put_Line("allocateLow");
val := value;
end allocateLow;
entry allocateHigh(val: out IntVec.Vector) when True is
begin
--Put_Line("allocateHigh");
val := value;
end allocateHigh;
procedure deallocate(val: IntVec.Vector) is
begin
--Put_Line("deallocate");
value := val;
end deallocate;
end Resource;
type ExecutionState is (none, waiting, executing, done);
type ExecutionStateArrT is array (0..9) of ExecutionState;
executionStates: ExecutionStateArrT := (others => none);
task type resourceUser(
id: Integer;
priority: Integer;
release: Integer;
execute: Integer;
r: access Resource
);
value: IntVec.Vector;
task body resourceUser is
begin
delay Duration(tick * Float(release));
executionStates(id) := waiting;
if priority = 1 then
r.allocateHigh(value);
else
r.allocateLow(value);
end if;
executionStates(id) := executing;
delay Duration(tick * Float(execute));
value.Append(id);
r.deallocate(value);
executionStates(id) := done;
end resourceUser;
task type executionLogger;
t : Integer := 0;
task body executionLogger is
begin
delay Duration(tick/2.0);
Put(" id:");
for i in 0..executionStates'length-1 loop
Integer_IO.Put(i, Width => 3);
end loop;
Put_Line("");
loop
Integer_IO.Put(t, Width => 4);
Put(" : ");
for state of executionStates loop
case state is
when none =>
Put(" ");
when waiting =>
Put("|");
when executing =>
Put("#");
when done =>
Put("^");
state := none;
end case;
if t rem 5 = 0 then
Put("--");
else
Put(" ");
end if;
end loop;
Put_Line("");
t := t+1;
delay Duration(tick);
end loop;
end executionLogger;
r: aliased Resource;
logger: executionLogger;
executionOrder: IntVec.Vector;
begin
Put_Line("started");
declare
user00: resourceUser(0, 0, 1, 1, r'Access);
user01: resourceUser(1, 0, 3, 1, r'Access);
user02: resourceUser(2, 1, 5, 1, r'Access);
user03: resourceUser(0, 1, 10, 2, r'Access);
user04: resourceUser(1, 0, 11, 1, r'Access);
user05: resourceUser(2, 1, 11, 1, r'Access);
user06: resourceUser(3, 0, 11, 1, r'Access);
user07: resourceUser(4, 1, 11, 1, r'Access);
user08: resourceUser(5, 0, 11, 1, r'Access);
user09: resourceUser(6, 1, 11, 1, r'Access);
user10: resourceUser(7, 0, 11, 1, r'Access);
user11: resourceUser(8, 1, 11, 1, r'Access);
user12: resourceUser(0, 1, 25, 3, r'Access);
user13: resourceUser(6, 0, 26, 2, r'Access);
user14: resourceUser(7, 0, 26, 2, r'Access);
user15: resourceUser(1, 1, 26, 2, r'Access);
user16: resourceUser(2, 1, 27, 2, r'Access);
user17: resourceUser(3, 1, 28, 2, r'Access);
user18: resourceUser(4, 1, 29, 2, r'Access);
user19: resourceUser(5, 1, 30, 2, r'Access);
begin
null;
end;
delay Duration(tick * 2.0);
abort logger;
r.allocateHigh(executionOrder);
Put_Line("Execution order: ");
for idx in executionOrder.Iterate loop
Put(Integer'Image(executionOrder(idx)));
end loop;
Put_Line("");
end protectobj;