xref: /minix3/minix/lib/libsys/clock_time.c (revision d91f738bd8d93aa6befa2a8d07581040607a512a)
1ad80a203SDavid van Moolenbroek 
2ad80a203SDavid van Moolenbroek #include "sysutil.h"
3ad80a203SDavid van Moolenbroek #include <sys/time.h>
4ad80a203SDavid van Moolenbroek 
5ad80a203SDavid van Moolenbroek /*
6ad80a203SDavid van Moolenbroek  * This routine returns the time in seconds since 1.1.1970.  MINIX is an
7ad80a203SDavid van Moolenbroek  * astrophysically naive system that assumes the earth rotates at a constant
8ad80a203SDavid van Moolenbroek  * rate and that such things as leap seconds do not exist.  If a non-NULL
9ad80a203SDavid van Moolenbroek  * pointer to a timespec structure is given, that structure is filled with
10ad80a203SDavid van Moolenbroek  * the current time in subsecond precision.
11ad80a203SDavid van Moolenbroek  */
12ad80a203SDavid van Moolenbroek time_t
clock_time(struct timespec * tv)13ad80a203SDavid van Moolenbroek clock_time(struct timespec *tv)
14ad80a203SDavid van Moolenbroek {
15*d91f738bSDavid van Moolenbroek 	struct minix_kerninfo *minix_kerninfo;
16ad80a203SDavid van Moolenbroek 	uint32_t system_hz;
17*d91f738bSDavid van Moolenbroek 	clock_t realtime;
18ad80a203SDavid van Moolenbroek 	time_t boottime, sec;
19ad80a203SDavid van Moolenbroek 
20*d91f738bSDavid van Moolenbroek 	minix_kerninfo = get_minix_kerninfo();
21ad80a203SDavid van Moolenbroek 
22*d91f738bSDavid van Moolenbroek 	/* We assume atomic 32-bit field retrieval.  TODO: 64-bit support. */
23*d91f738bSDavid van Moolenbroek 	boottime = minix_kerninfo->kclockinfo->boottime;
24*d91f738bSDavid van Moolenbroek 	realtime = minix_kerninfo->kclockinfo->realtime;
25*d91f738bSDavid van Moolenbroek 	system_hz = minix_kerninfo->kclockinfo->hz;
26ad80a203SDavid van Moolenbroek 
27ad80a203SDavid van Moolenbroek 	sec = boottime + realtime / system_hz;
28ad80a203SDavid van Moolenbroek 
29ad80a203SDavid van Moolenbroek 	if (tv != NULL) {
30ad80a203SDavid van Moolenbroek 		tv->tv_sec = sec;
31ad80a203SDavid van Moolenbroek 
32ad80a203SDavid van Moolenbroek 		/*
33ad80a203SDavid van Moolenbroek 		 * We do not want to overflow, and system_hz can be as high as
34ad80a203SDavid van Moolenbroek 		 * 50kHz.
35ad80a203SDavid van Moolenbroek 		 */
36ad80a203SDavid van Moolenbroek 		if (system_hz < LONG_MAX / 40000)
37ad80a203SDavid van Moolenbroek 			tv->tv_nsec = (realtime % system_hz) * 40000 /
38ad80a203SDavid van Moolenbroek 			    system_hz * 25000;
39ad80a203SDavid van Moolenbroek 		else
40ad80a203SDavid van Moolenbroek 			tv->tv_nsec = 0;	/* bad, but what's better? */
41ad80a203SDavid van Moolenbroek 	}
42ad80a203SDavid van Moolenbroek 
43ad80a203SDavid van Moolenbroek 	return sec;
44ad80a203SDavid van Moolenbroek }
45