(root)/
util-linux-2.39/
lib/
monotonic.c
       1  /*
       2   * Please, don't add this file to libcommon because clock_gettime() requires
       3   * -lrt on systems with old libc.
       4   *
       5   * No copyright is claimed.  This code is in the public domain; do with
       6   * it what you wish.
       7   */
       8  #include <time.h>
       9  #include <signal.h>
      10  #ifdef HAVE_SYSINFO
      11  #include <sys/sysinfo.h>
      12  #endif
      13  #include <sys/time.h>
      14  
      15  #include "c.h"
      16  #include "monotonic.h"
      17  
      18  int get_boot_time(struct timeval *boot_time)
      19  {
      20  #ifdef CLOCK_BOOTTIME
      21  	struct timespec hires_uptime;
      22  	struct timeval lores_uptime;
      23  #endif
      24  	struct timeval now;
      25  #ifdef HAVE_SYSINFO
      26  	struct sysinfo info;
      27  #endif
      28  
      29  	if (gettimeofday(&now, NULL) != 0)
      30  		return -errno;
      31  #ifdef CLOCK_BOOTTIME
      32  	if (clock_gettime(CLOCK_BOOTTIME, &hires_uptime) == 0) {
      33  		TIMESPEC_TO_TIMEVAL(&lores_uptime, &hires_uptime);
      34  		timersub(&now, &lores_uptime, boot_time);
      35  		return 0;
      36  	}
      37  #endif
      38  #ifdef HAVE_SYSINFO
      39  	/* fallback */
      40  	if (sysinfo(&info) != 0)
      41  		return -errno;
      42  
      43  	boot_time->tv_sec = now.tv_sec - info.uptime;
      44  	boot_time->tv_usec = 0;
      45  	return 0;
      46  #else
      47  	return -ENOSYS;
      48  #endif
      49  }
      50  
      51  usec_t get_suspended_time(void)
      52  {
      53  #if defined(CLOCK_BOOTTIME) && defined(CLOCK_MONOTONIC)
      54  	struct timespec boot, mono;
      55  
      56  	if (clock_gettime(CLOCK_BOOTTIME, &boot) == 0 &&
      57  	    clock_gettime(CLOCK_MONOTONIC, &mono) == 0)
      58  		return timespec_to_usec(&boot) - timespec_to_usec(&mono);
      59  #endif
      60  	return 0;
      61  }
      62  
      63  int gettime_monotonic(struct timeval *tv)
      64  {
      65  #ifdef CLOCK_MONOTONIC
      66  	/* Can slew only by ntp and adjtime */
      67  	int ret;
      68  	struct timespec ts;
      69  
      70  	/* Linux specific, can't slew */
      71  	if (!(ret = clock_gettime(UL_CLOCK_MONOTONIC, &ts))) {
      72  		tv->tv_sec = ts.tv_sec;
      73  		tv->tv_usec = ts.tv_nsec / 1000;
      74  	}
      75  	return ret;
      76  #else
      77  	return gettimeofday(tv, NULL);
      78  #endif
      79  }
      80  
      81