if CPU /= Unspecified_CPU
and then (CPU < Integer (System.Multiprocessors.CPU_Range'First)
- or else CPU > Integer (System.Multiprocessors.CPU_Range'Last)
- or else CPU > Integer (System.Multiprocessors.Number_Of_CPUs))
+ or else
+ CPU > Integer (System.Multiprocessors.CPU_Range'Last)
+ or else
+ CPU > Integer (System.Multiprocessors.Number_Of_CPUs))
then
raise Tasking_Error with "CPU not in range";
-- Normal CPU affinity
+
else
Base_CPU :=
(if CPU = Unspecified_CPU
Initialization.Defer_Abort (Self_ID);
- -- Loop through the From chain, changing their Master_of_Task
- -- fields, and to find the end of the chain.
+ -- 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;
-- Indicates the reason why this task terminates. Normal corresponds to
-- a task terminating due to completing the last statement of its body,
-- or as a result of waiting on a terminate alternative. If the task
- -- terminates because it is being aborted then Cause will be set to
- -- Abnormal. If the task terminates because of an exception raised by
- -- the execution of its task body, then Cause is set to
- -- Unhandled_Exception.
+ -- terminates because it is being aborted then Cause will be set
+ -- to Abnormal. If the task terminates because of an exception
+ -- raised by the execution of its task body, then Cause is set
+ -- to Unhandled_Exception.
EO : Exception_Occurrence;
-- If the task terminates because of an exception raised by the
-- smaller values resulted in segmentation faults from dynamic
-- stack analysis.
- Big_Overflow_Guard : constant := 16 * 1024;
+ Big_Overflow_Guard : constant := 64 * 1024 + 8 * 1024;
Small_Stack_Limit : constant := 64 * 1024;
-- ??? These three values are experimental, and seem to work on
-- most platforms. They still need to be analyzed further. They
- -- also need documentation, what are they???
+ -- also need documentation, what are they and why does the logic
+ -- differ depending on whether the stack is large or small???
Pattern_Size : Natural :=
- Natural (Self_ID.Common.Compiler_Data.Pri_Stack_Info.Size);
+ Natural (Self_ID.Common.
+ Compiler_Data.Pri_Stack_Info.Size);
-- Size of the pattern
Stack_Base : Address;
begin
Stack_Base := Self_ID.Common.Compiler_Data.Pri_Stack_Info.Base;
+
if Stack_Base = Null_Address then
-- On many platforms, we don't know the real stack base
else Big_Overflow_Guard);
else
-- Reduce by the size of the final guard page
+
Pattern_Size := Pattern_Size - Guard_Page_Size;
end if;
end if;
if Global_Task_Debug_Event_Set then
- Debug.Signal_Debug_Event
- (Debug.Debug_Event_Run, Self_ID);
+ Debug.Signal_Debug_Event (Debug.Debug_Event_Run, Self_ID);
end if;
begin
(Debug.Debug_Event_Abort_Terminated, Self_ID);
end if;
end if;
+
when others =>
-- ??? Using an E : others here causes CD2C11A to fail on Tru64
-- Terminate_Task --
--------------------
- -- Before we allow the thread to exit, we must clean up. This is a
- -- delicate job. We must wake up the task's master, who may immediately try
- -- to deallocate the ATCB out from under the current task WHILE IT IS STILL
- -- EXECUTING.
+ -- Before we allow the thread to exit, we must clean up. This is a delicate
+ -- job. We must wake up the task's master, who may immediately try to
+ -- deallocate the ATCB from the current task WHILE IT IS STILL EXECUTING.
-- To avoid this, the parent task must be blocked up to the latest
-- statement executed. The trouble is that we have another step that we
-- Since GCC cannot allocate stack chunks efficiently without reordering
-- some of the allocations, we have to handle this unexpected situation
- -- here. We should normally never have to call Vulnerable_Complete_Task
- -- here.
+ -- here. Normally we never have to call Vulnerable_Complete_Task here.
if Self_ID.Common.Activator /= null then
Vulnerable_Complete_Task (Self_ID);
if Single_Lock then
Utilities.Independent_Task_Count :=
Utilities.Independent_Task_Count - 1;
+
else
Write_Lock (Environment_Task);
Utilities.Independent_Task_Count :=
pragma Assert (Self_ID.Common.Activator /= null);
- -- Remove dangling reference to Activator, since a task may
- -- outlive its activator.
+ -- Remove dangling reference to Activator, since a task may outlive its
+ -- activator.
Self_ID.Common.Activator := null;
if C.Common.Activator = Self_ID and then C.Master_of_Task = CM then
- pragma Assert (C.Common.State = Unactivated);
-- 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.
+ pragma Assert (C.Common.State = Unactivated);
+
Write_Lock (C);
C.Common.Activator := null;
C.Common.State := Terminated;
declare
Detach_Interrupt_Entries_Index : constant Task_Entry_Index := 1;
-- Corresponds to the entry index of System.Interrupts.
- -- Interrupt_Manager.Detach_Interrupt_Entries.
- -- Be sure to update this value when changing
- -- Interrupt_Manager specs.
+ -- Interrupt_Manager.Detach_Interrupt_Entries. Be sure
+ -- to update this value when changing Interrupt_Manager specs.
type Param_Type is access all Task_Id;