1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
|
------------------------------------------------------------------------------
-- --
-- GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS --
-- --
-- S Y S T E M . T A S K I N G --
-- --
-- S p e c --
-- (Version for old GNARL) --
-- --
-- $Revision: 1.46 $ --
-- --
-- Copyright (C) 1992-1997 Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNARL; see file COPYING. If not, write --
-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
-- MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
-- this unit does not by itself cause the resulting executable to be --
-- covered by the GNU General Public License. This exception does not --
-- however invalidate any other reasons why the executable file might be --
-- covered by the GNU Public License. --
-- --
-- GNARL was developed by the GNARL team at Florida State University. It is --
-- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
-- State University (http://www.gnat.com). --
-- --
------------------------------------------------------------------------------
-- This package provides necessary type definitions for compiler interface.
-- Note: the compiler generates direct calls to this interface, via Rtsfind.
-- Any changes to this interface may require corresponding compiler changes.
with Ada.Finalization;
with Ada.Exceptions;
-- Used for: Exception_Id
with System.Parameters;
-- Used for: Size_Type
with System.Task_Primitives;
-- Used for: Task_Primitives.Lock
with System.Task_Specific_Data;
-- Used for: TSD
with System.Task_Info;
-- Used for: Task_Info_Type, Task_Image;
package System.Tasking is
---------------------------------
-- Task_ID related definitions --
---------------------------------
type Ada_Task_Control_Block;
type Task_ID is access Ada_Task_Control_Block;
-- This should be a private type. However, compiler generates internal
-- while compiling s-taprob.adb
Null_Task : constant Task_ID;
type Task_List is array (Positive range <>) of Task_ID;
function Self return Task_ID;
pragma Inline (Self);
-----------------------------------
-- Master_ID Related Definitions --
-----------------------------------
subtype Master_ID is Integer;
---------------------------
-- Priority Declarations --
---------------------------
Unspecified_Priority : constant Integer := System.Priority'First - 1;
Priority_Not_Boosted : constant Integer := System.Priority'First - 1;
subtype Rendezvous_Priority is Integer
range Priority_Not_Boosted .. System.Any_Priority'Last;
-----------------------
-- Enumeration types --
-----------------------
type Task_Stage is (
Created,
-- Task has been created but has not begun activation.
Can_Activate,
-- Task has begin activation.
Active,
-- Task has completed activation and is executing the task body.
Await_Dependents,
-- Task is trying to complete a task master other than itself,
-- and is waiting for the tasks dependent on that master to become
-- passive (be complete, terminated, or be waiting on a terminate
-- alternative).
Passive,
-- The task is passive.
Completing,
-- The task is committed to becoming complete, but has not yet
-- satisfied all of the conditions for completion. This
-- acts as a claim to completion; once Stage is set to this value,
-- no other task can continue with completion.
Complete,
-- The task is complete. The task and all of its dependents are
-- passive; some dependents may still be waiting on terminate
-- alternatives.
Terminated);
-- The task is terminated. All dependents waiting on terminate
-- alternatives have been awakened and have terminated themselves.
type Accepting_State is (
Not_Accepting, -- task is not ready to accept any entry call
Trivial_Accept, -- "accept E;"
Simple_Accept, -- "accept E do ... end E;"
Select_Wait); -- most general case
type Call_Modes is (Simple_Call, Conditional_Call, Asynchronous_Call);
type Select_Modes is (Simple_Mode, Else_Mode, Terminate_Mode, Delay_Mode);
-----------------------------------
-- ATC_Level related definitions --
-----------------------------------
Max_ATC_Nesting : constant Natural := 20;
subtype ATC_Level_Base is Integer range 0 .. Max_ATC_Nesting;
ATC_Level_Infinity : constant ATC_Level_Base := ATC_Level_Base'Last;
subtype ATC_Level is ATC_Level_Base range
ATC_Level_Base'First .. ATC_Level_Base'Last - 1;
subtype ATC_Level_Index is ATC_Level
range ATC_Level'First + 1 .. ATC_Level'Last;
-------------------------------
-- Entry related definitions --
-------------------------------
Null_Entry : constant := 0;
Max_Entry : constant := Integer'Last;
Interrupt_Entry : constant := -2;
Cancelled_Entry : constant := -1;
type Entry_Index is range Interrupt_Entry .. Max_Entry;
type Entry_Call_Record;
type Entry_Call_Link is access all Entry_Call_Record;
type Entry_Queue is record
Head : Entry_Call_Link;
Tail : Entry_Call_Link;
end record;
----------------------------
-- PO related definitions --
----------------------------
Null_Protected_Entry : constant := Null_Entry;
Max_Protected_Entry : constant := Max_Entry;
type Protected_Entry_Index is new Entry_Index
range Null_Protected_Entry .. Max_Protected_Entry;
subtype Positive_Protected_Entry_Index is
Protected_Entry_Index range 1 .. Protected_Entry_Index'Last;
type Protection (Num_Entries : Protected_Entry_Index) is limited private;
-- This type contains the GNARL state of a protected object. The
-- application-defined portion of the state (i.e. private objects)
-- is maintained by the compiler-generated code.
type Protection_Access is access all Protection;
Null_PO : constant Protection_Access := null;
type Communication_Block is private;
-- Objects of this type are passed between GNARL calls to allow RTS
-- information to be preserved.
------------------------------------
-- Rendezvous related definitions --
------------------------------------
Null_Task_Entry : constant := Null_Entry;
Max_Task_Entry : constant := Max_Entry;
type Task_Entry_Index is new Entry_Index
range Null_Task_Entry .. Max_Task_Entry;
type Task_Entry_Queue_Array is
array (Task_Entry_Index range <>) of
Entry_Queue;
No_Rendezvous : constant := 0;
Max_Select : constant Integer := Integer'Last;
-- RTS-defined
subtype Select_Index is Integer range No_Rendezvous .. Max_Select;
-- type Select_Index is range No_Rendezvous .. Max_Select;
subtype Positive_Select_Index is
Select_Index range 1 .. Select_Index'Last;
type Accept_Alternative is record -- should be packed
Null_Body : Boolean;
S : Task_Entry_Index;
end record;
type Accept_List is
array (Positive_Select_Index range <>) of Accept_Alternative;
type Accept_List_Access is access constant Accept_List;
----------------------------------
-- Entry_Call_Record definition --
----------------------------------
type Entry_Call_Record is record
Prev : Entry_Call_Link;
Next : Entry_Call_Link;
Self : Task_ID;
Level : ATC_Level;
-- One of Self and Level are redundant in this implementation, since
-- each Entry_Call_Record is at Self.Entry_Calls (Level). Since we must
-- have access to the entry call record to be reading this, we could
-- get Self from Level, or Level from Self. However, this requires
-- non-portable address arithmetic.
Mode : Call_Modes;
Abortable : Boolean;
-- This call is queued abortably.
-- Protection: Acceptor.L. If the call is not on a queue, it should
-- only be accessed by the task doing the call or requeue, and the
-- mutex need not be locked in those cases.
Done : Boolean;
-- The call has been completed.
-- Protection : Self.L, except in certain circumstances where
-- Self knows that the acceptor is suspended waiting for a call,
-- and Self holds the acceptor's mutex.
Has_Been_Abortable : Boolean;
-- The call has been blocked abortably at some point.
-- Currently only used for protected entry calls.
-- Protection: Called_PO.L.
E : Entry_Index;
Prio : System.Any_Priority;
-- The above fields are those that there may be some hope of packing.
-- They are gathered together to allow for compilers that lay records
-- out contiguously, to allow for such packing.
Uninterpreted_Data : System.Address;
Exception_To_Raise : Ada.Exceptions.Exception_Id;
-- The exception to raise once this call has been completed without
-- being aborted.
-- Server : Server_Record;
Called_Task : Task_ID;
-- For task entry calls only. Only one of Called_Task and Called_PO
-- are valid; the other must be Null_Task or null, respectively.
-- In general, Called_Task must be either a legitimate Task_ID or
-- Null_Task. Both Called_Task and Called_PO must be null
-- if the call record is not in use.
-- Protection: Called_Task.L. There are situations in which
-- it is necessary to access this field given only an Entry_Call_Record.
-- This is difficult, since Called_Task.L must be locked to access
-- Called_Task. This is done by doing the lock and then checking
-- to make sure that Called_Task has not changed; see
-- System.Tasking.Utilities.Lock_Server.
Acceptor_Prev_Call : Entry_Call_Link;
-- For task entry calls only.
Acceptor_Prev_Priority : Rendezvous_Priority := Priority_Not_Boosted;
-- For task entry calls only.
-- The priority of the most recent prior call being serviced.
-- For protected entry calls, this function should be performed by
-- GNULLI ceiling locking.
Called_PO : Protection_Access;
-- For protected entry calls only. Only one of Called_Task and
-- Called_PO are valid; the other must be Null_Task or Null_PO,
-- respectively. In general, Called_PO must be either a legitimate
-- Protection_Access value or null. Both Called_Task and
-- Called_PO must be null if the call record is not in use.
-- Protection: Called_PO.L. See notes under Called_Task, above.
end record;
------------------------------------
-- Task related other definitions --
------------------------------------
type Activation_Chain is limited private;
type Activation_Chain_Access is access all Activation_Chain;
type Task_Procedure_Access is access procedure (Arg : System.Address);
type Access_Boolean is access all Boolean;
type Access_Address is access all System.Address;
----------------------------------------------
-- Ada_Task_Control_Block (ATCB) definition --
----------------------------------------------
type Entry_Call_Array is array (ATC_Level_Index) of
aliased Entry_Call_Record;
D_I_Count : constant := 2;
-- This constant may be adjusted, to allow more Address-sized
-- attributes to be stored directly in the task control block.
subtype Direct_Index is Integer range 0 .. D_I_Count - 1;
-- Attributes with indices in this range are stored directly in
-- the task control block. Such attributes must be Address-sized.
-- Other attributes will be held in dynamically allocated records
-- chained off of the task control block.
type Direct_Attribute_Array is
array (Direct_Index) of aliased System.Address;
type Direct_Index_Vector is mod 2 ** D_I_Count;
-- This is a bit-vector type, used to store information about
-- the usage of the direct attribute fields.
-- Notes on protection (synchronization) of TRTS data structures.
-- Any field of the TCB can be written by the activator of a task when the
-- task is created, since no other task can access the new task's
-- state until creation is complete.
-- The protection for each field is described in a comment starting with
-- "Protection:".
-- When a lock is used to protect an ATCB field, this lock is simply named.
-- Some protection is described in terms of tasks related to the
-- ATCB being protected. These are:
-- Self: The task which is controlled by this ATCB.
-- Acceptor: A task accepting a call from Self.
-- Caller: A task calling an entry of Self.
-- Parent: The task executing the master on which Self depends.
-- Dependent: A task dependent on Self.
-- Activator: The task that created Self and initiated its activation.
-- Created: A task created and activated by Self.
type Ada_Task_Control_Block (Entry_Num : Task_Entry_Index) is record
LL_TCB : aliased System.Task_Primitives.Task_Control_Block;
-- Control block used by the underlying low-level tasking service
-- (GNULLI).
-- Protection: This is used only by the GNULLI implementation, which
-- takes care of all of its synchronization.
Task_Entry_Point : Task_Procedure_Access;
-- Information needed to call the procedure containing the code for
-- the body of this task.
-- Protection: Part of the synchronization between Self and
-- Activator. Activator writes it, once, before Self starts
-- executing. Self reads it, once, as part of its execution.
Task_Arg : System.Address;
-- The argument to to task procedure. Currently unused; this will
-- provide a handle for discriminant information.
-- Protection: Part of the synchronization between Self and
-- Activator. Activator writes it, once, before Self starts
-- executing. Thereafter, Self only reads it.
Task_Info : System.Task_Info.Task_Info_Type;
-- System-specific attributes of the task as specified by the
-- Task_Info pragma.
Stack_Size : System.Parameters.Size_Type;
-- Requested stack size.
-- Protection: Only used by Self.
Current_Priority : System.Any_Priority;
-- Active priority, except that the effects of protected object
-- priority ceilings are not reflected. This only reflects explicit
-- priority changes and priority inherited through task activation
-- and rendezvous.
-- Ada 95 notes: In Ada 95, this field will be transferred to the
-- Priority field of an Entry_Calls component when an entry call
-- is initiated. The Priority of the Entry_Calls component will not
-- change for the duration of the call. The accepting task can
-- use it to boost its own priority without fear of its changing in
-- the meantime.
-- This can safely be used in the priority ordering
-- of entry queues. Once a call is queued, its priority does not
-- change.
-- Since an entry call cannot be made while executing
-- a protected action, the priority of a task will never reflect a
-- priority ceiling change at the point of an entry call.
-- Protection: Only written by Self, and only accessed when Acceptor
-- accepts an entry or when Created activates, at which points Self is
-- suspended.
Base_Priority : System.Any_Priority;
-- Base priority, not changed during entry calls, only changed
-- via dynamic priorities package.
-- Protection: Only written by Self, accessed by anyone.
New_Base_Priority : System.Any_Priority;
-- New value for Base_Priority (for dynamic priorities package).
-- Protection: Self.L.
L : System.Task_Primitives.Lock;
-- General purpose lock; protects most fields in the ATCB.
Compiler_Data : System.Task_Specific_Data.TSD;
-- Task-specific data needed by the compiler to store
-- per-task structures.
-- Protection: Only accessed by Self.
-- the following declarations are for Rendezvous
Cond : System.Task_Primitives.Condition_Variable;
-- Used by Self to wait for a condition to become true.
-- It is invariant in the GNARL that a task waits only on its
-- own condition variable.
-- Protection: Condition variables are always associated with a lock.
-- The runtime places no restrictions on which lock is used, except
-- that it must protection the condition upon which the task is waiting.
All_Tasks_Link : Task_ID;
-- Used to link this task to the list of all tasks in the system.
-- Protection: All_Tasks.L.
Global_Task_Lock_Nesting : Natural;
-- This is the current nesting level of calls to
-- System.Tasking.Stages.Lock_Task_T.
-- This allows a task to call Lock_Task_T multiple times without
-- deadlocking. A task only locks All_Task_Lock when its
-- All_Tasks_Nesting goes from 0 to 1, and only unlocked when it
-- goes from 1 to 0.
-- Protection: Only accessed by Self.
Activation_Link : Task_ID;
-- Used to link this task to a list of tasks to be activated.
-- Protection: Only used by Activator.
Open_Accepts : Accept_List_Access;
-- This points to the Open_Accepts array of accept alternatives passed
-- to the RTS by the compiler-generated code to Selective_Wait.
-- Protection: Self.L.
Exception_To_Raise : Ada.Exceptions.Exception_Id;
-- An exception which should be raised by this task when it regains
-- control.
-- Protection: Read only by Self, under circumstances where it will
-- be notified by the writer when it is safe to read it:
-- 1. Written by Acceptor, when Self is suspended.
-- 2. Written by Notify_Exception, executed by Self through a
-- synchronous signal handler, which redirects control to a
-- routine to read it and raise the exception.
Chosen_Index : Select_Index;
-- The index in Open_Accepts of the entry call accepted by a selective
-- wait executed by this task.
-- Protection: Written by both Self and Caller. Usually protected
-- by Self.L. However, once the selection is known to have been
-- written it can be accessed without protection. This happens
-- after Self has updated it itself using information from a suspended
-- Caller, or after Caller has updated it and awakened Self.
Call : Entry_Call_Link;
-- The entry call that has been accepted by this task.
-- Protection: Self.L. Self will modify this field
-- when Self.Accepting is False, and will not need the mutex to do so.
-- Once a task sets Stage=Completing, no other task can access this
-- field.
-- The following fields are used to manage the task's life cycle.
Aborter_Link : Task_ID;
-- Link to the list of tasks which tries to abort this task but
-- blocked by another aborter who has already been aborting the task.
Activator : Task_ID;
-- The task that created this task, either by declaring it as a task
-- object or by executing a task allocator.
-- Protection: Set by Activator before Self is activated, and
-- read after Self is activated.
Parent : Task_ID;
Master_of_Task : Master_ID;
-- The task executing the master of this task, and the ID of this task's
-- master (unique only among masters currently active within Parent).
-- Protection: Set by Activator before Self is activated, and
-- read after Self is activated.
Master_Within : Master_ID;
-- The ID of the master currently executing within this task; that is,
-- the most deeply nested currently active master.
-- Protection: Only written by Self, and only read by Self or by
-- dependents when Self is attempting to exit a master. Since Self
-- will not write this field until the master is complete, the
-- synchronization should be adequate to prevent races.
Activation_Count : Integer;
-- This is the number of tasks that this task is activating, i.e. the
-- children that have started activation but have not completed it.
-- Protection: Self.L and Created.L. Both mutexes must be locked,
-- since Self.Activation_Count and Created.Stage must be synchronized.
Awake_Count : Integer;
-- Number of tasks dependent on this task (including this task) that are
-- still "awake": not terminated and not waiting on a terminate
-- alternative.
-- Protection: Self.L. Parent.L must also be locked when this is
-- updated, so that it can be synchronized with
-- Parent.Awaited_Dependent_Count, except under special circumstances
-- where we know that the two can be out of sync without allowing the
-- parent to terminate before its dependents.
Awaited_Dependent_Count : Integer;
-- This is the awake count of a master being completed by this task.
-- Protection: Self.L. Dependent.L must also be locked so that
-- this field and Dependent.Awake_Count can be synchronized, except
-- under special circumstances where we know that the two can be out
-- of sync without allowing the parent to terminate before its
-- dependents.
Terminating_Dependent_Count : Integer;
-- This is the count of tasks dependent on a master being completed by
-- this task which are waiting on a terminate alternative. Only valid
-- when there none of the dependents are awake.
-- Protection: Self.L.
Pending_Priority_Change : Boolean;
-- Flag to indicate pending priority change (for dynamic priorities
-- package). The base priority is updated on the next abortion
-- completion point (aka. synchronization point).
-- Protection: Self.L.
Pending_Action : Boolean;
-- Unified flag indicating pending action on abortion completion
-- point (aka. synchronization point). Currently set if:
-- . Pending_Priority_Change is set or
-- . Pending_ATC_Level is changed.
-- Protection: Self.L.
Pending_ATC_Level : ATC_Level_Base;
-- The ATC level to which this task is currently being aborted.
-- Protection: Self.L.
ATC_Nesting_Level : ATC_Level;
-- The dynamic level of ATC nesting (currently executing nested
-- asynchronous select statements) in this task.
-- Protection: This is only used by Self. However, decrementing it
-- in effect deallocates an Entry_Calls component, and care must be
-- taken that all references to that component are eliminated before
-- doing the decrement. This in turn will probably required locking
-- a protected object (for a protected entry call) or the Acceptor's
-- lock (for a task entry call). However, ATC_Nesting_Level itself can
-- be accessed without a lock.
Deferral_Level : Natural;
-- This is the number of times that Defer_Abortion has been called by
-- this task without a matching Undefer_Abortion call. Abortion is
-- only allowed when this zero.
-- Protection: Only updated by Self; access assumed to be atomic.
Elaborated : Access_Boolean;
-- Pointer to a flag indicating that this task's body has been
-- elaborated. The flag is created and managed by the
-- compiler-generated code.
-- Protection: The field itself is only accessed by Activator. The flag
-- that it points to is updated by Master and read by Activator; access
-- is assumed to be atomic.
Stage : Task_Stage;
-- The general stage of the task in it's life cycle.
-- Protection: Self.L.
-- beginning of flags
Cancel_Was_Successful : Boolean;
-- This indicates that the last attempt to cancel an entry call was
-- successful. It needs to be accurate between a call to
-- *Cancel_*_Entry_Call and the following call to Complete_*_Entry_Call.
-- These calls cannot be nested; that is, there can be no intervening
-- *Cancel_*_Entry_Call, so this single field is adequate.
-- Protection: Accessed only by Self.
Accepting : Accepting_State;
-- The ability of this task to accept an entry call.
-- Protection: Self.L.
Aborting : Boolean;
-- Self is in the process of aborting. While set, prevents multiple
-- abortion signals from being sent by different aborter while abortion
-- is acted upon. This is essential since an aborter which calls
-- Abort_To_Level could set the Pending_ATC_Level to yet a lower level
-- (than the current level), may be preempted and would send the
-- abortion signal when resuming execution. At this point, the abortee
-- may have completed abortion to the proper level such that the
-- signal (and resulting abortion exception) are not handled any more.
-- In other words, the flag prevents a race between multiple aborters
-- and the abortee.
-- Protection: Self.L.
Terminate_Alternative : Boolean;
-- Task is accepting Select with Terminate Alternative.
Interrupt_Entry : Boolean := false;
-- Indicates if one or more Interrupt Entries are attached to
-- the task. This flag is needed for cleaning up the Interrupt
-- Entry bindings.
-- end of flags
Entry_Calls : Entry_Call_Array;
-- An array of entry calls.
-- Protection: The elements of this array are on entry call queues
-- associated with protected objects or task entries, and are protected
-- by the protected object lock or Acceptor.L, respectively.
Entry_Queues : Task_Entry_Queue_Array (1 .. Entry_Num);
-- An array of task entry queues.
-- Protection: Self.L. Once a task has set Self.Stage to Completing, it
-- has exclusive access to this field.
Task_Image : System.Task_Info.Task_Image_Type;
-- holds an access to string that provides a readable id for task,
-- built from the variable of which it is a value or component.
Direct_Attributes : Direct_Attribute_Array;
-- for task attributes that have same size as Address
Is_Defined : Direct_Index_Vector := 0;
-- bit I is 1 iff Direct_Attributes (I) is defined
Indirect_Attributes : Access_Address;
-- a pointer to chain of records for other attributes that
-- are not address-sized, including all tagged types.
end record;
type Barrier_Function_Pointer is access
function
(O : System.Address;
E : Protected_Entry_Index)
return Boolean;
-- Pointer to a function which evaluates the barrier of a protected
-- entry body. O is a pointer to the compiler-generated record
-- representing the protected object, and E is the index of the
-- entry serviced by the body.
type Entry_Action_Pointer is access
procedure
(O : System.Address;
P : System.Address;
E : Protected_Entry_Index);
-- Pointer to a procedure which executes the sequence of statements
-- of a protected entry body. O is a pointer to the compiler-generated
-- record representing the protected object, P is a pointer to the
-- record of entry parameters, and E is the index of the
-- entry serviced by the body.
type Entry_Body is record
Barrier : Barrier_Function_Pointer;
Action : Entry_Action_Pointer;
end record;
-- The compiler-generated code passes objects of this type to the GNARL
-- to allow it to access the executable code of an entry body.
type Protected_Entry_Body_Array is
array (Positive_Protected_Entry_Index range <>) of Entry_Body;
-- This is an array of the executable code for all entry bodies of
-- a protected type.
type Protected_Entry_Body_Access is access all Protected_Entry_Body_Array;
private
Null_Task : constant Task_ID := null;
type Activation_Chain is new Task_ID;
type Communication_Block is record
Self : Task_ID;
Enqueued : Boolean := False;
Cancelled : Boolean;
end record;
type Protected_Entry_Queue_Array is
array (Protected_Entry_Index range <>) of
Entry_Queue;
type Protection (Num_Entries : Protected_Entry_Index) is new
Ada.Finalization.Limited_Controlled
with record
L : Task_Primitives.Lock;
Compiler_Info : System.Address;
Call_In_Progress : Entry_Call_Link;
Ceiling : System.Any_Priority;
Old_Base_Priority : System.Any_Priority;
Pending_Action : Boolean;
Entry_Bodies : Protected_Entry_Body_Access;
Entry_Queues : Protected_Entry_Queue_Array (1 .. Num_Entries);
end record;
procedure Finalize (Object : in out Protection);
-- Clean up a Protection object; in particular, finalize the associated
-- Lock object.
end System.Tasking;
|