1818with Ada.Unchecked_Conversion ;
1919with Ada.Unchecked_Deallocation ;
2020with System.Storage_Elements ;
21- with LSP.Server_Jobs ;
2221
2322package body LSP.Job_Schedulers is
2423
2524 procedure Free is new Ada.Unchecked_Deallocation
2625 (LSP.Server_Jobs.Server_Job'Class, LSP.Server_Jobs.Server_Job_Access);
2726
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+
2846 -- --------------
2947 -- Create_Job --
3048 -- --------------
3149
3250 procedure Create_Job
3351 (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;
3558 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 ;
3873 end Create_Job ;
3974
4075 -- ------------
@@ -43,7 +78,8 @@ package body LSP.Job_Schedulers is
4378
4479 function Has_Jobs (Self : Job_Scheduler'Class) return Boolean is
4580 begin
46- return Self.Message.Assigned;
81+ return Self.Blocker.Assigned or else
82+ (for some List of Self.Jobs => not List.Is_Empty);
4783 end Has_Jobs ;
4884
4985 -- --------
@@ -68,43 +104,83 @@ package body LSP.Job_Schedulers is
68104 LSP.Client_Message_Receivers.Client_Message_Receiver'Class;
69105 Waste : out LSP.Server_Messages.Server_Message_Access)
70106 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;
72126 begin
73- Waste := null ;
127+ if not Job.Assigned then
128+ Waste := null ;
74129
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
87139 return ;
88140 end if ;
89- end ;
141+ end loop ;
142+
143+ Execute (Job);
144+ Self.Done := Job; -- keep Job live till Complete call
145+ Job := null ;
90146 else
91- null ; -- TBD: find next job here
147+ Execute (Job);
148+ Free (Job);
92149 end if ;
150+ end Process_High_Priority_Job ;
93151
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 ;
96177
97- if Job.Is_Done then
98- -- TBD: Call complete?
99- Waste := Job.Message;
100- Free (Job);
101178 exit ;
102- else
103- raise Program_Error with " Unimplemeted" ;
104- -- TBD: put job back to the queue
105- end if ;
179+ end ;
106180 end loop ;
107- end Process_High_Priority_Job ;
181+
182+ Self.Complete_Last_Fence_Job (null );
183+ end Process_Job ;
108184
109185 -- --------------------
110186 -- Register_Handler --
0 commit comments