s-tassta.adb (Task_Wrapper): Make it Convention C...
2004-10-04 Olivier Hainque <hainque@act-europe.fr> * s-tassta.adb (Task_Wrapper): Make it Convention C, which makes sense in general and triggers stack alignment adjustment for thread entry points on targets where this is necessary. From-SVN: r88509
This commit is contained in:
parent
71c10a83a6
commit
a8e490b7eb
|
@ -1,3 +1,9 @@
|
||||||
|
2004-10-04 Olivier Hainque <hainque@act-europe.fr>
|
||||||
|
|
||||||
|
* s-tassta.adb (Task_Wrapper): Make it Convention C, which makes sense
|
||||||
|
in general and triggers stack alignment adjustment for thread entry
|
||||||
|
points on targets where this is necessary.
|
||||||
|
|
||||||
2004-10-04 Bernard Banner <banner@gnat.com>
|
2004-10-04 Bernard Banner <banner@gnat.com>
|
||||||
|
|
||||||
PR ada/13897
|
PR ada/13897
|
||||||
|
|
|
@ -141,28 +141,32 @@ package body System.Tasking.Stages is
|
||||||
-- tracing purposes.
|
-- tracing purposes.
|
||||||
|
|
||||||
procedure Task_Wrapper (Self_ID : Task_Id);
|
procedure Task_Wrapper (Self_ID : Task_Id);
|
||||||
-- This is the procedure that is called by the GNULL from the
|
pragma Convention (C, Task_Wrapper);
|
||||||
-- new context when a task is created. It waits for activation
|
-- This is the procedure that is called by the GNULL from the new context
|
||||||
-- and then calls the task body procedure. When the task body
|
-- when a task is created. It waits for activation and then calls the task
|
||||||
-- procedure completes, it terminates the task.
|
-- body procedure. When the task body procedure completes, it terminates
|
||||||
|
-- the task.
|
||||||
|
--
|
||||||
|
-- The Task_Wrapper's address will be provided to the underlying threads
|
||||||
|
-- library as the task entry point. Convention C is what makes most sense
|
||||||
|
-- for that purpose (Export C would make the function globally visible,
|
||||||
|
-- and affect the link name on which GDB depends). This will in addition
|
||||||
|
-- trigger an automatic stack alignment suitable for GCC's assumptions if
|
||||||
|
-- need be.
|
||||||
|
|
||||||
procedure Vulnerable_Complete_Task (Self_ID : Task_Id);
|
procedure Vulnerable_Complete_Task (Self_ID : Task_Id);
|
||||||
-- Complete the calling task.
|
-- Complete the calling task. This procedure must be called with
|
||||||
-- This procedure must be called with abort deferred.
|
-- abort deferred. It should only be called by Complete_Task and
|
||||||
-- It should only be called by Complete_Task and
|
|
||||||
-- Finalizate_Global_Tasks (for the environment task).
|
-- Finalizate_Global_Tasks (for the environment task).
|
||||||
|
|
||||||
procedure Vulnerable_Complete_Master (Self_ID : Task_Id);
|
procedure Vulnerable_Complete_Master (Self_ID : Task_Id);
|
||||||
-- Complete the current master of the calling task.
|
-- Complete the current master of the calling task. This procedure
|
||||||
-- This procedure must be called with abort deferred.
|
-- must be called with abort deferred. It should only be called by
|
||||||
-- It should only be called by Vulnerable_Complete_Task and
|
-- Vulnerable_Complete_Task and Complete_Master.
|
||||||
-- Complete_Master.
|
|
||||||
|
|
||||||
procedure Vulnerable_Complete_Activation (Self_ID : Task_Id);
|
procedure Vulnerable_Complete_Activation (Self_ID : Task_Id);
|
||||||
-- Signal to Self_ID's activator that Self_ID has
|
-- Signal to Self_ID's activator that Self_ID has completed activation.
|
||||||
-- completed activation.
|
-- This procedure must be called with abort deferred.
|
||||||
--
|
|
||||||
-- Call this procedure with abort deferred.
|
|
||||||
|
|
||||||
procedure Abort_Dependents (Self_ID : Task_Id);
|
procedure Abort_Dependents (Self_ID : Task_Id);
|
||||||
-- Abort all the direct dependents of Self at its current master
|
-- Abort all the direct dependents of Self at its current master
|
||||||
|
@ -193,12 +197,11 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
begin
|
begin
|
||||||
C := All_Tasks_List;
|
C := All_Tasks_List;
|
||||||
|
|
||||||
while C /= null loop
|
while C /= null loop
|
||||||
P := C.Common.Parent;
|
P := C.Common.Parent;
|
||||||
|
|
||||||
while P /= null loop
|
while P /= null loop
|
||||||
if P = Self_ID then
|
if P = Self_ID then
|
||||||
|
|
||||||
-- ??? C is supposed to take care of its own dependents, so
|
-- ??? C is supposed to take care of its own dependents, so
|
||||||
-- there should be no need to worry about them. Need to double
|
-- there should be no need to worry about them. Need to double
|
||||||
-- check this.
|
-- check this.
|
||||||
|
@ -277,9 +280,8 @@ package body System.Tasking.Stages is
|
||||||
All_Elaborated : Boolean := True;
|
All_Elaborated : Boolean := True;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
-- If pragma Detect_Blocking is active must be checked whether
|
-- If pragma Detect_Blocking is active, then we must check whether this
|
||||||
-- this potentially blocking operation is called from a
|
-- potentially blocking operation is called from a protected action.
|
||||||
-- protected action.
|
|
||||||
|
|
||||||
if System.Tasking.Detect_Blocking
|
if System.Tasking.Detect_Blocking
|
||||||
and then Self_ID.Common.Protected_Action_Nesting > 0
|
and then Self_ID.Common.Protected_Action_Nesting > 0
|
||||||
|
@ -295,16 +297,15 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
pragma Assert (Self_ID.Common.Wait_Count = 0);
|
pragma Assert (Self_ID.Common.Wait_Count = 0);
|
||||||
|
|
||||||
-- Lock RTS_Lock, to prevent activated tasks
|
-- Lock RTS_Lock, to prevent activated tasks from racing ahead before
|
||||||
-- from racing ahead before we finish activating the chain.
|
-- we finish activating the chain.
|
||||||
|
|
||||||
Lock_RTS;
|
Lock_RTS;
|
||||||
|
|
||||||
-- Check that all task bodies have been elaborated.
|
-- Check that all task bodies have been elaborated
|
||||||
|
|
||||||
C := Chain_Access.T_ID;
|
C := Chain_Access.T_ID;
|
||||||
Last_C := null;
|
Last_C := null;
|
||||||
|
|
||||||
while C /= null loop
|
while C /= null loop
|
||||||
if C.Common.Elaborated /= null
|
if C.Common.Elaborated /= null
|
||||||
and then not C.Common.Elaborated.all
|
and then not C.Common.Elaborated.all
|
||||||
|
@ -330,12 +331,10 @@ package body System.Tasking.Stages is
|
||||||
(Program_Error'Identity, "Some tasks have not been elaborated");
|
(Program_Error'Identity, "Some tasks have not been elaborated");
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
-- Activate all the tasks in the chain.
|
-- Activate all the tasks in the chain. Creation of the thread of
|
||||||
-- Creation of the thread of control was deferred until
|
-- control was deferred until activation. So create it now.
|
||||||
-- activation. So create it now.
|
|
||||||
|
|
||||||
C := Chain_Access.T_ID;
|
C := Chain_Access.T_ID;
|
||||||
|
|
||||||
while C /= null loop
|
while C /= null loop
|
||||||
if C.Common.State /= Terminated then
|
if C.Common.State /= Terminated then
|
||||||
pragma Assert (C.Common.State = Unactivated);
|
pragma Assert (C.Common.State = Unactivated);
|
||||||
|
@ -455,6 +454,7 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
procedure Complete_Activation is
|
procedure Complete_Activation is
|
||||||
Self_ID : constant Task_Id := STPO.Self;
|
Self_ID : constant Task_Id := STPO.Self;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Initialization.Defer_Abort_Nestable (Self_ID);
|
Initialization.Defer_Abort_Nestable (Self_ID);
|
||||||
|
|
||||||
|
@ -484,10 +484,8 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
procedure Complete_Master is
|
procedure Complete_Master is
|
||||||
Self_ID : constant Task_Id := STPO.Self;
|
Self_ID : constant Task_Id := STPO.Self;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
pragma Assert (Self_ID.Deferral_Level > 0);
|
pragma Assert (Self_ID.Deferral_Level > 0);
|
||||||
|
|
||||||
Vulnerable_Complete_Master (Self_ID);
|
Vulnerable_Complete_Master (Self_ID);
|
||||||
end Complete_Master;
|
end Complete_Master;
|
||||||
|
|
||||||
|
@ -499,6 +497,7 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
procedure Complete_Task is
|
procedure Complete_Task is
|
||||||
Self_ID : constant Task_Id := STPO.Self;
|
Self_ID : constant Task_Id := STPO.Self;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
pragma Assert (Self_ID.Deferral_Level > 0);
|
pragma Assert (Self_ID.Deferral_Level > 0);
|
||||||
|
|
||||||
|
@ -570,7 +569,6 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
begin
|
begin
|
||||||
T := New_ATCB (Num_Entries);
|
T := New_ATCB (Num_Entries);
|
||||||
|
|
||||||
exception
|
exception
|
||||||
when others =>
|
when others =>
|
||||||
Initialization.Undefer_Abort_Nestable (Self_ID);
|
Initialization.Undefer_Abort_Nestable (Self_ID);
|
||||||
|
@ -591,8 +589,8 @@ package body System.Tasking.Stages is
|
||||||
if not Self_ID.Callable then
|
if not Self_ID.Callable then
|
||||||
pragma Assert (Self_ID.Pending_ATC_Level = 0);
|
pragma Assert (Self_ID.Pending_ATC_Level = 0);
|
||||||
pragma Assert (Self_ID.Pending_Action);
|
pragma Assert (Self_ID.Pending_Action);
|
||||||
pragma Assert (Chain.T_ID = null
|
pragma Assert
|
||||||
or else Chain.T_ID.Common.State = Unactivated);
|
(Chain.T_ID = null or else Chain.T_ID.Common.State = Unactivated);
|
||||||
|
|
||||||
Unlock (Self_ID);
|
Unlock (Self_ID);
|
||||||
Unlock_RTS;
|
Unlock_RTS;
|
||||||
|
@ -630,16 +628,14 @@ package body System.Tasking.Stages is
|
||||||
Len := 1;
|
Len := 1;
|
||||||
T.Common.Task_Image (1) := Task_Image (Task_Image'First);
|
T.Common.Task_Image (1) := Task_Image (Task_Image'First);
|
||||||
|
|
||||||
|
-- Remove unwanted blank space generated by 'Image
|
||||||
|
|
||||||
for J in Task_Image'First + 1 .. Task_Image'Last loop
|
for J in Task_Image'First + 1 .. Task_Image'Last loop
|
||||||
|
|
||||||
-- Remove unwanted blank space generated by 'Image
|
|
||||||
|
|
||||||
if Task_Image (J) /= ' '
|
if Task_Image (J) /= ' '
|
||||||
or else Task_Image (J - 1) /= '('
|
or else Task_Image (J - 1) /= '('
|
||||||
then
|
then
|
||||||
Len := Len + 1;
|
Len := Len + 1;
|
||||||
T.Common.Task_Image (Len) := Task_Image (J);
|
T.Common.Task_Image (Len) := Task_Image (J);
|
||||||
|
|
||||||
exit when Len = T.Common.Task_Image'Last;
|
exit when Len = T.Common.Task_Image'Last;
|
||||||
end if;
|
end if;
|
||||||
end loop;
|
end loop;
|
||||||
|
@ -680,7 +676,6 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
procedure Enter_Master is
|
procedure Enter_Master is
|
||||||
Self_ID : constant Task_Id := STPO.Self;
|
Self_ID : constant Task_Id := STPO.Self;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Self_ID.Master_Within := Self_ID.Master_Within + 1;
|
Self_ID.Master_Within := Self_ID.Master_Within + 1;
|
||||||
end Enter_Master;
|
end Enter_Master;
|
||||||
|
@ -689,7 +684,7 @@ package body System.Tasking.Stages is
|
||||||
-- Expunge_Unactivated_Tasks --
|
-- Expunge_Unactivated_Tasks --
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
-- See procedure Close_Entries for the general case.
|
-- See procedure Close_Entries for the general case
|
||||||
|
|
||||||
procedure Expunge_Unactivated_Tasks (Chain : in out Activation_Chain) is
|
procedure Expunge_Unactivated_Tasks (Chain : in out Activation_Chain) is
|
||||||
Self_ID : constant Task_Id := STPO.Self;
|
Self_ID : constant Task_Id := STPO.Self;
|
||||||
|
@ -707,10 +702,9 @@ package body System.Tasking.Stages is
|
||||||
-- Experimentation has shown that abort is sometimes (but not
|
-- Experimentation has shown that abort is sometimes (but not
|
||||||
-- always) already deferred when this is called.
|
-- always) already deferred when this is called.
|
||||||
|
|
||||||
-- That may indicate an error. Find out what is going on.
|
-- That may indicate an error. Find out what is going on
|
||||||
|
|
||||||
C := Chain.T_ID;
|
C := Chain.T_ID;
|
||||||
|
|
||||||
while C /= null loop
|
while C /= null loop
|
||||||
pragma Assert (C.Common.State = Unactivated);
|
pragma Assert (C.Common.State = Unactivated);
|
||||||
|
|
||||||
|
@ -748,7 +742,7 @@ package body System.Tasking.Stages is
|
||||||
-- objects does anything with signals or the timer server, since
|
-- objects does anything with signals or the timer server, since
|
||||||
-- by that time those servers have terminated.
|
-- by that time those servers have terminated.
|
||||||
|
|
||||||
-- It is hard to see how that would occur.
|
-- It is hard to see how that would occur
|
||||||
|
|
||||||
-- However, a better solution might be to do all this finalization
|
-- However, a better solution might be to do all this finalization
|
||||||
-- using the global finalization chain.
|
-- using the global finalization chain.
|
||||||
|
@ -896,9 +890,11 @@ package body System.Tasking.Stages is
|
||||||
use type SSE.Storage_Offset;
|
use type SSE.Storage_Offset;
|
||||||
use System.Standard_Library;
|
use System.Standard_Library;
|
||||||
|
|
||||||
Secondary_Stack : aliased SSE.Storage_Array
|
Secondary_Stack :
|
||||||
(1 .. Self_ID.Common.Compiler_Data.Pri_Stack_Info.Size *
|
aliased SSE.Storage_Array
|
||||||
SSE.Storage_Offset (Parameters.Sec_Stack_Ratio) / 100);
|
(1 .. Self_ID.Common.Compiler_Data.Pri_Stack_Info.Size *
|
||||||
|
SSE.Storage_Offset (Parameters.Sec_Stack_Ratio) / 100);
|
||||||
|
|
||||||
Secondary_Stack_Address : System.Address := Secondary_Stack'Address;
|
Secondary_Stack_Address : System.Address := Secondary_Stack'Address;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -1041,14 +1037,13 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
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
|
-- Check if the current task is an independent task If so, decrement
|
||||||
-- If so, decrement the Independent_Task_Count value.
|
-- the Independent_Task_Count value.
|
||||||
|
|
||||||
if Master_of_Task = 2 then
|
if Master_of_Task = 2 then
|
||||||
if Single_Lock then
|
if Single_Lock then
|
||||||
Utilities.Independent_Task_Count :=
|
Utilities.Independent_Task_Count :=
|
||||||
Utilities.Independent_Task_Count - 1;
|
Utilities.Independent_Task_Count - 1;
|
||||||
|
|
||||||
else
|
else
|
||||||
Write_Lock (Environment_Task);
|
Write_Lock (Environment_Task);
|
||||||
Utilities.Independent_Task_Count :=
|
Utilities.Independent_Task_Count :=
|
||||||
|
@ -1072,8 +1067,7 @@ package body System.Tasking.Stages is
|
||||||
SSL.Destroy_TSD (Self_ID.Common.Compiler_Data);
|
SSL.Destroy_TSD (Self_ID.Common.Compiler_Data);
|
||||||
Initialization.Final_Task_Unlock (Self_ID);
|
Initialization.Final_Task_Unlock (Self_ID);
|
||||||
|
|
||||||
-- WARNING
|
-- WARNING: past this point, this thread must assume that the ATCB
|
||||||
-- past this point, this thread must assume that the ATCB
|
|
||||||
-- has been deallocated. It should not be accessed again.
|
-- has been deallocated. It should not be accessed again.
|
||||||
|
|
||||||
if Master_of_Task > 0 then
|
if Master_of_Task > 0 then
|
||||||
|
@ -1243,8 +1237,8 @@ package body System.Tasking.Stages is
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
Write_Lock (Self_ID);
|
Write_Lock (Self_ID);
|
||||||
C := All_Tasks_List;
|
|
||||||
|
|
||||||
|
C := All_Tasks_List;
|
||||||
while C /= null loop
|
while C /= null loop
|
||||||
if C.Common.Activator = Self_ID then
|
if C.Common.Activator = Self_ID then
|
||||||
return False;
|
return False;
|
||||||
|
@ -1290,8 +1284,8 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
Lock_RTS;
|
Lock_RTS;
|
||||||
Write_Lock (Self_ID);
|
Write_Lock (Self_ID);
|
||||||
C := All_Tasks_List;
|
|
||||||
|
|
||||||
|
C := All_Tasks_List;
|
||||||
while C /= null loop
|
while C /= null loop
|
||||||
if C.Common.Activator = Self_ID then
|
if C.Common.Activator = Self_ID then
|
||||||
pragma Assert (C.Common.State = Unactivated);
|
pragma Assert (C.Common.State = Unactivated);
|
||||||
|
@ -1402,8 +1396,8 @@ package body System.Tasking.Stages is
|
||||||
pragma Assert (Self_ID.Common.Wait_Count = 0);
|
pragma Assert (Self_ID.Common.Wait_Count = 0);
|
||||||
|
|
||||||
Write_Lock (Self_ID);
|
Write_Lock (Self_ID);
|
||||||
C := All_Tasks_List;
|
|
||||||
|
|
||||||
|
C := All_Tasks_List;
|
||||||
while C /= null loop
|
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);
|
Write_Lock (C);
|
||||||
|
@ -1428,7 +1422,7 @@ package body System.Tasking.Stages is
|
||||||
Unlock_RTS;
|
Unlock_RTS;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
-- Wait for all counted tasks to finish terminating themselves.
|
-- Wait for all counted tasks to finish terminating themselves
|
||||||
|
|
||||||
Write_Lock (Self_ID);
|
Write_Lock (Self_ID);
|
||||||
|
|
||||||
|
@ -1457,7 +1451,6 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
C := All_Tasks_List;
|
C := All_Tasks_List;
|
||||||
P := null;
|
P := null;
|
||||||
|
|
||||||
while C /= null loop
|
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
|
||||||
if P /= null then
|
if P /= null then
|
||||||
|
@ -1479,7 +1472,7 @@ package body System.Tasking.Stages is
|
||||||
|
|
||||||
Unlock_RTS;
|
Unlock_RTS;
|
||||||
|
|
||||||
-- Free all the ATCBs on the list To_Be_Freed.
|
-- Free all the ATCBs on the list To_Be_Freed
|
||||||
|
|
||||||
-- The ATCBs in the list are no longer in All_Tasks_List, and after
|
-- The ATCBs in the list are no longer in All_Tasks_List, and after
|
||||||
-- any interrupt entries are detached from them they should no longer
|
-- any interrupt entries are detached from them they should no longer
|
||||||
|
@ -1666,6 +1659,8 @@ package body System.Tasking.Stages is
|
||||||
System.Task_Primitives.Operations.Finalize_TCB (T);
|
System.Task_Primitives.Operations.Finalize_TCB (T);
|
||||||
end Vulnerable_Free_Task;
|
end Vulnerable_Free_Task;
|
||||||
|
|
||||||
|
-- Package elaboration code
|
||||||
|
|
||||||
begin
|
begin
|
||||||
-- Establish the Adafinal softlink.
|
-- Establish the Adafinal softlink.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue