------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                SYSTEM.MULTIPROCESSORS.DISPATCHING_DOMAINS                --
--                                                                          --
--                                  B o d y                                 --
--                                                                          --
--          Copyright (C) 2011-2021, 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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNARL was developed by the GNARL team at Florida State University.       --
-- Extensive contributions were provided by Ada Core Technologies, Inc.     --
--                                                                          --
------------------------------------------------------------------------------

--  Body used on targets where the operating system supports setting task
--  affinities.

with System.Tasking.Initialization;
with System.Task_Primitives.Operations; use System.Task_Primitives.Operations;

with Ada.Unchecked_Conversion;

package body System.Multiprocessors.Dispatching_Domains is

   package ST renames System.Tasking;

   -----------------------
   -- Local subprograms --
   -----------------------

   function Convert_Ids is new
     Ada.Unchecked_Conversion (Ada.Task_Identification.Task_Id, ST.Task_Id);

   procedure Unchecked_Set_Affinity
     (Domain : ST.Dispatching_Domain_Access;
      CPU    : CPU_Range;
      T      : ST.Task_Id);
   --  Internal procedure to move a task to a target domain and CPU. No checks
   --  are performed about the validity of the domain and the CPU because they
   --  are done by the callers of this procedure (either Assign_Task or
   --  Set_CPU).

   procedure Freeze_Dispatching_Domains;
   pragma Export
     (Ada, Freeze_Dispatching_Domains, "__gnat_freeze_dispatching_domains");
   --  Signal the time when no new dispatching domains can be created. It
   --  should be called before the environment task calls the main procedure
   --  (and after the elaboration code), so the binder-generated file needs to
   --  import and call this procedure.

   -----------------
   -- Assign_Task --
   -----------------

   procedure Assign_Task
     (Domain : in out Dispatching_Domain;
      CPU    : CPU_Range := Not_A_Specific_CPU;
      T      : Ada.Task_Identification.Task_Id :=
                 Ada.Task_Identification.Current_Task)
   is
      Target : constant ST.Task_Id := Convert_Ids (T);

   begin
      --  The exception Dispatching_Domain_Error is propagated if T is already
      --  assigned to a Dispatching_Domain other than
      --  System_Dispatching_Domain, or if CPU is not one of the processors of
      --  Domain (and is not Not_A_Specific_CPU).

      if Dispatching_Domain (Target.Common.Domain) /= System_Dispatching_Domain
      then
         raise Dispatching_Domain_Error with
           "task already in user-defined dispatching domain";

      elsif CPU /= Not_A_Specific_CPU and then CPU not in Domain'Range then
         raise Dispatching_Domain_Error with
           "processor does not belong to dispatching domain";
      end if;

      --  Assigning a task to System_Dispatching_Domain that is already
      --  assigned to that domain has no effect.

      if Domain = System_Dispatching_Domain then
         return;

      else
         --  Set the task affinity once we know it is possible

         Unchecked_Set_Affinity
           (ST.Dispatching_Domain_Access (Domain), CPU, Target);
      end if;
   end Assign_Task;

   ------------
   -- Create --
   ------------

   function Create (First : CPU; Last : CPU_Range) return Dispatching_Domain is
   begin
      return Create ((First .. Last => True));
   end Create;

   function Create (Set : CPU_Set) return Dispatching_Domain is
      ST_DD : aliased constant ST.Dispatching_Domain :=
        ST.Dispatching_Domain (Set);
      First : constant CPU       := Get_First_CPU (ST_DD'Unrestricted_Access);
      Last  : constant CPU_Range := Get_Last_CPU (ST_DD'Unrestricted_Access);
      subtype Rng is CPU_Range range First .. Last;

      use type ST.Dispatching_Domain;
      use type ST.Dispatching_Domain_Access;
      use type ST.Task_Id;

      T : ST.Task_Id;

      New_System_Domain : ST.Dispatching_Domain := ST.System_Domain.all;

      ST_DD_Slice : constant ST.Dispatching_Domain := ST_DD (Rng);

   begin
      --  The set of processors for creating a dispatching domain must
      --  comply with the following restrictions:
      --    - Not exceeding the range of available processors.
      --    - CPUs from the System_Dispatching_Domain.
      --    - The calling task must be the environment task.
      --    - The call to Create must take place before the call to the main
      --      subprogram.
      --    - Set does not contain a processor with a task assigned to it.
      --    - The allocation cannot leave System_Dispatching_Domain empty.

      --  Note that a previous version of the language forbade empty domains.

      if Rng'Last > Number_Of_CPUs then
         raise Dispatching_Domain_Error with
           "CPU not supported by the target";
      end if;

      declare
         System_Domain_Slice : constant ST.Dispatching_Domain :=
           ST.System_Domain (Rng);
         Actual : constant ST.Dispatching_Domain :=
           ST_DD_Slice and not System_Domain_Slice;
         Expected : constant ST.Dispatching_Domain := (Rng => False);
      begin
         if Actual /= Expected then
            raise Dispatching_Domain_Error with
              "CPU not currently in System_Dispatching_Domain";
         end if;
      end;

      if Self /= Environment_Task then
         raise Dispatching_Domain_Error with
           "only the environment task can create dispatching domains";
      end if;

      if ST.Dispatching_Domains_Frozen then
         raise Dispatching_Domain_Error with
           "cannot create dispatching domain after call to main procedure";
      end if;

      for Proc in Rng loop
         if ST_DD (Proc) and then
           ST.Dispatching_Domain_Tasks (Proc) /= 0
         then
            raise Dispatching_Domain_Error with "CPU has tasks assigned";
         end if;
      end loop;

      New_System_Domain (Rng) := New_System_Domain (Rng) and not ST_DD_Slice;

      if New_System_Domain = (New_System_Domain'Range => False) then
         raise Dispatching_Domain_Error with
           "would leave System_Dispatching_Domain empty";
      end if;

      return Result : constant Dispatching_Domain :=
        new ST.Dispatching_Domain'(ST_DD_Slice)
      do
         --  At this point we need to fix the processors belonging to the
         --  system domain, and change the affinity of every task that has
         --  been created and assigned to the system domain.

         ST.Initialization.Defer_Abort (Self);

         Lock_RTS;

         ST.System_Domain (Rng) := New_System_Domain (Rng);
         pragma Assert (ST.System_Domain.all = New_System_Domain);

         --  Iterate the list of tasks belonging to the default system
         --  dispatching domain and set the appropriate affinity.

         T := ST.All_Tasks_List;

         while T /= null loop
            if T.Common.Domain = ST.System_Domain then
               Set_Task_Affinity (T);
            end if;

            T := T.Common.All_Tasks_Link;
         end loop;

         Unlock_RTS;

         ST.Initialization.Undefer_Abort (Self);
      end return;
   end Create;

   -----------------------------
   -- Delay_Until_And_Set_CPU --
   -----------------------------

   procedure Delay_Until_And_Set_CPU
     (Delay_Until_Time : Ada.Real_Time.Time;
      CPU              : CPU_Range)
   is
   begin
      --  Not supported atomically by the underlying operating systems.
      --  Operating systems use to migrate the task immediately after the call
      --  to set the affinity.

      delay until Delay_Until_Time;
      Set_CPU (CPU);
   end Delay_Until_And_Set_CPU;

   --------------------------------
   -- Freeze_Dispatching_Domains --
   --------------------------------

   procedure Freeze_Dispatching_Domains is
   begin
      --  Signal the end of the elaboration code

      ST.Dispatching_Domains_Frozen := True;
   end Freeze_Dispatching_Domains;

   -------------
   -- Get_CPU --
   -------------

   function Get_CPU
     (T : Ada.Task_Identification.Task_Id :=
            Ada.Task_Identification.Current_Task) return CPU_Range
   is
   begin
      return Convert_Ids (T).Common.Base_CPU;
   end Get_CPU;

   -----------------
   -- Get_CPU_Set --
   -----------------

   function Get_CPU_Set (Domain : Dispatching_Domain) return CPU_Set is
   begin
      return CPU_Set (Domain.all);
   end Get_CPU_Set;

   ----------------------------
   -- Get_Dispatching_Domain --
   ----------------------------

   function Get_Dispatching_Domain
     (T : Ada.Task_Identification.Task_Id :=
            Ada.Task_Identification.Current_Task) return Dispatching_Domain
   is
   begin
      return Result : constant Dispatching_Domain :=
        Dispatching_Domain (Convert_Ids (T).Common.Domain)
      do
         pragma Assert (Result /= null);
      end return;
   end Get_Dispatching_Domain;

   -------------------
   -- Get_First_CPU --
   -------------------

   function Get_First_CPU (Domain : Dispatching_Domain) return CPU is
   begin
      for Proc in Domain'Range loop
         if Domain (Proc) then
            return Proc;
         end if;
      end loop;

      return CPU'First;
   end Get_First_CPU;

   ------------------
   -- Get_Last_CPU --
   ------------------

   function Get_Last_CPU (Domain : Dispatching_Domain) return CPU_Range is
   begin
      for Proc in reverse Domain'Range loop
         if Domain (Proc) then
            return Proc;
         end if;
      end loop;

      return CPU_Range'First;
   end Get_Last_CPU;

   -------------
   -- Set_CPU --
   -------------

   procedure Set_CPU
     (CPU : CPU_Range;
      T   : Ada.Task_Identification.Task_Id :=
              Ada.Task_Identification.Current_Task)
   is
      Target : constant ST.Task_Id := Convert_Ids (T);

   begin
      --  The exception Dispatching_Domain_Error is propagated if CPU is not
      --  one of the processors of the Dispatching_Domain on which T is
      --  assigned (and is not Not_A_Specific_CPU).

      if CPU /= Not_A_Specific_CPU and then
        (CPU not in Target.Common.Domain'Range or else
         not Target.Common.Domain (CPU))
      then
         raise Dispatching_Domain_Error with
           "processor does not belong to the task's dispatching domain";
      end if;

      Unchecked_Set_Affinity (Target.Common.Domain, CPU, Target);
   end Set_CPU;

   ----------------------------
   -- Unchecked_Set_Affinity --
   ----------------------------

   procedure Unchecked_Set_Affinity
     (Domain : ST.Dispatching_Domain_Access;
      CPU    : CPU_Range;
      T      : ST.Task_Id)
   is
      Source_CPU : constant CPU_Range := T.Common.Base_CPU;

      use type ST.Dispatching_Domain_Access;

   begin
      Write_Lock (T);

      --  Move to the new domain

      T.Common.Domain := Domain;

      --  Attach the CPU to the task

      T.Common.Base_CPU := CPU;

      --  Change the number of tasks attached to a given task in the system
      --  domain if needed.

      if not ST.Dispatching_Domains_Frozen
        and then (Domain = null or else Domain = ST.System_Domain)
      then
         --  Reduce the number of tasks attached to the CPU from which this
         --  task is being moved, if needed.

         if Source_CPU /= Not_A_Specific_CPU then
            ST.Dispatching_Domain_Tasks (Source_CPU) :=
              ST.Dispatching_Domain_Tasks (Source_CPU) - 1;
         end if;

         --  Increase the number of tasks attached to the CPU to which this
         --  task is being moved, if needed.

         if CPU /= Not_A_Specific_CPU then
            ST.Dispatching_Domain_Tasks (CPU) :=
              ST.Dispatching_Domain_Tasks (CPU) + 1;
         end if;
      end if;

      --  Change the actual affinity calling the operating system level

      Set_Task_Affinity (T);

      Unlock (T);
   end Unchecked_Set_Affinity;

end System.Multiprocessors.Dispatching_Domains;
