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 POSIX (Realtime Extension) 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 pragma Linker_Options ("-lrt"); 46 -- POSIX.1b Realtime Extensions library. Needed to have access to function 47 -- clock_gettime. 48 49 --------- 50 -- "+" -- 51 --------- 52 53 function "+" 54 (Left : CPU_Time; 55 Right : Ada.Real_Time.Time_Span) return CPU_Time 56 is 57 use type Ada.Real_Time.Time; 58 begin 59 return CPU_Time (Ada.Real_Time.Time (Left) + Right); 60 end "+"; 61 62 function "+" 63 (Left : Ada.Real_Time.Time_Span; 64 Right : CPU_Time) return CPU_Time 65 is 66 use type Ada.Real_Time.Time; 67 begin 68 return CPU_Time (Left + Ada.Real_Time.Time (Right)); 69 end "+"; 70 71 --------- 72 -- "-" -- 73 --------- 74 75 function "-" 76 (Left : CPU_Time; 77 Right : Ada.Real_Time.Time_Span) return CPU_Time 78 is 79 use type Ada.Real_Time.Time; 80 begin 81 return CPU_Time (Ada.Real_Time.Time (Left) - Right); 82 end "-"; 83 84 function "-" 85 (Left : CPU_Time; 86 Right : CPU_Time) return Ada.Real_Time.Time_Span 87 is 88 use type Ada.Real_Time.Time; 89 begin 90 return (Ada.Real_Time.Time (Left) - Ada.Real_Time.Time (Right)); 91 end "-"; 92 93 ----------- 94 -- Clock -- 95 ----------- 96 97 function Clock 98 (T : Ada.Task_Identification.Task_Id := 99 Ada.Task_Identification.Current_Task) return CPU_Time 100 is 101 TS : aliased timespec; 102 Clock_Id : aliased Interfaces.C.int; 103 Result : Interfaces.C.int; 104 105 function To_CPU_Time is 106 new Ada.Unchecked_Conversion (Duration, CPU_Time); 107 -- Time is equal to Duration (although it is a private type) and 108 -- CPU_Time is equal to Time. 109 110 function Convert_Ids is new 111 Ada.Unchecked_Conversion (Task_Id, System.Tasking.Task_Id); 112 113 function clock_gettime 114 (clock_id : Interfaces.C.int; 115 tp : access timespec) 116 return int; 117 pragma Import (C, clock_gettime, "clock_gettime"); 118 -- Function from the POSIX.1b Realtime Extensions library 119 120 function pthread_getcpuclockid 121 (tid : Thread_Id; 122 clock_id : access Interfaces.C.int) 123 return int; 124 pragma Import (C, pthread_getcpuclockid, "pthread_getcpuclockid"); 125 -- Function from the Thread CPU-Time Clocks option 126 127 begin 128 if T = Ada.Task_Identification.Null_Task_Id then 129 raise Program_Error; 130 else 131 -- Get the CPU clock for the task passed as parameter 132 133 Result := pthread_getcpuclockid 134 (Get_Thread_Id (Convert_Ids (T)), Clock_Id'Access); 135 pragma Assert (Result = 0); 136 end if; 137 138 Result := clock_gettime 139 (clock_id => Clock_Id, tp => TS'Unchecked_Access); 140 pragma Assert (Result = 0); 141 142 return To_CPU_Time (To_Duration (TS)); 143 end Clock; 144 145 -------------------------- 146 -- Clock_For_Interrupts -- 147 -------------------------- 148 149 function Clock_For_Interrupts return CPU_Time is 150 begin 151 -- According to AI 0170-1, D.14(18.1/3), if Interrupt_Clocks_Supported 152 -- is set to False the function raises Program_Error. 153 154 raise Program_Error; 155 return CPU_Time_First; 156 end Clock_For_Interrupts; 157 158 ----------- 159 -- Split -- 160 ----------- 161 162 procedure Split 163 (T : CPU_Time; 164 SC : out Ada.Real_Time.Seconds_Count; 165 TS : out Ada.Real_Time.Time_Span) 166 is 167 168 begin 169 Ada.Real_Time.Split (Ada.Real_Time.Time (T), SC, TS); 170 end Split; 171 172 ------------- 173 -- Time_Of -- 174 ------------- 175 176 function Time_Of 177 (SC : Ada.Real_Time.Seconds_Count; 178 TS : Ada.Real_Time.Time_Span := Ada.Real_Time.Time_Span_Zero) 179 return CPU_Time 180 is 181 begin 182 return CPU_Time (Ada.Real_Time.Time_Of (SC, TS)); 183 end Time_Of; 184 185end Ada.Execution_Time; 186