From e9906cbf174623cc53b32ad2a0f6d603d6f975b5 Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Mon, 3 Jan 2005 16:42:23 +0100 Subject: [PATCH] s-tasini.ads, [...] (Undefer_Abortion): Handle case of Self_Id.Deferral_Level = 0. * s-tasini.ads, s-tasini.adb (Undefer_Abortion): Handle case of Self_Id.Deferral_Level = 0. (Do_Pending_Action): Move this function to the spec. * s-tasren.adb (Selective_Wait [Terminate_Selected]): Call Do_Pending_Action explicitely when needed, in case we're using No_Abort restrictions. * s-tassta.adb (Create_Task): If Abort is not allowed, reset the deferral level since it will not get changed by the generated code. Keeping a default value of 1 would prevent some operations (e.g. select or delay) to proceed successfully. From-SVN: r92851 --- gcc/ada/s-tasini.adb | 22 +++++++++++++++++----- gcc/ada/s-tasini.ads | 8 ++++++++ gcc/ada/s-tasren.adb | 17 +++++++++++++++-- gcc/ada/s-tassta.adb | 13 +++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/gcc/ada/s-tasini.adb b/gcc/ada/s-tasini.adb index 871b2d035d57..c2bee15dc0f8 100644 --- a/gcc/ada/s-tasini.adb +++ b/gcc/ada/s-tasini.adb @@ -128,10 +128,6 @@ package body System.Tasking.Initialization is -- Local Subprograms -- ------------------------ - procedure Do_Pending_Action (Self_ID : Task_Id); - -- This is introduced to allow more efficient - -- in-line expansion of Undefer_Abort. - ---------------------------- -- Tasking Initialization -- ---------------------------- @@ -777,8 +773,24 @@ package body System.Tasking.Initialization is end if; Self_ID := STPO.Self; - pragma Assert (Self_ID.Deferral_Level > 0); + if Self_ID.Deferral_Level = 0 then + + -- In case there are different views on whether Abort is supported + -- between the expander and the run time, we may end up with + -- Self_ID.Deferral_Level being equal to zero, when called from + -- the procedure created by the expander that corresponds to a + -- task body. + + -- In this case, there's nothing to be done + + -- See related code in System.Tasking.Stages.Create_Task resetting + -- Deferral_Level when System.Restrictions.Abort_Allowed is False. + + return; + end if; + + pragma Assert (Self_ID.Deferral_Level > 0); Self_ID.Deferral_Level := Self_ID.Deferral_Level - 1; if Self_ID.Deferral_Level = 0 then diff --git a/gcc/ada/s-tasini.ads b/gcc/ada/s-tasini.ads index ca58df61e59e..62bfc0c3463b 100644 --- a/gcc/ada/s-tasini.ads +++ b/gcc/ada/s-tasini.ads @@ -131,6 +131,14 @@ package System.Tasking.Initialization is -- ????? -- Try to phase out all uses of the above versions. + procedure Do_Pending_Action (Self_ID : Task_Id); + -- Only call with no locks, and when Self_ID.Pending_Action = True + -- Perform necessary pending actions (e.g. abortion, priority change). + -- This procedure is usually called when needed as a result of + -- calling Undefer_Abort, although in the case of e.g. No_Abort + -- restriction, it can be necessary to force execution of pending + -- actions. + function Check_Abort_Status return Integer; -- Returns Boolean'Pos (True) iff abort signal should raise -- Standard.Abort_Signal. Only used by IRIX currently. diff --git a/gcc/ada/s-tasren.adb b/gcc/ada/s-tasren.adb index 5763272ce247..9002eeeb0313 100644 --- a/gcc/ada/s-tasren.adb +++ b/gcc/ada/s-tasren.adb @@ -55,6 +55,7 @@ with System.Tasking.Initialization; -- used for Defer_Abort -- Undefer_Abort -- Poll_Base_Priority_Change +-- Do_Pending_Action with System.Tasking.Queuing; -- used for Enqueue @@ -972,8 +973,20 @@ package body System.Tasking.Rendezvous is pragma Assert (Self_Id.Pending_ATC_Level = 0); pragma Assert (Self_Id.Awake_Count = 0); - -- Trust that it is OK to fall through. - null; + STPO.Unlock (Self_Id); + + if Single_Lock then + Unlock_RTS; + end if; + + Index := Self_Id.Chosen_Index; + Initialization.Undefer_Abort_Nestable (Self_Id); + + if Self_Id.Pending_Action then + Initialization.Do_Pending_Action (Self_Id); + end if; + + return; else -- Self_Id.Common.Call and Self_Id.Chosen_Index diff --git a/gcc/ada/s-tassta.adb b/gcc/ada/s-tassta.adb index 784dade88d81..e09b6a56459f 100644 --- a/gcc/ada/s-tassta.adb +++ b/gcc/ada/s-tassta.adb @@ -103,6 +103,9 @@ with System.Secondary_Stack; with System.Storage_Elements; -- used for Storage_Array +with System.Restrictions; +-- used for Abort_Allowed + with System.Standard_Library; -- used for Exception_Trace @@ -614,6 +617,16 @@ package body System.Tasking.Stages is (Storage_Error'Identity, "Failed to initialize task"); end if; + if not System.Restrictions.Abort_Allowed then + + -- If Abort is not allowed, reset the deferral level since it will + -- not get changed by the generated code. Keeping a default value + -- of one would prevent some operations (e.g. select or delay) to + -- proceed successfully. + + T.Deferral_Level := 0; + end if; + T.Master_of_Task := Master; T.Master_Within := T.Master_of_Task + 1;