diff mbox series

[Ada] Posix 2008: reimplement System.OS_Primitives.Clock using clock_gettime

Message ID 20180531104801.GA119638@adacore.com
State New
Headers show
Series [Ada] Posix 2008: reimplement System.OS_Primitives.Clock using clock_gettime | expand

Commit Message

Pierre-Marie de Rodat May 31, 2018, 10:48 a.m. UTC
gettimeofday is deprecated in Posix 2008, clock_gettime is the recommended
replacement.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-31  Doug Rupp  <rupp@adacore.com>

gcc/ada/

	* libgnat/s-osprim__posix2008.adb (Clock): Implement using
	clock_gettime.
diff mbox series

Patch

--- gcc/ada/libgnat/s-osprim__posix2008.adb
+++ gcc/ada/libgnat/s-osprim__posix2008.adb
@@ -32,8 +32,11 @@ 
 --  This version is for POSIX.1-2008-like operating systems
 
 with System.CRTL;
+with System.OS_Constants;
 package body System.OS_Primitives is
 
+   subtype int is System.CRTL.int;
+
    --  ??? These definitions are duplicated from System.OS_Interface because
    --  we don't want to depend on any package. Consider removing these
    --  declarations in System.OS_Interface and move these ones to the spec.
@@ -54,43 +57,22 @@  package body System.OS_Primitives is
    -----------
 
    function Clock return Duration is
+      TS     : aliased timespec;
+      Result : int;
 
-      type timeval is array (1 .. 3) of Long_Integer;
-      --  The timeval array is sized to contain Long_Long_Integer sec and
-      --  Long_Integer usec. If Long_Long_Integer'Size = Long_Integer'Size then
-      --  it will be overly large but that will not effect the implementation
-      --  since it is not accessed directly.
-
-      procedure timeval_to_duration
-        (T    : not null access timeval;
-         sec  : not null access Long_Long_Integer;
-         usec : not null access Long_Integer);
-      pragma Import (C, timeval_to_duration, "__gnat_timeval_to_duration");
-
-      Micro  : constant := 10**6;
-      sec    : aliased Long_Long_Integer;
-      usec   : aliased Long_Integer;
-      TV     : aliased timeval;
-      Result : Integer;
-      pragma Unreferenced (Result);
-
-      function gettimeofday
-        (Tv : access timeval;
-         Tz : System.Address := System.Null_Address) return Integer;
-      pragma Import (C, gettimeofday, "gettimeofday");
-
-   begin
-      --  The return codes for gettimeofday are as follows (from man pages):
-      --    EPERM  settimeofday is called by someone other than the superuser
-      --    EINVAL Timezone (or something else) is invalid
-      --    EFAULT One of tv or tz pointed outside accessible address space
+      type clockid_t is new int;
+      CLOCK_REALTIME : constant clockid_t :=
+         System.OS_Constants.CLOCK_REALTIME;
 
-      --  None of these codes signal a potential clock skew, hence the return
-      --  value is never checked.
+      function clock_gettime
+        (clock_id : clockid_t;
+         tp       : access timespec) return int;
+      pragma Import (C, clock_gettime, "clock_gettime");
 
-      Result := gettimeofday (TV'Access, System.Null_Address);
-      timeval_to_duration (TV'Access, sec'Access, usec'Access);
-      return Duration (sec) + Duration (usec) / Micro;
+   begin
+      Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+      pragma Assert (Result = 0);
+      return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
    end Clock;
 
    -----------------