libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
time.h
1/*
2 * CDDL HEADER START
3 *
4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
7 * 1.0 of the CDDL.
8 *
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
12 *
13 * CDDL HEADER END
14*/
15/*
16 * Copyright 2017 Saso Kiselkov. All rights reserved.
17 */
18
19#ifndef _ACF_UTILS_TIME_H_
20#define _ACF_UTILS_TIME_H_
21
22#include <stdint.h>
23#include <time.h>
24
25#include "assert.h"
26#include "core.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define USEC2SEC(usec) ((usec) / 1000000.0)
33#define SEC2USEC(sec) ((sec) * 1000000ll)
34#define NSEC2SEC(usec) ((usec) / 1000000000.0)
35#define SEC2NSEC(sec) ((sec) * 1000000000ll)
36
37static inline uint64_t
38microclock(void)
39{
40#if IBM
41 LARGE_INTEGER val, freq;
42 QueryPerformanceFrequency(&freq);
43 QueryPerformanceCounter(&val);
44 return ((val.QuadPart * 1000000llu) / freq.QuadPart);
45#else /* !IBM */
46 struct timespec ts;
47 VERIFY0(clock_gettime(CLOCK_REALTIME, &ts));
48 return ((ts.tv_sec * 1000000llu) + (ts.tv_nsec / 1000llu));
49#endif
50}
51
52/* Not portable */
53static inline uint64_t
54nanoclock(void)
55{
56#if IBM
57 return (microclock() * 1000llu);
58#else /* !IBM */
59 struct timespec ts;
60 VERIFY0(clock_gettime(CLOCK_MONOTONIC, &ts));
61 return (ts.tv_sec * 1000000000llu + ts.tv_nsec);
62#endif /* !IBM */
63}
64
65/*
66 * Converts a struct tm specified in UTC (not local time) into unixtime.
67 * This only considers the following fields from the tm structure, tm_year,
68 * tm_yday, tm_hour, tm_min and tm_sec. Any other fields are ignored.
69 */
70time_t lacf_timegm(const struct tm *tm);
71
72/*
73 * Returns time in the system's real time clock as the number of microseconds
74 * since UTC 1970-01-01 (unixtime). In essence, this is a microsecond-
75 * accurate time_t.
76 */
77static inline uint64_t
78lacf_microtime(void)
79{
80#if IBM
81 /*
82 * On windows, we emulate this by simply adding the millisecond
83 * portion onto the whole Unixtime seconds provided by time().
84 */
85 uint64_t time_micro = ((uint64_t)time(NULL)) * 1000000llu;
86 SYSTEMTIME st;
87 GetSystemTime(&st);
88 return (time_micro + (uint64_t)st.wMilliseconds * 1000llu);
89#else /* !IBM */
90 /* On Mac & Linux, microclock already does this */
91 return (microclock());
92#endif /* !IBM */
93}
94
95/*
96 * Takes day-of-year (or an X-Plane "local_date_days" value) and converts
97 * it to month + day-of-month in the format used in the "tm" structure
98 * (see the C89 standard gmtime, ctime, asctime or localtime functions).
99 *
100 * @param days The input value of the number of days since January 1.
101 * The function always assumes a non-leap year (consistent with
102 * X-Plane's behavior).
103 * @param tm_mon If not NULL, this is filled with the month (0-11).
104 * @param tm_mday If not NULL, this is filled with the day-of-month (1-31).
105 */
106static inline void
107lacf_yday_to_mon_mday(unsigned days, int *tm_mon, int *tm_mday)
108{
109 static const unsigned month2days[12] = {
110 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
111 };
112 for (int i = 11; i >= 0; i--) {
113 if (month2days[i] <= days) {
114 if (tm_mon != NULL)
115 *tm_mon = i;
116 if (tm_mday != NULL)
117 *tm_mday = days - month2days[i] + 1;
118 return;
119 }
120 }
121 VERIFY_FAIL();
122}
123
124#ifdef __cplusplus
125}
126#endif
127
128#endif /* _ACF_UTILS_TIME_H_ */
#define VERIFY_FAIL()
Definition assert.h:160
#define VERIFY0(x)
Definition assert.h:154