1 /* $NetBSD: timing.c,v 1.3 2006/05/10 21:53:14 mrg Exp $ */
3 /* Copyright (C) 1996 N.M. Maclaren
4 Copyright (C) 1996 The University of Cambridge
6 This includes all of the code needed to handle the time. It assumes rather
7 more than is defined by POSIX, unfortunately. Systems that do not have the
8 'X/Open' extensions may need changes. */
14 #include <sys/types.h>
23 #define MILLION_L 1000000l /* For conversion to/from timeval */
24 #define MILLION_D 1.0e6 /* Must be equal to MILLION_L */
28 double current_time (double offset
) {
30 /* Get the current UTC time in seconds since the Epoch plus an offset (usually
31 the time from the beginning of the century to the Epoch!) */
33 struct timeval current
;
36 if (gettimeofday(¤t
,NULL
))
37 fatal(1,"unable to read current machine/system time",NULL
);
38 return offset
+current
.tv_sec
+1.0e-6*current
.tv_usec
;
43 time_t convert_time (double value
, int *millisecs
) {
45 /* Convert the time to the ANSI C form. */
47 time_t result
= (time_t)value
;
49 if ((*millisecs
= (int)(1000.0*(value
-result
))) >= 1000) {
58 void adjust_time (double difference
, int immediate
, double ignore
) {
60 /* Adjust the current UTC time. This is portable, even if struct timeval uses
61 an unsigned long for tv_sec. */
63 struct timeval old
, new, adjust
, previous
;
67 /* Start by converting to timeval format. Note that we have to cater for
68 negative, unsigned values. */
70 previous
.tv_sec
= 0; /* XXX gcc */
71 previous
.tv_usec
= 0; /* XXX gcc */
73 if ((n
= (long)difference
) > difference
) --n
;
75 adjust
.tv_usec
= (long)(MILLION_D
*(difference
-n
));
77 if (gettimeofday(&old
,NULL
))
78 fatal(1,"unable to read machine/system time",NULL
);
79 new.tv_sec
= old
.tv_sec
+adjust
.tv_sec
;
80 new.tv_usec
= (n
= (long)old
.tv_usec
+(long)adjust
.tv_usec
);
82 new.tv_usec
+= MILLION_L
;
84 } else if (n
>= MILLION_L
) {
85 new.tv_usec
-= MILLION_L
;
89 /* Now diagnose the situation if necessary, and perform the dirty deed. */
93 "Times: old=(%ld,%.6ld) new=(%ld,%.6ld) adjust=(%ld,%.6ld)\n",
94 (long)old
.tv_sec
,(long)old
.tv_usec
,
95 (long)new.tv_sec
,(long)new.tv_usec
,
96 (long)adjust
.tv_sec
,(long)adjust
.tv_usec
);
99 if (settimeofday(&new,NULL
))
100 fatal(1,"unable to reset current system time",NULL
);
103 previous
.tv_usec
= 0;
105 if (adjtime(&adjust
,&previous
))
106 fatal(1,"unable to adjust current system time",NULL
);
107 if (previous
.tv_sec
!= 0 || previous
.tv_usec
!= 0) {
108 sprintf(text
,"(%ld,%.6ld)",
109 (long)previous
.tv_sec
,(long)previous
.tv_usec
);
110 if (previous
.tv_sec
+1.0e-6*previous
.tv_usec
> ignore
)
111 fatal(0,"outstanding time adjustment %s",text
);
113 fprintf(stderr
,"%s: outstanding time adjustment %s\n",