1
1
2
2
with Componolit.Interfaces.Log.Client ;
3
3
4
- package body Component is
4
+ package body Component with
5
+ SPARK_Mode
6
+ is
7
+ use type Block.Id;
8
+ use type Block.Request_Status;
9
+ use type Block.Request_Kind;
5
10
6
11
Log : Componolit.Interfaces.Log.Client_Session := Componolit.Interfaces.Log.Client.Create;
7
12
Dispatcher : Block.Dispatcher_Session := Block_Dispatcher.Create;
8
13
Server : Block.Server_Session := Block_Server.Create;
9
14
10
- subtype Block_Buffer is Buffer (1 .. 512 );
11
- type Disk is array (Block.Id range 0 .. 1023 ) of Block_Buffer;
15
+ subtype Disk is Buffer (0 .. 524287 ); -- Disk_Block_Size * Disk_Block_Count - 1
12
16
13
17
Ram_Disk : Disk;
14
18
@@ -23,18 +27,26 @@ package body Component is
23
27
Handled => False,
24
28
Success => False));
25
29
26
- use all type Block.Id;
27
- use all type Block.Count;
28
- use all type Block.Request_Kind;
29
- use all type Block.Request_Status;
30
-
31
30
procedure Construct (Cap : Componolit.Interfaces.Types.Capability)
32
31
is
33
32
begin
34
- Componolit.Interfaces.Log.Client.Initialize (Log, Cap, " Ada_Block_Server" );
35
- Block_Dispatcher.Initialize (Dispatcher, Cap);
36
- Block_Dispatcher.Register (Dispatcher);
37
- Componolit.Interfaces.Log.Client.Info (Log, " Dispatcher initialized" );
33
+ if not Componolit.Interfaces.Log.Client.Initialized (Log) then
34
+ Componolit.Interfaces.Log.Client.Initialize (Log, Cap, " Ada_Block_Server" );
35
+ end if ;
36
+ if Componolit.Interfaces.Log.Client.Initialized (Log) then
37
+ if not Block_Dispatcher.Initialized (Dispatcher) then
38
+ Block_Dispatcher.Initialize (Dispatcher, Cap);
39
+ end if ;
40
+ if Block_Dispatcher.Initialized (Dispatcher) then
41
+ Block_Dispatcher.Register (Dispatcher);
42
+ Componolit.Interfaces.Log.Client.Info (Log, " Dispatcher initialized" );
43
+ else
44
+ Componolit.Interfaces.Log.Client.Error (Log, " Failed to initialize dispatcher" );
45
+ Main.Vacate (Cap, Main.Failure);
46
+ end if ;
47
+ else
48
+ Main.Vacate (Cap, Main.Failure);
49
+ end if ;
38
50
end Construct ;
39
51
40
52
procedure Destruct
@@ -48,47 +60,59 @@ package body Component is
48
60
end if ;
49
61
end Destruct ;
50
62
51
- procedure Read (R : in out Cache_Element);
63
+ procedure Read (R : in out Cache_Element) with
64
+ Pre => Block_Server.Initialized (Server)
65
+ and then Block_Server.Status (R.Req) = Block.Pending
66
+ and then Block_Server.Kind (R.Req) = Block.Read
67
+ and then Block_Server.Start (R.Req) <= Block.Id (Ram_Disk'Length / Disk_Block_Size)
68
+ and then Block_Server.Length (R.Req) > 0
69
+ and then Block_Server.Length (R.Req) <= Block.Count (Ram_Disk'Length / Disk_Block_Size),
70
+ Post => Block_Server.Initialized (Server);
52
71
53
72
procedure Read (R : in out Cache_Element)
54
73
is
55
- Start : constant Block.Id := Block_Server.Start (R.Req);
74
+ Start : constant Block.Count := Block.Count ( Block_Server.Start (R.Req) );
56
75
Length : constant Block.Count := Block_Server.Length (R.Req);
57
- Buf : Buffer (1 .. Length * Block_Size (Block_Server.Instance (Server)));
58
76
begin
59
- if Buf'Length mod Block_Buffer'Length = 0 and then
60
- Start in Ram_Disk'Range and then
61
- Start + ( Length - 1 ) in Ram_Disk'Range
77
+ if
78
+ Start * Disk_Block_Size in Ram_Disk'Range
79
+ and then ( Start + Length) * Disk_Block_Size - 1 in Ram_Disk'Range
62
80
then
63
- for I in Block.Id range Start .. Start + (Length - 1 ) loop
64
- Buf (Buf'First + (I - Start) * Block_Buffer'Length ..
65
- Buf'First + (I - Start + 1 ) * Block_Buffer'Length - 1 ) := Ram_Disk (I);
66
- end loop ;
67
- Block_Server.Read (Server, R.Req, Buf);
81
+ Block_Server.Read
82
+ (Server,
83
+ R.Req,
84
+ Ram_Disk (Start * Disk_Block_Size .. (Start + Length) * Disk_Block_Size - 1 ));
68
85
R.Success := True;
86
+ else
87
+ R.Success := False;
69
88
end if ;
70
89
end Read ;
71
90
72
- procedure Write (R : in out Cache_Element);
91
+ procedure Write (R : in out Cache_Element) with
92
+ Pre => Block_Server.Initialized (Server)
93
+ and then Block_Server.Status (R.Req) = Block.Pending
94
+ and then Block_Server.Kind (R.Req) = Block.Write
95
+ and then Block_Server.Start (R.Req) <= Block.Id (Ram_Disk'Length / Disk_Block_Size)
96
+ and then Block_Server.Length (R.Req) > 0
97
+ and then Block_Server.Length (R.Req) <= Block.Count (Ram_Disk'Length / Disk_Block_Size),
98
+ Post => Block_Server.Initialized (Server);
73
99
74
100
procedure Write (R : in out Cache_Element)
75
101
is
76
- Start : constant Block.Id := Block_Server.Start (R.Req);
102
+ Start : constant Block.Count := Block.Count ( Block_Server.Start (R.Req) );
77
103
Length : constant Block.Count := Block_Server.Length (R.Req);
78
- B : Buffer (1 .. Length * Block_Size (Block_Server.Instance (Server)));
79
104
begin
80
105
if
81
- B'Length mod Block_Buffer'Length = 0 and then
82
- Start in Ram_Disk'Range and then
83
- Start + (Length - 1 ) in Ram_Disk'Range
106
+ Start * Disk_Block_Size in Ram_Disk'Range
107
+ and then (Start + Length) * Disk_Block_Size - 1 in Ram_Disk'Range
84
108
then
85
- Block_Server.Write (Server, R.Req, B);
86
- for I in Block.Id range Start .. Start + (Length - 1 ) loop
87
- Ram_Disk (I) :=
88
- B (B'First + (I - Start) * Block_Buffer'Length ..
89
- B'First + ((I - Start) + 1 ) * Block_Buffer'Length - 1 );
90
- end loop ;
109
+ Block_Server.Write
110
+ (Server,
111
+ R.Req,
112
+ Ram_Disk (Start * Disk_Block_Size .. (Start + Length) * Disk_Block_Size - 1 ));
91
113
R.Success := True;
114
+ else
115
+ R.Success := False;
92
116
end if ;
93
117
end Write ;
94
118
@@ -107,13 +131,22 @@ package body Component is
107
131
and then not Request_Cache (I).Handled
108
132
then
109
133
Request_Cache (I).Handled := True;
110
- case Block_Server.Kind (Request_Cache (I).Req) is
111
- when Block.Read =>
112
- Read (Request_Cache (I));
113
- when Block.Write =>
114
- Write (Request_Cache (I));
115
- when others => null ;
116
- end case ;
134
+ if
135
+ Block_Server.Start (Request_Cache (I).Req) <= Block.Id (Ram_Disk'Length / Disk_Block_Size)
136
+ and then Block_Server.Length (Request_Cache (I).Req) > 0
137
+ and then Block_Server.Length (Request_Cache (I).Req) <=
138
+ Block.Count (Ram_Disk'Length / Disk_Block_Size)
139
+ then
140
+ case Block_Server.Kind (Request_Cache (I).Req) is
141
+ when Block.Read =>
142
+ Read (Request_Cache (I));
143
+ when Block.Write =>
144
+ Write (Request_Cache (I));
145
+ when others => null ;
146
+ end case ;
147
+ else
148
+ Request_Cache (I).Success := False;
149
+ end if ;
117
150
end if ;
118
151
if
119
152
Block_Server.Status (Request_Cache (I).Req) = Block.Pending
@@ -131,14 +164,14 @@ package body Component is
131
164
is
132
165
pragma Unreferenced (S);
133
166
begin
134
- return Block.Count (Ram_Disk'Length) ;
167
+ return Disk_Block_Count ;
135
168
end Block_Count ;
136
169
137
170
function Block_Size (S : Block.Server_Instance) return Block.Size
138
171
is
139
172
pragma Unreferenced (S);
140
173
begin
141
- return Block.Size (Block_Buffer'Length) ;
174
+ return Disk_Block_Size ;
142
175
end Block_Size ;
143
176
144
177
function Writable (S : Block.Server_Instance) return Boolean
@@ -159,10 +192,28 @@ package body Component is
159
192
is
160
193
pragma Unreferenced (S);
161
194
pragma Unreferenced (B);
195
+ Max : Natural;
162
196
begin
163
- Componolit.Interfaces.Log.Client.Info (Log, " Server initialize with label: " & L);
164
- Ram_Disk := (others => (others => 0 ));
165
- Componolit.Interfaces.Log.Client.Info (Log, " Initialized" );
197
+ if Componolit.Interfaces.Log.Client.Initialized (Log) then
198
+ Max := Componolit.Interfaces.Log.Client.Maximum_Message_Length (Log);
199
+ Componolit.Interfaces.Log.Client.Info (Log, " Server initialize with label: " );
200
+ if L'Length <= Max then
201
+ Componolit.Interfaces.Log.Client.Info (Log, L);
202
+ else
203
+ for I in Natural range 0 .. Natural'Last / Max - L'First - 1 loop
204
+ pragma Loop_Invariant (Componolit.Interfaces.Log.Client.Initialized (Log));
205
+ pragma Loop_Invariant (Max = Componolit.Interfaces.Log.Client.Maximum_Message_Length (Log));
206
+ if L'First + (I + 1 ) * Max <= L'Last then
207
+ Componolit.Interfaces.Log.Client.Info (Log, L (L'First + I * Max .. L'First + (I + 1 ) * Max - 1 ));
208
+ else
209
+ Componolit.Interfaces.Log.Client.Info (Log, L (L'First + I * Max .. L'Last));
210
+ exit ;
211
+ end if ;
212
+ end loop ;
213
+ end if ;
214
+ Componolit.Interfaces.Log.Client.Info (Log, " Initialized" );
215
+ end if ;
216
+ Ram_Disk := (others => 0 );
166
217
end Initialize ;
167
218
168
219
procedure Finalize (S : Block.Server_Instance)
@@ -175,13 +226,18 @@ package body Component is
175
226
procedure Request (C : Block.Dispatcher_Capability)
176
227
is
177
228
begin
178
- if Block_Dispatcher.Valid_Session_Request (Dispatcher, C) and not Block_Server.Initialized (Server) then
179
- Block_Dispatcher.Session_Initialize (Dispatcher, C, Server);
180
- if Block_Server.Initialized (Server) then
181
- Block_Dispatcher.Session_Accept (Dispatcher, C, Server);
229
+ if Block_Dispatcher.Initialized (Dispatcher) then
230
+ if
231
+ Block_Dispatcher.Valid_Session_Request (Dispatcher, C)
232
+ and then not Block_Server.Initialized (Server)
233
+ then
234
+ Block_Dispatcher.Session_Initialize (Dispatcher, C, Server);
235
+ if Block_Server.Initialized (Server) then
236
+ Block_Dispatcher.Session_Accept (Dispatcher, C, Server);
237
+ end if ;
182
238
end if ;
239
+ Block_Dispatcher.Session_Cleanup (Dispatcher, C, Server);
183
240
end if ;
184
- Block_Dispatcher.Session_Cleanup (Dispatcher, C, Server);
185
241
end Request ;
186
242
187
243
end Component ;
0 commit comments