OSDN Git Service

* gimplify.c (gimplify_type_sizes) [POINTER_TYPE, REFERENCE_TYPE]:
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-taprop-vxworks.adb
index f83fc02..186e8c2 100644 (file)
@@ -1,12 +1,12 @@
 ------------------------------------------------------------------------------
 --                                                                          --
---                 GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS              --
+--                  GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                --
 --                                                                          --
 --     S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S    --
 --                                                                          --
 --                                  B o d y                                 --
 --                                                                          --
---         Copyright (C) 1992-2004, Free Software Foundation, Inc.          --
+--         Copyright (C) 1992-2006, Free Software Foundation, Inc.          --
 --                                                                          --
 -- GNARL is free software; you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -16,8 +16,8 @@
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
 -- Public License  distributed with GNARL; see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
+-- Boston, MA 02110-1301, USA.                                              --
 --                                                                          --
 -- As a special exception,  if other files  instantiate  generics from this --
 -- unit, or you link  this unit with other files  to produce an executable, --
@@ -49,40 +49,29 @@ with System.Interrupt_Management;
 --           Signal_ID
 --           Initialize_Interrupts
 
-with System.Soft_Links;
---  used for Defer/Undefer_Abort
-
---  Note that we do not use System.Tasking.Initialization directly since
---  this is a higher level package that we shouldn't depend on. For example
---  when using the restricted run time, it is replaced by
---  System.Tasking.Restricted.Initialization
-
-with System.OS_Interface;
---  used for various type, constant, and operations
-
-with System.Parameters;
---  used for Size_Type
+with Interfaces.C;
 
-with System.Tasking;
---  used for Ada_Task_Control_Block
---           Task_Id
---           ATCB components and types
+with System.Soft_Links;
+--  used for Abort_Defer/Undefer
 
-with Interfaces.C;
+--  We use System.Soft_Links instead of System.Tasking.Initialization
+--  because the later is a higher level package that we shouldn't depend on.
+--  For example when using the restricted run time, it is replaced by
+--  System.Tasking.Restricted.Stages.
 
 with Unchecked_Conversion;
 with Unchecked_Deallocation;
 
 package body System.Task_Primitives.Operations is
 
+   package SSL renames System.Soft_Links;
+
    use System.Tasking.Debug;
    use System.Tasking;
    use System.OS_Interface;
    use System.Parameters;
    use type Interfaces.C.int;
 
-   package SSL renames System.Soft_Links;
-
    subtype int is System.OS_Interface.int;
 
    Relative : constant := 0;
@@ -91,30 +80,21 @@ package body System.Task_Primitives.Operations is
    -- Local Data --
    ----------------
 
-   --  The followings are logically constants, but need to be initialized
-   --  at run time.
+   --  The followings are logically constants, but need to be initialized at
+   --  run time.
 
    Single_RTS_Lock : aliased RTS_Lock;
-   --  This is a lock to allow only one thread of control in the RTS at
-   --  time; it is used to execute in mutual exclusion from all other tasks.
+   --  This is a lock to allow only one thread of control in the RTS at a
+   --  time; it is used to execute in mutual exclusion from all other tasks.
    --  Used mainly in Single_Lock mode, but also to protect All_Tasks_List
 
-   ATCB_Key : aliased System.Address := System.Null_Address;
-   --  Key used to find the Ada Task_Id associated with a thread
-
-   ATCB_Key_Addr : System.Address := ATCB_Key'Address;
-   pragma Export (Ada, ATCB_Key_Addr, "__gnat_ATCB_key_addr");
-   --  Exported to support the temporary AE653 task registration
-   --  implementation. This mechanism is used to minimize impact on other
-   --  targets.
-
    Environment_Task_Id : Task_Id;
-   --  A variable to hold Task_Id for the environment task.
+   --  A variable to hold Task_Id for the environment task
 
    Unblocked_Signal_Mask : aliased sigset_t;
    --  The set of signals that should unblocked in all tasks
 
-   --  The followings are internal configuration constants needed.
+   --  The followings are internal configuration constants needed
 
    Time_Slice_Val : Integer;
    pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
@@ -125,13 +105,10 @@ package body System.Task_Primitives.Operations is
    Dispatching_Policy : Character;
    pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
 
