PageRenderTime 50ms CodeModel.GetById 26ms app.highlight 18ms RepoModel.GetById 2ms app.codeStats 0ms

/contrib/ntp/sntp/timing.c

https://bitbucket.org/freebsd/freebsd-head/
C | 112 lines | 69 code | 29 blank | 14 comment | 19 complexity | 0d6b3f81762552ae0200f4c15838e25d MD5 | raw file
  1/*  Copyright (C) 1996 N.M. Maclaren
  2    Copyright (C) 1996 The University of Cambridge
  3
  4This includes all of the code needed to handle the time.  It assumes rather
  5more than is defined by POSIX, unfortunately.  Systems that do not have the
  6'X/Open' extensions may need changes. */
  7
  8
  9
 10#include "header.h"
 11
 12#include <sys/types.h>
 13#include <sys/time.h>
 14
 15#define TIMING
 16#include "kludges.h"
 17#undef TIMING
 18
 19
 20
 21#define MILLION_L    1000000l          /* For conversion to/from timeval */
 22#define MILLION_D       1.0e6          /* Must be equal to MILLION_L */
 23
 24
 25
 26double current_time (double offset) {
 27
 28/* Get the current UTC time in seconds since the Epoch plus an offset (usually
 29the time from the beginning of the century to the Epoch!) */
 30
 31    struct timeval current;
 32
 33    errno = 0;
 34    if (gettimeofday(&current,NULL))
 35        fatal(1,"unable to read current machine/system time",NULL);
 36    return offset+current.tv_sec+1.0e-6*current.tv_usec;
 37}
 38
 39
 40
 41time_t convert_time (double value, int *millisecs) {
 42
 43/* Convert the time to the ANSI C form. */
 44
 45    time_t result = (time_t)value;
 46
 47    if ((*millisecs = (int)(1000.0*(value-result))) >= 1000) {
 48        *millisecs = 0;
 49        ++result;
 50    }
 51    return result;
 52}
 53
 54
 55
 56void adjust_time (double difference, int immediate, double ignore) {
 57
 58/* Adjust the current UTC time.  This is portable, even if struct timeval uses
 59an unsigned long for tv_sec. */
 60
 61    struct timeval old, new, adjust, previous;
 62    char text[40];
 63    long n;
 64
 65/* Start by converting to timeval format. Note that we have to cater for
 66negative, unsigned values. */
 67
 68    if ((n = (long)difference) > difference) --n;
 69    adjust.tv_sec = n;
 70    adjust.tv_usec = (long)(MILLION_D*(difference-n));
 71    errno = 0;
 72    if (gettimeofday(&old,NULL))
 73        fatal(1,"unable to read machine/system time",NULL);
 74    new.tv_sec = old.tv_sec+adjust.tv_sec;
 75    new.tv_usec = (n = (long)old.tv_usec+(long)adjust.tv_usec);
 76    if (n < 0) {
 77        new.tv_usec += MILLION_L;
 78        --new.tv_sec;
 79    } else if (n >= MILLION_L) {
 80        new.tv_usec -= MILLION_L;
 81        ++new.tv_sec;
 82    }
 83
 84/* Now diagnose the situation if necessary, and perform the dirty deed. */
 85
 86    if (verbose > 2)
 87        fprintf(stderr,
 88            "Times: old=(%ld,%.6ld) new=(%ld,%.6ld) adjust=(%ld,%.6ld)\n",
 89            (long)old.tv_sec,(long)old.tv_usec,
 90            (long)new.tv_sec,(long)new.tv_usec,
 91            (long)adjust.tv_sec,(long)adjust.tv_usec);
 92    if (immediate) {
 93        errno = 0;
 94        if (settimeofday(&new,NULL))
 95            fatal(1,"unable to reset current system time",NULL);
 96    } else {
 97	previous.tv_sec  = 0;
 98	previous.tv_usec = 0;
 99        errno = 0;
100        if (adjtime(&adjust,&previous))
101            fatal(1,"unable to adjust current system time",NULL);
102        if (previous.tv_sec != 0 || previous.tv_usec != 0) {
103            sprintf(text,"(%ld,%.6ld)",
104                (long)previous.tv_sec,(long)previous.tv_usec);
105            if (previous.tv_sec+1.0e-6*previous.tv_usec > ignore)
106                fatal(0,"outstanding time adjustment %s",text);
107            else if (verbose)
108                fprintf(stderr,"%s: outstanding time adjustment %s\n",
109                    argv0,text);
110        }
111    }
112}