File : a-exetim-darwin.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT RUN-TIME COMPONENTS                         --
   4 --                                                                          --
   5 --                   A D A . E X E C U T I O N _ T I M E                    --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --         Copyright (C) 2007-2016, Free Software Foundation, Inc.          --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 --  This is the Darwin version of this package
  33 
  34 with Ada.Task_Identification;  use Ada.Task_Identification;
  35 with Ada.Unchecked_Conversion;
  36 
  37 with System.Tasking;
  38 with System.OS_Interface; use System.OS_Interface;
  39 with System.Task_Primitives.Operations; use System.Task_Primitives.Operations;
  40 
  41 with Interfaces.C; use Interfaces.C;
  42 
  43 package body Ada.Execution_Time is
  44 
  45    ---------
  46    -- "+" --
  47    ---------
  48 
  49    function "+"
  50      (Left  : CPU_Time;
  51       Right : Ada.Real_Time.Time_Span) return CPU_Time
  52    is
  53       use type Ada.Real_Time.Time;
  54    begin
  55       return CPU_Time (Ada.Real_Time.Time (Left) + Right);
  56    end "+";
  57 
  58    function "+"
  59      (Left  : Ada.Real_Time.Time_Span;
  60       Right : CPU_Time) return CPU_Time
  61    is
  62       use type Ada.Real_Time.Time;
  63    begin
  64       return CPU_Time (Left + Ada.Real_Time.Time (Right));
  65    end "+";
  66 
  67    ---------
  68    -- "-" --
  69    ---------
  70 
  71    function "-"
  72      (Left  : CPU_Time;
  73       Right : Ada.Real_Time.Time_Span) return CPU_Time
  74    is
  75       use type Ada.Real_Time.Time;
  76    begin
  77       return CPU_Time (Ada.Real_Time.Time (Left) - Right);
  78    end "-";
  79 
  80    function "-"
  81      (Left  : CPU_Time;
  82       Right : CPU_Time) return Ada.Real_Time.Time_Span
  83    is
  84       use type Ada.Real_Time.Time;
  85    begin
  86       return (Ada.Real_Time.Time (Left) - Ada.Real_Time.Time (Right));
  87    end "-";
  88 
  89    -----------
  90    -- Clock --
  91    -----------
  92 
  93    function Clock
  94      (T : Ada.Task_Identification.Task_Id :=
  95         Ada.Task_Identification.Current_Task) return CPU_Time
  96    is
  97       function Convert_Ids is new
  98         Ada.Unchecked_Conversion (Task_Id, System.Tasking.Task_Id);
  99 
 100       function To_CPU_Time is
 101         new Ada.Unchecked_Conversion (Duration, CPU_Time);
 102       --  Time is equal to Duration (although it is a private type) and
 103       --  CPU_Time is equal to Time.
 104 
 105       subtype integer_t is Interfaces.C.int;
 106       subtype mach_port_t is integer_t;
 107       --  Type definition for Mach.
 108 
 109       type time_value_t is record
 110          seconds : integer_t;
 111          microseconds : integer_t;
 112       end record;
 113       pragma Convention (C, time_value_t);
 114       --  Mach time_value_t
 115 
 116       type thread_basic_info_t is record
 117          user_time     : time_value_t;
 118          system_time   : time_value_t;
 119          cpu_usage     : integer_t;
 120          policy        : integer_t;
 121          run_state     : integer_t;
 122          flags         : integer_t;
 123          suspend_count : integer_t;
 124          sleep_time    : integer_t;
 125       end record;
 126       pragma Convention (C, thread_basic_info_t);
 127       --  Mach structure from thread_info.h
 128 
 129       THREAD_BASIC_INFO       : constant := 3;
 130       THREAD_BASIC_INFO_COUNT : constant := 10;
 131       --  Flavors for basic info
 132 
 133       function thread_info (Target : mach_port_t;
 134                             Flavor : integer_t;
 135                             Thread_Info : System.Address;
 136                             Count : System.Address) return integer_t;
 137       pragma Import (C, thread_info);
 138       --  Mach call to get info on a thread
 139 
 140       function pthread_mach_thread_np (Thread : pthread_t) return mach_port_t;
 141       pragma Import (C, pthread_mach_thread_np);
 142       --  Get Mach thread from posix thread
 143 
 144       Result    : Interfaces.C.int;
 145       Thread    : pthread_t;
 146       Port      : mach_port_t;
 147       Ti        : thread_basic_info_t;
 148       Count     : integer_t;
 149    begin
 150       if T = Ada.Task_Identification.Null_Task_Id then
 151          raise Program_Error;
 152       end if;
 153 
 154       Thread := Get_Thread_Id (Convert_Ids (T));
 155       Port := pthread_mach_thread_np (Thread);
 156       pragma Assert (Port > 0);
 157 
 158       Count := THREAD_BASIC_INFO_COUNT;
 159       Result := thread_info (Port, THREAD_BASIC_INFO,
 160                              Ti'Address, Count'Address);
 161       pragma Assert (Result = 0);
 162       pragma Assert (Count = THREAD_BASIC_INFO_COUNT);
 163 
 164       return To_CPU_Time
 165         (Duration (Ti.user_time.seconds + Ti.system_time.seconds)
 166            + Duration (Ti.user_time.microseconds
 167                          + Ti.system_time.microseconds) / 1E6);
 168    end Clock;
 169 
 170    --------------------------
 171    -- Clock_For_Interrupts --
 172    --------------------------
 173 
 174    function Clock_For_Interrupts return CPU_Time is
 175    begin
 176       --  According to AI 0170-1, D.14(18.1/3), if Interrupt_Clocks_Supported
 177       --  is set to False the function raises Program_Error.
 178 
 179       raise Program_Error;
 180       return CPU_Time_First;
 181    end Clock_For_Interrupts;
 182 
 183    -----------
 184    -- Split --
 185    -----------
 186 
 187    procedure Split
 188      (T  : CPU_Time;
 189       SC : out Ada.Real_Time.Seconds_Count;
 190       TS : out Ada.Real_Time.Time_Span)
 191    is
 192       use type Ada.Real_Time.Time;
 193    begin
 194       Ada.Real_Time.Split (Ada.Real_Time.Time (T), SC, TS);
 195    end Split;
 196 
 197    -------------
 198    -- Time_Of --
 199    -------------
 200 
 201    function Time_Of
 202      (SC : Ada.Real_Time.Seconds_Count;
 203       TS : Ada.Real_Time.Time_Span := Ada.Real_Time.Time_Span_Zero)
 204       return CPU_Time
 205    is
 206    begin
 207       return CPU_Time (Ada.Real_Time.Time_Of (SC, TS));
 208    end Time_Of;
 209 
 210 end Ada.Execution_Time;