-   FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
-   --  Indicates whether FIFO_Within_Priorities is set.
-
    Mutex_Protocol : Priority_Type;
 
    Foreign_Task_Elaborated : aliased Boolean := True;
-   --  Used to identified fake tasks (i.e., non-Ada Threads).
+   --  Used to identified fake tasks (i.e., non-Ada Threads)
 
    --------------------
    -- Local Packages --
@@ -139,29 +116,37 @@ package body System.Task_Primitives.Operations is
 
    package Specific is
 
+      procedure Initialize;
+      pragma Inline (Initialize);
+      --  Initialize task specific data
+
       function Is_Valid_Task return Boolean;
       pragma Inline (Is_Valid_Task);
       --  Does executing thread have a TCB?
 
       procedure Set (Self_Id : Task_Id);
       pragma Inline (Set);
-      --  Set the self id for the current task.
+      --  Set the self id for the current task
+
+      procedure Delete;
+      pragma Inline (Delete);
+      --  Delete the task specific data associated with the current task
 
       function Self return Task_Id;
       pragma Inline (Self);
-      --  Return a pointer to the Ada Task Control Block of the calling task.
+      --  Return a pointer to the Ada Task Control Block of the calling task
 
    end Specific;
 
    package body Specific is separate;
-   --  The body of this package is target specific.
+   --  The body of this package is target specific
 
    ---------------------------------
    -- Support for foreign threads --
    ---------------------------------
 
    function Register_Foreign_Thread (Thread : Thread_Id) return Task_Id;
-   --  Allocate and Initialize a new ATCB for the current Thread.
+   --  Allocate and Initialize a new ATCB for the current Thread
 
    function Register_Foreign_Thread
      (Thread : Thread_Id) return Task_Id is separate;
@@ -171,7 +156,7 @@ package body System.Task_Primitives.Operations is
    -----------------------
 
    procedure Abort_Handler (signo : Signal);
-   --  Handler for the abort (SIGABRT) signal to handle asynchronous abortion.
+   --  Handler for the abort (SIGABRT) signal to handle asynchronous abort
 
    procedure Install_Signal_Handlers;
    --  Install the default signal handlers for the current task
@@ -298,7 +283,6 @@ package body System.Task_Primitives.Operations is
 
    procedure Finalize_Lock (L : access Lock) is
       Result : int;
-
    begin
       Result := semDelete (L.Mutex);
       pragma Assert (Result = 0);
@@ -306,7 +290,6 @@ package body System.Task_Primitives.Operations is
 
    procedure Finalize_Lock (L : access RTS_Lock) is
       Result : int;
-
    begin
       Result := semDelete (L.Mutex);
       pragma Assert (Result = 0);
@@ -318,7 +301,6 @@ package body System.Task_Primitives.Operations is
 
    procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
       Result : int;
-
    begin
       if L.Protocol = Prio_Protect
         and then int (Self.Common.Current_Priority) > L.Prio_Ceiling
@@ -338,7 +320,6 @@ package body System.Task_Primitives.Operations is
       Global_Lock : Boolean := False)
    is
       Result : int;
-
    begin
       if not Single_Lock or else Global_Lock then
          Result := semTake (L.Mutex, WAIT_FOREVER);
@@ -348,7 +329,6 @@ package body System.Task_Primitives.Operations is
 
    procedure Write_Lock (T : Task_Id) is
       Result : int;
-
    begin
       if not Single_Lock then
          Result := semTake (T.Common.LL.L.Mutex, WAIT_FOREVER);
@@ -370,8 +350,7 @@ package body System.Task_Primitives.Operations is
    ------------
 
    procedure Unlock (L : access Lock) is
-      Result  : int;
-
+      Result : int;
    begin
       Result := semGive (L.Mutex);
       pragma Assert (Result = 0);
@@ -379,7 +358,6 @@ package body System.Task_Primitives.Operations is
 
    procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
       Result : int;
-
    begin
       if not Single_Lock or else Global_Lock then
          Result := semGive (L.Mutex);
@@ -389,7 +367,6 @@ package body System.Task_Primitives.Operations is
 
    procedure Unlock (T : Task_Id) is
       Result : int;
-
    begin
       if not Single_Lock then
          Result := semGive (T.Common.LL.L.Mutex);
@@ -409,7 +386,8 @@ package body System.Task_Primitives.Operations is
    begin
       pragma Assert (Self_ID = Self);
 
