-- Turn off polling, we do not want ATC polling to take place during tasking
-- operations. It causes infinite loops and other problems.
-with Ada.Unchecked_Deallocation;
-
with Interfaces.C;
with System.Multiprocessors;
with System.Tasking.Debug;
with System.Interrupt_Management;
+with System.OS_Constants;
with System.OS_Primitives;
with System.Task_Info;
package body System.Task_Primitives.Operations is
+ package OSC renames System.OS_Constants;
package SSL renames System.Soft_Links;
use System.Tasking.Debug;
package body Specific is separate;
-- The body of this package is target specific
+ ----------------------------------
+ -- ATCB allocation/deallocation --
+ ----------------------------------
+
+ package body ATCB_Allocation is separate;
+ -- The body of this package is shared across several targets
+
---------------------------------
-- Support for foreign threads --
---------------------------------
TS : aliased timespec;
Result : Interfaces.C.int;
begin
- Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+ Result := clock_gettime (OSC.CLOCK_RT_Ada, TS'Unchecked_Access);
pragma Assert (Result = 0);
return To_Duration (TS);
end Monotonic_Clock;
procedure Enter_Task (Self_ID : Task_Id) is
begin
Self_ID.Common.LL.Thread := thr_self;
-
- Self_ID.Common.LL.LWP := lwp_self;
+ Self_ID.Common.LL.LWP := lwp_self;
Set_Task_Affinity (Self_ID);
-
Specific.Set (Self_ID);
-- We need the above code even if we do direct fetch of Task_Id in Self
-- for the main task on Sun, x86 Solaris and for gcc 2.7.2.
end Enter_Task;
- --------------
- -- New_ATCB --
- --------------
-
- function New_ATCB (Entry_Num : Task_Entry_Index) return Task_Id is
- begin
- return new Ada_Task_Control_Block (Entry_Num);
- end New_ATCB;
-
-------------------
-- Is_Valid_Task --
-------------------
-- task, and the CPU value is not contained within the range of
-- processors for the domain.
- if T.Common.Domain /= null and then
- T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU and then
- (T.Common.Base_CPU not in T.Common.Domain'Range
- or else not T.Common.Domain (T.Common.Base_CPU))
+ if T.Common.Domain /= null
+ and then T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU
+ and then
+ (T.Common.Base_CPU not in T.Common.Domain'Range
+ or else not T.Common.Domain (T.Common.Base_CPU))
then
Succeeded := False;
return;
Opts := THR_DETACHED + THR_BOUND;
end if;
+ -- Note: the use of Unrestricted_Access in the following call is needed
+ -- because otherwise we have an error of getting a access-to-volatile
+ -- value which points to a non-volatile object. But in this case it is
+ -- safe to do this, since we know we have no problems with aliasing and
+ -- Unrestricted_Access bypasses this check.
+
Result :=
thr_create
(System.Null_Address,
Thread_Body_Access (Wrapper),
To_Address (T),
Opts,
- T.Common.LL.Thread'Access);
+ T.Common.LL.Thread'Unrestricted_Access);
Succeeded := Result = 0;
pragma Assert
------------------
procedure Finalize_TCB (T : Task_Id) is
- Result : Interfaces.C.int;
- Tmp : Task_Id := T;
- Is_Self : constant Boolean := T = Self;
-
- procedure Free is new
- Ada.Unchecked_Deallocation (Ada_Task_Control_Block, Task_Id);
+ Result : Interfaces.C.int;
begin
T.Common.LL.Thread := Null_Thread_Id;
Known_Tasks (T.Known_Tasks_Index) := null;
end if;
- Free (Tmp);
-
- if Is_Self then
- Specific.Set (null);
- end if;
+ ATCB_Allocation.Free_ATCB (T);
end Finalize_TCB;
---------------