Blame tests/test_clock.c

Packit 6bd9ab
/*
Packit 6bd9ab
   test_clock.c - tests for finding usable system clocks
Packit 6bd9ab
   This file is part of the nss-pam-ldapd library.
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 2013-2015 Arthur de Jong
Packit 6bd9ab
Packit 6bd9ab
   This library is free software; you can redistribute it and/or
Packit 6bd9ab
   modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
   License as published by the Free Software Foundation; either
Packit 6bd9ab
   version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
Packit 6bd9ab
   This library is distributed in the hope that it will be useful,
Packit 6bd9ab
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
   Lesser General Public License for more details.
Packit 6bd9ab
Packit 6bd9ab
   You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
   License along with this library; if not, write to the Free Software
Packit 6bd9ab
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
   02110-1301 USA
Packit 6bd9ab
*/
Packit 6bd9ab
Packit 6bd9ab
#include "config.h"
Packit 6bd9ab
Packit 6bd9ab
#include <stdio.h>
Packit 6bd9ab
#include <assert.h>
Packit 6bd9ab
#include <time.h>
Packit 6bd9ab
#include <errno.h>
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
#include <stdlib.h>
Packit 6bd9ab
Packit 6bd9ab
#include "compat/attrs.h"
Packit 6bd9ab
Packit 6bd9ab
/* use clock_gettime() to see if the specified clock is supported */
Packit 6bd9ab
static int test_clock_gettime(clockid_t c, const char *cname)
Packit 6bd9ab
{
Packit 6bd9ab
  struct timespec t1 = {0, 0};
Packit 6bd9ab
  struct timespec t2 = {0, 0};
Packit 6bd9ab
  struct timespec t3 = {0, 50 * 1000 * 1000}; /* 50 msec */
Packit 6bd9ab
  struct timespec t4 = {0, 0};
Packit 6bd9ab
  long diff;
Packit 6bd9ab
  int result = 0;
Packit 6bd9ab
  /* see if we can get resolution (not important so ignore any failures) */
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  if (clock_getres(c, &t1))
Packit 6bd9ab
    printf("     clock %s resolution not supported: %s\n", cname, strerror(errno));
Packit 6bd9ab
  if ((t1.tv_sec != 0) || (t1.tv_nsec != 0))
Packit 6bd9ab
    printf("     clock %s resolution: %ld.%09ld\n", cname, (long)t1.tv_sec, (long)t1.tv_nsec);
Packit 6bd9ab
  /* see if we can get the time */
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  if (clock_gettime(c, &t2))
Packit 6bd9ab
  {
Packit 6bd9ab
    printf("FAIL clock %s get time not supported: %s\n",
Packit 6bd9ab
           cname, strerror(errno));
Packit 6bd9ab
    if ((t2.tv_sec != 0) || (t2.tv_nsec != 0))
Packit 6bd9ab
      printf("     clock %s time: %ld.%09ld\n", cname, (long)t2.tv_sec, (long)t2.tv_nsec);
Packit 6bd9ab
    return -1;
Packit 6bd9ab
  }
Packit 6bd9ab
  else
Packit 6bd9ab
    printf("OK   clock %s time: %ld.%09ld\n", cname, (long)t2.tv_sec, (long)t2.tv_nsec);
Packit 6bd9ab
  /* quick sleep (assume we're not interrupted) */
Packit 6bd9ab
  (void)nanosleep(&t3, NULL);
Packit 6bd9ab
  /* see if we can get the time again */
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  if (clock_gettime(c, &t4))
Packit 6bd9ab
  {
Packit 6bd9ab
    printf("FAIL clock %s get time twice not supported: %s\n",
Packit 6bd9ab
           cname, strerror(errno));
Packit 6bd9ab
    if ((t4.tv_sec != 0) || (t4.tv_nsec != 0))
Packit 6bd9ab
      printf("     clock %s time: %ld.%09ld\n", cname, (long)t4.tv_sec, (long)t4.tv_nsec);
Packit 6bd9ab
    return -1;
Packit 6bd9ab
  }
Packit 6bd9ab
  else
Packit 6bd9ab
    printf("OK   clock %s time: %ld.%09ld\n", cname, (long)t4.tv_sec, (long)t4.tv_nsec);
Packit 6bd9ab
  /* calculate difference */
Packit 6bd9ab
  diff = ((long)t4.tv_sec - (long)t2.tv_sec - (long)t3.tv_sec) * 1000000000L +
Packit 6bd9ab
         ((long)t4.tv_nsec - (long)t2.tv_nsec - (long)t3.tv_nsec);
Packit 6bd9ab
  if ((diff < (-10 * 1000 * 1000)) || (diff > (20 * 1000 * 1000)))
Packit 6bd9ab
  {
Packit 6bd9ab
    result = -1;
Packit 6bd9ab
    printf("FAIL ");
Packit 6bd9ab
  }
Packit 6bd9ab
  else
Packit 6bd9ab
    printf("OK   ");
Packit 6bd9ab
  printf("clock %s time diff: %s%ld.%09ld %.1f%%\n", cname, (diff < 0) ? "-" : "",
Packit 6bd9ab
         (labs(diff) / 1000000000L), (labs(diff) % 1000000000L),
Packit 6bd9ab
         (float)labs(diff) / (float)((long)t3.tv_sec * 10000000L + (long)t3.tv_nsec / 100));
Packit 6bd9ab
  return result;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* wrapper for test_clock_gettime() that passes the clock name */
Packit 6bd9ab
#define TEST_CLOCK_GETTIME(clock) test_clock_gettime(clock, #clock)
Packit 6bd9ab
Packit 6bd9ab
int main(int UNUSED(argc), char UNUSED(*argv[]))
Packit 6bd9ab
{
Packit 6bd9ab
  int found_clocks = 0;
Packit 6bd9ab
#ifdef CLOCK_MONOTONIC_RAW
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_RAW))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_MONOTONIC_FAST
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_FAST))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_MONOTONIC_COARSE
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_COARSE))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_MONOTONIC
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_UPTIME_FAST
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_UPTIME_FAST))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_UPTIME
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_UPTIME))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_BOOTTIME
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_BOOTTIME))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_MONOTONIC_PRECISE
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_PRECISE))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_UPTIME_PRECISE
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_UPTIME_PRECISE))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_HIGHRES
Packit 6bd9ab
#if CLOCK_HIGHRES == CLOCK_MONOTONIC
Packit 6bd9ab
  printf("     CLOCK_HIGHRES == CLOCK_MONOTONIC\n");
Packit 6bd9ab
#else
Packit 6bd9ab
  /* for Solaris, should be similar to CLOCK_MONOTONIC (it may be an alias) */
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_HIGHRES))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_REALTIME_FAST
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME_FAST))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
#ifdef CLOCK_REALTIME_COARSE
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME_COARSE))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#ifdef CLOCK_REALTIME_PRECISE
Packit 6bd9ab
  if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME_PRECISE))
Packit 6bd9ab
    found_clocks++;
Packit 6bd9ab
#endif
Packit 6bd9ab
  printf("%d usable clocks found\n", found_clocks);
Packit 6bd9ab
  return !(found_clocks > 0);
Packit 6bd9ab
}