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-2019, 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-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 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 34with Ada.Task_Identification; use Ada.Task_Identification; 35with Ada.Unchecked_Conversion; 36 37with System.Tasking; 38with System.OS_Interface; use System.OS_Interface; 39with System.Task_Primitives.Operations; use System.Task_Primitives.Operations; 40 41with Interfaces.C; use Interfaces.C; 42 43package 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 begin 193 Ada.Real_Time.Split (Ada.Real_Time.Time (T), SC, TS); 194 end Split; 195 196 ------------- 197 -- Time_Of -- 198 ------------- 199 200 function Time_Of 201 (SC : Ada.Real_Time.Seconds_Count; 202 TS : Ada.Real_Time.Time_Span := Ada.Real_Time.Time_Span_Zero) 203 return CPU_Time 204 is 205 begin 206 return CPU_Time (Ada.Real_Time.Time_Of (SC, TS)); 207 end Time_Of; 208 209end Ada.Execution_Time; 210