/* High resolution monotonic clock, falling back to the realtime clock if the target does not support such a clock. Arguments: secs - OUTPUT, seconds nanosecs - OUTPUT, nanoseconds tk - OUTPUT, clock resolution [counts/sec] If the target supports a monotonic clock, the OUTPUT arguments represent a monotonically incrementing clock starting from some unspecified time in the past. If a monotonic clock is not available, falls back to the realtime clock which is not monotonic. Return value: 0 for success, -1 for error. In case of error, errno is set. */ static int gf_gettime_mono (time_t * secs, long * nanosecs, long * tck) { int err; #ifdef HAVE_CLOCK_GETTIME struct timespec ts; *tck = 1000000000; err = clock_gettime (GF_CLOCK_MONOTONIC, &ts); *secs = ts.tv_sec; *nanosecs = ts.tv_nsec; return err; #else #if defined(HAVE_CLOCK_GETTIME_LIBRT) && SUPPORTS_WEAK && GTHREAD_USE_WEAK if (weak_gettime) { struct timespec ts; *tck = 1000000000; err = weak_gettime (GF_CLOCK_MONOTONIC, &ts); *secs = ts.tv_sec; *nanosecs = ts.tv_nsec; return err; } #endif *tck = 1000000; err = gf_gettime (secs, nanosecs); *nanosecs *= 1000; return err; #endif }
/* High resolution monotonic clock, falling back to the realtime clock if the target does not support such a clock. Arguments: secs - OUTPUT, seconds fracsecs - OUTPUT, fractional seconds, units given by tk argument tk - OUTPUT, clock resolution [counts/sec] If the target supports a monotonic clock, the OUTPUT arguments represent a monotonically incrementing clock starting from some unspecified time in the past. If a monotonic clock is not available, falls back to the realtime clock which is not monotonic. Return value: 0 for success, -1 for error. In case of error, errno is set. */ static int gf_gettime_mono (time_t * secs, long * fracsecs, long * tck) { int err; #ifdef HAVE_CLOCK_GETTIME struct timespec ts; *tck = 1000000000; err = clock_gettime (GF_CLOCK_MONOTONIC, &ts); *secs = ts.tv_sec; *fracsecs = ts.tv_nsec; return err; #else #if SUPPORTS_WEAKREF && defined(HAVE_CLOCK_GETTIME_LIBRT) if (weak_gettime) { struct timespec ts; *tck = 1000000000; err = weak_gettime (GF_CLOCK_MONOTONIC, &ts); *secs = ts.tv_sec; *fracsecs = ts.tv_nsec; return err; } #endif *tck = 1000000; err = gf_gettime (secs, fracsecs); return err; #endif }
void date_and_time (char *__date, char *__time, char *__zone, gfc_array_i4 *__values, GFC_INTEGER_4 __date_len, GFC_INTEGER_4 __time_len, GFC_INTEGER_4 __zone_len) { int i; char date[DATE_LEN + 1]; char timec[TIME_LEN + 1]; char zone[ZONE_LEN + 1]; GFC_INTEGER_4 values[VALUES_SIZE]; time_t lt; struct tm local_time; struct tm UTC_time; long usecs; if (!gf_gettime (<, &usecs)) { values[7] = usecs / 1000; localtime_r (<, &local_time); gmtime_r (<, &UTC_time); /* All arguments can be derived from VALUES. */ values[0] = 1900 + local_time.tm_year; values[1] = 1 + local_time.tm_mon; values[2] = local_time.tm_mday; values[3] = (local_time.tm_min - UTC_time.tm_min + 60 * (local_time.tm_hour - UTC_time.tm_hour + 24 * (local_time.tm_yday - UTC_time.tm_yday))); values[4] = local_time.tm_hour; values[5] = local_time.tm_min; values[6] = local_time.tm_sec; if (__date) snprintf (date, DATE_LEN + 1, "%04d%02d%02d", values[0], values[1], values[2]); if (__time) snprintf (timec, TIME_LEN + 1, "%02d%02d%02d.%03d", values[4], values[5], values[6], values[7]); if (__zone) snprintf (zone, ZONE_LEN + 1, "%+03d%02d", values[3] / 60, abs (values[3] % 60)); } else { memset (date, ' ', DATE_LEN); date[DATE_LEN] = '\0'; memset (timec, ' ', TIME_LEN); timec[TIME_LEN] = '\0'; memset (zone, ' ', ZONE_LEN); zone[ZONE_LEN] = '\0'; for (i = 0; i < VALUES_SIZE; i++) values[i] = - GFC_INTEGER_4_HUGE; } /* Copy the values into the arguments. */ if (__values) { index_type len, delta, elt_size; elt_size = GFC_DESCRIPTOR_SIZE (__values); len = GFC_DESCRIPTOR_EXTENT(__values,0); delta = GFC_DESCRIPTOR_STRIDE(__values,0); if (delta == 0) delta = 1; if (unlikely (len < VALUES_SIZE)) runtime_error ("Incorrect extent in VALUE argument to" " DATE_AND_TIME intrinsic: is %ld, should" " be >=%ld", (long int) len, (long int) VALUES_SIZE); /* Cope with different type kinds. */ if (elt_size == 4) { GFC_INTEGER_4 *vptr4 = __values->base_addr; for (i = 0; i < VALUES_SIZE; i++, vptr4 += delta) *vptr4 = values[i]; } else if (elt_size == 8) { GFC_INTEGER_8 *vptr8 = (GFC_INTEGER_8 *)__values->base_addr; for (i = 0; i < VALUES_SIZE; i++, vptr8 += delta) { if (values[i] == - GFC_INTEGER_4_HUGE) *vptr8 = - GFC_INTEGER_8_HUGE; else *vptr8 = values[i]; } } else abort (); } if (__zone) fstrcpy (__zone, __zone_len, zone, ZONE_LEN); if (__time) fstrcpy (__time, __time_len, timec, TIME_LEN); if (__date) fstrcpy (__date, __date_len, date, DATE_LEN); }