source:
rtems/contrib/crossrpms/patches/gcc-ada-4.3.2-rtems4.10-20080910.diff
@
016c9ea
Last change on this file since 016c9ea was d45dff4, checked in by Joel Sherrill <joel.sherrill@…>, on 09/25/08 at 18:28:24 | |
---|---|
|
|
File size: 96.5 KB |
-
gcc/ada/gsocket.h
diff -urN gcc-4.3.2-orig/gcc/ada/gsocket.h gcc-4.3.2/gcc/ada/gsocket.h
old new 175 175 176 176 #if defined (_AIX) || defined (__FreeBSD__) || defined (__hpux__) || defined (__osf__) || defined (_WIN32) || defined (__APPLE__) 177 177 # define HAVE_THREAD_SAFE_GETxxxBYyyy 1 178 #elif defined (sgi) || defined (linux) || (defined (sun) && defined (__SVR4) && !defined (__vxworks)) 178 #elif defined (sgi) || defined (linux) || (defined (sun) && defined (__SVR4) && !defined (__vxworks)) || defined(__rtems__) 179 179 # define HAVE_GETxxxBYyyy_R 1 180 180 #endif 181 181 -
gcc/ada/Makefile.in
diff -urN gcc-4.3.2-orig/gcc/ada/Makefile.in gcc-4.3.2/gcc/ada/Makefile.in
old new 392 392 a-intnam.ads<a-intnam-vxworks.ads \ 393 393 a-numaux.ads<a-numaux-vxworks.ads \ 394 394 s-inmaop.adb<s-inmaop-posix.adb \ 395 s-interr.adb<s-interr- vxworks.adb \395 s-interr.adb<s-interr-hwint.adb \ 396 396 s-intman.ads<s-intman-vxworks.ads \ 397 397 s-intman.adb<s-intman-vxworks.adb \ 398 398 s-osinte.adb<s-osinte-vxworks.adb \ … … 473 473 EXTRA_GNATRTL_NONTASKING_OBJS=s-vxwexc.o 474 474 else 475 475 LIBGNAT_TARGET_PAIRS += \ 476 s-interr.adb<s-interr- vxworks.adb \476 s-interr.adb<s-interr-hwint.adb \ 477 477 s-tpopsp.adb<s-tpopsp-vxworks.adb \ 478 478 system.ads<system-vxworks-ppc.ads 479 479 … … 506 506 g-io.adb<g-io-vxworks-ppc-cert.adb \ 507 507 g-io.ads<g-io-vxworks-ppc-cert.ads \ 508 508 s-inmaop.adb<s-inmaop-posix.adb \ 509 s-interr.adb<s-interr- vxworks.adb \509 s-interr.adb<s-interr-hwint.adb \ 510 510 s-intman.ads<s-intman-vxworks.ads \ 511 511 s-intman.adb<s-intman-vxworks.adb \ 512 512 s-osinte.adb<s-osinte-vxworks.adb \ … … 553 553 a-intnam.ads<a-intnam-vxworks.ads \ 554 554 a-numaux.ads<a-numaux-vxworks.ads \ 555 555 s-inmaop.adb<s-inmaop-posix.adb \ 556 s-interr.adb<s-interr- vxworks.adb \556 s-interr.adb<s-interr-hwint.adb \ 557 557 s-intman.ads<s-intman-vxworks.ads \ 558 558 s-intman.adb<s-intman-vxworks.adb \ 559 559 s-osinte.adb<s-osinte-vxworks.adb \ … … 628 628 EXTRA_GNATRTL_NONTASKING_OBJS=s-vxwexc.o 629 629 else 630 630 LIBGNAT_TARGET_PAIRS += \ 631 s-interr.adb<s-interr- vxworks.adb \631 s-interr.adb<s-interr-hwint.adb \ 632 632 s-tpopsp.adb<s-tpopsp-vxworks.adb \ 633 633 system.ads<system-vxworks-x86.ads 634 634 … … 656 656 a-intnam.ads<a-intnam-vxworks.ads \ 657 657 a-numaux.ads<a-numaux-vxworks.ads \ 658 658 s-inmaop.adb<s-inmaop-posix.adb \ 659 s-interr.adb<s-interr- vxworks.adb \659 s-interr.adb<s-interr-hwint.adb \ 660 660 s-intman.ads<s-intman-vxworks.ads \ 661 661 s-intman.adb<s-intman-vxworks.adb \ 662 662 s-osinte.adb<s-osinte-vxworks.adb \ … … 1148 1148 s-taspri.ads<s-taspri-posix.ads \ 1149 1149 s-tpopsp.adb<s-tpopsp-rtems.adb \ 1150 1150 g-soccon.ads<g-soccon-rtems.ads \ 1151 s-stchop.adb<s-stchop-rtems.adb 1151 s-stchop.adb<s-stchop-rtems.adb \ 1152 s-interr.adb<s-interr-hwint.adb 1152 1153 endif 1153 1154 1154 1155 ifeq ($(strip $(filter-out alpha% dec osf%,$(targ))),) -
gcc/ada/s-interr-hwint.adb
diff -urN gcc-4.3.2-orig/gcc/ada/s-interr-hwint.adb gcc-4.3.2/gcc/ada/s-interr-hwint.adb
old new 1 ------------------------------------------------------------------------------ 2 -- -- 3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- 4 -- -- 5 -- S Y S T E M . I N T E R R U P T S -- 6 -- -- 7 -- B o d y -- 8 -- -- 9 -- Copyright (C) 1992-2008, Free Software Foundation, Inc. -- 10 -- -- 11 -- GNARL is free software; you can redistribute it and/or modify it under -- 12 -- terms of the GNU General Public License as published by the Free Soft- -- 13 -- ware Foundation; either version 2, or (at your option) any later ver- -- 14 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- -- 15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17 -- for more details. You should have received a copy of the GNU General -- 18 -- Public License distributed with GNARL; see file COPYING. If not, write -- 19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- 20 -- Boston, MA 02110-1301, USA. -- 21 -- -- 22 -- As a special exception, if other files instantiate generics from this -- 23 -- unit, or you link this unit with other files to produce an executable, -- 24 -- this unit does not by itself cause the resulting executable to be -- 25 -- covered by the GNU General Public License. This exception does not -- 26 -- however invalidate any other reasons why the executable file might be -- 27 -- covered by the GNU Public License. -- 28 -- -- 29 -- GNARL was developed by the GNARL team at Florida State University. -- 30 -- Extensive contributions were provided by Ada Core Technologies, Inc. -- 31 -- -- 32 ------------------------------------------------------------------------------ 33 34 -- Invariants: 35 36 -- All user-handleable signals are masked at all times in all tasks/threads 37 -- except possibly for the Interrupt_Manager task. 38 39 -- When a user task wants to have the effect of masking/unmasking an signal, 40 -- it must call Block_Interrupt/Unblock_Interrupt, which will have the effect 41 -- of unmasking/masking the signal in the Interrupt_Manager task. These 42 -- comments do not apply to vectored hardware interrupts, which may be masked 43 -- or unmasked using routined interfaced to the relevant embedded RTOS system 44 -- calls. 45 46 -- Once we associate a Signal_Server_Task with an signal, the task never goes 47 -- away, and we never remove the association. On the other hand, it is more 48 -- convenient to terminate an associated Interrupt_Server_Task for a vectored 49 -- hardware interrupt (since we use a binary semaphore for synchronization 50 -- with the umbrella handler). 51 52 -- There is no more than one signal per Signal_Server_Task and no more than 53 -- one Signal_Server_Task per signal. The same relation holds for hardware 54 -- interrupts and Interrupt_Server_Task's at any given time. That is, only 55 -- one non-terminated Interrupt_Server_Task exists for a give interrupt at 56 -- any time. 57 58 -- Within this package, the lock L is used to protect the various status 59 -- tables. If there is a Server_Task associated with a signal or interrupt, 60 -- we use the per-task lock of the Server_Task instead so that we protect the 61 -- status between Interrupt_Manager and Server_Task. Protection among 62 -- service requests are ensured via user calls to the Interrupt_Manager 63 -- entries. 64 65 -- This is reasonably generic version of this package, supporting vectored 66 -- hardware interrupts using non-RTOS specific adapter routines which 67 -- should easily implemented on any RTOS capable of supporting GNAT. 68 69 with Unchecked_Conversion; 70 71 with System.OS_Interface; use System.OS_Interface; 72 73 with Ada.Task_Identification; 74 -- used for Task_Id type 75 76 with Ada.Exceptions; 77 -- used for Raise_Exception 78 79 with System.Interrupt_Management; 80 -- used for Reserve 81 82 with System.Task_Primitives.Operations; 83 -- used for Write_Lock 84 -- Unlock 85 -- Abort 86 -- Wakeup_Task 87 -- Sleep 88 -- Initialize_Lock 89 90 with System.Storage_Elements; 91 -- used for To_Address 92 -- To_Integer 93 -- Integer_Address 94 95 with System.Tasking.Utilities; 96 -- used for Make_Independent 97 98 with System.Tasking.Rendezvous; 99 -- used for Call_Simple 100 pragma Elaborate_All (System.Tasking.Rendezvous); 101 102 package body System.Interrupts is 103 104 use Tasking; 105 use Ada.Exceptions; 106 107 package POP renames System.Task_Primitives.Operations; 108 109 function To_Ada is new Unchecked_Conversion 110 (System.Tasking.Task_Id, Ada.Task_Identification.Task_Id); 111 112 function To_System is new Unchecked_Conversion 113 (Ada.Task_Identification.Task_Id, Task_Id); 114 115 ----------------- 116 -- Local Tasks -- 117 ----------------- 118 119 -- WARNING: System.Tasking.Stages performs calls to this task with 120 -- low-level constructs. Do not change this spec without synchronizing it. 121 122 task Interrupt_Manager is 123 entry Detach_Interrupt_Entries (T : Task_Id); 124 125 entry Attach_Handler 126 (New_Handler : Parameterless_Handler; 127 Interrupt : Interrupt_ID; 128 Static : Boolean; 129 Restoration : Boolean := False); 130 131 entry Exchange_Handler 132 (Old_Handler : out Parameterless_Handler; 133 New_Handler : Parameterless_Handler; 134 Interrupt : Interrupt_ID; 135 Static : Boolean); 136 137 entry Detach_Handler 138 (Interrupt : Interrupt_ID; 139 Static : Boolean); 140 141 entry Bind_Interrupt_To_Entry 142 (T : Task_Id; 143 E : Task_Entry_Index; 144 Interrupt : Interrupt_ID); 145 146 pragma Interrupt_Priority (System.Interrupt_Priority'First); 147 end Interrupt_Manager; 148 149 task type Interrupt_Server_Task 150 (Interrupt : Interrupt_ID; Int_Sema : Binary_Semaphore_Id) is 151 -- Server task for vectored hardware interrupt handling 152 pragma Interrupt_Priority (System.Interrupt_Priority'First + 2); 153 end Interrupt_Server_Task; 154 155 type Interrupt_Task_Access is access Interrupt_Server_Task; 156 157 ------------------------------- 158 -- Local Types and Variables -- 159 ------------------------------- 160 161 type Entry_Assoc is record 162 T : Task_Id; 163 E : Task_Entry_Index; 164 end record; 165 166 type Handler_Assoc is record 167 H : Parameterless_Handler; 168 Static : Boolean; -- Indicates static binding; 169 end record; 170 171 User_Handler : array (Interrupt_ID) of Handler_Assoc := 172 (others => (null, Static => False)); 173 pragma Volatile_Components (User_Handler); 174 -- Holds the protected procedure handler (if any) and its Static 175 -- information for each interrupt or signal. A handler is static 176 -- iff it is specified through the pragma Attach_Handler. 177 178 User_Entry : array (Interrupt_ID) of Entry_Assoc := 179 (others => (T => Null_Task, E => Null_Task_Entry)); 180 pragma Volatile_Components (User_Entry); 181 -- Holds the task and entry index (if any) for each interrupt / signal 182 183 -- Type and Head, Tail of the list containing Registered Interrupt 184 -- Handlers. These definitions are used to register the handlers 185 -- specified by the pragma Interrupt_Handler. 186 187 type Registered_Handler; 188 type R_Link is access all Registered_Handler; 189 190 type Registered_Handler is record 191 H : System.Address := System.Null_Address; 192 Next : R_Link := null; 193 end record; 194 195 Registered_Handler_Head : R_Link := null; 196 Registered_Handler_Tail : R_Link := null; 197 198 Server_ID : array (Interrupt_ID) of System.Tasking.Task_Id := 199 (others => System.Tasking.Null_Task); 200 pragma Atomic_Components (Server_ID); 201 -- Holds the Task_Id of the Server_Task for each interrupt / signal. 202 -- Task_Id is needed to accomplish locking per interrupt base. Also 203 -- is needed to determine whether to create a new Server_Task. 204 205 Semaphore_ID_Map : array 206 (Interrupt_ID range 0 .. System.OS_Interface.Max_HW_Interrupt) 207 of Binary_Semaphore_Id := (others => 0); 208 -- Array of binary semaphores associated with vectored interrupts 209 -- Note that the last bound should be Max_HW_Interrupt, but this will raise 210 -- Storage_Error if Num_HW_Interrupts is null, so use an extra 4 bytes 211 -- instead. 212 213 Interrupt_Access_Hold : Interrupt_Task_Access; 214 -- Variable for allocating an Interrupt_Server_Task 215 216 Default_Handler : array (HW_Interrupt) of 217 System.OS_Interface.Interrupt_Handler; 218 -- Vectored interrupt handlers installed prior to program startup. 219 -- These are saved only when the umbrella handler is installed for 220 -- a given interrupt number. 221 222 ----------------------- 223 -- Local Subprograms -- 224 ----------------------- 225 226 procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID); 227 -- Check if Id is a reserved interrupt, and if so raise Program_Error 228 -- with an appropriate message, otherwise return. 229 230 procedure Finalize_Interrupt_Servers; 231 -- Unbind the handlers for hardware interrupt server tasks at program 232 -- termination. 233 234 function Is_Registered (Handler : Parameterless_Handler) return Boolean; 235 -- See if Handler has been "pragma"ed using Interrupt_Handler. 236 -- Always consider a null handler as registered. 237 238 procedure Notify_Interrupt (Param : System.Address); 239 pragma Convention (C, Notify_Interrupt); 240 -- Umbrella handler for vectored interrupts (not signals) 241 242 procedure Install_Default_Action (Interrupt : HW_Interrupt); 243 -- Restore a handler that was in place prior to program execution 244 245 procedure Install_Umbrella_Handler 246 (Interrupt : HW_Interrupt; 247 Handler : System.OS_Interface.Interrupt_Handler); 248 -- Install the runtime umbrella handler for a vectored hardware 249 -- interrupt 250 251 procedure Unimplemented (Feature : String); 252 pragma No_Return (Unimplemented); 253 -- Used to mark a call to an unimplemented function. Raises Program_Error 254 -- with an appropriate message noting that Feature is unimplemented. 255 256 -------------------- 257 -- Attach_Handler -- 258 -------------------- 259 260 -- Calling this procedure with New_Handler = null and Static = True 261 -- means we want to detach the current handler regardless of the 262 -- previous handler's binding status (ie. do not care if it is a 263 -- dynamic or static handler). 264 265 -- This option is needed so that during the finalization of a PO, we 266 -- can detach handlers attached through pragma Attach_Handler. 267 268 procedure Attach_Handler 269 (New_Handler : Parameterless_Handler; 270 Interrupt : Interrupt_ID; 271 Static : Boolean := False) is 272 begin 273 Check_Reserved_Interrupt (Interrupt); 274 Interrupt_Manager.Attach_Handler (New_Handler, Interrupt, Static); 275 end Attach_Handler; 276 277 ----------------------------- 278 -- Bind_Interrupt_To_Entry -- 279 ----------------------------- 280 281 -- This procedure raises a Program_Error if it tries to 282 -- bind an interrupt to which an Entry or a Procedure is 283 -- already bound. 284 285 procedure Bind_Interrupt_To_Entry 286 (T : Task_Id; 287 E : Task_Entry_Index; 288 Int_Ref : System.Address) 289 is 290 Interrupt : constant Interrupt_ID := 291 Interrupt_ID (Storage_Elements.To_Integer (Int_Ref)); 292 293 begin 294 Check_Reserved_Interrupt (Interrupt); 295 Interrupt_Manager.Bind_Interrupt_To_Entry (T, E, Interrupt); 296 end Bind_Interrupt_To_Entry; 297 298 --------------------- 299 -- Block_Interrupt -- 300 --------------------- 301 302 procedure Block_Interrupt (Interrupt : Interrupt_ID) is 303 begin 304 Unimplemented ("Block_Interrupt"); 305 end Block_Interrupt; 306 307 ------------------------------ 308 -- Check_Reserved_Interrupt -- 309 ------------------------------ 310 311 procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID) is 312 begin 313 if Is_Reserved (Interrupt) then 314 Raise_Exception 315 (Program_Error'Identity, 316 "Interrupt" & Interrupt_ID'Image (Interrupt) & " is reserved"); 317 else 318 return; 319 end if; 320 end Check_Reserved_Interrupt; 321 322 --------------------- 323 -- Current_Handler -- 324 --------------------- 325 326 function Current_Handler 327 (Interrupt : Interrupt_ID) return Parameterless_Handler 328 is 329 begin 330 Check_Reserved_Interrupt (Interrupt); 331 332 -- ??? Since Parameterless_Handler is not Atomic, the 333 -- current implementation is wrong. We need a new service in 334 -- Interrupt_Manager to ensure atomicity. 335 336 return User_Handler (Interrupt).H; 337 end Current_Handler; 338 339 -------------------- 340 -- Detach_Handler -- 341 -------------------- 342 343 -- Calling this procedure with Static = True means we want to Detach the 344 -- current handler regardless of the previous handler's binding status 345 -- (i.e. do not care if it is a dynamic or static handler). 346 347 -- This option is needed so that during the finalization of a PO, we can 348 -- detach handlers attached through pragma Attach_Handler. 349 350 procedure Detach_Handler 351 (Interrupt : Interrupt_ID; 352 Static : Boolean := False) is 353 begin 354 Check_Reserved_Interrupt (Interrupt); 355 Interrupt_Manager.Detach_Handler (Interrupt, Static); 356 end Detach_Handler; 357 358 ------------------------------ 359 -- Detach_Interrupt_Entries -- 360 ------------------------------ 361 362 procedure Detach_Interrupt_Entries (T : Task_Id) is 363 begin 364 Interrupt_Manager.Detach_Interrupt_Entries (T); 365 end Detach_Interrupt_Entries; 366 367 ---------------------- 368 -- Exchange_Handler -- 369 ---------------------- 370 371 -- Calling this procedure with New_Handler = null and Static = True 372 -- means we want to detach the current handler regardless of the 373 -- previous handler's binding status (ie. do not care if it is a 374 -- dynamic or static handler). 375 376 -- This option is needed so that during the finalization of a PO, we 377 -- can detach handlers attached through pragma Attach_Handler. 378 379 procedure Exchange_Handler 380 (Old_Handler : out Parameterless_Handler; 381 New_Handler : Parameterless_Handler; 382 Interrupt : Interrupt_ID; 383 Static : Boolean := False) 384 is 385 begin 386 Check_Reserved_Interrupt (Interrupt); 387 Interrupt_Manager.Exchange_Handler 388 (Old_Handler, New_Handler, Interrupt, Static); 389 end Exchange_Handler; 390 391 -------------- 392 -- Finalize -- 393 -------------- 394 395 procedure Finalize (Object : in out Static_Interrupt_Protection) is 396 begin 397 -- ??? loop to be executed only when we're not doing library level 398 -- finalization, since in this case all interrupt / signal tasks are 399 -- gone. 400 401 if not Interrupt_Manager'Terminated then 402 for N in reverse Object.Previous_Handlers'Range loop 403 Interrupt_Manager.Attach_Handler 404 (New_Handler => Object.Previous_Handlers (N).Handler, 405 Interrupt => Object.Previous_Handlers (N).Interrupt, 406 Static => Object.Previous_Handlers (N).Static, 407 Restoration => True); 408 end loop; 409 end if; 410 411 Tasking.Protected_Objects.Entries.Finalize 412 (Tasking.Protected_Objects.Entries.Protection_Entries (Object)); 413 end Finalize; 414 415 -------------------------------- 416 -- Finalize_Interrupt_Servers -- 417 -------------------------------- 418 419 -- Restore default handlers for interrupt servers 420 421 -- This is called by the Interrupt_Manager task when it receives the abort 422 -- signal during program finalization. 423 424 procedure Finalize_Interrupt_Servers is 425 HW_Interrupts : constant Boolean := HW_Interrupt'Last >= 0; 426 427 begin 428 if HW_Interrupts then 429 for Int in HW_Interrupt loop 430 if Server_ID (Interrupt_ID (Int)) /= null 431 and then 432 not Ada.Task_Identification.Is_Terminated 433 (To_Ada (Server_ID (Interrupt_ID (Int)))) 434 then 435 Interrupt_Manager.Attach_Handler 436 (New_Handler => null, 437 Interrupt => Interrupt_ID (Int), 438 Static => True, 439 Restoration => True); 440 end if; 441 end loop; 442 end if; 443 end Finalize_Interrupt_Servers; 444 445 ------------------------------------- 446 -- Has_Interrupt_Or_Attach_Handler -- 447 ------------------------------------- 448 449 function Has_Interrupt_Or_Attach_Handler 450 (Object : access Dynamic_Interrupt_Protection) 451 return Boolean 452 is 453 pragma Unreferenced (Object); 454 begin 455 return True; 456 end Has_Interrupt_Or_Attach_Handler; 457 458 function Has_Interrupt_Or_Attach_Handler 459 (Object : access Static_Interrupt_Protection) 460 return Boolean 461 is 462 pragma Unreferenced (Object); 463 begin 464 return True; 465 end Has_Interrupt_Or_Attach_Handler; 466 467 ---------------------- 468 -- Ignore_Interrupt -- 469 ---------------------- 470 471 procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is 472 begin 473 Unimplemented ("Ignore_Interrupt"); 474 end Ignore_Interrupt; 475 476 ---------------------------- 477 -- Install_Default_Action -- 478 ---------------------------- 479 480 procedure Install_Default_Action (Interrupt : HW_Interrupt) is 481 begin 482 -- Restore original interrupt handler 483 484 Interrupt_Vector_Set 485 (System.OS_Interface.Interrupt_Number_To_Vector (int (Interrupt)), 486 Default_Handler (Interrupt)); 487 Default_Handler (Interrupt) := null; 488 end Install_Default_Action; 489 490 ---------------------- 491 -- Install_Handlers -- 492 ---------------------- 493 494 procedure Install_Handlers 495 (Object : access Static_Interrupt_Protection; 496 New_Handlers : New_Handler_Array) 497 is 498 begin 499 for N in New_Handlers'Range loop 500 501 -- We need a lock around this ??? 502 503 Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt; 504 Object.Previous_Handlers (N).Static := User_Handler 505 (New_Handlers (N).Interrupt).Static; 506 507 -- We call Exchange_Handler and not directly Interrupt_Manager. 508 -- Exchange_Handler so we get the Is_Reserved check. 509 510 Exchange_Handler 511 (Old_Handler => Object.Previous_Handlers (N).Handler, 512 New_Handler => New_Handlers (N).Handler, 513 Interrupt => New_Handlers (N).Interrupt, 514 Static => True); 515 end loop; 516 end Install_Handlers; 517 518 ------------------------------ 519 -- Install_Umbrella_Handler -- 520 ------------------------------ 521 522 procedure Install_Umbrella_Handler 523 (Interrupt : HW_Interrupt; 524 Handler : System.OS_Interface.Interrupt_Handler) 525 is 526 Vec : constant Interrupt_Vector := 527 Interrupt_Number_To_Vector (int (Interrupt)); 528 529 Old_Handler : constant System.OS_Interface.Interrupt_Handler := 530 Interrupt_Vector_Get (Interrupt_Number_To_Vector (int (Interrupt))); 531 532 Status : int; 533 pragma Unreferenced (Status); 534 -- ??? shouldn't we test Stat at least in a pragma Assert? 535 begin 536 -- Only install umbrella handler when no Ada handler has already been 537 -- installed. Note that the interrupt number is passed as a parameter 538 -- when an interrupt occurs, so the umbrella handler has a different 539 -- wrapper generated by intConnect for each interrupt number. 540 541 if Default_Handler (Interrupt) = null then 542 Status := Interrupt_Connect 543 (Vec, Handler, System.Address (Interrupt)); 544 Default_Handler (Interrupt) := Old_Handler; 545 end if; 546 end Install_Umbrella_Handler; 547 548 ---------------- 549 -- Is_Blocked -- 550 ---------------- 551 552 function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is 553 begin 554 Unimplemented ("Is_Blocked"); 555 return False; 556 end Is_Blocked; 557 558 ----------------------- 559 -- Is_Entry_Attached -- 560 ----------------------- 561 562 function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is 563 begin 564 Check_Reserved_Interrupt (Interrupt); 565 return User_Entry (Interrupt).T /= Null_Task; 566 end Is_Entry_Attached; 567 568 ------------------------- 569 -- Is_Handler_Attached -- 570 ------------------------- 571 572 function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is 573 begin 574 Check_Reserved_Interrupt (Interrupt); 575 return User_Handler (Interrupt).H /= null; 576 end Is_Handler_Attached; 577 578 ---------------- 579 -- Is_Ignored -- 580 ---------------- 581 582 function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is 583 begin 584 Unimplemented ("Is_Ignored"); 585 return False; 586 end Is_Ignored; 587 588 ------------------- 589 -- Is_Registered -- 590 ------------------- 591 592 function Is_Registered (Handler : Parameterless_Handler) return Boolean is 593 type Fat_Ptr is record 594 Object_Addr : System.Address; 595 Handler_Addr : System.Address; 596 end record; 597 598 function To_Fat_Ptr is new Unchecked_Conversion 599 (Parameterless_Handler, Fat_Ptr); 600 601 Ptr : R_Link; 602 Fat : Fat_Ptr; 603 604 begin 605 if Handler = null then 606 return True; 607 end if; 608 609 Fat := To_Fat_Ptr (Handler); 610 611 Ptr := Registered_Handler_Head; 612 613 while Ptr /= null loop 614 if Ptr.H = Fat.Handler_Addr then 615 return True; 616 end if; 617 618 Ptr := Ptr.Next; 619 end loop; 620 621 return False; 622 end Is_Registered; 623 624 ----------------- 625 -- Is_Reserved -- 626 ----------------- 627 628 function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is 629 use System.Interrupt_Management; 630 begin 631 return Reserve (System.Interrupt_Management.Interrupt_ID (Interrupt)); 632 end Is_Reserved; 633 634 ---------------------- 635 -- Notify_Interrupt -- 636 ---------------------- 637 638 -- Umbrella handler for vectored hardware interrupts (as opposed to 639 -- signals and exceptions). As opposed to the signal implementation, 640 -- this handler is only installed in the vector table while there is 641 -- an active association of an Ada handler to the interrupt. 642 643 -- Otherwise, the handler that existed prior to program startup is 644 -- in the vector table. This ensures that handlers installed by 645 -- the BSP are active unless explicitly replaced in the program text. 646 647 -- Each Interrupt_Server_Task has an associated binary semaphore 648 -- on which it pends once it's been started. This routine determines 649 -- The appropriate semaphore and and issues a Binary_Semaphore_Release 650 -- call, waking the server task. When a handler is unbound, 651 -- System.Interrupts.Unbind_Handler issues a Binary_Semaphore_Flush, 652 -- and the server task deletes its semaphore and terminates. 653 654 procedure Notify_Interrupt (Param : System.Address) is 655 Interrupt : constant Interrupt_ID := Interrupt_ID (Param); 656 657 Status : int; 658 pragma Unreferenced (Status); 659 -- ??? shouldn't we test Stat at least in a pragma Assert? 660 begin 661 Status := Binary_Semaphore_Release (Semaphore_ID_Map (Interrupt)); 662 end Notify_Interrupt; 663 664 --------------- 665 -- Reference -- 666 --------------- 667 668 function Reference (Interrupt : Interrupt_ID) return System.Address is 669 begin 670 Check_Reserved_Interrupt (Interrupt); 671 return Storage_Elements.To_Address 672 (Storage_Elements.Integer_Address (Interrupt)); 673 end Reference; 674 675 -------------------------------- 676 -- Register_Interrupt_Handler -- 677 -------------------------------- 678 679 procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is 680 New_Node_Ptr : R_Link; 681 682 begin 683 -- This routine registers a handler as usable for dynamic 684 -- interrupt handler association. Routines attaching and detaching 685 -- handlers dynamically should determine whether the handler is 686 -- registered. Program_Error should be raised if it is not registered. 687 688 -- Pragma Interrupt_Handler can only appear in a library 689 -- level PO definition and instantiation. Therefore, we do not need 690 -- to implement an unregister operation. Nor do we need to 691 -- protect the queue structure with a lock. 692 693 pragma Assert (Handler_Addr /= System.Null_Address); 694 695 New_Node_Ptr := new Registered_Handler; 696 New_Node_Ptr.H := Handler_Addr; 697 698 if Registered_Handler_Head = null then 699 Registered_Handler_Head := New_Node_Ptr; 700 Registered_Handler_Tail := New_Node_Ptr; 701 702 else 703 Registered_Handler_Tail.Next := New_Node_Ptr; 704 Registered_Handler_Tail := New_Node_Ptr; 705 end if; 706 end Register_Interrupt_Handler; 707 708 ----------------------- 709 -- Unblock_Interrupt -- 710 ----------------------- 711 712 procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is 713 begin 714 Unimplemented ("Unblock_Interrupt"); 715 end Unblock_Interrupt; 716 717 ------------------ 718 -- Unblocked_By -- 719 ------------------ 720 721 function Unblocked_By 722 (Interrupt : Interrupt_ID) return System.Tasking.Task_Id 723 is 724 begin 725 Unimplemented ("Unblocked_By"); 726 return Null_Task; 727 end Unblocked_By; 728 729 ------------------------ 730 -- Unignore_Interrupt -- 731 ------------------------ 732 733 procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is 734 begin 735 Unimplemented ("Unignore_Interrupt"); 736 end Unignore_Interrupt; 737 738 ------------------- 739 -- Unimplemented -- 740 ------------------- 741 742 procedure Unimplemented (Feature : String) is 743 begin 744 Raise_Exception 745 (Program_Error'Identity, 746 Feature & " not implemented for hardware interrupts"); 747 end Unimplemented; 748 749 ----------------------- 750 -- Interrupt_Manager -- 751 ----------------------- 752 753 task body Interrupt_Manager is 754 755 -------------------- 756 -- Local Routines -- 757 -------------------- 758 759 procedure Bind_Handler (Interrupt : Interrupt_ID); 760 -- This procedure does not do anything if a signal is blocked. 761 -- Otherwise, we have to interrupt Server_Task for status change through 762 -- a wakeup signal. 763 764 procedure Unbind_Handler (Interrupt : Interrupt_ID); 765 -- This procedure does not do anything if a signal is blocked. 766 -- Otherwise, we have to interrupt Server_Task for status change 767 -- through an abort signal. 768 769 procedure Unprotected_Exchange_Handler 770 (Old_Handler : out Parameterless_Handler; 771 New_Handler : Parameterless_Handler; 772 Interrupt : Interrupt_ID; 773 Static : Boolean; 774 Restoration : Boolean := False); 775 776 procedure Unprotected_Detach_Handler 777 (Interrupt : Interrupt_ID; 778 Static : Boolean); 779 780 ------------------ 781 -- Bind_Handler -- 782 ------------------ 783 784 procedure Bind_Handler (Interrupt : Interrupt_ID) is 785 begin 786 Install_Umbrella_Handler 787 (HW_Interrupt (Interrupt), Notify_Interrupt'Access); 788 end Bind_Handler; 789 790 -------------------- 791 -- Unbind_Handler -- 792 -------------------- 793 794 procedure Unbind_Handler (Interrupt : Interrupt_ID) is 795 Status : int; 796 pragma Unreferenced (Status); 797 -- ??? shouldn't we test Stat at least in a pragma Assert? 798 begin 799 -- Hardware interrupt 800 801 Install_Default_Action (HW_Interrupt (Interrupt)); 802 803 -- Flush server task off semaphore, allowing it to terminate 804 805 Status := Binary_Semaphore_Flush (Semaphore_ID_Map (Interrupt)); 806 end Unbind_Handler; 807 808 -------------------------------- 809 -- Unprotected_Detach_Handler -- 810 -------------------------------- 811 812 procedure Unprotected_Detach_Handler 813 (Interrupt : Interrupt_ID; 814 Static : Boolean) 815 is 816 Old_Handler : Parameterless_Handler; 817 begin 818 if User_Entry (Interrupt).T /= Null_Task then 819 -- If an interrupt entry is installed raise 820 -- Program_Error. (propagate it to the caller). 821 822 Raise_Exception (Program_Error'Identity, 823 "An interrupt entry is already installed"); 824 end if; 825 826 -- Note : Static = True will pass the following check. This is the 827 -- case when we want to detach a handler regardless of the static 828 -- status of the Current_Handler. 829 830 if not Static and then User_Handler (Interrupt).Static then 831 832 -- Trying to detach a static Interrupt Handler. raise 833 -- Program_Error. 834 835 Raise_Exception (Program_Error'Identity, 836 "Trying to detach a static Interrupt Handler"); 837 end if; 838 839 Old_Handler := User_Handler (Interrupt).H; 840 841 -- The new handler 842 843 User_Handler (Interrupt).H := null; 844 User_Handler (Interrupt).Static := False; 845 846 if Old_Handler /= null then 847 Unbind_Handler (Interrupt); 848 end if; 849 end Unprotected_Detach_Handler; 850 851 ---------------------------------- 852 -- Unprotected_Exchange_Handler -- 853 ---------------------------------- 854 855 procedure Unprotected_Exchange_Handler 856 (Old_Handler : out Parameterless_Handler; 857 New_Handler : Parameterless_Handler; 858 Interrupt : Interrupt_ID; 859 Static : Boolean; 860 Restoration : Boolean := False) 861 is 862 begin 863 if User_Entry (Interrupt).T /= Null_Task then 864 865 -- If an interrupt entry is already installed, raise 866 -- Program_Error. (propagate it to the caller). 867 868 Raise_Exception 869 (Program_Error'Identity, 870 "An interrupt is already installed"); 871 end if; 872 873 -- Note : A null handler with Static = True will 874 -- pass the following check. This is the case when we want to 875 -- detach a handler regardless of the Static status 876 -- of Current_Handler. 877 -- We don't check anything if Restoration is True, since we 878 -- may be detaching a static handler to restore a dynamic one. 879 880 if not Restoration and then not Static 881 and then (User_Handler (Interrupt).Static 882 883 -- Trying to overwrite a static Interrupt Handler with a 884 -- dynamic Handler 885 886 -- The new handler is not specified as an 887 -- Interrupt Handler by a pragma. 888 889 or else not Is_Registered (New_Handler)) 890 then 891 Raise_Exception 892 (Program_Error'Identity, 893 "Trying to overwrite a static Interrupt Handler with a " & 894 "dynamic Handler"); 895 end if; 896 897 -- Save the old handler 898 899 Old_Handler := User_Handler (Interrupt).H; 900 901 -- The new handler 902 903 User_Handler (Interrupt).H := New_Handler; 904 905 if New_Handler = null then 906 907 -- The null handler means we are detaching the handler 908 909 User_Handler (Interrupt).Static := False; 910 911 else 912 User_Handler (Interrupt).Static := Static; 913 end if; 914 915 -- Invoke a corresponding Server_Task if not yet created. 916 -- Place Task_Id info in Server_ID array. 917 918 if New_Handler /= null 919 and then 920 (Server_ID (Interrupt) = Null_Task 921 or else 922 Ada.Task_Identification.Is_Terminated 923 (To_Ada (Server_ID (Interrupt)))) 924 then 925 Interrupt_Access_Hold := 926 new Interrupt_Server_Task (Interrupt, Binary_Semaphore_Create); 927 Server_ID (Interrupt) := 928 To_System (Interrupt_Access_Hold.all'Identity); 929 end if; 930 931 if (New_Handler = null) and then Old_Handler /= null then 932 933 -- Restore default handler 934 935 Unbind_Handler (Interrupt); 936 937 elsif Old_Handler = null then 938 939 -- Save default handler 940 941 Bind_Handler (Interrupt); 942 end if; 943 end Unprotected_Exchange_Handler; 944 945 -- Start of processing for Interrupt_Manager 946 947 begin 948 -- By making this task independent of any master, when the process 949 -- goes away, the Interrupt_Manager will terminate gracefully. 950 951 System.Tasking.Utilities.Make_Independent; 952 953 loop 954 -- A block is needed to absorb Program_Error exception 955 956 declare 957 Old_Handler : Parameterless_Handler; 958 959 begin 960 select 961 accept Attach_Handler 962 (New_Handler : Parameterless_Handler; 963 Interrupt : Interrupt_ID; 964 Static : Boolean; 965 Restoration : Boolean := False) 966 do 967 Unprotected_Exchange_Handler 968 (Old_Handler, New_Handler, Interrupt, Static, Restoration); 969 end Attach_Handler; 970 971 or 972 accept Exchange_Handler 973 (Old_Handler : out Parameterless_Handler; 974 New_Handler : Parameterless_Handler; 975 Interrupt : Interrupt_ID; 976 Static : Boolean) 977 do 978 Unprotected_Exchange_Handler 979 (Old_Handler, New_Handler, Interrupt, Static); 980 end Exchange_Handler; 981 982 or 983 accept Detach_Handler 984 (Interrupt : Interrupt_ID; 985 Static : Boolean) 986 do 987 Unprotected_Detach_Handler (Interrupt, Static); 988 end Detach_Handler; 989 or 990 accept Bind_Interrupt_To_Entry 991 (T : Task_Id; 992 E : Task_Entry_Index; 993 Interrupt : Interrupt_ID) 994 do 995 -- If there is a binding already (either a procedure or an 996 -- entry), raise Program_Error (propagate it to the caller). 997 998 if User_Handler (Interrupt).H /= null 999 or else User_Entry (Interrupt).T /= Null_Task 1000 then 1001 Raise_Exception 1002 (Program_Error'Identity, 1003 "A binding for this interrupt is already present"); 1004 end if; 1005 1006 User_Entry (Interrupt) := Entry_Assoc'(T => T, E => E); 1007 1008 -- Indicate the attachment of interrupt entry in the ATCB. 1009 -- This is needed so when an interrupt entry task terminates 1010 -- the binding can be cleaned. The call to unbinding must be 1011 -- make by the task before it terminates. 1012 1013 T.Interrupt_Entry := True; 1014 1015 -- Invoke a corresponding Server_Task if not yet created. 1016 -- Place Task_Id info in Server_ID array. 1017 1018 if Server_ID (Interrupt) = Null_Task 1019 or else 1020 Ada.Task_Identification.Is_Terminated 1021 (To_Ada (Server_ID (Interrupt))) 1022 then 1023 Interrupt_Access_Hold := new Interrupt_Server_Task 1024 (Interrupt, Binary_Semaphore_Create); 1025 Server_ID (Interrupt) := 1026 To_System (Interrupt_Access_Hold.all'Identity); 1027 end if; 1028 1029 Bind_Handler (Interrupt); 1030 end Bind_Interrupt_To_Entry; 1031 1032 or 1033 accept Detach_Interrupt_Entries (T : Task_Id) do 1034 for Int in Interrupt_ID'Range loop 1035 if not Is_Reserved (Int) then 1036 if User_Entry (Int).T = T then 1037 User_Entry (Int) := 1038 Entry_Assoc' 1039 (T => Null_Task, E => Null_Task_Entry); 1040 Unbind_Handler (Int); 1041 end if; 1042 end if; 1043 end loop; 1044 1045 -- Indicate in ATCB that no interrupt entries are attached 1046 1047 T.Interrupt_Entry := False; 1048 end Detach_Interrupt_Entries; 1049 end select; 1050 1051 exception 1052 -- If there is a Program_Error we just want to propagate it to 1053 -- the caller and do not want to stop this task. 1054 1055 when Program_Error => 1056 null; 1057 1058 when others => 1059 pragma Assert (False); 1060 null; 1061 end; 1062 end loop; 1063 1064 exception 1065 when Standard'Abort_Signal => 1066 -- Flush interrupt server semaphores, so they can terminate 1067 Finalize_Interrupt_Servers; 1068 raise; 1069 end Interrupt_Manager; 1070 1071 --------------------------- 1072 -- Interrupt_Server_Task -- 1073 --------------------------- 1074 1075 -- Server task for vectored hardware interrupt handling 1076 1077 task body Interrupt_Server_Task is 1078 Self_Id : constant Task_Id := Self; 1079 Tmp_Handler : Parameterless_Handler; 1080 Tmp_ID : Task_Id; 1081 Tmp_Entry_Index : Task_Entry_Index; 1082 1083 Status : int; 1084 pragma Unreferenced (Status); 1085 -- ??? shouldn't we test Stat at least in a pragma Assert? 1086 begin 1087 System.Tasking.Utilities.Make_Independent; 1088 Semaphore_ID_Map (Interrupt) := Int_Sema; 1089 1090 loop 1091 -- Pend on semaphore that will be triggered by the 1092 -- umbrella handler when the associated interrupt comes in 1093 1094 Status := Binary_Semaphore_Obtain (Int_Sema); 1095 1096 if User_Handler (Interrupt).H /= null then 1097 1098 -- Protected procedure handler 1099 1100 Tmp_Handler := User_Handler (Interrupt).H; 1101 Tmp_Handler.all; 1102 1103 elsif User_Entry (Interrupt).T /= Null_Task then 1104 1105 -- Interrupt entry handler 1106 1107 Tmp_ID := User_Entry (Interrupt).T; 1108 Tmp_Entry_Index := User_Entry (Interrupt).E; 1109 System.Tasking.Rendezvous.Call_Simple 1110 (Tmp_ID, Tmp_Entry_Index, System.Null_Address); 1111 1112 else 1113 -- Semaphore has been flushed by an unbind operation in 1114 -- the Interrupt_Manager. Terminate the server task. 1115 1116 -- Wait for the Interrupt_Manager to complete its work 1117 1118 POP.Write_Lock (Self_Id); 1119 1120 -- Delete the associated semaphore 1121 1122 Status := Binary_Semaphore_Delete (Int_Sema); 1123 1124 -- Set status for the Interrupt_Manager 1125 1126 Semaphore_ID_Map (Interrupt) := 0; 1127 Server_ID (Interrupt) := Null_Task; 1128 POP.Unlock (Self_Id); 1129 1130 exit; 1131 end if; 1132 end loop; 1133 end Interrupt_Server_Task; 1134 1135 begin 1136 -- Get Interrupt_Manager's ID so that Abort_Interrupt can be sent 1137 1138 Interrupt_Manager_ID := To_System (Interrupt_Manager'Identity); 1139 end System.Interrupts; -
gcc/ada/s-interr-vxworks.adb
diff -urN gcc-4.3.2-orig/gcc/ada/s-interr-vxworks.adb gcc-4.3.2/gcc/ada/s-interr-vxworks.adb
old new 1 ------------------------------------------------------------------------------2 -- --3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --4 -- --5 -- S Y S T E M . I N T E R R U P T S --6 -- --7 -- B o d y --8 -- --9 -- Copyright (C) 1992-2007, Free Software Foundation, Inc. --10 -- --11 -- GNARL is free software; you can redistribute it and/or modify it under --12 -- terms of the GNU General Public License as published by the Free Soft- --13 -- ware Foundation; either version 2, or (at your option) any later ver- --14 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --17 -- for more details. You should have received a copy of the GNU General --18 -- Public License distributed with GNARL; see file COPYING. If not, write --19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --20 -- Boston, MA 02110-1301, USA. --21 -- --22 -- As a special exception, if other files instantiate generics from this --23 -- unit, or you link this unit with other files to produce an executable, --24 -- this unit does not by itself cause the resulting executable to be --25 -- covered by the GNU General Public License. This exception does not --26 -- however invalidate any other reasons why the executable file might be --27 -- covered by the GNU Public License. --28 -- --29 -- GNARL was developed by the GNARL team at Florida State University. --30 -- Extensive contributions were provided by Ada Core Technologies, Inc. --31 -- --32 ------------------------------------------------------------------------------33 34 -- Invariants:35 36 -- All user-handleable signals are masked at all times in all tasks/threads37 -- except possibly for the Interrupt_Manager task.38 39 -- When a user task wants to have the effect of masking/unmasking an signal,40 -- it must call Block_Interrupt/Unblock_Interrupt, which will have the effect41 -- of unmasking/masking the signal in the Interrupt_Manager task. These42 -- comments do not apply to vectored hardware interrupts, which may be masked43 -- or unmasked using routined interfaced to the relevant VxWorks system44 -- calls.45 46 -- Once we associate a Signal_Server_Task with an signal, the task never goes47 -- away, and we never remove the association. On the other hand, it is more48 -- convenient to terminate an associated Interrupt_Server_Task for a vectored49 -- hardware interrupt (since we use a binary semaphore for synchronization50 -- with the umbrella handler).51 52 -- There is no more than one signal per Signal_Server_Task and no more than53 -- one Signal_Server_Task per signal. The same relation holds for hardware54 -- interrupts and Interrupt_Server_Task's at any given time. That is, only55 -- one non-terminated Interrupt_Server_Task exists for a give interrupt at56 -- any time.57 58 -- Within this package, the lock L is used to protect the various status59 -- tables. If there is a Server_Task associated with a signal or interrupt,60 -- we use the per-task lock of the Server_Task instead so that we protect the61 -- status between Interrupt_Manager and Server_Task. Protection among62 -- service requests are ensured via user calls to the Interrupt_Manager63 -- entries.64 65 -- This is the VxWorks version of this package, supporting vectored hardware66 -- interrupts.67 68 with Ada.Unchecked_Conversion;69 70 with System.OS_Interface; use System.OS_Interface;71 72 with Interfaces.VxWorks;73 74 with Ada.Task_Identification;75 -- used for Task_Id type76 77 with Ada.Exceptions;78 -- used for Raise_Exception79 80 with System.Interrupt_Management;81 -- used for Reserve82 83 with System.Task_Primitives.Operations;84 -- used for Write_Lock85 -- Unlock86 -- Abort87 -- Wakeup_Task88 -- Sleep89 -- Initialize_Lock90 91 with System.Storage_Elements;92 -- used for To_Address93 -- To_Integer94 -- Integer_Address95 96 with System.Tasking.Utilities;97 -- used for Make_Independent98 99 with System.Tasking.Rendezvous;100 -- used for Call_Simple101 pragma Elaborate_All (System.Tasking.Rendezvous);102 103 package body System.Interrupts is104 105 use Tasking;106 use Ada.Exceptions;107 108 package POP renames System.Task_Primitives.Operations;109 110 function To_Ada is new Ada.Unchecked_Conversion111 (System.Tasking.Task_Id, Ada.Task_Identification.Task_Id);112 113 function To_System is new Ada.Unchecked_Conversion114 (Ada.Task_Identification.Task_Id, Task_Id);115 116 -----------------117 -- Local Tasks --118 -----------------119 120 -- WARNING: System.Tasking.Stages performs calls to this task with121 -- low-level constructs. Do not change this spec without synchronizing it.122 123 task Interrupt_Manager is124 entry Detach_Interrupt_Entries (T : Task_Id);125 126 entry Attach_Handler127 (New_Handler : Parameterless_Handler;128 Interrupt : Interrupt_ID;129 Static : Boolean;130 Restoration : Boolean := False);131 132 entry Exchange_Handler133 (Old_Handler : out Parameterless_Handler;134 New_Handler : Parameterless_Handler;135 Interrupt : Interrupt_ID;136 Static : Boolean);137 138 entry Detach_Handler139 (Interrupt : Interrupt_ID;140 Static : Boolean);141 142 entry Bind_Interrupt_To_Entry143 (T : Task_Id;144 E : Task_Entry_Index;145 Interrupt : Interrupt_ID);146 147 pragma Interrupt_Priority (System.Interrupt_Priority'First);148 end Interrupt_Manager;149 150 task type Interrupt_Server_Task151 (Interrupt : Interrupt_ID; Int_Sema : SEM_ID) is152 -- Server task for vectored hardware interrupt handling153 pragma Interrupt_Priority (System.Interrupt_Priority'First + 2);154 end Interrupt_Server_Task;155 156 type Interrupt_Task_Access is access Interrupt_Server_Task;157 158 -------------------------------159 -- Local Types and Variables --160 -------------------------------161 162 type Entry_Assoc is record163 T : Task_Id;164 E : Task_Entry_Index;165 end record;166 167 type Handler_Assoc is record168 H : Parameterless_Handler;169 Static : Boolean; -- Indicates static binding;170 end record;171 172 User_Handler : array (Interrupt_ID) of Handler_Assoc :=173 (others => (null, Static => False));174 pragma Volatile_Components (User_Handler);175 -- Holds the protected procedure handler (if any) and its Static176 -- information for each interrupt or signal. A handler is static177 -- iff it is specified through the pragma Attach_Handler.178 179 User_Entry : array (Interrupt_ID) of Entry_Assoc :=180 (others => (T => Null_Task, E => Null_Task_Entry));181 pragma Volatile_Components (User_Entry);182 -- Holds the task and entry index (if any) for each interrupt / signal183 184 -- Type and Head, Tail of the list containing Registered Interrupt185 -- Handlers. These definitions are used to register the handlers186 -- specified by the pragma Interrupt_Handler.187 188 type Registered_Handler;189 type R_Link is access all Registered_Handler;190 191 type Registered_Handler is record192 H : System.Address := System.Null_Address;193 Next : R_Link := null;194 end record;195 196 Registered_Handler_Head : R_Link := null;197 Registered_Handler_Tail : R_Link := null;198 199 Server_ID : array (Interrupt_ID) of System.Tasking.Task_Id :=200 (others => System.Tasking.Null_Task);201 pragma Atomic_Components (Server_ID);202 -- Holds the Task_Id of the Server_Task for each interrupt / signal.203 -- Task_Id is needed to accomplish locking per interrupt base. Also204 -- is needed to determine whether to create a new Server_Task.205 206 Semaphore_ID_Map : array207 (Interrupt_ID range 0 .. System.OS_Interface.Max_HW_Interrupt)208 of SEM_ID := (others => 0);209 -- Array of binary semaphores associated with vectored interrupts210 -- Note that the last bound should be Max_HW_Interrupt, but this will raise211 -- Storage_Error if Num_HW_Interrupts is null, so use an extra 4 bytes212 -- instead.213 214 Interrupt_Access_Hold : Interrupt_Task_Access;215 -- Variable for allocating an Interrupt_Server_Task216 217 Default_Handler : array (HW_Interrupt) of Interfaces.VxWorks.VOIDFUNCPTR;218 -- Vectored interrupt handlers installed prior to program startup.219 -- These are saved only when the umbrella handler is installed for220 -- a given interrupt number.221 222 -----------------------223 -- Local Subprograms --224 -----------------------225 226 procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID);227 -- Check if Id is a reserved interrupt, and if so raise Program_Error228 -- with an appropriate message, otherwise return.229 230 procedure Finalize_Interrupt_Servers;231 -- Unbind the handlers for hardware interrupt server tasks at program232 -- termination.233 234 function Is_Registered (Handler : Parameterless_Handler) return Boolean;235 -- See if Handler has been "pragma"ed using Interrupt_Handler.236 -- Always consider a null handler as registered.237 238 procedure Notify_Interrupt (Param : System.Address);239 -- Umbrella handler for vectored interrupts (not signals)240 241 procedure Install_Default_Action (Interrupt : HW_Interrupt);242 -- Restore a handler that was in place prior to program execution243 244 procedure Install_Umbrella_Handler245 (Interrupt : HW_Interrupt;246 Handler : Interfaces.VxWorks.VOIDFUNCPTR);247 -- Install the runtime umbrella handler for a vectored hardware248 -- interrupt249 250 procedure Unimplemented (Feature : String);251 pragma No_Return (Unimplemented);252 -- Used to mark a call to an unimplemented function. Raises Program_Error253 -- with an appropriate message noting that Feature is unimplemented.254 255 --------------------256 -- Attach_Handler --257 --------------------258 259 -- Calling this procedure with New_Handler = null and Static = True260 -- means we want to detach the current handler regardless of the261 -- previous handler's binding status (ie. do not care if it is a262 -- dynamic or static handler).263 264 -- This option is needed so that during the finalization of a PO, we265 -- can detach handlers attached through pragma Attach_Handler.266 267 procedure Attach_Handler268 (New_Handler : Parameterless_Handler;269 Interrupt : Interrupt_ID;270 Static : Boolean := False) is271 begin272 Check_Reserved_Interrupt (Interrupt);273 Interrupt_Manager.Attach_Handler (New_Handler, Interrupt, Static);274 end Attach_Handler;275 276 -----------------------------277 -- Bind_Interrupt_To_Entry --278 -----------------------------279 280 -- This procedure raises a Program_Error if it tries to281 -- bind an interrupt to which an Entry or a Procedure is282 -- already bound.283 284 procedure Bind_Interrupt_To_Entry285 (T : Task_Id;286 E : Task_Entry_Index;287 Int_Ref : System.Address)288 is289 Interrupt : constant Interrupt_ID :=290 Interrupt_ID (Storage_Elements.To_Integer (Int_Ref));291 292 begin293 Check_Reserved_Interrupt (Interrupt);294 Interrupt_Manager.Bind_Interrupt_To_Entry (T, E, Interrupt);295 end Bind_Interrupt_To_Entry;296 297 ---------------------298 -- Block_Interrupt --299 ---------------------300 301 procedure Block_Interrupt (Interrupt : Interrupt_ID) is302 begin303 Unimplemented ("Block_Interrupt");304 end Block_Interrupt;305 306 ------------------------------307 -- Check_Reserved_Interrupt --308 ------------------------------309 310 procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID) is311 begin312 if Is_Reserved (Interrupt) then313 Raise_Exception314 (Program_Error'Identity,315 "Interrupt" & Interrupt_ID'Image (Interrupt) & " is reserved");316 else317 return;318 end if;319 end Check_Reserved_Interrupt;320 321 ---------------------322 -- Current_Handler --323 ---------------------324 325 function Current_Handler326 (Interrupt : Interrupt_ID) return Parameterless_Handler327 is328 begin329 Check_Reserved_Interrupt (Interrupt);330 331 -- ??? Since Parameterless_Handler is not Atomic, the332 -- current implementation is wrong. We need a new service in333 -- Interrupt_Manager to ensure atomicity.334 335 return User_Handler (Interrupt).H;336 end Current_Handler;337 338 --------------------339 -- Detach_Handler --340 --------------------341 342 -- Calling this procedure with Static = True means we want to Detach the343 -- current handler regardless of the previous handler's binding status344 -- (i.e. do not care if it is a dynamic or static handler).345 346 -- This option is needed so that during the finalization of a PO, we can347 -- detach handlers attached through pragma Attach_Handler.348 349 procedure Detach_Handler350 (Interrupt : Interrupt_ID;351 Static : Boolean := False) is352 begin353 Check_Reserved_Interrupt (Interrupt);354 Interrupt_Manager.Detach_Handler (Interrupt, Static);355 end Detach_Handler;356 357 ------------------------------358 -- Detach_Interrupt_Entries --359 ------------------------------360 361 procedure Detach_Interrupt_Entries (T : Task_Id) is362 begin363 Interrupt_Manager.Detach_Interrupt_Entries (T);364 end Detach_Interrupt_Entries;365 366 ----------------------367 -- Exchange_Handler --368 ----------------------369 370 -- Calling this procedure with New_Handler = null and Static = True371 -- means we want to detach the current handler regardless of the372 -- previous handler's binding status (ie. do not care if it is a373 -- dynamic or static handler).374 375 -- This option is needed so that during the finalization of a PO, we376 -- can detach handlers attached through pragma Attach_Handler.377 378 procedure Exchange_Handler379 (Old_Handler : out Parameterless_Handler;380 New_Handler : Parameterless_Handler;381 Interrupt : Interrupt_ID;382 Static : Boolean := False)383 is384 begin385 Check_Reserved_Interrupt (Interrupt);386 Interrupt_Manager.Exchange_Handler387 (Old_Handler, New_Handler, Interrupt, Static);388 end Exchange_Handler;389 390 --------------391 -- Finalize --392 --------------393 394 procedure Finalize (Object : in out Static_Interrupt_Protection) is395 begin396 -- ??? loop to be executed only when we're not doing library level397 -- finalization, since in this case all interrupt / signal tasks are398 -- gone.399 400 if not Interrupt_Manager'Terminated then401 for N in reverse Object.Previous_Handlers'Range loop402 Interrupt_Manager.Attach_Handler403 (New_Handler => Object.Previous_Handlers (N).Handler,404 Interrupt => Object.Previous_Handlers (N).Interrupt,405 Static => Object.Previous_Handlers (N).Static,406 Restoration => True);407 end loop;408 end if;409 410 Tasking.Protected_Objects.Entries.Finalize411 (Tasking.Protected_Objects.Entries.Protection_Entries (Object));412 end Finalize;413 414 --------------------------------415 -- Finalize_Interrupt_Servers --416 --------------------------------417 418 -- Restore default handlers for interrupt servers419 420 -- This is called by the Interrupt_Manager task when it receives the abort421 -- signal during program finalization.422 423 procedure Finalize_Interrupt_Servers is424 HW_Interrupts : constant Boolean := HW_Interrupt'Last >= 0;425 426 begin427 if HW_Interrupts then428 for Int in HW_Interrupt loop429 if Server_ID (Interrupt_ID (Int)) /= null430 and then431 not Ada.Task_Identification.Is_Terminated432 (To_Ada (Server_ID (Interrupt_ID (Int))))433 then434 Interrupt_Manager.Attach_Handler435 (New_Handler => null,436 Interrupt => Interrupt_ID (Int),437 Static => True,438 Restoration => True);439 end if;440 end loop;441 end if;442 end Finalize_Interrupt_Servers;443 444 -------------------------------------445 -- Has_Interrupt_Or_Attach_Handler --446 -------------------------------------447 448 function Has_Interrupt_Or_Attach_Handler449 (Object : access Dynamic_Interrupt_Protection)450 return Boolean451 is452 pragma Unreferenced (Object);453 begin454 return True;455 end Has_Interrupt_Or_Attach_Handler;456 457 function Has_Interrupt_Or_Attach_Handler458 (Object : access Static_Interrupt_Protection)459 return Boolean460 is461 pragma Unreferenced (Object);462 begin463 return True;464 end Has_Interrupt_Or_Attach_Handler;465 466 ----------------------467 -- Ignore_Interrupt --468 ----------------------469 470 procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is471 begin472 Unimplemented ("Ignore_Interrupt");473 end Ignore_Interrupt;474 475 ----------------------------476 -- Install_Default_Action --477 ----------------------------478 479 procedure Install_Default_Action (Interrupt : HW_Interrupt) is480 begin481 -- Restore original interrupt handler482 483 Interfaces.VxWorks.intVecSet484 (Interfaces.VxWorks.INUM_TO_IVEC (Integer (Interrupt)),485 Default_Handler (Interrupt));486 Default_Handler (Interrupt) := null;487 end Install_Default_Action;488 489 ----------------------490 -- Install_Handlers --491 ----------------------492 493 procedure Install_Handlers494 (Object : access Static_Interrupt_Protection;495 New_Handlers : New_Handler_Array)496 is497 begin498 for N in New_Handlers'Range loop499 500 -- We need a lock around this ???501 502 Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt;503 Object.Previous_Handlers (N).Static := User_Handler504 (New_Handlers (N).Interrupt).Static;505 506 -- We call Exchange_Handler and not directly Interrupt_Manager.507 -- Exchange_Handler so we get the Is_Reserved check.508 509 Exchange_Handler510 (Old_Handler => Object.Previous_Handlers (N).Handler,511 New_Handler => New_Handlers (N).Handler,512 Interrupt => New_Handlers (N).Interrupt,513 Static => True);514 end loop;515 end Install_Handlers;516 517 ------------------------------518 -- Install_Umbrella_Handler --519 ------------------------------520 521 procedure Install_Umbrella_Handler522 (Interrupt : HW_Interrupt;523 Handler : Interfaces.VxWorks.VOIDFUNCPTR)524 is525 use Interfaces.VxWorks;526 527 Vec : constant Interrupt_Vector :=528 INUM_TO_IVEC (Interfaces.VxWorks.int (Interrupt));529 530 Old_Handler : constant VOIDFUNCPTR :=531 intVecGet532 (INUM_TO_IVEC (Interfaces.VxWorks.int (Interrupt)));533 534 Stat : Interfaces.VxWorks.STATUS;535 pragma Unreferenced (Stat);536 -- ??? shouldn't we test Stat at least in a pragma Assert?537 538 begin539 -- Only install umbrella handler when no Ada handler has already been540 -- installed. Note that the interrupt number is passed as a parameter541 -- when an interrupt occurs, so the umbrella handler has a different542 -- wrapper generated by intConnect for each interrupt number.543 544 if Default_Handler (Interrupt) = null then545 Stat :=546 intConnect (Vec, Handler, System.Address (Interrupt));547 Default_Handler (Interrupt) := Old_Handler;548 end if;549 end Install_Umbrella_Handler;550 551 ----------------552 -- Is_Blocked --553 ----------------554 555 function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is556 begin557 Unimplemented ("Is_Blocked");558 return False;559 end Is_Blocked;560 561 -----------------------562 -- Is_Entry_Attached --563 -----------------------564 565 function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is566 begin567 Check_Reserved_Interrupt (Interrupt);568 return User_Entry (Interrupt).T /= Null_Task;569 end Is_Entry_Attached;570 571 -------------------------572 -- Is_Handler_Attached --573 -------------------------574 575 function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is576 begin577 Check_Reserved_Interrupt (Interrupt);578 return User_Handler (Interrupt).H /= null;579 end Is_Handler_Attached;580 581 ----------------582 -- Is_Ignored --583 ----------------584 585 function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is586 begin587 Unimplemented ("Is_Ignored");588 return False;589 end Is_Ignored;590 591 -------------------592 -- Is_Registered --593 -------------------594 595 function Is_Registered (Handler : Parameterless_Handler) return Boolean is596 type Fat_Ptr is record597 Object_Addr : System.Address;598 Handler_Addr : System.Address;599 end record;600 601 function To_Fat_Ptr is new Ada.Unchecked_Conversion602 (Parameterless_Handler, Fat_Ptr);603 604 Ptr : R_Link;605 Fat : Fat_Ptr;606 607 begin608 if Handler = null then609 return True;610 end if;611 612 Fat := To_Fat_Ptr (Handler);613 614 Ptr := Registered_Handler_Head;615 616 while Ptr /= null loop617 if Ptr.H = Fat.Handler_Addr then618 return True;619 end if;620 621 Ptr := Ptr.Next;622 end loop;623 624 return False;625 end Is_Registered;626 627 -----------------628 -- Is_Reserved --629 -----------------630 631 function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is632 use System.Interrupt_Management;633 begin634 return Reserve (System.Interrupt_Management.Interrupt_ID (Interrupt));635 end Is_Reserved;636 637 ----------------------638 -- Notify_Interrupt --639 ----------------------640 641 -- Umbrella handler for vectored hardware interrupts (as opposed to642 -- signals and exceptions). As opposed to the signal implementation,643 -- this handler is only installed in the vector table while there is644 -- an active association of an Ada handler to the interrupt.645 646 -- Otherwise, the handler that existed prior to program startup is647 -- in the vector table. This ensures that handlers installed by648 -- the BSP are active unless explicitly replaced in the program text.649 650 -- Each Interrupt_Server_Task has an associated binary semaphore651 -- on which it pends once it's been started. This routine determines652 -- The appropriate semaphore and and issues a semGive call, waking653 -- the server task. When a handler is unbound,654 -- System.Interrupts.Unbind_Handler issues a semFlush, and the655 -- server task deletes its semaphore and terminates.656 657 procedure Notify_Interrupt (Param : System.Address) is658 Interrupt : constant Interrupt_ID := Interrupt_ID (Param);659 660 Discard_Result : STATUS;661 pragma Unreferenced (Discard_Result);662 663 begin664 Discard_Result := semGive (Semaphore_ID_Map (Interrupt));665 end Notify_Interrupt;666 667 ---------------668 -- Reference --669 ---------------670 671 function Reference (Interrupt : Interrupt_ID) return System.Address is672 begin673 Check_Reserved_Interrupt (Interrupt);674 return Storage_Elements.To_Address675 (Storage_Elements.Integer_Address (Interrupt));676 end Reference;677 678 --------------------------------679 -- Register_Interrupt_Handler --680 --------------------------------681 682 procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is683 New_Node_Ptr : R_Link;684 685 begin686 -- This routine registers a handler as usable for dynamic687 -- interrupt handler association. Routines attaching and detaching688 -- handlers dynamically should determine whether the handler is689 -- registered. Program_Error should be raised if it is not registered.690 691 -- Pragma Interrupt_Handler can only appear in a library692 -- level PO definition and instantiation. Therefore, we do not need693 -- to implement an unregister operation. Nor do we need to694 -- protect the queue structure with a lock.695 696 pragma Assert (Handler_Addr /= System.Null_Address);697 698 New_Node_Ptr := new Registered_Handler;699 New_Node_Ptr.H := Handler_Addr;700 701 if Registered_Handler_Head = null then702 Registered_Handler_Head := New_Node_Ptr;703 Registered_Handler_Tail := New_Node_Ptr;704 705 else706 Registered_Handler_Tail.Next := New_Node_Ptr;707 Registered_Handler_Tail := New_Node_Ptr;708 end if;709 end Register_Interrupt_Handler;710 711 -----------------------712 -- Unblock_Interrupt --713 -----------------------714 715 procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is716 begin717 Unimplemented ("Unblock_Interrupt");718 end Unblock_Interrupt;719 720 ------------------721 -- Unblocked_By --722 ------------------723 724 function Unblocked_By725 (Interrupt : Interrupt_ID) return System.Tasking.Task_Id726 is727 begin728 Unimplemented ("Unblocked_By");729 return Null_Task;730 end Unblocked_By;731 732 ------------------------733 -- Unignore_Interrupt --734 ------------------------735 736 procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is737 begin738 Unimplemented ("Unignore_Interrupt");739 end Unignore_Interrupt;740 741 -------------------742 -- Unimplemented --743 -------------------744 745 procedure Unimplemented (Feature : String) is746 begin747 Raise_Exception748 (Program_Error'Identity,749 Feature & " not implemented on VxWorks");750 end Unimplemented;751 752 -----------------------753 -- Interrupt_Manager --754 -----------------------755 756 task body Interrupt_Manager is757 758 --------------------759 -- Local Routines --760 --------------------761 762 procedure Bind_Handler (Interrupt : Interrupt_ID);763 -- This procedure does not do anything if a signal is blocked.764 -- Otherwise, we have to interrupt Server_Task for status change through765 -- a wakeup signal.766 767 procedure Unbind_Handler (Interrupt : Interrupt_ID);768 -- This procedure does not do anything if a signal is blocked.769 -- Otherwise, we have to interrupt Server_Task for status change770 -- through an abort signal.771 772 procedure Unprotected_Exchange_Handler773 (Old_Handler : out Parameterless_Handler;774 New_Handler : Parameterless_Handler;775 Interrupt : Interrupt_ID;776 Static : Boolean;777 Restoration : Boolean := False);778 779 procedure Unprotected_Detach_Handler780 (Interrupt : Interrupt_ID;781 Static : Boolean);782 783 ------------------784 -- Bind_Handler --785 ------------------786 787 procedure Bind_Handler (Interrupt : Interrupt_ID) is788 begin789 Install_Umbrella_Handler790 (HW_Interrupt (Interrupt), Notify_Interrupt'Access);791 end Bind_Handler;792 793 --------------------794 -- Unbind_Handler --795 --------------------796 797 procedure Unbind_Handler (Interrupt : Interrupt_ID) is798 S : STATUS;799 use type STATUS;800 801 begin802 -- Hardware interrupt803 804 Install_Default_Action (HW_Interrupt (Interrupt));805 806 -- Flush server task off semaphore, allowing it to terminate807 808 S := semFlush (Semaphore_ID_Map (Interrupt));809 pragma Assert (S = 0);810 end Unbind_Handler;811 812 --------------------------------813 -- Unprotected_Detach_Handler --814 --------------------------------815 816 procedure Unprotected_Detach_Handler817 (Interrupt : Interrupt_ID;818 Static : Boolean)819 is820 Old_Handler : Parameterless_Handler;821 begin822 if User_Entry (Interrupt).T /= Null_Task then823 -- If an interrupt entry is installed raise824 -- Program_Error. (propagate it to the caller).825 826 Raise_Exception (Program_Error'Identity,827 "An interrupt entry is already installed");828 end if;829 830 -- Note : Static = True will pass the following check. This is the831 -- case when we want to detach a handler regardless of the static832 -- status of the Current_Handler.833 834 if not Static and then User_Handler (Interrupt).Static then835 836 -- Trying to detach a static Interrupt Handler. raise837 -- Program_Error.838 839 Raise_Exception (Program_Error'Identity,840 "Trying to detach a static Interrupt Handler");841 end if;842 843 Old_Handler := User_Handler (Interrupt).H;844 845 -- The new handler846 847 User_Handler (Interrupt).H := null;848 User_Handler (Interrupt).Static := False;849 850 if Old_Handler /= null then851 Unbind_Handler (Interrupt);852 end if;853 end Unprotected_Detach_Handler;854 855 ----------------------------------856 -- Unprotected_Exchange_Handler --857 ----------------------------------858 859 procedure Unprotected_Exchange_Handler860 (Old_Handler : out Parameterless_Handler;861 New_Handler : Parameterless_Handler;862 Interrupt : Interrupt_ID;863 Static : Boolean;864 Restoration : Boolean := False)865 is866 begin867 if User_Entry (Interrupt).T /= Null_Task then868 869 -- If an interrupt entry is already installed, raise870 -- Program_Error. (propagate it to the caller).871 872 Raise_Exception873 (Program_Error'Identity,874 "An interrupt is already installed");875 end if;876 877 -- Note : A null handler with Static = True will878 -- pass the following check. This is the case when we want to879 -- detach a handler regardless of the Static status880 -- of Current_Handler.881 -- We don't check anything if Restoration is True, since we882 -- may be detaching a static handler to restore a dynamic one.883 884 if not Restoration and then not Static885 and then (User_Handler (Interrupt).Static886 887 -- Trying to overwrite a static Interrupt Handler with a888 -- dynamic Handler889 890 -- The new handler is not specified as an891 -- Interrupt Handler by a pragma.892 893 or else not Is_Registered (New_Handler))894 then895 Raise_Exception896 (Program_Error'Identity,897 "Trying to overwrite a static Interrupt Handler with a " &898 "dynamic Handler");899 end if;900 901 -- Save the old handler902 903 Old_Handler := User_Handler (Interrupt).H;904 905 -- The new handler906 907 User_Handler (Interrupt).H := New_Handler;908 909 if New_Handler = null then910 911 -- The null handler means we are detaching the handler912 913 User_Handler (Interrupt).Static := False;914 915 else916 User_Handler (Interrupt).Static := Static;917 end if;918 919 -- Invoke a corresponding Server_Task if not yet created.920 -- Place Task_Id info in Server_ID array.921 922 if New_Handler /= null923 and then924 (Server_ID (Interrupt) = Null_Task925 or else926 Ada.Task_Identification.Is_Terminated927 (To_Ada (Server_ID (Interrupt))))928 then929 Interrupt_Access_Hold :=930 new Interrupt_Server_Task931 (Interrupt, semBCreate (SEM_Q_FIFO, SEM_EMPTY));932 Server_ID (Interrupt) :=933 To_System (Interrupt_Access_Hold.all'Identity);934 end if;935 936 if (New_Handler = null) and then Old_Handler /= null then937 938 -- Restore default handler939 940 Unbind_Handler (Interrupt);941 942 elsif Old_Handler = null then943 944 -- Save default handler945 946 Bind_Handler (Interrupt);947 end if;948 end Unprotected_Exchange_Handler;949 950 -- Start of processing for Interrupt_Manager951 952 begin953 -- By making this task independent of any master, when the process954 -- goes away, the Interrupt_Manager will terminate gracefully.955 956 System.Tasking.Utilities.Make_Independent;957 958 loop959 -- A block is needed to absorb Program_Error exception960 961 declare962 Old_Handler : Parameterless_Handler;963 964 begin965 select966 accept Attach_Handler967 (New_Handler : Parameterless_Handler;968 Interrupt : Interrupt_ID;969 Static : Boolean;970 Restoration : Boolean := False)971 do972 Unprotected_Exchange_Handler973 (Old_Handler, New_Handler, Interrupt, Static, Restoration);974 end Attach_Handler;975 976 or977 accept Exchange_Handler978 (Old_Handler : out Parameterless_Handler;979 New_Handler : Parameterless_Handler;980 Interrupt : Interrupt_ID;981 Static : Boolean)982 do983 Unprotected_Exchange_Handler984 (Old_Handler, New_Handler, Interrupt, Static);985 end Exchange_Handler;986 987 or988 accept Detach_Handler989 (Interrupt : Interrupt_ID;990 Static : Boolean)991 do992 Unprotected_Detach_Handler (Interrupt, Static);993 end Detach_Handler;994 or995 accept Bind_Interrupt_To_Entry996 (T : Task_Id;997 E : Task_Entry_Index;998 Interrupt : Interrupt_ID)999 do1000 -- If there is a binding already (either a procedure or an1001 -- entry), raise Program_Error (propagate it to the caller).1002 1003 if User_Handler (Interrupt).H /= null1004 or else User_Entry (Interrupt).T /= Null_Task1005 then1006 Raise_Exception1007 (Program_Error'Identity,1008 "A binding for this interrupt is already present");1009 end if;1010 1011 User_Entry (Interrupt) := Entry_Assoc'(T => T, E => E);1012 1013 -- Indicate the attachment of interrupt entry in the ATCB.1014 -- This is needed so when an interrupt entry task terminates1015 -- the binding can be cleaned. The call to unbinding must be1016 -- make by the task before it terminates.1017 1018 T.Interrupt_Entry := True;1019 1020 -- Invoke a corresponding Server_Task if not yet created.1021 -- Place Task_Id info in Server_ID array.1022 1023 if Server_ID (Interrupt) = Null_Task1024 or else1025 Ada.Task_Identification.Is_Terminated1026 (To_Ada (Server_ID (Interrupt)))1027 then1028 Interrupt_Access_Hold := new Interrupt_Server_Task1029 (Interrupt, semBCreate (SEM_Q_FIFO, SEM_EMPTY));1030 Server_ID (Interrupt) :=1031 To_System (Interrupt_Access_Hold.all'Identity);1032 end if;1033 1034 Bind_Handler (Interrupt);1035 end Bind_Interrupt_To_Entry;1036 1037 or1038 accept Detach_Interrupt_Entries (T : Task_Id) do1039 for Int in Interrupt_ID'Range loop1040 if not Is_Reserved (Int) then1041 if User_Entry (Int).T = T then1042 User_Entry (Int) :=1043 Entry_Assoc'1044 (T => Null_Task, E => Null_Task_Entry);1045 Unbind_Handler (Int);1046 end if;1047 end if;1048 end loop;1049 1050 -- Indicate in ATCB that no interrupt entries are attached1051 1052 T.Interrupt_Entry := False;1053 end Detach_Interrupt_Entries;1054 end select;1055 1056 exception1057 -- If there is a Program_Error we just want to propagate it to1058 -- the caller and do not want to stop this task.1059 1060 when Program_Error =>1061 null;1062 1063 when others =>1064 pragma Assert (False);1065 null;1066 end;1067 end loop;1068 1069 exception1070 when Standard'Abort_Signal =>1071 -- Flush interrupt server semaphores, so they can terminate1072 Finalize_Interrupt_Servers;1073 raise;1074 end Interrupt_Manager;1075 1076 ---------------------------1077 -- Interrupt_Server_Task --1078 ---------------------------1079 1080 -- Server task for vectored hardware interrupt handling1081 1082 task body Interrupt_Server_Task is1083 Self_Id : constant Task_Id := Self;1084 Tmp_Handler : Parameterless_Handler;1085 Tmp_ID : Task_Id;1086 Tmp_Entry_Index : Task_Entry_Index;1087 S : STATUS;1088 1089 use type STATUS;1090 1091 begin1092 System.Tasking.Utilities.Make_Independent;1093 Semaphore_ID_Map (Interrupt) := Int_Sema;1094 1095 loop1096 -- Pend on semaphore that will be triggered by the1097 -- umbrella handler when the associated interrupt comes in1098 1099 S := semTake (Int_Sema, WAIT_FOREVER);1100 pragma Assert (S = 0);1101 1102 if User_Handler (Interrupt).H /= null then1103 1104 -- Protected procedure handler1105 1106 Tmp_Handler := User_Handler (Interrupt).H;1107 Tmp_Handler.all;1108 1109 elsif User_Entry (Interrupt).T /= Null_Task then1110 1111 -- Interrupt entry handler1112 1113 Tmp_ID := User_Entry (Interrupt).T;1114 Tmp_Entry_Index := User_Entry (Interrupt).E;1115 System.Tasking.Rendezvous.Call_Simple1116 (Tmp_ID, Tmp_Entry_Index, System.Null_Address);1117 1118 else1119 -- Semaphore has been flushed by an unbind operation in1120 -- the Interrupt_Manager. Terminate the server task.1121 1122 -- Wait for the Interrupt_Manager to complete its work1123 1124 POP.Write_Lock (Self_Id);1125 1126 -- Delete the associated semaphore1127 1128 S := semDelete (Int_Sema);1129 1130 pragma Assert (S = 0);1131 1132 -- Set status for the Interrupt_Manager1133 1134 Semaphore_ID_Map (Interrupt) := 0;1135 Server_ID (Interrupt) := Null_Task;1136 POP.Unlock (Self_Id);1137 1138 exit;1139 end if;1140 end loop;1141 end Interrupt_Server_Task;1142 1143 begin1144 -- Get Interrupt_Manager's ID so that Abort_Interrupt can be sent1145 1146 Interrupt_Manager_ID := To_System (Interrupt_Manager'Identity);1147 end System.Interrupts; -
gcc/ada/s-osinte-rtems.ads
diff -urN gcc-4.3.2-orig/gcc/ada/s-osinte-rtems.ads gcc-4.3.2/gcc/ada/s-osinte-rtems.ads
old new 37 37 38 38 -- This is the RTEMS version of this package 39 39 40 -- These are guesses based on what I think the GNARL team will want to 41 -- call the rtems configurations. We use CPU-rtems for the rtems 42 -- configurations. 40 -- 41 -- RTEMS target names are of the form CPU-rtems. 42 -- This implementation is designed to work on ALL RTEMS targets. 43 -- The RTEMS implementation is primarily based upon the POSIX threads 44 -- API but there are also bindings to GNAT/RTEMS support routines 45 -- to insulate this code from C API specific details and, in some 46 -- cases, obtain target architecture and BSP specific information 47 -- that is unavailable at the time this package is built. 43 48 44 49 -- This package encapsulates all direct interfaces to OS services 45 50 -- that are needed by children of System. 46 51 47 52 -- PLEASE DO NOT add any with-clauses to this package 48 -- or remove the pragma Elaborate_Body.53 -- or remove the pragma Preelaborate. 49 54 -- It is designed to be a bottom-level (leaf) package. 50 55 51 56 with Interfaces.C; … … 84 89 -- Signals -- 85 90 ------------- 86 91 87 Max_Interrupt : constant := 31; 92 Num_HW_Interrupts : constant := 256; 93 94 Max_HW_Interrupt : constant := Num_HW_Interrupts - 1; 95 type HW_Interrupt is new int range 0 .. Max_HW_Interrupt; 96 97 Max_Interrupt : constant := Max_HW_Interrupt; 98 88 99 type Signal is new int range 0 .. Max_Interrupt; 89 100 90 101 SIGXCPU : constant := 0; -- XCPU … … 475 486 destructor : destructor_pointer) return int; 476 487 pragma Import (C, pthread_key_create, "pthread_key_create"); 477 488 489 ------------------------------------------------------------ 490 -- Binary Semaphore Wrapper to Support Interrupt Tasks -- 491 ------------------------------------------------------------ 492 493 type Binary_Semaphore_Id is new rtems_id; 494 495 function Binary_Semaphore_Create return Binary_Semaphore_Id; 496 pragma Import ( 497 C, 498 Binary_Semaphore_Create, 499 "__gnat_binary_semaphore_create"); 500 501 function Binary_Semaphore_Delete (ID : Binary_Semaphore_Id) return int; 502 pragma Import ( 503 C, 504 Binary_Semaphore_Delete, 505 "__gnat_binary_semaphore_delete"); 506 507 function Binary_Semaphore_Obtain (ID : Binary_Semaphore_Id) return int; 508 pragma Import ( 509 C, 510 Binary_Semaphore_Obtain, 511 "__gnat_binary_semaphore_obtain"); 512 513 function Binary_Semaphore_Release (ID : Binary_Semaphore_Id) return int; 514 pragma Import ( 515 C, 516 Binary_Semaphore_Release, 517 "__gnat_binary_semaphore_release"); 518 519 function Binary_Semaphore_Flush (ID : Binary_Semaphore_Id) return int; 520 pragma Import ( 521 C, 522 Binary_Semaphore_Flush, 523 "__gnat_binary_semaphore_flush"); 524 525 ------------------------------------------------------------ 526 -- Hardware Interrupt Wrappers to Support Interrupt Tasks -- 527 ------------------------------------------------------------ 528 529 type Interrupt_Handler is access procedure (parameter : System.Address); 530 pragma Convention (C, Interrupt_Handler); 531 type Interrupt_Vector is new System.Address; 532 533 function Interrupt_Connect 534 (Vector : Interrupt_Vector; 535 Handler : Interrupt_Handler; 536 Parameter : System.Address := System.Null_Address) return int; 537 pragma Import (C, Interrupt_Connect, "__gnat_interrupt_connect"); 538 -- Use this to set up an user handler. The routine installs a 539 -- a user handler which is invoked after RTEMS has saved enough 540 -- context for a high-level language routine to be safely invoked. 541 542 function Interrupt_Vector_Get 543 (Vector : Interrupt_Vector) return Interrupt_Handler; 544 pragma Import (C, Interrupt_Vector_Get, "__gnat_interrupt_get"); 545 -- Use this to get the existing handler for later restoral. 546 547 procedure Interrupt_Vector_Set 548 (Vector : Interrupt_Vector; 549 Handler : Interrupt_Handler); 550 pragma Import (C, Interrupt_Vector_Set, "__gnat_interrupt_set"); 551 -- Use this to restore a handler obtained using Interrupt_Vector_Get. 552 553 function Interrupt_Number_To_Vector (intNum : int) return Interrupt_Vector; 554 -- Convert a logical interrupt number to the hardware interrupt vector 555 -- number used to connect the interrupt. 556 pragma Import ( 557 C, 558 Interrupt_Number_To_Vector, 559 "__gnat_interrupt_number_to_vector" 560 ); 561 478 562 private 479 563 480 564 type sigset_t is new int; … … 507 591 schedpolicy : int; 508 592 schedparam : struct_sched_param; 509 593 cputime_clocked_allowed : int; 510 de atchstate: int;594 detatchstate : int; 511 595 end record; 512 596 pragma Convention (C, pthread_attr_t); 513 597 514 598 type pthread_condattr_t is record 515 flags : int; 599 is_initialized : int; 600 process_shared : int; 516 601 end record; 517 602 pragma Convention (C, pthread_condattr_t); 518 603 -
gcc/ada/s-osinte-vxworks.adb
diff -urN gcc-4.3.2-orig/gcc/ada/s-osinte-vxworks.adb gcc-4.3.2/gcc/ada/s-osinte-vxworks.adb
old new 239 239 return int (Ticks); 240 240 end To_Clock_Ticks; 241 241 242 ----------------------------- 243 -- Binary_Semaphore_Create -- 244 ----------------------------- 245 246 function Binary_Semaphore_Create return Binary_Semaphore_Id is 247 begin 248 return semBCreate (SEM_Q_FIFO, SEM_EMPTY); 249 end Binary_Semaphore_Create; 250 251 ----------------------------- 252 -- Binary_Semaphore_Delete -- 253 ----------------------------- 254 255 function Binary_Semaphore_Delete (ID : Binary_Semaphore_Id) return int is 256 begin 257 return semDelete (ID); 258 end Binary_Semaphore_Obtain; 259 260 ----------------------------- 261 -- Binary_Semaphore_Obtain -- 262 ----------------------------- 263 264 function Binary_Semaphore_Obtain (ID : Binary_Semaphore_Id) return int is 265 begin 266 return semTake (ID, WAIT_FOREVER); 267 end Binary_Semaphore_Obtain; 268 269 ------------------------------ 270 -- Binary_Semaphore_Release -- 271 ------------------------------ 272 273 function Binary_Semaphore_Release (ID : Binary_Semaphore_Id) return int is 274 begin 275 return semGive (ID); 276 end Binary_Semaphore_Release; 277 278 ---------------------------- 279 -- Binary_Semaphore_Flush -- 280 ---------------------------- 281 282 function Binary_Semaphore_Flush (ID : Binary_Semaphore_Id) return int is 283 begin 284 return semFlush (ID); 285 end Binary_Semaphore_Flush; 286 287 288 ---------------------------- 289 -- Interrupt_Connect -- 290 ---------------------------- 291 292 function Interrupt_Connect 293 (Vector : Interrupt_Vector; 294 Handler : Interrupt_Handler; 295 Parameter : System.Address := System.Null_Address) return int is 296 begin 297 return intConnect (Vector, Handler, Parameter); 298 end Interrupt_Connect; 299 300 ---------------------------- 301 -- Interrupt_Vector_Get -- 302 ---------------------------- 303 304 function Interrupt_Vector_Get 305 (Vector : Interrupt_Vector) return Interrupt_Handler is 306 begin 307 return intVecGet (Vector); 308 end Interrupt_Get; 309 310 ---------------------------- 311 -- Interrupt_Vector_Set -- 312 ---------------------------- 313 314 procedure Interrupt_Vector_Set 315 (Vector : Interrupt_Vector; 316 Handler : Interrupt_Handler) is 317 begin 318 intVecSet (Interfaces.VxWorks.INUM_TO_IVEC (Vector), Handler); 319 end Interrupt_Vector_Set; 320 321 ----------------------------r -- 322 -- Interrupt_Number_To_Vector -- 323 ----------------------------r -- 324 325 function Interrupt_Number_To_Vector (intNum : int) return Interrupt_Vector is 326 begin 327 return INUM_TO_IVEC (Interfaces.VxWorks.int (Interrupt)); 328 end Interrupt_Number_To_Vector; 329 242 330 end System.OS_Interface; -
gcc/ada/s-osinte-vxworks.ads
diff -urN gcc-4.3.2-orig/gcc/ada/s-osinte-vxworks.ads gcc-4.3.2/gcc/ada/s-osinte-vxworks.ads
old new 393 393 pragma Import (C, semFlush, "semFlush"); 394 394 -- Release all threads blocked on the semaphore 395 395 396 ------------------------------------------------------------ 397 -- Binary Semaphore Wrapper to Support Interrupt Tasks -- 398 ------------------------------------------------------------ 399 400 type Binary_Semaphore_Id is new SEM_ID; 401 402 function Binary_Semaphore_Create return Binary_Semaphore_Id; 403 404 function Binary_Semaphore_Delete (ID : Binary_Semaphore_Id) return int; 405 406 function Binary_Semaphore_Obtain (ID : Binary_Semaphore_Id) return int; 407 408 function Binary_Semaphore_Release (ID : Binary_Semaphore_Id) return int; 409 410 function Binary_Semaphore_Flush (ID : Binary_Semaphore_Id) return int; 411 412 ------------------------------------------------------------ 413 -- Hardware Interrupt Wrappers to Support Interrupt Tasks -- 414 ------------------------------------------------------------ 415 416 type Interrupt_Handler is access procedure (parameter : System.Address); 417 type Interrupt_Vector is new System.Address; 418 419 function Interrupt_Connect 420 (Vector : Interrupt_Vector; 421 Handler : Interrupt_Handler; 422 Parameter : System.Address := System.Null_Address) return int; 423 -- Use this to set up an user handler. The routine installs a 424 -- a user handler which is invoked after RTEMS has saved enough 425 -- context for a high-level language routine to be safely invoked. 426 427 function Interrupt_Vector_Get 428 (Vector : Interrupt_Vector) return Interrupt_Handler; 429 -- Use this to get the existing handler for later restoral. 430 431 procedure Interrupt_Vector_Set 432 (Vector : Interrupt_Vector; 433 Handler : Interrupt_Handler); 434 -- Use this to restore a handler obtained using Interrupt_Vector_Get. 435 436 function Interrupt_Number_To_Vector (intNum : int) return Interrupt_Vector; 437 -- Convert a logical interrupt number to the hardware interrupt vector 438 -- number used to connect the interrupt. 439 396 440 private 397 441 type sigset_t is new long; 398 442 -
gcc/ada/s-stchop-rtems.adb
diff -urN gcc-4.3.2-orig/gcc/ada/s-stchop-rtems.adb gcc-4.3.2/gcc/ada/s-stchop-rtems.adb
old new 1 ------------------------------------------------------------------------------ 2 -- -- 3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- 4 -- -- 5 -- S Y S T E M . S T A C K _ C H E C K I N G . O P E R A T I O N S -- 6 -- -- 7 -- B o d y -- 8 -- -- 9 -- Copyright (C) 1999-2008, Free Software Foundation, Inc. -- 10 -- -- 11 -- GNARL is free software; you can redistribute it and/or modify it under -- 12 -- terms of the GNU General Public License as published by the Free Soft- -- 13 -- ware Foundation; either version 2, or (at your option) any later ver- -- 14 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- -- 15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17 -- for more details. You should have received a copy of the GNU General -- 18 -- Public License distributed with GNARL; see file COPYING. If not, write -- 19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- 20 -- Boston, MA 02110-1301, USA. -- 21 -- -- 22 -- As a special exception, if other files instantiate generics from this -- 23 -- unit, or you link this unit with other files to produce an executable, -- 24 -- this unit does not by itself cause the resulting executable to be -- 25 -- covered by the GNU General Public License. This exception does not -- 26 -- however invalidate any other reasons why the executable file might be -- 27 -- covered by the GNU Public License. -- 28 -- -- 29 -- GNARL was developed by the GNARL team at Florida State University. -- 30 -- Extensive contributions were provided by Ada Core Technologies, Inc. -- 31 -- -- 32 ------------------------------------------------------------------------------ 33 34 -- This is the RTEMS version of this package. 35 -- This file should be kept synchronized with the general implementation 36 -- provided by s-stchop.adb. 37 38 pragma Restrictions (No_Elaboration_Code); 39 -- We want to guarantee the absence of elaboration code because the 40 -- binder does not handle references to this package. 41 42 with Ada.Exceptions; 43 44 with Interfaces.C; use Interfaces.C; 45 46 package body System.Stack_Checking.Operations is 47 48 ---------------------------- 49 -- Invalidate_Stack_Cache -- 50 ---------------------------- 51 52 procedure Invalidate_Stack_Cache (Any_Stack : Stack_Access) is 53 pragma Warnings (Off, Any_Stack); 54 begin 55 Cache := Null_Stack; 56 end Invalidate_Stack_Cache; 57 58 ----------------------------- 59 -- Notify_Stack_Attributes -- 60 ----------------------------- 61 62 procedure Notify_Stack_Attributes 63 (Initial_SP : System.Address; 64 Size : System.Storage_Elements.Storage_Offset) 65 is 66 67 -- RTEMS keeps all the information we need. 68 69 pragma Unreferenced (Size); 70 pragma Unreferenced (Initial_SP); 71 72 begin 73 null; 74 end Notify_Stack_Attributes; 75 76 ----------------- 77 -- Stack_Check -- 78 ----------------- 79 80 function Stack_Check 81 (Stack_Address : System.Address) return Stack_Access 82 is 83 pragma Unreferenced (Stack_Address); 84 85 -- RTEMS has a routine to check this. So use it. 86 function rtems_stack_checker_is_blown return Interfaces.C.int; 87 pragma Import (C, 88 rtems_stack_checker_is_blown, "rtems_stack_checker_is_blown"); 89 90 begin 91 -- RTEMS has a routine to check this. So use it. 92 93 if rtems_stack_checker_is_blown /= 0 then 94 Ada.Exceptions.Raise_Exception 95 (E => Storage_Error'Identity, 96 Message => "stack overflow detected"); 97 end if; 98 99 return null; 100 101 end Stack_Check; 102 103 ------------------------ 104 -- Update_Stack_Cache -- 105 ------------------------ 106 107 procedure Update_Stack_Cache (Stack : Stack_Access) is 108 begin 109 if not Multi_Processor then 110 Cache := Stack; 111 end if; 112 end Update_Stack_Cache; 113 114 end System.Stack_Checking.Operations;
Note: See TracBrowser
for help on using the repository browser.