------------------------------------------------------------------------------
--                                                                          --
--                 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-2021, 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.     --
--                                                                          --
------------------------------------------------------------------------------

with System.Stack_Usage;

--  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;
