Exemplo n.º 1
0
/* 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
}
Exemplo n.º 2
0
/* 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 (&lt, &usecs))
    {
      values[7] = usecs / 1000;

      localtime_r (&lt, &local_time);
      gmtime_r (&lt, &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);
}