------------------------------------------------------------------------------
--                                                                          --
--                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
--                                                                          --
--            S Y S T E M . S T A C K _ U S A G E . T A S K I N G           --
--                                                                          --
--                                  B o d y                                 --
--                                                                          --
--           Copyright (C) 2009-2023, Free Software Foundation, Inc.        --
--                                                                          --
-- GNAT 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.     --
--                                                                          --
------------------------------------------------------------------------------

--  This is why this package is part of GNARL:

with System.Tasking.Debug;
with System.Task_Primitives.Operations;

with System.IO;

package body System.Stack_Usage.Tasking is
   use System.IO;

   procedure Report_For_Task (Id : System.Tasking.Task_Id);
   --  A generic procedure calculating stack usage for a given task

   procedure Compute_All_Tasks;
   --  Compute the stack usage for all tasks and saves it in
   --  System.Stack_Usage.Result_Array

   procedure Compute_Current_Task;
   --  Compute the stack usage for a given task and saves it in the precise
   --  slot in System.Stack_Usage.Result_Array;

   procedure Report_Impl (All_Tasks : Boolean; Do_Print : Boolean);
   --  Report the stack usage of either all tasks (All_Tasks = True) or of the
   --  current task (All_Task = False). If Print is True, then results are
   --  printed on stderr

   procedure Convert
     (TS  : System.Stack_Usage.Task_Result;
      Res : out Stack_Usage_Result);
   --  Convert an object of type System.Stack_Usage in a Stack_Usage_Result

   -------------
   -- Convert --
   -------------

   procedure Convert
     (TS  : System.Stack_Usage.Task_Result;
      Res : out Stack_Usage_Result) is
   begin
      Res := TS;
   end Convert;

   ---------------------
   -- Report_For_Task --
   ---------------------

   procedure Report_For_Task (Id : System.Tasking.Task_Id) is
   begin
      System.Stack_Usage.Compute_Result (Id.Common.Analyzer);
      System.Stack_Usage.Report_Result (Id.Common.Analyzer);
   end Report_For_Task;

   -----------------------
   -- Compute_All_Tasks --
   -----------------------

   procedure Compute_All_Tasks is
      Id : System.Tasking.Task_Id;
      use type System.Tasking.Task_Id;
   begin
      if not System.Stack_Usage.Is_Enabled then
         Put_Line ("Stack Usage not enabled: bind with -uNNN switch");
      else

         --  Loop over all tasks

         for J in System.Tasking.Debug.Known_Tasks'First + 1
           .. System.Tasking.Debug.Known_Tasks'Last
         loop
            Id := System.Tasking.Debug.Known_Tasks (J);
            exit when Id = null;

            --  Calculate the task usage for a given task

            Report_For_Task (Id);
         end loop;

      end if;
   end Compute_All_Tasks;

   --------------------------
   -- Compute_Current_Task --
   --------------------------

   procedure Compute_Current_Task is
   begin
      if not System.Stack_Usage.Is_Enabled then
         Put_Line ("Stack Usage not enabled: bind with -uNNN switch");
      else

         --  The current task

         Report_For_Task (System.Tasking.Self);

      end if;
   end Compute_Current_Task;

   -----------------
   -- Report_Impl --
   -----------------

   procedure Report_Impl (All_Tasks : Boolean; Do_Print : Boolean) is
   begin

      --  Lock the runtime

      System.Task_Primitives.Operations.Lock_RTS;

      --  Calculate results

      if All_Tasks then
         Compute_All_Tasks;
      else
         Compute_Current_Task;
      end if;

      --  Output results
      if Do_Print then
         System.Stack_Usage.Output_Results;
      end if;

      --  Unlock the runtime

      System.Task_Primitives.Operations.Unlock_RTS;

   end Report_Impl;

   ----------------------
   -- Report_All_Tasks --
   ----------------------

   procedure Report_All_Tasks is
   begin
      Report_Impl (True, True);
   end Report_All_Tasks;

   -------------------------
   -- Report_Current_Task --
   -------------------------

   procedure Report_Current_Task is
      Res : Stack_Usage_Result;
   begin
      Res := Get_Current_Task_Usage;
      Print (Res);
   end Report_Current_Task;

   -------------------------
   -- Get_All_Tasks_Usage --
   -------------------------

   function Get_All_Tasks_Usage return Stack_Usage_Result_Array is
      Res : Stack_Usage_Result_Array
        (1 .. System.Stack_Usage.Result_Array'Length);
   begin
      Report_Impl (True, False);

      for J in Res'Range loop
         Convert (System.Stack_Usage.Result_Array (J), Res (J));
      end loop;

      return Res;
   end Get_All_Tasks_Usage;

   ----------------------------
   -- Get_Current_Task_Usage --
   ----------------------------

   function Get_Current_Task_Usage return Stack_Usage_Result is
      Res : Stack_Usage_Result;
      Original : System.Stack_Usage.Task_Result;
      Found : Boolean := False;
   begin

      Report_Impl (False, False);

      --  Look for the task info in System.Stack_Usage.Result_Array;
      --  the search is based on task name

      for T in System.Stack_Usage.Result_Array'Range loop
         if System.Stack_Usage.Result_Array (T).Task_Name =
           System.Tasking.Self.Common.Analyzer.Task_Name
         then
            Original := System.Stack_Usage.Result_Array (T);
            Found := True;
            exit;
         end if;
      end loop;

      --  Be sure a task has been found

      pragma Assert (Found);

      Convert (Original, Res);
      return Res;
   end Get_Current_Task_Usage;

   -----------
   -- Print --
   -----------

   procedure Print (Obj : Stack_Usage_Result) is
      Pos : Positive := Obj.Task_Name'Last;

   begin
      --  Simply trim the string containing the task name

      for S in Obj.Task_Name'Range loop
         if Obj.Task_Name (S) = ' ' then
            Pos := S;
            exit;
         end if;
      end loop;

      declare
         T_Name : constant String :=
                    Obj.Task_Name (Obj.Task_Name'First .. Pos);
      begin
         Put_Line
           ("| " & T_Name & " | " & Natural'Image (Obj.Stack_Size) &
            Natural'Image (Obj.Value));
      end;
   end Print;

end System.Stack_Usage.Tasking;
