File: s-taskin.ads

package info (click to toggle)
gnat 3.10p-3
  • links: PTS
  • area: main
  • in suites: hamm, slink
  • size: 49,492 kB
  • ctags: 33,976
  • sloc: ansic: 347,844; ada: 227,415; sh: 8,759; yacc: 7,861; asm: 5,252; makefile: 3,632; objc: 475; cpp: 400; sed: 261; pascal: 95
file content (749 lines) | stat: -rw-r--r-- 31,161 bytes parent folder | download
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;