1-- C940005.A 2-- 3-- Grant of Unlimited Rights 4-- 5-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, 6-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained 7-- unlimited rights in the software and documentation contained herein. 8-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making 9-- this public release, the Government intends to confer upon all 10-- recipients unlimited rights equal to those held by the Government. 11-- These rights include rights to use, duplicate, release or disclose the 12-- released technical data and computer software in whole or in part, in 13-- any manner and for any purpose whatsoever, and to have or permit others 14-- to do so. 15-- 16-- DISCLAIMER 17-- 18-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR 19-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED 20-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE 21-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE 22-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A 23-- PARTICULAR PURPOSE OF SAID MATERIAL. 24--* 25-- 26-- OBJECTIVE: 27-- Check that the body of a protected function can have internal calls 28-- to other protected functions and that the body of a protected 29-- procedure can have internal calls to protected procedures and to 30-- protected functions. 31-- 32-- TEST DESCRIPTION: 33-- Simulate a meter at a freeway on-ramp which, when real-time sensors 34-- determine that the freeway is becoming saturated, triggers stop lights 35-- which control the access of vehicles to prevent further saturation. 36-- Each on-ramp is represented by a protected object - in this case only 37-- one is shown (Test_Ramp). The routines to sample and alter the states 38-- of the various sensors, to queue the vehicles on the meter and to 39-- release them are all part of the protected object and can be shared 40-- by various tasks. Apart from the function/procedure tests this example 41-- has a mix of other tasking features. 42-- 43-- 44-- CHANGE HISTORY: 45-- 06 Dec 94 SAIC ACVC 2.0 46-- 13 Nov 95 SAIC Updated and fixed bugs ACVC 2.0.1 47-- 48--! 49 50 51with Report; 52with ImpDef; 53with Ada.Calendar; 54 55procedure C940005 is 56 57begin 58 59 Report.Test ("C940005", "Check internal calls of protected functions" & 60 " and procedures"); 61 62 declare -- encapsulate the test 63 64 function "+" (Left : Ada.Calendar.Time; Right: Duration) 65 return Ada.Calendar.Time renames Ada.Calendar."+"; 66 67 -- Weighted load given to each potential problem area and accumulated 68 type Load_Factor is range 0..8; 69 Clear_Level : constant Load_Factor := 0; 70 Minimum_Level : constant Load_Factor := 1; 71 Moderate_Level : constant Load_Factor := 2; 72 Serious_Level : constant Load_Factor := 4; 73 Critical_Level : constant Load_Factor := 6; 74 75 -- Weighted loads given to each Sample Point (pure weights, not levels) 76 Local_Overload_wt : constant Load_Factor := 1; 77 Next_Ramp_in_Overload_wt : constant Load_Factor := 1; 78 Ramp_Junction_in_Overload_wt : constant Load_Factor :=2; --higher wght 79 -- :::: other weighted loads 80 81 TC_Multiplier : integer := 1; -- changed half way through 82 TC_Expected_Passage_Total : constant integer := 486; 83 84 -- This is the time between synchronizing pulses to the ramps. 85 -- In reality one would expect a time of 5 to 10 seconds. In 86 -- the interests of speeding up the test suite a shorter time 87 -- is used 88 Pulse_Time_Delta : constant duration := ImpDef.Long_Switch_To_New_Task; 89 90 -- control over stopping tasks 91 protected Control is 92 procedure Stop_Now; 93 function Stop return Boolean; 94 private 95 Halt : Boolean := False; 96 end Control; 97 98 protected body Control is 99 procedure Stop_Now is 100 begin 101 Halt := True; 102 end Stop_Now; 103 104 function Stop return Boolean is 105 begin 106 return Halt; 107 end Stop; 108 end Control; 109 110 task Pulse_Task; -- task to generate a pulse for each ramp 111 112 -- Carrier task. One is created for each vehicle arriving at the ramp 113 task type Vehicle; 114 type acc_Vehicle is access Vehicle; 115 116 --================================================================ 117 protected Test_Ramp is 118 function Next_Ramp_in_Overload return Load_Factor; 119 function Local_Overload return Load_Factor; 120 function Freeway_Overload return Load_Factor; 121 function Freeway_Breakdown return Boolean; 122 function Meter_in_use_State return Boolean; 123 procedure Set_Local_Overload; 124 procedure Add_Meter_Queue; 125 procedure Subtract_Meter_Queue; 126 procedure Time_Pulse_Received; 127 entry Wait_at_Meter; 128 procedure TC_Passage (Pass_Point : Integer); 129 function TC_Get_Passage_Total return integer; 130 -- ::::::::: many routines are not shown (for example none of the 131 -- clears, none of the real-time-sensor handlers) 132 133 private 134 135 Release_One_Vehicle : Boolean := false; 136 Meter_in_Use : Boolean := false; 137 Fwy_Break_State : Boolean := false; 138 139 140 Ramp_Count : integer range 0..20 := 0; 141 Ramp_Count_Threshold : integer := 15; 142 143 -- Current state of the various Sample Points 144 Local_State : Load_Factor := Clear_Level; 145 Next_Ramp_State : Load_Factor := Clear_Level; 146 -- :::: other Sample Point states not shown 147 148 TC_Passage_Total : integer := 0; 149 end Test_Ramp; 150 --================================================================ 151 protected body Test_Ramp is 152 153 procedure Start_Meter is 154 begin 155 Meter_in_Use := True; 156 null; -- stub :::: trigger the metering hardware 157 end Start_Meter; 158 159 -- External call for Meter_in_Use 160 function Meter_in_Use_State return Boolean is 161 begin 162 return Meter_in_Use; 163 end Meter_in_Use_State; 164 165 -- Trace the paths through the various routines by totaling the 166 -- weighted call parameters 167 procedure TC_Passage (Pass_Point : Integer) is 168 begin 169 TC_Passage_Total := TC_Passage_Total+(Pass_Point*TC_Multiplier); 170 end TC_Passage; 171 172 -- For the final check of the whole test 173 function TC_Get_Passage_Total return integer is 174 begin 175 return TC_Passage_Total; 176 end TC_Get_Passage_Total; 177 178 -- These Set/Clear routines are triggered by real-time sensors that 179 -- reflect traffic state 180 procedure Set_Local_Overload is 181 begin 182 Local_State := Local_Overload_wt; 183 if not Meter_in_Use then 184 Start_Meter; -- LOCAL INTERNAL PROCEDURE FROM PROCEDURE 185 end if; 186 end Set_Local_Overload; 187 188 --::::: Set/Clear routines for all the other sensors not shown 189 190 function Local_Overload return Load_Factor is 191 begin 192 return Local_State; 193 end Local_Overload; 194 195 function Next_Ramp_in_Overload return Load_Factor is 196 begin 197 return Next_Ramp_State; 198 end Next_Ramp_in_Overload; 199 200 -- :::::::: other overload factor states not shown 201 202 -- return the summation of all the load factors 203 function Freeway_Overload return Load_Factor is 204 begin 205 return Local_Overload -- EACH IS A CALL OF A 206 -- + :::: others -- FUNCTION FROM WITHIN 207 + Next_Ramp_in_Overload; -- A FUNCTION 208 end Freeway_Overload; 209 210 -- Freeway Breakdown is defined as traffic moving < 5mph 211 function Freeway_Breakdown return Boolean is 212 begin 213 return Fwy_Break_State; 214 end Freeway_Breakdown; 215 216 -- Keep count of vehicles currently on meter queue - we can't use 217 -- the 'count because we need the outcall trigger 218 procedure Add_Meter_Queue is 219 TC_Pass_Point : constant integer := 22; 220 begin 221 Ramp_Count := Ramp_Count + 1; 222 TC_Passage ( TC_Pass_Point ); -- note passage through here 223 if Ramp_Count > Ramp_Count_Threshold then 224 null; -- :::: stub, trigger surface street notification 225 end if; 226 end Add_Meter_Queue; 227 -- 228 procedure Subtract_Meter_Queue is 229 TC_Pass_Point : constant integer := 24; 230 begin 231 Ramp_Count := Ramp_Count - 1; 232 TC_Passage ( TC_Pass_Point ); -- note passage through here 233 end Subtract_Meter_Queue; 234 235 -- Here each Vehicle task queues itself awaiting release 236 entry Wait_at_Meter when Release_One_Vehicle is 237 -- EXAMPLE OF ENTRY WITH BARRIERS AND PERSISTENT SIGNAL 238 TC_Pass_Point : constant integer := 23; 239 begin 240 TC_Passage ( TC_Pass_Point ); -- note passage through here 241 Release_One_Vehicle := false; -- Consume the signal 242 -- Decrement number of vehicles on ramp 243 Subtract_Meter_Queue; -- CALL PROCEDURE FROM WITHIN ENTRY BODY 244 end Wait_at_Meter; 245 246 247 procedure Time_Pulse_Received is 248 Load : Load_factor := Freeway_Overload; -- CALL MULTILEVEL 249 -- FUNCTION 250 -- FROM WITHIN PROCEDURE 251 begin 252 -- if broken down, no vehicles are released 253 if not Freeway_Breakdown then -- CALL FUNCTION FROM A PROCEDURE 254 if Load < Moderate_Level then 255 Release_One_Vehicle := true; 256 end if; 257 null; -- stub ::: If other levels, release every other 258 -- pulse, every third pulse etc. 259 end if; 260 end Time_Pulse_Received; 261 262 end Test_Ramp; 263 --================================================================ 264 265 266 -- Simulate the arrival of a vehicle at the Ramp_Receiver and the 267 -- generation of an accompanying carrier task 268 procedure New_Arrival is 269 Next_Vehicle_Task: acc_Vehicle := new Vehicle; 270 TC_Pass_Point : constant integer := 3; 271 begin 272 Test_Ramp.TC_Passage ( TC_Pass_Point ); -- Note passage through here 273 null; 274 end New_arrival; 275 276 277 -- Carrier task. One is created for each vehicle arriving at the ramp 278 task body Vehicle is 279 TC_Pass_point : constant integer := 1; 280 TC_Pass_Point_2 : constant integer := 21; 281 TC_Pass_Point_3 : constant integer := 2; 282 begin 283 Test_Ramp.TC_Passage ( TC_Pass_Point ); -- note passage through here 284 if Test_Ramp.Meter_in_Use_State then 285 Test_Ramp.TC_Passage ( TC_Pass_Point_2 ); -- note passage 286 -- Increment count of number of vehicles on ramp 287 Test_Ramp.Add_Meter_Queue; -- CALL a protected PROCEDURE 288 -- which is also called from within 289 -- enter the meter queue 290 Test_Ramp.Wait_at_Meter; -- CALL a protected ENTRY 291 end if; 292 Test_Ramp.TC_Passage ( TC_Pass_Point_3 ); -- note passage thru here 293 null; --:::: call to the first in the series of the Ramp_Sensors 294 -- this "passes" the vehicle from one sensor to the next 295 exception 296 when others => 297 Report.Failed ("Unexpected exception in Vehicle Task"); 298 end Vehicle; 299 300 301 -- Task transmits a synchronizing "pulse" to all ramps 302 -- 303 task body Pulse_Task is 304 Pulse_Time : Ada.Calendar.Time := Ada.Calendar.Clock; 305 begin 306 While not Control.Stop loop 307 delay until Pulse_Time; 308 Test_Ramp.Time_Pulse_Received; -- causes INTERNAL CALLS 309 -- :::::::::: and to all the others 310 Pulse_Time := Pulse_Time + Pulse_Time_Delta; -- calculate next 311 end loop; 312 exception 313 when others => 314 Report.Failed ("Unexpected exception in Pulse_Task"); 315 end Pulse_Task; 316 317 318 begin -- declare 319 320 -- Test driver. This is ALL test control code 321 322 -- First simulate calls to the protected functions and procedures 323 -- from without the protected object 324 -- 325 -- CALL FUNCTIONS 326 if Test_Ramp.Local_Overload /= Clear_Level then 327 Report.Failed ("External Call to Local_Overload incorrect"); 328 end if; 329 if Test_Ramp.Next_Ramp_in_Overload /= Clear_Level then 330 Report.Failed ("External Call to Next_Ramp_in_Overload incorrect"); 331 end if; 332 if Test_Ramp.Freeway_Overload /= Clear_Level then 333 Report.Failed ("External Call to Freeway_Overload incorrect"); 334 end if; 335 336 -- Now Simulate the arrival of a vehicle to verify path through test 337 New_Arrival; 338 delay Pulse_Time_Delta*2; -- allow it to pass through the complex 339 340 TC_Multiplier := 5; -- change the weights for the paths for the next 341 -- part of the test 342 343 -- Simulate a real-time sensor reporting overload 344 Test_Ramp.Set_Local_Overload; -- CALL A PROCEDURE (and change levels) 345 346 -- CALL FUNCTIONS again 347 if Test_Ramp.Local_Overload /= Minimum_Level then 348 Report.Failed ("External Call to Local_Overload incorrect - 2"); 349 end if; 350 if Test_Ramp.Freeway_Overload /= Minimum_Level then 351 Report.Failed ("External Call to Freeway_Overload incorrect -2"); 352 end if; 353 354 -- Now Simulate the arrival of another vehicle again causing 355 -- INTERNAL CALLS but following different paths (queuing on the 356 -- meter etc.) 357 New_Arrival; 358 delay Pulse_Time_Delta*2; -- allow it to pass through the complex 359 360 Control.Stop_Now; -- finish test 361 362 if TC_Expected_Passage_Total /= Test_Ramp.TC_Get_Passage_Total then 363 Report.Failed ("Unexpected paths taken"); 364 end if; 365 366 end; -- declare 367 368 Report.Result; 369 370end C940005; 371