This patch exports Make_Independent from GNAT.Threads. No simple test
available.
Tested on x86_64-pc-linux-gnu, committed on trunk
2017-11-09 Bob Duff <[email protected]>
* libgnarl/g-thread.ads, libgnarl/g-thread.adb: (Make_Independent):
Export this so users can use it without importing
System.Tasking.Utilities.
* libgnarl/s-tassta.adb (Vulnerable_Complete_Task): Relax assertion
that fails when Make_Independent is called on a user task.
* libgnarl/s-taskin.ads (Master_Of_Task): Avoid unusual
capitalization style ((style) bad casing of "Master_of_Task").
Index: libgnat/g-altive.ads
===================================================================
--- libgnat/g-altive.ads (revision 254579)
+++ libgnat/g-altive.ads (revision 254580)
@@ -668,18 +668,18 @@
-- type of A. The quad-word operations are only implemented by one
-- Altivec primitive operation. That means that, if QW_Operation is a
-- quad-word operation, we should have:
--- QW_Operation (To_Type_of_A (B)) = QW_Operation (A)
+-- QW_Operation (To_Type_Of_A (B)) = QW_Operation (A)
-- That is true iff:
--- To_Quad_Word (To_Type_of_A (B)) = To_Quad_Word (A)
+-- To_Quad_Word (To_Type_Of_A (B)) = To_Quad_Word (A)
-- As To_Quad_Word is a bijection. we have:
--- To_Type_of_A (B) = A
+-- To_Type_Of_A (B) = A
-- resp. any combination of A, B, C:
--- To_Type_of_A (C) = A
--- To_Type_of_B (A) = B
--- To_Type_of_C (B) = C
+-- To_Type_Of_A (C) = A
+-- To_Type_Of_B (A) = B
+-- To_Type_Of_C (B) = C
-- ...
-- Making sure that the properties described above are verified by the
Index: libgnat/s-spsufi.adb
===================================================================
--- libgnat/s-spsufi.adb (revision 254579)
+++ libgnat/s-spsufi.adb (revision 254580)
@@ -71,9 +71,9 @@
-- requires that "The subpool no longer belongs to any pool" BEFORE
-- calling Deallocate_Subpool. The actual dispatching call required is:
--
- -- Deallocate_Subpool(Pool_of_Subpool(Subpool).all, Subpool);
+ -- Deallocate_Subpool(Pool_Of_Subpool(Subpool).all, Subpool);
--
- -- but that can't be taken literally, because Pool_of_Subpool will
+ -- but that can't be taken literally, because Pool_Of_Subpool will
-- return null.
declare
Index: libgnarl/s-tassta.adb
===================================================================
--- libgnarl/s-tassta.adb (revision 254579)
+++ libgnarl/s-tassta.adb (revision 254580)
@@ -151,7 +151,7 @@
-- duplicate master ids. For example, suppose we have three nested
-- task bodies T1,T2,T3. And suppose T1 also calls P which calls Q (and
-- both P and Q are task masters). Q will have the same master id as
- -- Master_of_Task of T3. Previous versions of this would abort T3 when
+ -- Master_Of_Task of T3. Previous versions of this would abort T3 when
-- Q calls Complete_Master, which was completely wrong.
begin
@@ -160,7 +160,7 @@
P := C.Common.Parent;
if P = Self_ID then
- if C.Master_of_Task = Self_ID.Master_Within then
+ if C.Master_Of_Task = Self_ID.Master_Within then
pragma Debug
(Debug.Trace (Self_ID, "Aborting", 'X', C));
Utilities.Abort_One_Task (Self_ID, C);
@@ -304,7 +304,7 @@
P.Alive_Count := P.Alive_Count + 1;
if P.Common.State = Master_Completion_Sleep and then
- C.Master_of_Task = P.Master_Within
+ C.Master_Of_Task = P.Master_Within
then
pragma Assert (Self_ID /= P);
P.Common.Wait_Count := P.Common.Wait_Count + 1;
@@ -498,7 +498,7 @@
-- has already awaited its dependent tasks. This raises Program_Error,
-- by 4.8(10.3/2). See AI-280. Ignore this check for foreign threads.
- if Self_ID.Master_of_Task /= Foreign_Task_Level
+ if Self_ID.Master_Of_Task /= Foreign_Task_Level
and then Master > Self_ID.Master_Within
then
raise Program_Error with
@@ -559,10 +559,10 @@
P := Self_ID;
- if P.Master_of_Task <= Independent_Task_Level then
+ if P.Master_Of_Task <= Independent_Task_Level then
P := Environment_Task;
else
- while P /= null and then P.Master_of_Task >= Master loop
+ while P /= null and then P.Master_Of_Task >= Master loop
P := P.Common.Parent;
end loop;
end if;
@@ -621,13 +621,13 @@
-- a regular library level task, otherwise the run-time will get
-- confused when waiting for these tasks to terminate.
- T.Master_of_Task := Library_Task_Level;
+ T.Master_Of_Task := Library_Task_Level;
else
- T.Master_of_Task := Master;
+ T.Master_Of_Task := Master;
end if;
- T.Master_Within := T.Master_of_Task + 1;
+ T.Master_Within := T.Master_Of_Task + 1;
for L in T.Entry_Calls'Range loop
T.Entry_Calls (L).Self := T;
@@ -710,7 +710,7 @@
pragma Debug
(Debug.Trace
- (Self_ID, "Created task in " & T.Master_of_Task'Img, 'C', T));
+ (Self_ID, "Created task in " & T.Master_Of_Task'Img, 'C', T));
end Create_Task;
--------------------
@@ -988,11 +988,11 @@
Initialization.Defer_Abort_Nestable (Self_ID);
- -- Loop through the From chain, changing their Master_of_Task fields,
+ -- Loop through the From chain, changing their Master_Of_Task fields,
-- and to find the end of the chain.
loop
- C.Master_of_Task := New_Master;
+ C.Master_Of_Task := New_Master;
exit when C.Common.Activation_Link = null;
C := C.Common.Activation_Link;
end loop;
@@ -1094,7 +1094,7 @@
pragma Assert (Self_ID.Deferral_Level = 1);
Debug.Master_Hook
- (Self_ID, Self_ID.Common.Parent, Self_ID.Master_of_Task);
+ (Self_ID, Self_ID.Common.Parent, Self_ID.Master_Of_Task);
if Use_Alternate_Stack then
Self_ID.Common.Task_Alternate_Stack := Task_Alternate_Stack'Address;
@@ -1307,7 +1307,7 @@
-- environment task), because they are implementation artifacts that
-- should be invisible to Ada programs.
- elsif Self_ID.Master_of_Task /= Independent_Task_Level then
+ elsif Self_ID.Master_Of_Task /= Independent_Task_Level then
-- Look for a fall-back handler following the master relationship
-- for the task. As specified in ARM C.7.3 par. 9/2, "the fall-back
@@ -1377,7 +1377,7 @@
procedure Terminate_Task (Self_ID : Task_Id) is
Environment_Task : constant Task_Id := STPO.Environment_Task;
- Master_of_Task : Integer;
+ Master_Of_Task : Integer;
Deallocate : Boolean;
begin
@@ -1397,12 +1397,12 @@
Lock_RTS;
end if;
- Master_of_Task := Self_ID.Master_of_Task;
+ Master_Of_Task := Self_ID.Master_Of_Task;
-- Check if the current task is an independent task If so, decrement
-- the Independent_Task_Count value.
- if Master_of_Task = Independent_Task_Level then
+ if Master_Of_Task = Independent_Task_Level then
if Single_Lock then
Utilities.Independent_Task_Count :=
Utilities.Independent_Task_Count - 1;
@@ -1439,7 +1439,7 @@
Free_Task (Self_ID);
end if;
- if Master_of_Task > 0 then
+ if Master_Of_Task > 0 then
STPO.Exit_Task;
end if;
end Terminate_Task;
@@ -1606,11 +1606,11 @@
C := All_Tasks_List;
while C /= null loop
- if C.Common.Activator = Self_ID and then C.Master_of_Task = CM then
+ if C.Common.Activator = Self_ID and then C.Master_Of_Task = CM then
return False;
end if;
- if C.Common.Parent = Self_ID and then C.Master_of_Task = CM then
+ if C.Common.Parent = Self_ID and then C.Master_Of_Task = CM then
Write_Lock (C);
if C.Common.State = Unactivated then
@@ -1662,9 +1662,9 @@
-- Terminate unactivated (never-to-be activated) tasks
- if C.Common.Activator = Self_ID and then C.Master_of_Task = CM then
+ if C.Common.Activator = Self_ID and then C.Master_Of_Task = CM then
- -- Usually, C.Common.Activator = Self_ID implies C.Master_of_Task
+ -- Usually, C.Common.Activator = Self_ID implies C.Master_Of_Task
-- = CM. The only case where C is pending activation by this
-- task, but the master of C is not CM is in Ada 2005, when C is
-- part of a return object of a build-in-place function.
@@ -1681,7 +1681,7 @@
-- Count it if directly dependent on this master
- if C.Common.Parent = Self_ID and then C.Master_of_Task = CM then
+ if C.Common.Parent = Self_ID and then C.Master_Of_Task = CM then
Write_Lock (C);
if C.Awake_Count /= 0 then
@@ -1781,7 +1781,7 @@
C := All_Tasks_List;
while C /= null loop
- if C.Common.Parent = Self_ID and then C.Master_of_Task = CM then
+ if C.Common.Parent = Self_ID and then C.Master_Of_Task = CM then
Write_Lock (C);
pragma Assert (C.Awake_Count = 0);
@@ -1840,7 +1840,7 @@
-- while the task calls Free_Task itself, in Terminate_Task.
if C.Common.Parent = Self_ID
- and then C.Master_of_Task >= CM
+ and then C.Master_Of_Task >= CM
and then not C.Free_On_Termination
then
if P /= null then
@@ -1912,7 +1912,7 @@
if (T.Common.Parent /= null
and then T.Common.Parent.Common.Parent /= null)
- or else T.Master_of_Task > Library_Task_Level
+ or else T.Master_Of_Task > Library_Task_Level
then
Initialization.Task_Lock (Self_ID);
@@ -1977,7 +1977,7 @@
pragma Assert (Self_ID = Self);
pragma Assert
(Self_ID.Master_Within in
- Self_ID.Master_of_Task + 1 .. Self_ID.Master_of_Task + 3);
+ Self_ID.Master_Of_Task .. Self_ID.Master_Of_Task + 3);
pragma Assert (Self_ID.Common.Wait_Count = 0);
pragma Assert (Self_ID.Open_Accepts = null);
pragma Assert (Self_ID.ATC_Nesting_Level = 1);
@@ -2007,10 +2007,10 @@
Unlock_RTS;
end if;
- -- If Self_ID.Master_Within = Self_ID.Master_of_Task + 2 we may have
+ -- If Self_ID.Master_Within = Self_ID.Master_Of_Task + 2 we may have
-- dependent tasks for which we need to wait. Otherwise we just exit.
- if Self_ID.Master_Within = Self_ID.Master_of_Task + 2 then
+ if Self_ID.Master_Within = Self_ID.Master_Of_Task + 2 then
Vulnerable_Complete_Master (Self_ID);
end if;
end Vulnerable_Complete_Task;
Index: libgnarl/s-tassta.ads
===================================================================
--- libgnarl/s-tassta.ads (revision 254579)
+++ libgnarl/s-tassta.ads (revision 254580)
@@ -285,7 +285,7 @@
(From, To : Activation_Chain_Access;
New_Master : Master_ID);
-- Compiler interface only. Do not call from within the RTS.
- -- Move all tasks on From list to To list, and change their Master_of_Task
+ -- Move all tasks on From list to To list, and change their Master_Of_Task
-- to be New_Master. This is used to implement build-in-place function
-- returns. Tasks that are part of the return object are initially placed
-- on an activation chain local to the return statement, and their master
Index: libgnarl/s-tasren.adb
===================================================================
--- libgnarl/s-tasren.adb (revision 254579)
+++ libgnarl/s-tasren.adb (revision 254580)
@@ -1138,7 +1138,7 @@
Parent.Awake_Count := Parent.Awake_Count + 1;
if Parent.Common.State = Master_Completion_Sleep
- and then Acceptor.Master_of_Task = Parent.Master_Within
+ and then Acceptor.Master_Of_Task = Parent.Master_Within
then
Parent.Common.Wait_Count :=
Parent.Common.Wait_Count + 1;
Index: libgnarl/s-tasuti.adb
===================================================================
--- libgnarl/s-tasuti.adb (revision 254579)
+++ libgnarl/s-tasuti.adb (revision 254580)
@@ -258,7 +258,7 @@
pragma Assert (Parent = Environment_Task);
- Self_Id.Master_of_Task := Independent_Task_Level;
+ Self_Id.Master_Of_Task := Independent_Task_Level;
-- Update Independent_Task_Count that is needed for the GLADE
-- termination rule. See also pending update in
@@ -396,7 +396,7 @@
end loop;
if P.Common.State = Master_Phase_2_Sleep
- and then C.Master_of_Task = P.Master_Within
+ and then C.Master_Of_Task = P.Master_Within
then
pragma Assert (P.Common.Wait_Count > 0);
P.Common.Wait_Count := P.Common.Wait_Count - 1;
@@ -462,7 +462,7 @@
-- P has non-passive dependents
if P.Common.State = Master_Completion_Sleep
- and then C.Master_of_Task = P.Master_Within
+ and then C.Master_Of_Task = P.Master_Within
then
pragma Debug
(Debug.Trace
Index: libgnarl/s-tporft.adb
===================================================================
--- libgnarl/s-tporft.adb (revision 254579)
+++ libgnarl/s-tporft.adb (revision 254580)
@@ -70,8 +70,8 @@
Unlock_RTS;
pragma Assert (Succeeded);
- Self_Id.Master_of_Task := 0;
- Self_Id.Master_Within := Self_Id.Master_of_Task + 1;
+ Self_Id.Master_Of_Task := 0;
+ Self_Id.Master_Within := Self_Id.Master_Of_Task + 1;
for L in Self_Id.Entry_Calls'Range loop
Self_Id.Entry_Calls (L).Self := Self_Id;
Index: libgnarl/s-tasuti.ads
===================================================================
--- libgnarl/s-tasuti.ads (revision 254579)
+++ libgnarl/s-tasuti.ads (revision 254580)
@@ -54,9 +54,9 @@
--
-- This is a dangerous operation, and should never be used on nested tasks
-- or tasks that depend on any objects that might be finalized earlier than
- -- the termination of the environment task. It is for internal use by the
- -- GNARL, to prevent such internal server tasks from preventing a partition
- -- from terminating.
+ -- the termination of the environment task. It is primarily for internal
+ -- use by the GNARL, to prevent such internal server tasks from preventing
+ -- a partition from terminating.
--
-- Also note that the run time assumes that the parent of an independent
-- task is the environment task. If this is not the case, Make_Independent
Index: libgnarl/g-thread.adb
===================================================================
--- libgnarl/g-thread.adb (revision 254579)
+++ libgnarl/g-thread.adb (revision 254580)
@@ -33,6 +33,7 @@
with System.Task_Primitives.Operations;
with System.Tasking;
with System.Tasking.Stages; use System.Tasking.Stages;
+with System.Tasking.Utilities;
with System.OS_Interface; use System.OS_Interface;
with System.Soft_Links; use System.Soft_Links;
with Ada.Unchecked_Conversion;
@@ -172,6 +173,15 @@
Thr.all := Task_Primitives.Operations.Get_Thread_Id (To_Id (Id));
end Get_Thread;
+ ----------------------
+ -- Make_Independent --
+ ----------------------
+
+ function Make_Independent return Boolean is
+ begin
+ return System.Tasking.Utilities.Make_Independent;
+ end Make_Independent;
+
----------------
-- To_Task_Id --
----------------
Index: libgnarl/s-taskin.ads
===================================================================
--- libgnarl/s-taskin.ads (revision 254579)
+++ libgnarl/s-taskin.ads (revision 254580)
@@ -982,7 +982,7 @@
-- updated it itself using information from a suspended Caller, or
-- after Caller has updated it and awakened Self.
- Master_of_Task : Master_Level;
+ Master_Of_Task : Master_Level;
-- The task executing the master of this task, and the ID of this task's
-- master (unique only among masters currently active within Parent).
--
Index: libgnarl/g-thread.ads
===================================================================
--- libgnarl/g-thread.ads (revision 254579)
+++ libgnarl/g-thread.ads (revision 254580)
@@ -146,4 +146,15 @@
-- Given a low level Id, as returned by Create_Thread, return a Task_Id,
-- so that operations in Ada.Task_Identification can be used.
+ function Make_Independent return Boolean;
+ -- If a procedure loads a shared library containing tasks, and that
+ -- procedure is considered to be a master by the compiler (because it
+ -- contains tasks or class-wide objects that might contain tasks),
+ -- then the tasks in the shared library need to call Make_Independent
+ -- because otherwise they will depend on the procedure that loaded the
+ -- shared library.
+ --
+ -- See System.Tasking.Utilities.Make_Independent in s-tasuti.ads for
+ -- further documentation.
+
end GNAT.Threads;
Index: libgnarl/s-tasini.adb
===================================================================
--- libgnarl/s-tasini.adb (revision 254579)
+++ libgnarl/s-tasini.adb (revision 254580)
@@ -325,8 +325,8 @@
-- of the environment task.
Self_Id := Environment_Task;
- Self_Id.Master_of_Task := Environment_Task_Level;
- Self_Id.Master_Within := Self_Id.Master_of_Task + 1;
+ Self_Id.Master_Of_Task := Environment_Task_Level;
+ Self_Id.Master_Within := Self_Id.Master_Of_Task + 1;
for L in Self_Id.Entry_Calls'Range loop
Self_Id.Entry_Calls (L).Self := Self_Id;
Index: exp_util.adb
===================================================================
--- exp_util.adb (revision 254579)
+++ exp_util.adb (revision 254580)
@@ -4991,7 +4991,7 @@
-- is transformed into
- -- Val : Constrained_Subtype_of_T := Maybe_Modified_Expr;
+ -- Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr;
--
-- Here are the main cases :
--