18
18
with Ada.Unchecked_Conversion ;
19
19
with Ada.Unchecked_Deallocation ;
20
20
with System.Storage_Elements ;
21
- with LSP.Server_Jobs ;
22
21
23
22
package body LSP.Job_Schedulers is
24
23
25
24
procedure Free is new Ada.Unchecked_Deallocation
26
25
(LSP.Server_Jobs.Server_Job'Class, LSP.Server_Jobs.Server_Job_Access);
27
26
27
+ procedure Complete_Last_Fence_Job
28
+ (Self : in out Job_Scheduler'Class;
29
+ Next : LSP.Server_Messages.Server_Message_Access);
30
+ -- Call Complete on the last done Fence job (if any) and free it
31
+
32
+ -- ---------------------------
33
+ -- Complete_Last_Fence_Job --
34
+ -- ---------------------------
35
+
36
+ procedure Complete_Last_Fence_Job
37
+ (Self : in out Job_Scheduler'Class;
38
+ Next : LSP.Server_Messages.Server_Message_Access) is
39
+ begin
40
+ if Self.Done.Assigned then
41
+ Self.Done.Complete (Next);
42
+ Free (Self.Done);
43
+ end if ;
44
+ end Complete_Last_Fence_Job ;
45
+
28
46
-- --------------
29
47
-- Create_Job --
30
48
-- --------------
31
49
32
50
procedure Create_Job
33
51
(Self : in out Job_Scheduler'Class;
34
- Message : in out LSP.Server_Messages.Server_Message_Access) is
52
+ Message : in out LSP.Server_Messages.Server_Message_Access)
53
+ is
54
+ Cursor : constant Handler_Maps.Cursor :=
55
+ Self.Handlers.Find (Message'Tag);
56
+
57
+ Job : LSP.Server_Jobs.Server_Job_Access;
35
58
begin
36
- Self.Message := Message;
37
- Message := null ;
59
+ if Handler_Maps.Has_Element (Cursor) then
60
+
61
+ Job := Handler_Maps.Element (Cursor).Create_Job (Message);
62
+
63
+ if Job.Assigned then
64
+ Message := null ;
65
+
66
+ if Job.Priority in Self.Jobs'Range then
67
+ Self.Jobs (Job.Priority).Append (Job);
68
+ else
69
+ Self.Blocker := Job;
70
+ end if ;
71
+ end if ;
72
+ end if ;
38
73
end Create_Job ;
39
74
40
75
-- ------------
@@ -43,7 +78,8 @@ package body LSP.Job_Schedulers is
43
78
44
79
function Has_Jobs (Self : Job_Scheduler'Class) return Boolean is
45
80
begin
46
- return Self.Message.Assigned;
81
+ return Self.Blocker.Assigned or else
82
+ (for some List of Self.Jobs => not List.Is_Empty);
47
83
end Has_Jobs ;
48
84
49
85
-- --------
@@ -68,43 +104,83 @@ package body LSP.Job_Schedulers is
68
104
LSP.Client_Message_Receivers.Client_Message_Receiver'Class;
69
105
Waste : out LSP.Server_Messages.Server_Message_Access)
70
106
is
71
- Job : LSP.Server_Jobs.Server_Job_Access;
107
+ use all type LSP.Server_Jobs.Job_Priority;
108
+
109
+ procedure Execute (Job : LSP.Server_Jobs.Server_Job_Access);
110
+
111
+ -- -----------
112
+ -- Execute --
113
+ -- -----------
114
+
115
+ procedure Execute (Job : LSP.Server_Jobs.Server_Job_Access) is
116
+ begin
117
+ Self.Complete_Last_Fence_Job (Job.Message);
118
+ Waste := Job.Message;
119
+
120
+ while not Job.Is_Done loop
121
+ Job.Execute (Client);
122
+ end loop ;
123
+ end Execute ;
124
+
125
+ Job : LSP.Server_Jobs.Server_Job_Access renames Self.Blocker;
72
126
begin
73
- Waste := null ;
127
+ if not Job.Assigned then
128
+ Waste := null ;
74
129
75
- -- Process the most recent message if any
76
- if Self.Message.Assigned then
77
- declare
78
- Cursor : constant Handler_Maps.Cursor :=
79
- Self.Handlers.Find (Self.Message'Tag);
80
- begin
81
- if Handler_Maps.Has_Element (Cursor) then
82
- Job := Handler_Maps.Element (Cursor).Create_Job (Self.Message);
83
- Self.Message := null ;
84
- else
85
- Waste := Self.Message;
86
- Self.Message := null ;
130
+ return ;
131
+ end if ;
132
+
133
+ if Job.Priority = Fence then
134
+ -- Process other jobs before any Fence job
135
+ while (for some List of Self.Jobs => not List.Is_Empty) loop
136
+ Self.Process_Job (Client, Waste);
137
+
138
+ if Waste.Assigned then
87
139
return ;
88
140
end if ;
89
- end ;
141
+ end loop ;
142
+
143
+ Execute (Job);
144
+ Self.Done := Job; -- keep Job live till Complete call
145
+ Job := null ;
90
146
else
91
- null ; -- TBD: find next job here
147
+ Execute (Job);
148
+ Free (Job);
92
149
end if ;
150
+ end Process_High_Priority_Job ;
93
151
94
- while Job.Assigned loop
95
- Job.Execute (Client);
152
+ -- ---------------
153
+ -- Process_Job --
154
+ -- ---------------
155
+
156
+ procedure Process_Job
157
+ (Self : in out Job_Scheduler'Class;
158
+ Client :
159
+ in out LSP.Client_Message_Receivers.Client_Message_Receiver'Class;
160
+ Waste : out LSP.Server_Messages.Server_Message_Access) is
161
+ begin
162
+ for List of reverse Self.Jobs when not List.Is_Empty loop
163
+ declare
164
+ Job : LSP.Server_Jobs.Server_Job_Access := List.First_Element;
165
+ begin
166
+ List.Delete_First;
167
+ Self.Complete_Last_Fence_Job (Job.Message);
168
+ Job.Execute (Client);
169
+
170
+ if Job.Is_Done then
171
+ Waste := Job.Message;
172
+ Free (Job);
173
+ else
174
+ Waste := null ;
175
+ List.Append (Job); -- Push the job back to the queue
176
+ end if ;
96
177
97
- if Job.Is_Done then
98
- -- TBD: Call complete?
99
- Waste := Job.Message;
100
- Free (Job);
101
178
exit ;
102
- else
103
- raise Program_Error with " Unimplemeted" ;
104
- -- TBD: put job back to the queue
105
- end if ;
179
+ end ;
106
180
end loop ;
107
- end Process_High_Priority_Job ;
181
+
182
+ Self.Complete_Last_Fence_Job (null );
183
+ end Process_Job ;
108
184
109
185
-- --------------------
110
186
-- Register_Handler --
0 commit comments