> > > It may be surprising to have the RTEMS file used by other OS. The > > > original comment should have mentionned that in the first place, but > > > the file was only used with RTEMS. With your change, the file is > > > effectively shared, so it would be best to rename it. > > > > Could you please suggest an appropriate file name? This may be > > obvious for you, but with my limited knowledge of GNAT internals, the > > diff between s-osprim__rtems.adb and __unix/optide.adb is not > > sufficient to guess why a separate implementation is/was required. > > Would it be possible to drop it altogether and use s-osprim__posix.adb > instead? > Otherwise what's the remaining difference between > s-osprim__posix.adb and s-osprim__rtems.adb? The difference should > help us find a proper name based on properties of the file.
At first view, it seems possible and desirable to merge _posix and _rtems, but working on this right now would be counter-productive. I suggest to apply patches 1-2 and fix PR114065 first. Then the cosmetic changes in patches 3-6 (and possibly a trivial backport of 8). After that, we will have all the time in the long winter afternoons to discuss file names in patch 7. > Can you post also a diff between version 11 and version 12? It's not > practical to review the complete changes from scratch at this stage, > the patch is too big. The diff between git version branches are attached.
diff --git a/gcc/ada/doc/gnat_rm/the_gnat_library.rst b/gcc/ada/doc/gnat_rm/the_gnat_library.rst index bcec49f..58c790f 100644 --- a/gcc/ada/doc/gnat_rm/the_gnat_library.rst +++ b/gcc/ada/doc/gnat_rm/the_gnat_library.rst @@ -674,6 +674,8 @@ Machine-specific implementations are available in some cases. Extends the facilities provided by ``Ada.Calendar`` to include handling of days of the week, an extended ``Split`` and ``Time_Of`` capability. +Also provides conversion of ``Ada.Calendar.Duration`` values to and from the +C ``timeval`` format. .. _`GNAT.Calendar.Time_IO_(g-catiio.ads)`: diff --git a/gcc/ada/libgnarl/s-osinte__android.ads b/gcc/ada/libgnarl/s-osinte__android.ads index ee3a5dc..ecf4a32 100644 --- a/gcc/ada/libgnarl/s-osinte__android.ads +++ b/gcc/ada/libgnarl/s-osinte__android.ads @@ -207,7 +207,7 @@ package System.OS_Interface is type clockid_t is new int; function clock_gettime - (clock_id : clockid_t; tp : access C_time.timespec) return int; + (clock_id : clockid_t; tp : access C_Time.timespec) return int; pragma Import (C, clock_gettime, "clock_gettime"); function clock_getres diff --git a/gcc/ada/libgnat/a-calcon.ads b/gcc/ada/libgnat/a-calcon.ads index ad4ca64..196028e 100644 --- a/gcc/ada/libgnat/a-calcon.ads +++ b/gcc/ada/libgnat/a-calcon.ads @@ -30,9 +30,10 @@ ------------------------------------------------------------------------------ -- This package provides various routines for conversion between Ada and Unix --- time models - Time, Duration and struct tm. +-- time models - Time, Duration, struct tm and struct timespec. with Interfaces.C; +with System.C_Time; package Ada.Calendar.Conversions is @@ -67,6 +68,20 @@ package Ada.Calendar.Conversions is -- the input values are out of the defined ranges or if tm_sec equals 60 -- and the instance in time is not a leap second occurrence. + function To_Duration + (tv_sec : System.C_Time.Tv_Sec_Long; + tv_nsec : System.C_Time.Tv_Nsec_Long) + return System.C_Time.Non_Negative_Duration + renames System.C_Time.To_Duration; + -- Deprecated. Please use C_Time directly. + + procedure To_Struct_Timespec + (D : System.C_Time.Non_Negative_Duration; + tv_sec : out System.C_Time.Tv_Sec_Long; + tv_nsec : out System.C_Time.Tv_Nsec_Long) + renames System.C_Time.To_Struct_Timespec; + -- Deprecated. Please use C_Time directly. + procedure To_Struct_Tm (T : Time; tm_year : out Interfaces.C.int; diff --git a/gcc/ada/libgnat/g-calend.ads b/gcc/ada/libgnat/g-calend.ads index f317ab4..7791943 100644 --- a/gcc/ada/libgnat/g-calend.ads +++ b/gcc/ada/libgnat/g-calend.ads @@ -40,6 +40,7 @@ -- Day_Of_Week, Day_In_Year and Week_In_Year. with Ada.Calendar.Formatting; +with System.C_Time; package GNAT.Calendar is @@ -144,6 +145,19 @@ package GNAT.Calendar is -- Return the week number as defined in ISO 8601 along with the year in -- which the week occurs. + subtype timeval is System.C_Time.timeval; + -- Deprecated. Please use C_Time directly. + + function To_Duration (T : not null access timeval) + return System.C_Time.Non_Negative_Duration + with Inline + is (System.C_Time.To_Duration (T.all)); + -- Deprecated. Please use C_Time directly. + + function To_Timeval (D : System.C_Time.Non_Negative_Duration) return timeval + renames System.C_Time.To_Timeval; + -- Deprecated. Please use C_Time directly. + private function Julian_Day diff --git a/gcc/ada/libgnat/s-c_time.adb b/gcc/ada/libgnat/s-c_time.adb index 26820a4..d44727c 100644 --- a/gcc/ada/libgnat/s-c_time.adb +++ b/gcc/ada/libgnat/s-c_time.adb @@ -36,6 +36,9 @@ package body System.C_Time is -- 32 0.02 42_949_672.94 -- 64 0.000_000_001 9_223_372_036.854_775_807 + -- The overflows listed in comments must raise Constraint_Error. + pragma Unsuppress (Overflow_Check); + ----------------- -- In_Duration -- ----------------- @@ -72,7 +75,7 @@ package body System.C_Time is -- Milliseconds_To_Timeval -- ----------------------------- - function Milliseconds_To_Timeval (M : Interfaces.C.int) return timeval is + function Milliseconds_To_Timeval (M : Non_Negative_Int) return timeval is use Interfaces.C; Q : constant int range 0 .. int'Last / 1_000 := M / 1_000; R : constant int range 0 .. 999 := M mod 1_000; @@ -85,7 +88,7 @@ package body System.C_Time is -- Nanoseconds_To_Timespec -- ----------------------------- - function Nanoseconds_To_Timespec (N : Interfaces.C.int) return timespec is + function Nanoseconds_To_Timespec (N : Non_Negative_Int) return timespec is use Interfaces.C; Q : constant int range 0 .. int'Last / 10**9 := N / 10**9; R : constant int range 0 .. 999_999_999 := N mod 10**9; @@ -98,31 +101,60 @@ package body System.C_Time is -- To_Duration -- ----------------- - function To_Duration (T : timeval) return Duration is + function To_Duration (T : timeval) return Non_Negative_Duration is + Usec : usec_t range 0 .. 1_009_999; Frac : Duration range 0.0 .. 1.0; begin if Duration'Size = 64 then - Frac := Duration (T.tv_usec) / 1_000_000; + Usec := T.tv_usec; else - -- Fix the rounding (999_999.0 / 1_000_000 = 0.98). - Frac := Duration (T.tv_usec + 10_000) / 1_000_000; + -- Fix the rounding (999_999.0 / 1_000_000 = 0.98) + -- with a bias of half Duration'Small = 10 ms. + Usec := T.tv_usec + 10_000; end if; + Frac := Duration (Usec) / 1_000_000; + return Duration (T.tv_sec) + Frac; + -- Both the conversion and the addition may overflow. end To_Duration; - function To_Duration (T : timespec) return Duration is + function To_Duration (T : timespec) return Non_Negative_Duration is Frac : Duration range 0.0 .. 1.0; begin if Duration'Size = 64 then Frac := Duration (T.tv_nsec) / 1_000_000_000; else -- Avoid an overflow (Duration'Last < 999_999_999). - -- Fix the rounding (999_999_999.0 / 1_000_000_000 = 0.98). + -- Fix the rounding (999_999_999.0 / 1_000_000_000 = 0.98) + -- with a bias of half Duration'Small = 10 ms. Frac := Duration (T.tv_nsec / 10_000_000 + 1) / 100; end if; + return Duration (T.tv_sec) + Frac; + -- Both the conversion and the addition may overflow. end To_Duration; + function To_Duration (tv_sec : Tv_Sec_Long; + tv_nsec : Tv_Nsec_Long) + return Non_Negative_Duration is + begin + return To_Duration (timespec'(tv_sec => time_t (tv_sec), + tv_nsec => nsec_t (tv_nsec))); + end To_Duration; + + ------------------------ + -- To_Struct_Timespec -- + ------------------------ + + procedure To_Struct_Timespec (D : Non_Negative_Duration; + tv_sec : out Tv_Sec_Long; + tv_nsec : out Tv_Nsec_Long) is + T : constant timespec := To_Timespec (D); + begin + tv_sec := Tv_Sec_Long (T.tv_sec); -- May overflow Interfaces.C.long. + tv_nsec := Tv_Nsec_Long (T.tv_nsec); + end To_Struct_Timespec; + ----------------- -- To_Timespec -- ----------------- @@ -133,7 +165,7 @@ package body System.C_Time is tv_nsec => 1_000 * nsec_t (T.tv_usec)); end To_Timespec; - function To_Timespec (D : Duration) return timespec is + function To_Timespec (D : Non_Negative_Duration) return timespec is -- See To_Timeval. Dm1 : constant Duration range -1.0 .. Duration'Last - 1.0 := D - 1.0; Sec : constant time_t range -1 .. time_t'Last := time_t (Dm1); @@ -143,13 +175,14 @@ package body System.C_Time is if Duration'Size = 64 then Nsec := nsec_t (1_000_000_000 * Frac); else - -- Avoid an overflow when Duration'Last < 999_999_999. - Nsec := 10_000_000 * nsec_t (100 * Frac); + -- Duration'Last < 500_000_000 so there is an overflow issue, + -- easy to solve because Frac has few significative digits. + Nsec := 20_000_000 * nsec_t (50 * Frac); end if; if Nsec < 0 then - return (Sec, Nsec + 1_000_000_000); + return (tv_sec => Sec, tv_nsec => Nsec + 1_000_000_000); else - return (Sec + 1, Nsec); + return (tv_sec => Sec + 1, tv_nsec => Nsec); end if; end To_Timespec; @@ -157,7 +190,9 @@ package body System.C_Time is -- To_Timeval -- ----------------- - function To_Timeval (D : Duration) return timeval is + function To_Timeval (D : Non_Negative_Duration) return timeval is + + -- Most comments also apply to the timespec variant. -- Sec := time_t (D); -- Usec := usec_t (1_000_000 * (D - Duration (Sec))); @@ -167,17 +202,25 @@ package body System.C_Time is -- Sec := time_t (D - 0.5); -- Usec := usec_t (1_000_000 * (D - Duration (Sec))); - -- fails when D is - -- 0.0 (Sec is rounded down and Usec = 1_000_000) - -- 0.999_999_999 (Usec is rounded up to 1_000_000) + -- leads to Usec = 1_000_000 when D is + -- 0.0 (Sec is rounded down) + -- 0.999_999_999 (Usec is rounded up) (not an issue with timespec) - -- Converting D - 1 seems to solve overflow and simplify roundings. Dm1 : constant Duration range -1.0 .. Duration'Last - 1.0 := D - 1.0; + -- Converting D - 1 avoids overflows and simplifies roundings. + Sec : constant time_t range -1 .. time_t'Last := time_t (Dm1); + -- The conversion of Dm1 may overflow if time_t has 32 bits. + Frac : constant Duration range -0.5 .. 0.5 := Dm1 - Duration (Sec); + -- The conversion back is always possible, Sec <= Duration'Last - 0.5. + Usec : constant usec_t range -500_000 .. 500_000 := usec_t (1_000_000 * Frac); begin + -- Add the second substracted at the beginning, in a way fixing + -- the Usec interval if necessary. + -- In both cases, tv_sec may exceed MAX_tv_sec. if Usec < 0 then return (tv_sec => Sec, tv_usec => Usec + 1_000_000); else diff --git a/gcc/ada/libgnat/s-c_time.ads b/gcc/ada/libgnat/s-c_time.ads index e943dd0..8eaf22d 100644 --- a/gcc/ada/libgnat/s-c_time.ads +++ b/gcc/ada/libgnat/s-c_time.ads @@ -36,50 +36,63 @@ with Interfaces.C; private with System.OS_Constants; package System.C_Time - with Preelaborate + with Pure is - type timeval is private; -- Non negative duration in microseconds. + -- These C structs represent non negative durations with different + -- accuracies and maximal values. + type timespec is private; -- accurate to 1 nanosecond + type timeval is private; -- accurate to 1 microsecond - Timeval_Zero : constant timeval; - -- g-sothco.ads - - function To_Timeval (D : Duration) return timeval - with Pre => 0.0 <= D; - -- The value is rounded if Duration'Size = 64. - - function In_Duration (T : timeval) return Boolean - with Inline; - -- True if computing To_Duration (T) is safe, - -- False if Constraint Error would be raised. + -- Duration is accurate to either 1 nanosecond or 20 milliseconds. + subtype Non_Negative_Duration is Duration range 0.0 .. Duration'Last; - function To_Duration (T : timeval) return Duration - with Post => 0.0 <= To_Duration'Result; - -- The value is rounded if Duration'Size = 32. + -- All conversions round if the target type is less accurate than + -- the source type, away from zero if the source value is midway + -- between two values of the target type. + -- They raise Constraint_Error when the value, after rounding, + -- exceeds the last value of the target type. - type timespec is private; -- Non negative duration in nanoseconds. + function To_Duration (T : timespec) return Non_Negative_Duration; + function To_Duration (T : timeval) return Non_Negative_Duration; - function To_Timespec (D : Duration) return timespec - with Pre => 0.0 <= D; + function To_Timespec (D : Non_Negative_Duration) return timespec; + function To_Timeval (D : Non_Negative_Duration) return timeval; - function To_Duration (T : timespec) return Duration - with Post => 0.0 <= To_Duration'Result; - -- The value is rounded if Duration'Size = 32. + Timeval_Zero : constant timeval; + -- g-sothco.ads - -- Direct conversions avoiding an intermediate Duration that may - -- loose precision (when Duration'Size = 32) or overflow (when - -- time_t'Size = 64). + function In_Duration (T : timeval) return Boolean with Inline; + -- True if computing To_Duration (T) is safe, + -- False if Constraint Error would be raised. + -- g-socket.adb: - function Milliseconds_To_Timeval (M : Interfaces.C.int) return timeval - with Inline, - Pre => Interfaces.C."<=" (0, M); + subtype Non_Negative_Int is + Interfaces.C.int range 0 .. Interfaces.C.int'Last; - function Nanoseconds_To_Timespec (N : Interfaces.C.int) return timespec - with Inline, - Pre => Interfaces.C."<=" (0, N); + function Milliseconds_To_Timeval (M : Non_Negative_Int) return timeval + with Inline; + -- g-spogwa.adb - function To_Timespec (T : timeval) return timespec + function Nanoseconds_To_Timespec (N : Non_Negative_Int) return timespec + with Inline; + function To_Timespec (T : timeval) return timespec with Inline; + -- s-osinte__darwin.adb + + -- These functions are provided for backward compatibility, + -- but lead to non portable interfaces with C. + -- Tv_sec and tv_nsec do not match the long int type on x32, + -- or on 32 bits ARM with a 2038-compatible GNU libc. + + subtype Tv_Sec_Long is Interfaces.C.long range 0 .. Interfaces.C.long'Last; + subtype Tv_Nsec_Long is Interfaces.C.long range 0 .. 999_999_999; + function To_Duration (tv_sec : Tv_Sec_Long; + tv_nsec : Tv_Nsec_Long) return Non_Negative_Duration with Inline; + procedure To_Struct_Timespec (D : Non_Negative_Duration; + tv_sec : out Tv_Sec_Long; + tv_nsec : out Tv_Nsec_Long) with Inline; + -- a-calcon.ads private diff --git a/gcc/ada/libgnat/s-os_lib.adb b/gcc/ada/libgnat/s-os_lib.adb index 976d39c..20e109a 100644 --- a/gcc/ada/libgnat/s-os_lib.adb +++ b/gcc/ada/libgnat/s-os_lib.adb @@ -2980,7 +2980,7 @@ package body System.OS_Lib is -- To_Ada -- ------------ - function To_Ada (Time : Long_Long_Integer) return OS_Time is + function To_Ada (Time : time_t) return OS_Time is begin return OS_Time (Time); end To_Ada; @@ -3014,6 +3014,15 @@ package body System.OS_Lib is return Return_Val; end To_Path_String_Access; + ---------- + -- To_C -- + ---------- + + function To_C (Time : OS_Time) return time_t is + begin + return time_t (Time); + end To_C; + ------------------ -- Wait_Process -- ------------------ diff --git a/gcc/ada/libgnat/s-os_lib.ads b/gcc/ada/libgnat/s-os_lib.ads index c69e357..10157b6 100644 --- a/gcc/ada/libgnat/s-os_lib.ads +++ b/gcc/ada/libgnat/s-os_lib.ads @@ -165,8 +165,15 @@ package System.OS_Lib is -- Time_t Stuff -- ------------------ - function To_Ada (Time : Long_Long_Integer) return OS_Time; - -- Convert C time_t type to OS_Time + -- Note: Do not use time_t in the compiler and host-based tools; instead + -- use OS_Time. + + subtype time_t is Long_Long_Integer; + -- Supported for backward compatibility, but no longer related + -- with the C time_t type. For that, see System.C_Time. + + function To_C (Time : OS_Time) return time_t; + function To_Ada (Time : time_t) return OS_Time; ---------------- -- File Stuff -- @@ -1105,6 +1112,7 @@ private pragma Import (Intrinsic, ">"); pragma Import (Intrinsic, "<="); pragma Import (Intrinsic, ">="); + pragma Inline (To_C); pragma Inline (To_Ada); type Process_Id is new Integer; diff --git a/gcc/ada/libgnat/s-osprim__rtems.adb b/gcc/ada/libgnat/s-osprim__rtems.adb index f7b607a..6116345 100644 --- a/gcc/ada/libgnat/s-osprim__rtems.adb +++ b/gcc/ada/libgnat/s-osprim__rtems.adb @@ -29,7 +29,7 @@ -- -- ------------------------------------------------------------------------------ --- This version is for POSIX-like operating systems +-- This version is for POSIX-like operating systems, Darwin and Linux/x32. with System.C_Time; diff --git a/gcc/ada/libgnat/s-osprim__unix.adb b/gcc/ada/libgnat/s-osprim__unix.adb index c1c7e51..62e5e59 100644 --- a/gcc/ada/libgnat/s-osprim__unix.adb +++ b/gcc/ada/libgnat/s-osprim__unix.adb @@ -30,7 +30,8 @@ ------------------------------------------------------------------------------ -- This version uses gettimeofday and select --- This file is suitable for OpenNT, Dec Unix and SCO UnixWare. +-- This file is suitable for OpenNT, Dec Unix, SCO UnixWare +-- and Solaris (32 and 64 bits). with System.C_Time; diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index 8551d78..f579c93 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -1740,9 +1740,9 @@ CND(IPV6_V6ONLY, "Restricted to IPv6 communications only") -- Sizes (in bytes) of the components of struct timeval */ #define SIZEOF_tv_sec (sizeof tv.tv_sec) -CND(SIZEOF_tv_sec, "tv_sec, time_t") +CND(SIZEOF_tv_sec, "tv_sec") #define SIZEOF_tv_usec (sizeof tv.tv_usec) -CND(SIZEOF_tv_usec, "tv_usec, suseconds_t") +CND(SIZEOF_tv_usec, "tv_usec") /* -- Maximum allowed value for tv_sec @@ -1772,7 +1772,7 @@ CNS(MAX_tv_sec, "") -- The tv_sec field is the same than in struct timeval. */ #define SIZEOF_tv_nsec (sizeof (ts.tv_nsec)) -CND(SIZEOF_tv_nsec, "tv_nsec, long except on x32"); +CND(SIZEOF_tv_nsec, "tv_nsec"); } /*
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index f579c93..a64e578 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -1785,7 +1785,7 @@ CND(SIZEOF_tv_nsec, "tv_nsec"); -- The test is safe in files that do not require GNU specifically. */ -#ifdef __USE_TIME_BITS64 +#if defined(__USE_TIME64_REDIRECTS) || (__TIMESIZE == 32 && __USE_TIME_BITS64) C("Glibc_Use_Time_Bits64", Boolean, "True", "Y2038 Glibc transition") #else C("Glibc_Use_Time_Bits64", Boolean, "False", "Y2038 Glibc transition")
diff --git a/gcc/ada/libgnat/g-calend.ads b/gcc/ada/libgnat/g-calend.ads index 7791943..4a21d49 100644 --- a/gcc/ada/libgnat/g-calend.ads +++ b/gcc/ada/libgnat/g-calend.ads @@ -150,7 +150,6 @@ package GNAT.Calendar is function To_Duration (T : not null access timeval) return System.C_Time.Non_Negative_Duration - with Inline is (System.C_Time.To_Duration (T.all)); -- Deprecated. Please use C_Time directly. diff --git a/gcc/ada/libgnat/s-c_time.adb b/gcc/ada/libgnat/s-c_time.adb index d44727c..4a96c8d 100644 --- a/gcc/ada/libgnat/s-c_time.adb +++ b/gcc/ada/libgnat/s-c_time.adb @@ -67,8 +67,8 @@ package body System.C_Time is Maybe_Sec : constant := (if Dur_Covers_Tv_Sec then 1 else Sec); begin return Dur_Covers_Tv_Sec - or else T.tv_sec < Maybe_Sec - or else (T.tv_sec = Maybe_Sec and then T.tv_usec <= Usec); + or else T.tv_sec < Maybe_Sec + or else (T.tv_sec = Maybe_Sec and then T.tv_usec <= Usec); end In_Duration; -----------------------------
diff --git a/gcc/ada/libgnarl/a-exetim__posix.adb b/gcc/ada/libgnarl/a-exetim__posix.adb index db873fb..7fbd6c1 100644 --- a/gcc/ada/libgnarl/a-exetim__posix.adb +++ b/gcc/ada/libgnarl/a-exetim__posix.adb @@ -35,6 +35,7 @@ with Ada.Task_Identification; use Ada.Task_Identification; with Ada.Unchecked_Conversion; with System.C_Time; +with System.OS_Constants; with System.Tasking; with System.OS_Interface; use System.OS_Interface; with System.Task_Primitives.Operations; use System.Task_Primitives.Operations; @@ -115,7 +116,9 @@ package body Ada.Execution_Time is (clock_id : Interfaces.C.int; tp : access System.C_Time.timespec) return int; - pragma Import (C, clock_gettime, "clock_gettime"); + pragma Import (C, clock_gettime, + (if System.OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_gettime64" else "clock_gettime")); -- Function from the POSIX.1b Realtime Extensions library function pthread_getcpuclockid diff --git a/gcc/ada/libgnarl/s-linux__loongarch.ads b/gcc/ada/libgnarl/s-linux__loongarch.ads index 44d8c65..ae22441 100644 --- a/gcc/ada/libgnarl/s-linux__loongarch.ads +++ b/gcc/ada/libgnarl/s-linux__loongarch.ads @@ -43,7 +43,6 @@ package System.Linux is -- Time -- ---------- - subtype int is Interfaces.C.int; subtype clockid_t is Interfaces.C.int; ----------- diff --git a/gcc/ada/libgnarl/s-osinte__gnu.ads b/gcc/ada/libgnarl/s-osinte__gnu.ads index b4597c5..90ef2d5 100644 --- a/gcc/ada/libgnarl/s-osinte__gnu.ads +++ b/gcc/ada/libgnarl/s-osinte__gnu.ads @@ -39,6 +39,7 @@ -- Preelaborate. This package is designed to be a bottom-level (leaf) package with Interfaces.C; +with System.Os_Constants; with System.C_Time; with Ada.Unchecked_Conversion; @@ -208,7 +209,8 @@ package System.OS_Interface is -- Indicates whether time slicing is supported (i.e SCHED_RR is supported) function nanosleep (rqtp, rmtp : access C_Time.timespec) return int; - pragma Import (C, nanosleep, "nanosleep"); + pragma Import (C, nanosleep, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__nanosleep64" else "nanosleep")); type clockid_t is new int; CLOCK_REALTIME : constant clockid_t := 0; @@ -218,12 +220,14 @@ package System.OS_Interface is (clock_id : clockid_t; tp : access C_Time.timespec) return int; - pragma Import (C, clock_gettime, "clock_gettime"); + pragma Import (C, clock_gettime, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_gettime64" else "clock_gettime")); function clock_getres (clock_id : clockid_t; res : access C_Time.timespec) return int; - pragma Import (C, clock_getres, "clock_getres"); + pragma Import (C, clock_getres, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_getres64" else "clock_getres")); -- From: /usr/include/unistd.h function sysconf (name : int) return long; @@ -477,7 +481,9 @@ package System.OS_Interface is (cond : access pthread_cond_t; mutex : access pthread_mutex_t; abstime : access C_Time.timespec) return int; - pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait"); + pragma Import (C, pthread_cond_timedwait, + (if OS_Constants.Glibc_Use_Time_Bits64 then "__pthread_cond_timedwait64" + else "pthread_cond_timedwait")); Relative_Timed_Wait : constant Boolean := False; -- pthread_cond_timedwait requires an absolute delay time diff --git a/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads b/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads index 9b40c9a..59e6f79 100644 --- a/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads +++ b/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads @@ -40,6 +40,7 @@ with Ada.Unchecked_Conversion; with Interfaces.C; +with System.OS_Constants; with System.C_Time; package System.OS_Interface is @@ -203,7 +204,8 @@ package System.OS_Interface is -- Indicates whether time slicing is supported (i.e SCHED_RR is supported) function nanosleep (rqtp, rmtp : access C_Time.timespec) return int; - pragma Import (C, nanosleep, "nanosleep"); + pragma Import (C, nanosleep, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__nanosleep64" else "nanosleep")); type clockid_t is new int; CLOCK_REALTIME : constant clockid_t := 0; @@ -212,12 +214,14 @@ package System.OS_Interface is (clock_id : clockid_t; tp : access C_Time.timespec) return int; - pragma Import (C, clock_gettime, "clock_gettime"); + pragma Import (C, clock_gettime, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_gettime64" else "clock_gettime"); function clock_getres (clock_id : clockid_t; res : access C_Time.timespec) return int; - pragma Import (C, clock_getres, "clock_getres"); + pragma Import (C, clock_getres, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_getres64" else "clock_getres"); function sysconf (name : int) return long; pragma Import (C, sysconf); @@ -420,7 +424,9 @@ package System.OS_Interface is (cond : access pthread_cond_t; mutex : access pthread_mutex_t; abstime : access C_Time.timespec) return int; - pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait"); + pragma Import (C, pthread_cond_timedwait, + (if OS_Constants.Glibc_Use_Time_Bits64 then "__pthread_cond_timedwait64" + else "pthread_cond_timedwait"); -------------------------- -- POSIX.1c Section 13 -- diff --git a/gcc/ada/libgnarl/s-osinte__linux.ads b/gcc/ada/libgnarl/s-osinte__linux.ads index 9de227e..7a0d37d 100644 --- a/gcc/ada/libgnarl/s-osinte__linux.ads +++ b/gcc/ada/libgnarl/s-osinte__linux.ads @@ -229,12 +229,14 @@ package System.OS_Interface is function clock_gettime (clock_id : clockid_t; tp : access C_Time.timespec) return int; - pragma Import (C, clock_gettime, "clock_gettime"); + pragma Import (C, clock_gettime, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_gettime64" else "clock_gettime")); function clock_getres (clock_id : clockid_t; res : access C_Time.timespec) return int; - pragma Import (C, clock_getres, "clock_getres"); + pragma Import (C, clock_getres, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__clock_getres64" else "clock_getres")); function sysconf (name : int) return long; pragma Import (C, sysconf); @@ -445,7 +447,9 @@ package System.OS_Interface is (cond : access pthread_cond_t; mutex : access pthread_mutex_t; abstime : access C_Time.timespec) return int; - pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait"); + pragma Import (C, pthread_cond_timedwait, + (if OS_Constants.Glibc_Use_Time_Bits64 then "__pthread_cond_timedwait64" + else "pthread_cond_timedwait")); -------------------------- -- POSIX.1c Section 13 -- diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb index ccc4feb..02c2bab 100644 --- a/gcc/ada/libgnat/g-socket.adb +++ b/gcc/ada/libgnat/g-socket.adb @@ -2629,6 +2629,7 @@ package body GNAT.Sockets is (1 .. (if Option.Name = Bind_To_Device then C.size_t (ASU.Length (Option.Device) + 1) else 0)); + VT : aliased System.C_Time.timeval; Len : C.int; Add : System.Address := Null_Address; Res : C.int; diff --git a/gcc/ada/libgnat/g-spogwa.adb b/gcc/ada/libgnat/g-spogwa.adb index 530a6cd..598f3fc 100644 --- a/gcc/ada/libgnat/g-spogwa.adb +++ b/gcc/ada/libgnat/g-spogwa.adb @@ -42,7 +42,9 @@ is writefds : access FD_Set_Type; exceptfds : access FD_Set_Type; timeout : access System.C_Time.timeval) return Integer - with Import => True, Convention => Stdcall, External_Name => "select"; + with Import => True, Convention => Stdcall, + External_Name => (if System.OS_Constants.Glibc_Use_Time_Bits64 + then "__select64" else "select"); Timeout_V : aliased System.C_Time.timeval; Timeout_A : access System.C_Time.timeval; diff --git a/gcc/ada/libgnat/s-optide.adb b/gcc/ada/libgnat/s-optide.adb index 4ad16a2..a9025d0 100644 --- a/gcc/ada/libgnat/s-optide.adb +++ b/gcc/ada/libgnat/s-optide.adb @@ -41,7 +41,8 @@ is return Integer with Import, Convention => C, - External_Name => "nanosleep"; + External_Name => (if OS_Constants.Glibc_Use_Time_Bits64 + then "__nanosleep64" else "nanosleep"); Request : aliased C_Time.timespec; Remaind : aliased C_Time.timespec; diff --git a/gcc/ada/libgnat/s-osprim__posix.adb b/gcc/ada/libgnat/s-osprim__posix.adb index b331d5c..f647968 100644 --- a/gcc/ada/libgnat/s-osprim__posix.adb +++ b/gcc/ada/libgnat/s-osprim__posix.adb @@ -31,6 +31,7 @@ -- This version is for POSIX-like operating systems with System.C_Time; +with System.OS_Constants; package body System.OS_Primitives is @@ -47,7 +48,8 @@ package body System.OS_Primitives is function gettimeofday (Tv : access C_Time.timeval; Tz : System.Address := System.Null_Address) return Integer; - pragma Import (C, gettimeofday, "gettimeofday"); + pragma Import (C, gettimeofday, (if OS_Constants.Glibc_Use_Time_Bits64 + then "__gettimeofday64" else "gettimeofday")); begin -- The return codes for gettimeofday are as follows (from man pages): diff --git a/gcc/ada/libgnat/s-osprim__posix2008.adb b/gcc/ada/libgnat/s-osprim__posix2008.adb index 7f44efa..0dbde83 100644 --- a/gcc/ada/libgnat/s-osprim__posix2008.adb +++ b/gcc/ada/libgnat/s-osprim__posix2008.adb @@ -54,7 +54,8 @@ package body System.OS_Primitives is function clock_gettime (clock_id : clockid_t; tp : access C_Time.timespec) return int; - pragma Import (C, clock_gettime, "clock_gettime"); + pragma Import (C, clock_gettime, (if OS_Constants.Glibc_Use_Time_Bits64 + thon "__clock_gettime64" else "clock_gettime")); begin Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access); diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index 5beb929..8551d78 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -1775,6 +1775,22 @@ CNS(MAX_tv_sec, "") CND(SIZEOF_tv_nsec, "tv_nsec, long except on x32"); } +/* + + -- Functions with time_t suseconds_t timeval timespec parameters like + -- clock_get{res,time} gettimeofday nanosleep + -- pthread_cond_{,timed}wait select + -- must be imported from the GNU C library with + -- External_Name => (if Glibc_Use_Time_Bits64 then "__foo64" else "foo") + -- The test is safe in files that do not require GNU specifically. + +*/ +#ifdef __USE_TIME_BITS64 + C("Glibc_Use_Time_Bits64", Boolean, "True", "Y2038 Glibc transition") +#else + C("Glibc_Use_Time_Bits64", Boolean, "False", "Y2038 Glibc transition") +#endif + /* -- Sizes of various data types
diff --git a/gcc/ada/libgnat/s-c_time.adb b/gcc/ada/libgnat/s-c_time.adb index 9f862ec..26820a4 100644 --- a/gcc/ada/libgnat/s-c_time.adb +++ b/gcc/ada/libgnat/s-c_time.adb @@ -78,7 +78,7 @@ package body System.C_Time is R : constant int range 0 .. 999 := M mod 1_000; begin return (tv_sec => time_t (Q), - tv_usec => 1_000 * suseconds_t (R)); + tv_usec => 1_000 * usec_t (R)); end Milliseconds_To_Timeval; ----------------------------- @@ -90,8 +90,8 @@ package body System.C_Time is Q : constant int range 0 .. int'Last / 10**9 := N / 10**9; R : constant int range 0 .. 999_999_999 := N mod 10**9; begin - return (tv_sec => time_t (Q), - tv_nsec => snseconds_t (R)); + return (tv_sec => time_t (Q), + tv_nsec => nsec_t (R)); end Nanoseconds_To_Timespec; ----------------- @@ -130,7 +130,7 @@ package body System.C_Time is function To_Timespec (T : timeval) return timespec is begin return (tv_sec => T.tv_sec, - tv_nsec => 1_000 * snseconds_t (T.tv_usec)); + tv_nsec => 1_000 * nsec_t (T.tv_usec)); end To_Timespec; function To_Timespec (D : Duration) return timespec is @@ -138,13 +138,13 @@ package body System.C_Time is Dm1 : constant Duration range -1.0 .. Duration'Last - 1.0 := D - 1.0; Sec : constant time_t range -1 .. time_t'Last := time_t (Dm1); Frac : constant Duration range -0.5 .. 0.5 := Dm1 - Duration (Sec); - Nsec : snseconds_t range -500_000_000 .. 500_000_000; + Nsec : nsec_t range -500_000_000 .. 500_000_000; begin if Duration'Size = 64 then - Nsec := snseconds_t (1_000_000_000 * Frac); + Nsec := nsec_t (1_000_000_000 * Frac); else -- Avoid an overflow when Duration'Last < 999_999_999. - Nsec := 10_000_000 * snseconds_t (100 * Frac); + Nsec := 10_000_000 * nsec_t (100 * Frac); end if; if Nsec < 0 then return (Sec, Nsec + 1_000_000_000); @@ -160,13 +160,13 @@ package body System.C_Time is function To_Timeval (D : Duration) return timeval is -- Sec := time_t (D); - -- Usec := suseconds_t (1_000_000 * (D - Duration (Sec))); + -- Usec := usec_t (1_000_000 * (D - Duration (Sec))); -- fails when D is -- Duration'Last (Sec is rounded up and Duration (Sec) overflows) -- 0.9 (Sec is rounded up and Usec < 0) -- Sec := time_t (D - 0.5); - -- Usec := suseconds_t (1_000_000 * (D - Duration (Sec))); + -- Usec := usec_t (1_000_000 * (D - Duration (Sec))); -- fails when D is -- 0.0 (Sec is rounded down and Usec = 1_000_000) -- 0.999_999_999 (Usec is rounded up to 1_000_000) @@ -175,8 +175,8 @@ package body System.C_Time is Dm1 : constant Duration range -1.0 .. Duration'Last - 1.0 := D - 1.0; Sec : constant time_t range -1 .. time_t'Last := time_t (Dm1); Frac : constant Duration range -0.5 .. 0.5 := Dm1 - Duration (Sec); - Usec : constant suseconds_t range -500_000 .. 500_000 - := suseconds_t (1_000_000 * Frac); + Usec : constant usec_t range -500_000 .. 500_000 + := usec_t (1_000_000 * Frac); begin if Usec < 0 then return (tv_sec => Sec, tv_usec => Usec + 1_000_000); diff --git a/gcc/ada/libgnat/s-c_time.ads b/gcc/ada/libgnat/s-c_time.ads index 0feabb3..e943dd0 100644 --- a/gcc/ada/libgnat/s-c_time.ads +++ b/gcc/ada/libgnat/s-c_time.ads @@ -87,23 +87,26 @@ private 2 ** (OS_Constants.SIZEOF_tv_sec * 8 - 1) - 1 with Convention => C, Size => OS_Constants.SIZEOF_tv_sec * 8; - type suseconds_t is range -2 ** (OS_Constants.SIZEOF_tv_usec * 8 - 1) .. - 2 ** (OS_Constants.SIZEOF_tv_usec * 8 - 1) - 1 + type usec_t is range -2 ** (OS_Constants.SIZEOF_tv_usec * 8 - 1) .. + 2 ** (OS_Constants.SIZEOF_tv_usec * 8 - 1) - 1 with Convention => C, Size => OS_Constants.SIZEOF_tv_usec * 8; + -- Larger than the suseconds_t C type on ARM 32 bits with GNU libc + -- when __TIME_BITS=64. - type snseconds_t is range -2 ** (OS_Constants.SIZEOF_tv_nsec * 8 - 1) .. - 2 ** (OS_Constants.SIZEOF_tv_nsec * 8 - 1) - 1 + type nsec_t is range -2 ** (OS_Constants.SIZEOF_tv_nsec * 8 - 1) .. + 2 ** (OS_Constants.SIZEOF_tv_nsec * 8 - 1) - 1 with Convention => C, Size => OS_Constants.SIZEOF_tv_nsec * 8; + -- Larger than the signed long int C type on x32. type timeval is record - tv_sec : time_t range 0 .. OS_Constants.MAX_tv_sec; -- seconds - tv_usec : suseconds_t range 0 .. 999_999; -- microseconds + tv_sec : time_t range 0 .. OS_Constants.MAX_tv_sec; -- seconds + tv_usec : usec_t range 0 .. 999_999; -- microseconds end record with Convention => C; type timespec is record - tv_sec : time_t range 0 .. OS_Constants.MAX_tv_sec; -- seconds - tv_nsec : snseconds_t range 0 .. 999_999_999; -- nanoseconds + tv_sec : time_t range 0 .. OS_Constants.MAX_tv_sec; -- seconds + tv_nsec : nsec_t range 0 .. 999_999_999; -- nanoseconds end record with Convention => C;
diff --git a/gcc/ada/libgnarl/s-osinte__gnu.ads b/gcc/ada/libgnarl/s-osinte__gnu.ads index 90ef2d5..08884ec 100644 --- a/gcc/ada/libgnarl/s-osinte__gnu.ads +++ b/gcc/ada/libgnarl/s-osinte__gnu.ads @@ -39,7 +39,7 @@ -- Preelaborate. This package is designed to be a bottom-level (leaf) package with Interfaces.C; -with System.Os_Constants; +with System.OS_Constants; with System.C_Time; with Ada.Unchecked_Conversion;