-      --  Release the mutex before sleeping.
+      --  Release the mutex before sleeping
+
       if Single_Lock then
          Result := semGive (Single_RTS_Lock.Mutex);
       else
@@ -418,15 +396,16 @@ package body System.Task_Primitives.Operations is
 
       pragma Assert (Result = 0);
 
-      --  Perform a blocking operation to take the CV semaphore.
-      --  Note that a blocking operation in VxWorks will reenable
-      --  task scheduling. When we are no longer blocked and control
-      --  is returned, task scheduling will again be disabled.
+      --  Perform a blocking operation to take the CV semaphore. Note that a
+      --  blocking operation in VxWorks will reenable task scheduling. When we
+      --  are no longer blocked and control is returned, task scheduling will
+      --  again be disabled.
 
       Result := semTake (Self_ID.Common.LL.CV, WAIT_FOREVER);
       pragma Assert (Result = 0);
 
-      --  Take the mutex back.
+      --  Take the mutex back
+
       if Single_Lock then
          Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
       else
@@ -440,9 +419,8 @@ package body System.Task_Primitives.Operations is
    -- Timed_Sleep --
    -----------------
 
-   --  This is for use within the run-time system, so abort is
-   --  assumed to be already deferred, and the caller should be
-   --  holding its own ATCB lock.
+   --  This is for use within the run-time system, so abort is assumed to be
+   --  already deferred, and the caller should be holding its own ATCB lock.
 
    procedure Timed_Sleep
      (Self_ID  : Task_Id;
@@ -467,9 +445,9 @@ package body System.Task_Primitives.Operations is
       if Mode = Relative then
          Absolute := Orig + Time;
 
-         --  Systematically add one since the first tick will delay
-         --  *at most* 1 / Rate_Duration seconds, so we need to add one to
-         --  be on the safe side.
+         --  Systematically add one since the first tick will delay *at most*
+         --  1 / Rate_Duration seconds, so we need to add one to be on the
+         --  safe side.
 
          Ticks := To_Clock_Ticks (Time);
 
@@ -484,7 +462,8 @@ package body System.Task_Primitives.Operations is
 
       if Ticks > 0 then
          loop
-            --  Release the mutex before sleeping.
+            --  Release the mutex before sleeping
+
             if Single_Lock then
                Result := semGive (Single_RTS_Lock.Mutex);
             else
@@ -493,14 +472,15 @@ package body System.Task_Primitives.Operations is
 
             pragma Assert (Result = 0);
 
-            --  Perform a blocking operation to take the CV semaphore.
-            --  Note that a blocking operation in VxWorks will reenable
-            --  task scheduling. When we are no longer blocked and control
-            --  is returned, task scheduling will again be disabled.
+            --  Perform a blocking operation to take the CV semaphore. Note
+            --  that a blocking operation in VxWorks will reenable task
+            --  scheduling. When we are no longer blocked and control is
+            --  returned, task scheduling will again be disabled.
 
             Result := semTake (Self_ID.Common.LL.CV, Ticks);
 
             if Result = 0 then
+
                --  Somebody may have called Wakeup for us
 
                Wakeup := True;
@@ -508,10 +488,11 @@ package body System.Task_Primitives.Operations is
             else
                if errno /= S_objLib_OBJ_TIMEOUT then
                   Wakeup := True;
+
                else
-                  --  If Ticks = int'last, it was most probably truncated
-                  --  so let's make another round after recomputing Ticks
-                  --  from the the absolute time.
+                  --  If Ticks = int'last, it was most probably truncated so
+                  --  let's make another round after recomputing Ticks from
+                  --  the the absolute time.
 
                   if Ticks /= int'Last then
                      Timedout := True;
@@ -525,7 +506,8 @@ package body System.Task_Primitives.Operations is
                end if;
             end if;
 
-            --  Take the mutex back.
+            --  Take the mutex back
+
             if Single_Lock then
                Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
             else
@@ -540,7 +522,8 @@ package body System.Task_Primitives.Operations is
       else
          Timedout := True;
 
-         --  Should never hold a lock while yielding.
+         --  Should never hold a lock while yielding
+
          if Single_Lock then
             Result := semGive (Single_RTS_Lock.Mutex);
             taskDelay (0);
@@ -558,13 +541,13 @@ package body System.Task_Primitives.Operations is
    -- Timed_Delay --
    -----------------
 
-   --  This is for use in implementing delay statements, so
-   --  we assume the caller is holding no locks.
+   --  This is for use in implementing delay statements, so we assume the
+   --  caller is holding no locks.
 
    procedure Timed_Delay
-     (Self_ID  : Task_Id;
-      Time     : Duration;
-      Mode     : ST.Delay_Modes)
+     (Self_ID : Task_Id;
+      Time    : Duration;
+      Mode    : ST.Delay_Modes)
    is
       Orig     : constant Duration := Monotonic_Clock;
       Absolute : Duration;
@@ -574,17 +557,14 @@ package body System.Task_Primitives.Operations is
       Aborted  : Boolean := False;
 
    begin
-      SSL.Abort_Defer.all;
-
       if Mode = Relative then
          Absolute := Orig + Time;
          Ticks    := To_Clock_Ticks (Time);
 
          if Ticks > 0 and then Ticks < int'Last then
 
-            --  The first tick will delay anytime between 0 and
-            --  1 / sysClkRateGet seconds, so we need to add one to
-            --  be on the safe side.
+            --  First tick will delay anytime between 0 and 1 / sysClkRateGet
+            --  seconds, so we need to add one to be on the safe side.
 
             Ticks := Ticks + 1;
          end if;
@@ -595,7 +575,9 @@ package body System.Task_Primitives.Operations is
       end if;
 
       if Ticks > 0 then
-         --  Modifying State and Pending_Priority_Change, locking the TCB.
+
+         --  Modifying State and Pending_Priority_Change, locking the TCB
+
          if Single_Lock then
             Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
          else
@@ -630,6 +612,7 @@ package body System.Task_Primitives.Operations is
             Result := semTake (Self_ID.Common.LL.CV, Ticks);
 
             if Result /= 0 then
+
                --  If Ticks = int'last, it was most probably truncated
                --  so let's make another round after recomputing Ticks
                --  from the the absolute time.
@@ -646,7 +629,7 @@ package body System.Task_Primitives.Operations is
             end if;
 
             --  Take back the lock after having slept, to protect further
-            --  access to Self_ID
+            --  access to Self_ID.
 
             if Single_Lock then
                Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
@@ -670,8 +653,6 @@ package body System.Task_Primitives.Operations is
       else
          taskDelay (0);
       end if;
-
-      SSL.Abort_Undefer.all;
    end Timed_Delay;
 
    ---------------------
@@ -746,9 +727,10 @@ package body System.Task_Primitives.Operations is
           (T.Common.LL.Thread, To_VxWorks_Priority (int (Prio)));
       pragma Assert (Result = 0);
 
-      if FIFO_Within_Priorities then
+      if Dispatching_Policy = 'F' then
 
          --  Annex D requirement [RM D.2.2 par. 9]:
+
          --    If the task drops its priority due to the loss of inherited
          --    priority, it is added at the head of the ready queue for its
          --    new active priority.
@@ -794,7 +776,7 @@ package body System.Task_Primitives.Operations is
    procedure Enter_Task (Self_ID : Task_Id) is
       procedure Init_Float;
       pragma Import (C, Init_Float, "__gnat_init_float");
-      --  Properly initializes the FPU for PPC/MIPS systems.
+      --  Properly initializes the FPU for PPC/MIPS systems
 
    begin
       Self_ID.Common.LL.Thread := taskIdSelf;
@@ -802,7 +784,8 @@ package body System.Task_Primitives.Operations is
 
       Init_Float;
 
-      --  Install the signal handlers.
+      --  Install the signal handlers
+
       --  This is called for each task since there is no signal inheritance
       --  between VxWorks tasks.
 
@@ -882,38 +865,26 @@ package body System.Task_Primitives.Operations is
    is
       Adjusted_Stack_Size : size_t;
    begin
-      if Stack_Size = Unspecified_Size then
-         Adjusted_Stack_Size := size_t (Default_Stack_Size);
+      --  Ask for four extra bytes of stack space so that the ATCB pointer can
+      --  be stored below the stack limit, plus extra space for the frame of
+      --  Task_Wrapper. This is so the user gets the amount of stack requested
+      --  exclusive of the needs.
 
-      elsif Stack_Size < Minimum_Stack_Size then
-         Adjusted_Stack_Size := size_t (Minimum_Stack_Size);
+      --  We also have to allocate n more bytes for the task name storage and
+      --  enough space for the Wind Task Control Block which is around 0x778
+      --  bytes. VxWorks also seems to carve out additional space, so use 2048
+      --  as a nice round number. We might want to increment to the nearest
+      --  page size in case we ever support VxVMI.
 
-      else
-         Adjusted_Stack_Size := size_t (Stack_Size);
-      end if;
+      --  ??? - we should come back and visit this so we can set the task name
+      --        to something appropriate.
 
-      --  Ask for 4 extra bytes of stack space so that the ATCB
-      --  pointer can be stored below the stack limit, plus extra
-      --  space for the frame of Task_Wrapper.  This is so the user
-      --  gets the amount of stack requested exclusive of the needs
-      --  of the runtime.
-      --
-      --  We also have to allocate n more bytes for the task name
-      --  storage and enough space for the Wind Task Control Block
-      --  which is around 0x778 bytes.  VxWorks also seems to carve out
-      --  additional space, so use 2048 as a nice round number.
-      --  We might want to increment to the nearest page size in
-      --  case we ever support VxVMI.
-      --
-      --  XXX - we should come back and visit this so we can
-      --        set the task name to something appropriate.
-
-      Adjusted_Stack_Size := Adjusted_Stack_Size + 2048;
+      Adjusted_Stack_Size := size_t (Stack_Size) + 2048;
 
       --  Since the initial signal mask of a thread is inherited from the
-      --  creator, and the Environment task has all its signals masked, we
-      --  do not need to manipulate caller's signal mask at this point.
-      --  All tasks in RTS will have All_Tasks_Mask initially.
+      --  creator, and the Environment task has all its signals masked, we do
+      --  not need to manipulate caller's signal mask at this point. All tasks
+      --  in RTS will have All_Tasks_Mask initially.
 
       if T.Common.Task_Image_Len = 0 then
          T.Common.LL.Thread := taskSpawn
@@ -926,6 +897,7 @@ package body System.Task_Primitives.Operations is
       else
          declare
             Name : aliased String (1 .. T.Common.Task_Image_Len + 1);
+
          begin
             Name (1 .. Name'Last - 1) :=
               T.Common.Task_Image (1 .. T.Common.Task_Image_Len);
@@ -981,8 +953,7 @@ package body System.Task_Primitives.Operations is
       Free (Tmp);
 
       if Is_Self then
-         Result := taskVarDelete (taskIdSelf, ATCB_Key'Access);
-         pragma Assert (Result /= ERROR);
+         Specific.Delete;
       end if;
    end Finalize_TCB;
 
@@ -1001,14 +972,171 @@ package body System.Task_Primitives.Operations is
 
    procedure Abort_Task (T : Task_Id) is
       Result : int;
-
    begin
       Result := kill (T.Common.LL.Thread,
-        Signal (Interrupt_Management.Abort_Task_Signal));
+                      Signal (Interrupt_Management.Abort_Task_Signal));
       pragma Assert (Result = 0);
    end Abort_Task;
 
    ----------------
+   -- Initialize --
+   ----------------
+
+   procedure Initialize (S : in out Suspension_Object) is
+   begin
+      --  Initialize internal state. It is always initialized to False (ARM
+      --  D.10 par. 6).
+
+      S.State := False;
+      S.Waiting := False;
+
+      --  Initialize internal mutex
+
+      --  Use simpler binary semaphore instead of VxWorks
+      --  mutual exclusion semaphore, because we don't need
+      --  the fancier semantics and their overhead.
+
+      S.L := semBCreate (SEM_Q_FIFO, SEM_FULL);
+
+      --  Initialize internal condition variable
+
+      S.CV := semBCreate (SEM_Q_FIFO, SEM_EMPTY);
+   end Initialize;
+
+   --------------
+   -- Finalize --
+   --------------
+
+   procedure Finalize (S : in out Suspension_Object) is
+      Result : STATUS;
+   begin
+      --  Destroy internal mutex
+
+      Result := semDelete (S.L);
+      pragma Assert (Result = OK);
+
+      --  Destroy internal condition variable
+
+      Result := semDelete (S.CV);
+      pragma Assert (Result = OK);
+   end Finalize;
+
+   -------------------
+   -- Current_State --
+   -------------------
+
+   function Current_State (S : Suspension_Object) return Boolean is
+   begin
+      --  We do not want to use lock on this read operation. State is marked
+      --  as Atomic so that we ensure that the value retrieved is correct.
+
+      return S.State;
+   end Current_State;
+
+   ---------------
+   -- Set_False --
+   ---------------
+
+   procedure Set_False (S : in out Suspension_Object) is
+      Result  : STATUS;
+   begin
+      SSL.Abort_Defer.all;
+
+      Result := semTake (S.L, WAIT_FOREVER);
+      pragma Assert (Result = OK);
+
+      S.State := False;
+
+      Result := semGive (S.L);
+      pragma Assert (Result = OK);
+
+      SSL.Abort_Undefer.all;
+   end Set_False;
+
+   --------------
+   -- Set_True --
+   --------------
+
+   procedure Set_True (S : in out Suspension_Object) is
+      Result : STATUS;
+   begin
+      SSL.Abort_Defer.all;
+
+      Result := semTake (S.L, WAIT_FOREVER);
+      pragma Assert (Result = OK);
+
+      --  If there is already a task waiting on this suspension object then
+      --  we resume it, leaving the state of the suspension object to False,
+      --  as it is specified in ARM D.10 par. 9. Otherwise, it just leaves
+      --  the state to True.
+
+      if S.Waiting then
+         S.Waiting := False;
+         S.State := False;
+
+         Result := semGive (S.CV);
+         pragma Assert (Result = OK);
+      else
+         S.State := True;
+      end if;
+
+      Result := semGive (S.L);
+      pragma Assert (Result = OK);
+
+      SSL.Abort_Undefer.all;
+   end Set_True;
+
+   ------------------------
+   -- Suspend_Until_True --
+   ------------------------
+
+   procedure Suspend_Until_True (S : in out Suspension_Object) is
+      Result : STATUS;
+   begin
+      SSL.Abort_Defer.all;
+
+      Result := semTake (S.L, WAIT_FOREVER);
+
+      if S.Waiting then
+         --  Program_Error must be raised upon calling Suspend_Until_True
+         --  if another task is already waiting on that suspension object
+         --  (ARM D.10 par. 10).
+
+         Result := semGive (S.L);
+         pragma Assert (Result = OK);
+
+         SSL.Abort_Undefer.all;
+
+         raise Program_Error;
+      else
+         --  Suspend the task if the state is False. Otherwise, the task
+         --  continues its execution, and the state of the suspension object
+         --  is set to False (ARM D.10 par. 9).
+
+         if S.State then
+            S.State := False;
+
+            Result := semGive (S.L);
+            pragma Assert (Result = 0);
+
+            SSL.Abort_Undefer.all;
+         else
+            S.Waiting := True;
+
+            --  Release the mutex before sleeping
+
+            Result := semGive (S.L);
+            pragma Assert (Result = OK);
+
+            SSL.Abort_Undefer.all;
+
+            Result := semTake (S.CV, WAIT_FOREVER);
+            pragma Assert (Result = 0);
+         end if;
+      end if;
+   end Suspend_Until_True;
+
+   ----------------
    -- Check_Exit --
    ----------------
 
@@ -1099,8 +1227,12 @@ package body System.Task_Primitives.Operations is
 
    procedure Initialize (Environment_Task : Task_Id) is
       Result : int;
-
    begin
+      Environment_Task_Id := Environment_Task;
+
+      Interrupt_Management.Initialize;
+      Specific.Initialize;
+
       if Locking_Policy = 'C' then
          Mutex_Protocol := Prio_Protect;
       elsif Locking_Policy = 'I' then
@@ -1110,7 +1242,7 @@ package body System.Task_Primitives.Operations is
       end if;
 
       if Time_Slice_Val > 0 then
-         Result := kernelTimeSlice
+         Result := Set_Time_Slice
            (To_Clock_Ticks
              (Duration (Time_Slice_Val) / Duration (1_000_000.0)));
       end if;
@@ -1125,9 +1257,7 @@ package body System.Task_Primitives.Operations is
          end if;
       end loop;
 
-      Environment_Task_Id := Environment_Task;
-
-      --  Initialize the lock used to synchronize chain of all ATCBs.
+      --  Initialize the lock used to synchronize chain of all ATCBs
 
       Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);