VirtualBox

source: vbox/trunk/include/iprt/time.h@ 95897

Last change on this file since 95897 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 41.1 KB
Line 
1/** @file
2 * IPRT - Time.
3 */
4
5/*
6 * Copyright (C) 2006-2022 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_time_h
27#define IPRT_INCLUDED_time_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34#include <iprt/assertcompile.h>
35
36RT_C_DECLS_BEGIN
37
38/** @defgroup grp_rt_time RTTime - Time
39 * @ingroup grp_rt
40 * @{
41 */
42
43/** Time Specification.
44 *
45 * Use the inline RTTimeSpecGet/Set to operate on structure this so we
46 * can easily change the representation if required later.
47 *
48 * The current representation is in nanoseconds relative to the unix epoch
49 * (1970-01-01 00:00:00 UTC). This gives us an approximate span from
50 * 1678 to 2262 without sacrificing the resolution offered by the various
51 * host OSes (BSD & LINUX 1ns, NT 100ns).
52 */
53typedef struct RTTIMESPEC
54{
55 /** Nanoseconds since epoch.
56 * The name is intentially too long to be comfortable to use because you should be
57 * using inline helpers! */
58 int64_t i64NanosecondsRelativeToUnixEpoch;
59} RTTIMESPEC;
60
61
62/** @name RTTIMESPEC methods
63 * @{ */
64
65/**
66 * Gets the time as nanoseconds relative to the unix epoch.
67 *
68 * @returns Nanoseconds relative to unix epoch.
69 * @param pTime The time spec to interpret.
70 */
71DECLINLINE(int64_t) RTTimeSpecGetNano(PCRTTIMESPEC pTime)
72{
73 return pTime->i64NanosecondsRelativeToUnixEpoch;
74}
75
76
77/**
78 * Sets the time give by nanoseconds relative to the unix epoch.
79 *
80 * @returns pTime.
81 * @param pTime The time spec to modify.
82 * @param i64Nano The new time in nanoseconds.
83 */
84DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNano(PRTTIMESPEC pTime, int64_t i64Nano)
85{
86 pTime->i64NanosecondsRelativeToUnixEpoch = i64Nano;
87 return pTime;
88}
89
90
91/**
92 * Gets the time as microseconds relative to the unix epoch.
93 *
94 * @returns microseconds relative to unix epoch.
95 * @param pTime The time spec to interpret.
96 */
97DECLINLINE(int64_t) RTTimeSpecGetMicro(PCRTTIMESPEC pTime)
98{
99 return pTime->i64NanosecondsRelativeToUnixEpoch / RT_NS_1US;
100}
101
102
103/**
104 * Sets the time given by microseconds relative to the unix epoch.
105 *
106 * @returns pTime.
107 * @param pTime The time spec to modify.
108 * @param i64Micro The new time in microsecond.
109 */
110DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMicro(PRTTIMESPEC pTime, int64_t i64Micro)
111{
112 pTime->i64NanosecondsRelativeToUnixEpoch = i64Micro * RT_NS_1US;
113 return pTime;
114}
115
116
117/**
118 * Gets the time as milliseconds relative to the unix epoch.
119 *
120 * @returns milliseconds relative to unix epoch.
121 * @param pTime The time spec to interpret.
122 */
123DECLINLINE(int64_t) RTTimeSpecGetMilli(PCRTTIMESPEC pTime)
124{
125 return pTime->i64NanosecondsRelativeToUnixEpoch / RT_NS_1MS;
126}
127
128
129/**
130 * Sets the time given by milliseconds relative to the unix epoch.
131 *
132 * @returns pTime.
133 * @param pTime The time spec to modify.
134 * @param i64Milli The new time in milliseconds.
135 */
136DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMilli(PRTTIMESPEC pTime, int64_t i64Milli)
137{
138 pTime->i64NanosecondsRelativeToUnixEpoch = i64Milli * RT_NS_1MS;
139 return pTime;
140}
141
142
143/**
144 * Gets the time as seconds relative to the unix epoch.
145 *
146 * @returns seconds relative to unix epoch.
147 * @param pTime The time spec to interpret.
148 */
149DECLINLINE(int64_t) RTTimeSpecGetSeconds(PCRTTIMESPEC pTime)
150{
151 return pTime->i64NanosecondsRelativeToUnixEpoch / RT_NS_1SEC;
152}
153
154
155/**
156 * Sets the time given by seconds relative to the unix epoch.
157 *
158 * @returns pTime.
159 * @param pTime The time spec to modify.
160 * @param i64Seconds The new time in seconds.
161 */
162DECLINLINE(PRTTIMESPEC) RTTimeSpecSetSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
163{
164 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * RT_NS_1SEC;
165 return pTime;
166}
167
168
169/**
170 * Makes the time spec absolute like abs() does (i.e. a positive value).
171 *
172 * @returns pTime.
173 * @param pTime The time spec to modify.
174 */
175DECLINLINE(PRTTIMESPEC) RTTimeSpecAbsolute(PRTTIMESPEC pTime)
176{
177 if (pTime->i64NanosecondsRelativeToUnixEpoch < 0)
178 pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
179 return pTime;
180}
181
182
183/**
184 * Negates the time.
185 *
186 * @returns pTime.
187 * @param pTime The time spec to modify.
188 */
189DECLINLINE(PRTTIMESPEC) RTTimeSpecNegate(PRTTIMESPEC pTime)
190{
191 pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
192 return pTime;
193}
194
195
196/**
197 * Adds a time period to the time.
198 *
199 * @returns pTime.
200 * @param pTime The time spec to modify.
201 * @param pTimeAdd The time spec to add to pTime.
202 */
203DECLINLINE(PRTTIMESPEC) RTTimeSpecAdd(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeAdd)
204{
205 pTime->i64NanosecondsRelativeToUnixEpoch += pTimeAdd->i64NanosecondsRelativeToUnixEpoch;
206 return pTime;
207}
208
209
210/**
211 * Adds a time period give as nanoseconds from the time.
212 *
213 * @returns pTime.
214 * @param pTime The time spec to modify.
215 * @param i64Nano The time period in nanoseconds.
216 */
217DECLINLINE(PRTTIMESPEC) RTTimeSpecAddNano(PRTTIMESPEC pTime, int64_t i64Nano)
218{
219 pTime->i64NanosecondsRelativeToUnixEpoch += i64Nano;
220 return pTime;
221}
222
223
224/**
225 * Adds a time period give as microseconds from the time.
226 *
227 * @returns pTime.
228 * @param pTime The time spec to modify.
229 * @param i64Micro The time period in microseconds.
230 */
231DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMicro(PRTTIMESPEC pTime, int64_t i64Micro)
232{
233 pTime->i64NanosecondsRelativeToUnixEpoch += i64Micro * RT_NS_1US;
234 return pTime;
235}
236
237
238/**
239 * Adds a time period give as milliseconds from the time.
240 *
241 * @returns pTime.
242 * @param pTime The time spec to modify.
243 * @param i64Milli The time period in milliseconds.
244 */
245DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMilli(PRTTIMESPEC pTime, int64_t i64Milli)
246{
247 pTime->i64NanosecondsRelativeToUnixEpoch += i64Milli * RT_NS_1MS;
248 return pTime;
249}
250
251
252/**
253 * Adds a time period give as seconds from the time.
254 *
255 * @returns pTime.
256 * @param pTime The time spec to modify.
257 * @param i64Seconds The time period in seconds.
258 */
259DECLINLINE(PRTTIMESPEC) RTTimeSpecAddSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
260{
261 pTime->i64NanosecondsRelativeToUnixEpoch += i64Seconds * RT_NS_1SEC;
262 return pTime;
263}
264
265
266/**
267 * Subtracts a time period from the time.
268 *
269 * @returns pTime.
270 * @param pTime The time spec to modify.
271 * @param pTimeSub The time spec to subtract from pTime.
272 */
273DECLINLINE(PRTTIMESPEC) RTTimeSpecSub(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeSub)
274{
275 pTime->i64NanosecondsRelativeToUnixEpoch -= pTimeSub->i64NanosecondsRelativeToUnixEpoch;
276 return pTime;
277}
278
279
280/**
281 * Subtracts a time period give as nanoseconds from the time.
282 *
283 * @returns pTime.
284 * @param pTime The time spec to modify.
285 * @param i64Nano The time period in nanoseconds.
286 */
287DECLINLINE(PRTTIMESPEC) RTTimeSpecSubNano(PRTTIMESPEC pTime, int64_t i64Nano)
288{
289 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Nano;
290 return pTime;
291}
292
293
294/**
295 * Subtracts a time period give as microseconds from the time.
296 *
297 * @returns pTime.
298 * @param pTime The time spec to modify.
299 * @param i64Micro The time period in microseconds.
300 */
301DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMicro(PRTTIMESPEC pTime, int64_t i64Micro)
302{
303 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Micro * RT_NS_1US;
304 return pTime;
305}
306
307
308/**
309 * Subtracts a time period give as milliseconds from the time.
310 *
311 * @returns pTime.
312 * @param pTime The time spec to modify.
313 * @param i64Milli The time period in milliseconds.
314 */
315DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMilli(PRTTIMESPEC pTime, int64_t i64Milli)
316{
317 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Milli * RT_NS_1MS;
318 return pTime;
319}
320
321
322/**
323 * Subtracts a time period give as seconds from the time.
324 *
325 * @returns pTime.
326 * @param pTime The time spec to modify.
327 * @param i64Seconds The time period in seconds.
328 */
329DECLINLINE(PRTTIMESPEC) RTTimeSpecSubSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
330{
331 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Seconds * RT_NS_1SEC;
332 return pTime;
333}
334
335
336/**
337 * Gives the time in seconds and nanoseconds.
338 *
339 * @returns pTime.
340 * @param pTime The time spec to interpret.
341 * @param *pi32Seconds Where to store the time period in seconds.
342 * @param *pi32Nano Where to store the time period in nanoseconds.
343 */
344DECLINLINE(void) RTTimeSpecGetSecondsAndNano(PRTTIMESPEC pTime, int32_t *pi32Seconds, int32_t *pi32Nano)
345{
346 int64_t i64 = RTTimeSpecGetNano(pTime);
347 int32_t i32Nano = (int32_t)(i64 % RT_NS_1SEC);
348 i64 /= RT_NS_1SEC;
349 if (i32Nano < 0)
350 {
351 i32Nano += RT_NS_1SEC;
352 i64--;
353 }
354 *pi32Seconds = (int32_t)i64;
355 *pi32Nano = i32Nano;
356}
357
358/** @def RTTIME_LINUX_KERNEL_PREREQ
359 * Prerequisite minimum linux kernel version.
360 * @note Cannot really be moved to iprt/cdefs.h, see the-linux-kernel.h */
361/** @def RTTIME_LINUX_KERNEL_PREREQ_LT
362 * Prerequisite maxium linux kernel version (LT=less-than).
363 * @note Cannot really be moved to iprt/cdefs.h, see the-linux-kernel.h */
364#if defined(RT_OS_LINUX) && defined(LINUX_VERSION_CODE) && defined(KERNEL_VERSION)
365# define RTTIME_LINUX_KERNEL_PREREQ(a, b, c) (LINUX_VERSION_CODE >= KERNEL_VERSION(a, b, c))
366# define RTTIME_LINUX_KERNEL_PREREQ_LT(a, b, c) (!RTTIME_LINUX_KERNEL_PREREQ(a, b, c))
367#else
368# define RTTIME_LINUX_KERNEL_PREREQ(a, b, c) 0
369# define RTTIME_LINUX_KERNEL_PREREQ_LT(a, b, c) 0
370#endif
371
372/* PORTME: Add struct timeval guard macro here. */
373#if defined(RTTIME_INCL_TIMEVAL) \
374 || defined(_SYS__TIMEVAL_H_) \
375 || defined(_SYS_TIME_H) \
376 || defined(_TIMEVAL) \
377 || defined(_STRUCT_TIMEVAL) \
378 || ( defined(RT_OS_LINUX) \
379 && defined(_LINUX_TIME_H) \
380 && ( !defined(__KERNEL__) \
381 || RTTIME_LINUX_KERNEL_PREREQ_LT(5,6,0) /* @bugref{9757} */ ) ) \
382 || (defined(RT_OS_NETBSD) && defined(_SYS_TIME_H_))
383
384/**
385 * Gets the time as POSIX timeval.
386 *
387 * @returns pTime.
388 * @param pTime The time spec to interpret.
389 * @param pTimeval Where to store the time as POSIX timeval.
390 */
391DECLINLINE(struct timeval *) RTTimeSpecGetTimeval(PCRTTIMESPEC pTime, struct timeval *pTimeval)
392{
393 int64_t i64 = RTTimeSpecGetMicro(pTime);
394 int32_t i32Micro = (int32_t)(i64 % RT_US_1SEC);
395 i64 /= RT_US_1SEC;
396 if (i32Micro < 0)
397 {
398 i32Micro += RT_US_1SEC;
399 i64--;
400 }
401 pTimeval->tv_sec = (time_t)i64;
402 pTimeval->tv_usec = i32Micro;
403 return pTimeval;
404}
405
406/**
407 * Sets the time as POSIX timeval.
408 *
409 * @returns pTime.
410 * @param pTime The time spec to modify.
411 * @param pTimeval Pointer to the POSIX timeval struct with the new time.
412 */
413DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimeval(PRTTIMESPEC pTime, const struct timeval *pTimeval)
414{
415 return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
416}
417
418#endif /* various ways of detecting struct timeval */
419
420
421/* PORTME: Add struct timespec guard macro here. */
422#if defined(RTTIME_INCL_TIMESPEC) \
423 || defined(_SYS__TIMESPEC_H_) \
424 || defined(TIMEVAL_TO_TIMESPEC) \
425 || defined(_TIMESPEC) \
426 || ( defined(_STRUCT_TIMESPEC) \
427 && ( !defined(RT_OS_LINUX) \
428 || !defined(__KERNEL__) \
429 || RTTIME_LINUX_KERNEL_PREREQ_LT(5,6,0) /* @bugref{9757} */ ) ) \
430 || (defined(RT_OS_NETBSD) && defined(_SYS_TIME_H_))
431
432/**
433 * Gets the time as POSIX timespec.
434 *
435 * @returns pTimespec.
436 * @param pTime The time spec to interpret.
437 * @param pTimespec Where to store the time as POSIX timespec.
438 */
439DECLINLINE(struct timespec *) RTTimeSpecGetTimespec(PCRTTIMESPEC pTime, struct timespec *pTimespec)
440{
441 int64_t i64 = RTTimeSpecGetNano(pTime);
442 int32_t i32Nano = (int32_t)(i64 % RT_NS_1SEC);
443 i64 /= RT_NS_1SEC;
444 if (i32Nano < 0)
445 {
446 i32Nano += RT_NS_1SEC;
447 i64--;
448 }
449 pTimespec->tv_sec = (time_t)i64;
450 pTimespec->tv_nsec = i32Nano;
451 return pTimespec;
452}
453
454/**
455 * Sets the time as POSIX timespec.
456 *
457 * @returns pTime.
458 * @param pTime The time spec to modify.
459 * @param pTimespec Pointer to the POSIX timespec struct with the new time.
460 */
461DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec(PRTTIMESPEC pTime, const struct timespec *pTimespec)
462{
463 return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
464}
465
466#endif /* various ways of detecting struct timespec */
467
468
469#if defined(RT_OS_LINUX) && defined(_LINUX_TIME64_H) /* since linux 3.17 */
470
471/**
472 * Gets the time a linux 64-bit timespec structure.
473 * @returns pTimespec.
474 * @param pTime The time spec to modify.
475 * @param pTimespec Where to store the time as linux 64-bit timespec.
476 */
477DECLINLINE(struct timespec64 *) RTTimeSpecGetTimespec64(PCRTTIMESPEC pTime, struct timespec64 *pTimespec)
478{
479 int64_t i64 = RTTimeSpecGetNano(pTime);
480 int32_t i32Nano = (int32_t)(i64 % RT_NS_1SEC);
481 i64 /= RT_NS_1SEC;
482 if (i32Nano < 0)
483 {
484 i32Nano += RT_NS_1SEC;
485 i64--;
486 }
487 pTimespec->tv_sec = i64;
488 pTimespec->tv_nsec = i32Nano;
489 return pTimespec;
490}
491
492/**
493 * Sets the time from a linux 64-bit timespec structure.
494 * @returns pTime.
495 * @param pTime The time spec to modify.
496 * @param pTimespec Pointer to the linux 64-bit timespec struct with the new time.
497 */
498DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec64(PRTTIMESPEC pTime, const struct timespec64 *pTimespec)
499{
500 return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
501}
502
503#endif /* RT_OS_LINUX && _LINUX_TIME64_H */
504
505
506/** The offset of the unix epoch and the base for NT time (in 100ns units).
507 * Nt time starts at 1601-01-01 00:00:00. */
508#define RTTIME_NT_TIME_OFFSET_UNIX (116444736000000000LL)
509
510
511/**
512 * Gets the time as NT time.
513 *
514 * @returns NT time.
515 * @param pTime The time spec to interpret.
516 */
517DECLINLINE(int64_t) RTTimeSpecGetNtTime(PCRTTIMESPEC pTime)
518{
519 return pTime->i64NanosecondsRelativeToUnixEpoch / 100
520 + RTTIME_NT_TIME_OFFSET_UNIX;
521}
522
523
524/**
525 * Sets the time given by Nt time.
526 *
527 * @returns pTime.
528 * @param pTime The time spec to modify.
529 * @param u64NtTime The new time in Nt time.
530 */
531DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtTime(PRTTIMESPEC pTime, uint64_t u64NtTime)
532{
533 pTime->i64NanosecondsRelativeToUnixEpoch =
534 ((int64_t)u64NtTime - RTTIME_NT_TIME_OFFSET_UNIX) * 100;
535 return pTime;
536}
537
538
539#ifdef _FILETIME_
540
541/**
542 * Gets the time as NT file time.
543 *
544 * @returns pFileTime.
545 * @param pTime The time spec to interpret.
546 * @param pFileTime Pointer to NT filetime structure.
547 */
548DECLINLINE(PFILETIME) RTTimeSpecGetNtFileTime(PCRTTIMESPEC pTime, PFILETIME pFileTime)
549{
550 *((uint64_t *)pFileTime) = RTTimeSpecGetNtTime(pTime);
551 return pFileTime;
552}
553
554/**
555 * Sets the time as NT file time.
556 *
557 * @returns pTime.
558 * @param pTime The time spec to modify.
559 * @param pFileTime Where to store the time as Nt file time.
560 */
561DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtFileTime(PRTTIMESPEC pTime, const FILETIME *pFileTime)
562{
563 return RTTimeSpecSetNtTime(pTime, *(const uint64_t *)pFileTime);
564}
565
566#endif /* _FILETIME_ */
567
568
569/** The offset to the start of DOS time.
570 * DOS time starts 1980-01-01 00:00:00. */
571#define RTTIME_OFFSET_DOS_TIME (315532800000000000LL)
572
573
574/**
575 * Gets the time as seconds relative to the start of dos time.
576 *
577 * @returns seconds relative to the start of dos time.
578 * @param pTime The time spec to interpret.
579 */
580DECLINLINE(int64_t) RTTimeSpecGetDosSeconds(PCRTTIMESPEC pTime)
581{
582 return (pTime->i64NanosecondsRelativeToUnixEpoch - RTTIME_OFFSET_DOS_TIME)
583 / RT_NS_1SEC;
584}
585
586
587/**
588 * Sets the time given by seconds relative to the start of dos time.
589 *
590 * @returns pTime.
591 * @param pTime The time spec to modify.
592 * @param i64Seconds The new time in seconds relative to the start of dos time.
593 */
594DECLINLINE(PRTTIMESPEC) RTTimeSpecSetDosSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
595{
596 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * RT_NS_1SEC
597 + RTTIME_OFFSET_DOS_TIME;
598 return pTime;
599}
600
601
602/**
603 * Compare two time specs.
604 *
605 * @returns true they are equal.
606 * @returns false they are not equal.
607 * @param pTime1 The 1st time spec.
608 * @param pTime2 The 2nd time spec.
609 */
610DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2)
611{
612 return pTime1->i64NanosecondsRelativeToUnixEpoch == pTime2->i64NanosecondsRelativeToUnixEpoch;
613}
614
615
616/**
617 * Compare two time specs.
618 *
619 * @returns 0 if equal, -1 if @a pLeft is smaller, 1 if @a pLeft is larger.
620 * @returns false they are not equal.
621 * @param pLeft The 1st time spec.
622 * @param pRight The 2nd time spec.
623 */
624DECLINLINE(int) RTTimeSpecCompare(PCRTTIMESPEC pLeft, PCRTTIMESPEC pRight)
625{
626 if (pLeft->i64NanosecondsRelativeToUnixEpoch == pRight->i64NanosecondsRelativeToUnixEpoch)
627 return 0;
628 return pLeft->i64NanosecondsRelativeToUnixEpoch < pRight->i64NanosecondsRelativeToUnixEpoch ? -1 : 1;
629}
630
631
632/**
633 * Converts a time spec to a ISO date string.
634 *
635 * @returns psz on success.
636 * @returns NULL on buffer underflow.
637 * @param pTime The time spec.
638 * @param psz Where to store the string.
639 * @param cb The size of the buffer.
640 */
641RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb);
642
643/**
644 * Attempts to convert an ISO date string to a time structure.
645 *
646 * We're a little forgiving with zero padding, unspecified parts, and leading
647 * and trailing spaces.
648 *
649 * @retval pTime on success,
650 * @retval NULL on failure.
651 * @param pTime The time spec.
652 * @param pszString The ISO date string to convert.
653 */
654RTDECL(PRTTIMESPEC) RTTimeSpecFromString(PRTTIMESPEC pTime, const char *pszString);
655
656/** @} */
657
658
659/**
660 * Exploded time.
661 */
662typedef struct RTTIME
663{
664 /** The year number. */
665 int32_t i32Year;
666 /** The month of the year (1-12). January is 1. */
667 uint8_t u8Month;
668 /** The day of the week (0-6). Monday is 0. */
669 uint8_t u8WeekDay;
670 /** The day of the year (1-366). January the 1st is 1. */
671 uint16_t u16YearDay;
672 /** The day of the month (1-31). */
673 uint8_t u8MonthDay;
674 /** Hour of the day (0-23). */
675 uint8_t u8Hour;
676 /** The minute of the hour (0-59). */
677 uint8_t u8Minute;
678 /** The second of the minute (0-60).
679 * (u32Nanosecond / 1000000) */
680 uint8_t u8Second;
681 /** The nanoseconds of the second (0-999999999). */
682 uint32_t u32Nanosecond;
683 /** Flags, of the RTTIME_FLAGS_* \#defines. */
684 uint32_t fFlags;
685 /** UTC time offset in minutes (-840-840). Positive for timezones east of
686 * UTC, negative for zones to the west. Same as what RTTimeLocalDeltaNano
687 * & RTTimeLocalDeltaNanoFor returns, just different unit. */
688 int32_t offUTC;
689} RTTIME;
690AssertCompileSize(RTTIME, 24);
691/** Pointer to a exploded time structure. */
692typedef RTTIME *PRTTIME;
693/** Pointer to a const exploded time structure. */
694typedef const RTTIME *PCRTTIME;
695
696/** @name RTTIME::fFlags values.
697 * @{ */
698/** Set if the time is UTC. If clear the time local time. */
699#define RTTIME_FLAGS_TYPE_MASK 3
700/** the time is UTC time. */
701#define RTTIME_FLAGS_TYPE_UTC 2
702/** The time is local time. */
703#define RTTIME_FLAGS_TYPE_LOCAL 3
704
705/** Set if the time is local and daylight saving time is in effect.
706 * Not bit is not valid if RTTIME_FLAGS_NO_DST_DATA is set. */
707#define RTTIME_FLAGS_DST RT_BIT(4)
708/** Set if the time is local and there is no data available on daylight saving time. */
709#define RTTIME_FLAGS_NO_DST_DATA RT_BIT(5)
710/** Set if the year is a leap year.
711 * This is mutual exclusiv with RTTIME_FLAGS_COMMON_YEAR. */
712#define RTTIME_FLAGS_LEAP_YEAR RT_BIT(6)
713/** Set if the year is a common year.
714 * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
715#define RTTIME_FLAGS_COMMON_YEAR RT_BIT(7)
716/** The mask of valid flags. */
717#define RTTIME_FLAGS_MASK UINT32_C(0xff)
718/** @} */
719
720
721/**
722 * Gets the current system time (UTC).
723 *
724 * @returns pTime.
725 * @param pTime Where to store the time.
726 */
727RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime);
728
729/**
730 * Sets the system time.
731 *
732 * @returns IPRT status code
733 * @param pTime The new system time (UTC).
734 *
735 * @remarks This will usually fail because changing the wall time is usually
736 * requires extra privileges.
737 */
738RTDECL(int) RTTimeSet(PCRTTIMESPEC pTime);
739
740/**
741 * Explodes a time spec (UTC).
742 *
743 * @returns pTime.
744 * @param pTime Where to store the exploded time.
745 * @param pTimeSpec The time spec to exploded.
746 */
747RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
748
749/**
750 * Implodes exploded time to a time spec (UTC).
751 *
752 * @returns pTime on success.
753 * @returns NULL if the pTime data is invalid.
754 * @param pTimeSpec Where to store the imploded UTC time.
755 * If pTime specifies a time which outside the range, maximum or
756 * minimum values will be returned.
757 * @param pTime Pointer to the exploded time to implode.
758 * The fields u8Month, u8WeekDay and u8MonthDay are not used,
759 * and all the other fields are expected to be within their
760 * bounds. Use RTTimeNormalize() to calculate u16YearDay and
761 * normalize the ranges of the fields.
762 */
763RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
764
765/**
766 * Normalizes the fields of a time structure.
767 *
768 * It is possible to calculate year-day from month/day and vice
769 * versa. If you adjust any of of these, make sure to zero the
770 * other so you make it clear which of the fields to use. If
771 * it's ambiguous, the year-day field is used (and you get
772 * assertions in debug builds).
773 *
774 * All the time fields and the year-day or month/day fields will
775 * be adjusted for overflows. (Since all fields are unsigned, there
776 * is no underflows.) It is possible to exploit this for simple
777 * date math, though the recommended way of doing that to implode
778 * the time into a timespec and do the math on that.
779 *
780 * @returns pTime on success.
781 * @returns NULL if the data is invalid.
782 *
783 * @param pTime The time structure to normalize.
784 *
785 * @remarks This function doesn't work with local time, only with UTC time.
786 */
787RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
788
789/**
790 * Gets the current local system time.
791 *
792 * @returns pTime.
793 * @param pTime Where to store the local time.
794 */
795RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
796
797/**
798 * Gets the current delta between UTC and local time.
799 *
800 * @code
801 * RTTIMESPEC LocalTime;
802 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
803 * @endcode
804 *
805 * @returns Returns the nanosecond delta between UTC and local time.
806 */
807RTDECL(int64_t) RTTimeLocalDeltaNano(void);
808
809/**
810 * Gets the delta between UTC and local time at the given time.
811 *
812 * @code
813 * RTTIMESPEC LocalTime;
814 * RTTimeNow(&LocalTime);
815 * RTTimeSpecAddNano(&LocalTime, RTTimeLocalDeltaNanoFor(&LocalTime));
816 * @endcode
817 *
818 * @param pTimeSpec The time spec giving the time to get the delta for.
819 * @returns Returns the nanosecond delta between UTC and local time.
820 */
821RTDECL(int64_t) RTTimeLocalDeltaNanoFor(PCRTTIMESPEC pTimeSpec);
822
823/**
824 * Explodes a time spec to the localized timezone.
825 *
826 * @returns pTime.
827 * @param pTime Where to store the exploded time.
828 * @param pTimeSpec The time spec to exploded (UTC).
829 */
830RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
831
832/**
833 * Normalizes the fields of a time structure containing local time.
834 *
835 * See RTTimeNormalize for details.
836 *
837 * @returns pTime on success.
838 * @returns NULL if the data is invalid.
839 * @param pTime The time structure to normalize.
840 */
841RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
842
843/**
844 * Converts a time structure to UTC, relying on UTC offset information
845 * if it contains local time.
846 *
847 * @returns pTime on success.
848 * @returns NULL if the data is invalid.
849 * @param pTime The time structure to convert.
850 */
851RTDECL(PRTTIME) RTTimeConvertToZulu(PRTTIME pTime);
852
853/**
854 * Converts a time spec to a ISO date string.
855 *
856 * @returns psz on success.
857 * @returns NULL on buffer underflow.
858 * @param pTime The time. Caller should've normalized this.
859 * @param psz Where to store the string.
860 * @param cb The size of the buffer.
861 */
862RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
863
864/**
865 * Converts a time spec to a ISO date string, extended version.
866 *
867 * @returns Output string length on success (positive), VERR_BUFFER_OVERFLOW
868 * (negative) or VERR_OUT_OF_RANGE (negative) on failure.
869 * @param pTime The time. Caller should've normalized this.
870 * @param psz Where to store the string.
871 * @param cb The size of the buffer.
872 * @param cFractionDigits Number of digits in the fraction. Max is 9.
873 */
874RTDECL(ssize_t) RTTimeToStringEx(PCRTTIME pTime, char *psz, size_t cb, unsigned cFractionDigits);
875
876/** Suggested buffer length for RTTimeToString and RTTimeToStringEx output, including terminator. */
877#define RTTIME_STR_LEN 40
878
879/**
880 * Attempts to convert an ISO date string to a time structure.
881 *
882 * We're a little forgiving with zero padding, unspecified parts, and leading
883 * and trailing spaces.
884 *
885 * @retval pTime on success,
886 * @retval NULL on failure.
887 * @param pTime Where to store the time on success.
888 * @param pszString The ISO date string to convert.
889 */
890RTDECL(PRTTIME) RTTimeFromString(PRTTIME pTime, const char *pszString);
891
892/**
893 * Formats the given time on a RTC-2822 compliant format.
894 *
895 * @returns Output string length on success (positive), VERR_BUFFER_OVERFLOW
896 * (negative) on failure.
897 * @param pTime The time. Caller should've normalized this.
898 * @param psz Where to store the string.
899 * @param cb The size of the buffer.
900 * @param fFlags RTTIME_RFC2822_F_XXX
901 * @sa RTTIME_RFC2822_LEN
902 */
903RTDECL(ssize_t) RTTimeToRfc2822(PRTTIME pTime, char *psz, size_t cb, uint32_t fFlags);
904
905/** Suggested buffer length for RTTimeToRfc2822 output, including terminator. */
906#define RTTIME_RFC2822_LEN 40
907/** @name RTTIME_RFC2822_F_XXX
908 * @{ */
909/** Use the deprecated GMT timezone instead of +/-0000.
910 * This is required by the HTTP RFC-7231 7.1.1.1. */
911#define RTTIME_RFC2822_F_GMT RT_BIT_32(0)
912/** @} */
913
914/**
915 * Attempts to convert an RFC-2822 date string to a time structure.
916 *
917 * We're a little forgiving with zero padding, unspecified parts, and leading
918 * and trailing spaces.
919 *
920 * @retval pTime on success,
921 * @retval NULL on failure.
922 * @param pTime Where to store the time on success.
923 * @param pszString The ISO date string to convert.
924 */
925RTDECL(PRTTIME) RTTimeFromRfc2822(PRTTIME pTime, const char *pszString);
926
927/**
928 * Checks if a year is a leap year or not.
929 *
930 * @returns true if it's a leap year.
931 * @returns false if it's a common year.
932 * @param i32Year The year in question.
933 */
934RTDECL(bool) RTTimeIsLeapYear(int32_t i32Year);
935
936/**
937 * Compares two normalized time structures.
938 *
939 * @retval 0 if equal.
940 * @retval -1 if @a pLeft is earlier than @a pRight.
941 * @retval 1 if @a pRight is earlier than @a pLeft.
942 *
943 * @param pLeft The left side time. NULL is accepted.
944 * @param pRight The right side time. NULL is accepted.
945 *
946 * @note A NULL time is considered smaller than anything else. If both are
947 * NULL, they are considered equal.
948 */
949RTDECL(int) RTTimeCompare(PCRTTIME pLeft, PCRTTIME pRight);
950
951/**
952 * Gets the current nanosecond timestamp.
953 *
954 * @returns nanosecond timestamp.
955 */
956RTDECL(uint64_t) RTTimeNanoTS(void);
957
958/**
959 * Gets the current millisecond timestamp.
960 *
961 * @returns millisecond timestamp.
962 */
963RTDECL(uint64_t) RTTimeMilliTS(void);
964
965/**
966 * Debugging the time api.
967 *
968 * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
969 */
970RTDECL(uint32_t) RTTimeDbgSteps(void);
971
972/**
973 * Debugging the time api.
974 *
975 * @returns the number of times the TSC interval expired RTTimeNanoTS().
976 */
977RTDECL(uint32_t) RTTimeDbgExpired(void);
978
979/**
980 * Debugging the time api.
981 *
982 * @returns the number of bad previous values encountered by RTTimeNanoTS().
983 */
984RTDECL(uint32_t) RTTimeDbgBad(void);
985
986/**
987 * Debugging the time api.
988 *
989 * @returns the number of update races in RTTimeNanoTS().
990 */
991RTDECL(uint32_t) RTTimeDbgRaces(void);
992
993
994RTDECL(const char *) RTTimeNanoTSWorkerName(void);
995
996
997/** @name RTTimeNanoTS GIP worker functions, for TM.
998 * @{ */
999
1000/** Extra info optionally returned by the RTTimeNanoTS GIP workers. */
1001typedef struct RTITMENANOTSEXTRA
1002{
1003 /** The TSC value used (delta adjusted). */
1004 uint64_t uTSCValue;
1005} RTITMENANOTSEXTRA;
1006/** Pointer to extra info optionally returned by the RTTimeNanoTS GIP workers. */
1007typedef RTITMENANOTSEXTRA *PRTITMENANOTSEXTRA;
1008
1009/** Pointer to a RTTIMENANOTSDATA structure. */
1010typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
1011
1012/**
1013 * Nanosecond timestamp data.
1014 *
1015 * This is used to keep track of statistics and callback so IPRT
1016 * and TM (VirtualBox) can share code.
1017 *
1018 * @remark Keep this in sync with the assembly version in timesupA.asm.
1019 */
1020typedef struct RTTIMENANOTSDATA
1021{
1022 /** Where the previous timestamp is stored.
1023 * This is maintained to ensure that time doesn't go backwards or anything. */
1024 uint64_t volatile *pu64Prev;
1025
1026 /**
1027 * Helper function that's used by the assembly routines when something goes bust.
1028 *
1029 * @param pData Pointer to this structure.
1030 * @param u64NanoTS The calculated nano ts.
1031 * @param u64DeltaPrev The delta relative to the previously returned timestamp.
1032 * @param u64PrevNanoTS The previously returned timestamp (as it was read it).
1033 */
1034 DECLCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
1035
1036 /**
1037 * Callback for when rediscovery is required.
1038 *
1039 * @returns Nanosecond timestamp.
1040 * @param pData Pointer to this structure.
1041 * @param pExtra Where to return extra time info. Optional.
1042 */
1043 DECLCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra));
1044
1045 /**
1046 * Callback for when some CPU index related stuff goes wrong.
1047 *
1048 * @returns Nanosecond timestamp.
1049 * @param pData Pointer to this structure.
1050 * @param pExtra Where to return extra time info. Optional.
1051 * @param idApic The APIC ID if available, otherwise (UINT16_MAX-1).
1052 * @param iCpuSet The CPU set index if available, otherwise
1053 * (UINT16_MAX-1).
1054 * @param iGipCpu The GIP CPU array index if available, otherwise
1055 * (UINT16_MAX-1).
1056 */
1057 DECLCALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra,
1058 uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
1059
1060 /** Number of 1ns steps because of overshooting the period. */
1061 uint32_t c1nsSteps;
1062 /** The number of times the interval expired (overflow). */
1063 uint32_t cExpired;
1064 /** Number of "bad" previous values. */
1065 uint32_t cBadPrev;
1066 /** The number of update races. */
1067 uint32_t cUpdateRaces;
1068} RTTIMENANOTSDATA;
1069
1070#ifndef IN_RING3
1071/**
1072 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
1073 */
1074typedef struct RTTIMENANOTSDATAR3
1075{
1076 R3PTRTYPE(uint64_t volatile *) pu64Prev;
1077 DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
1078 DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra));
1079 DECLR3CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra,
1080 uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
1081 uint32_t c1nsSteps;
1082 uint32_t cExpired;
1083 uint32_t cBadPrev;
1084 uint32_t cUpdateRaces;
1085} RTTIMENANOTSDATAR3;
1086#else
1087typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
1088#endif
1089
1090#ifndef IN_RING0
1091/**
1092 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
1093 */
1094typedef struct RTTIMENANOTSDATAR0
1095{
1096 R0PTRTYPE(uint64_t volatile *) pu64Prev;
1097 DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
1098 DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra));
1099 DECLR0CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra,
1100 uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
1101 uint32_t c1nsSteps;
1102 uint32_t cExpired;
1103 uint32_t cBadPrev;
1104 uint32_t cUpdateRaces;
1105} RTTIMENANOTSDATAR0;
1106#else
1107typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
1108#endif
1109
1110#ifndef IN_RC
1111/**
1112 * The RC layout of the RTTIMENANOTSDATA structure.
1113 */
1114typedef struct RTTIMENANOTSDATARC
1115{
1116 RCPTRTYPE(uint64_t volatile *) pu64Prev;
1117 DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
1118 DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra));
1119 DECLRCCALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra,
1120 uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu));
1121 uint32_t c1nsSteps;
1122 uint32_t cExpired;
1123 uint32_t cBadPrev;
1124 uint32_t cUpdateRaces;
1125} RTTIMENANOTSDATARC;
1126#else
1127typedef RTTIMENANOTSDATA RTTIMENANOTSDATARC;
1128#endif
1129
1130/** Internal RTTimeNanoTS worker (assembly). */
1131typedef DECLCALLBACKTYPE(uint64_t, FNTIMENANOTSINTERNAL,(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra));
1132/** Pointer to an internal RTTimeNanoTS worker (assembly). */
1133typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
1134RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarNoDelta(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1135RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarNoDelta(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1136#ifdef IN_RING3
1137RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicId(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1138RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicIdExt0B(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1139RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicIdExt8000001E(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1140RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscp(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1141RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1142RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseIdtrLim(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1143RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1144RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt0B(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1145RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt8000001E(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1146RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1147RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1148RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicId(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1149RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicIdExt0B(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1150RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicIdExt8000001E(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1151RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscp(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1152RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1153RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseIdtrLim(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1154RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1155RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt0B(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1156RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt8000001E(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1157RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1158RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1159#else
1160RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1161RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDelta(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1162RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1163RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDelta(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra);
1164#endif
1165
1166/** @} */
1167
1168
1169/**
1170 * Gets the current nanosecond timestamp.
1171 *
1172 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
1173 * resolution or performance optimizations.
1174 *
1175 * @returns nanosecond timestamp.
1176 */
1177RTDECL(uint64_t) RTTimeSystemNanoTS(void);
1178
1179/**
1180 * Gets the current millisecond timestamp.
1181 *
1182 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
1183 * resolution or performance optimizations.
1184 *
1185 * @returns millisecond timestamp.
1186 */
1187RTDECL(uint64_t) RTTimeSystemMilliTS(void);
1188
1189/**
1190 * Get the nanosecond timestamp relative to program startup.
1191 *
1192 * @returns Timestamp relative to program startup.
1193 */
1194RTDECL(uint64_t) RTTimeProgramNanoTS(void);
1195
1196/**
1197 * Get the microsecond timestamp relative to program startup.
1198 *
1199 * @returns Timestamp relative to program startup.
1200 */
1201RTDECL(uint64_t) RTTimeProgramMicroTS(void);
1202
1203/**
1204 * Get the millisecond timestamp relative to program startup.
1205 *
1206 * @returns Timestamp relative to program startup.
1207 */
1208RTDECL(uint64_t) RTTimeProgramMilliTS(void);
1209
1210/**
1211 * Get the second timestamp relative to program startup.
1212 *
1213 * @returns Timestamp relative to program startup.
1214 */
1215RTDECL(uint32_t) RTTimeProgramSecTS(void);
1216
1217/**
1218 * Get the RTTimeNanoTS() of when the program started.
1219 *
1220 * @returns Program startup timestamp.
1221 */
1222RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
1223
1224
1225/**
1226 * Time zone information.
1227 */
1228typedef struct RTTIMEZONEINFO
1229{
1230 /** Unix time zone name (continent/country[/city]|). */
1231 const char *pszUnixName;
1232 /** Windows time zone name. */
1233 const char *pszWindowsName;
1234 /** The length of the unix time zone name. */
1235 uint8_t cchUnixName;
1236 /** The length of the windows time zone name. */
1237 uint8_t cchWindowsName;
1238 /** Two letter country/territory code if applicable, otherwise 'ZZ'. */
1239 char szCountry[3];
1240 /** Two letter windows country/territory code if applicable.
1241 * Empty string if no windows mapping. */
1242 char szWindowsCountry[3];
1243#if 0 /* Add when needed and it's been extracted. */
1244 /** The standard delta in minutes (add to UTC). */
1245 int16_t cMinStdDelta;
1246 /** The daylight saving time delta in minutes (add to UTC). */
1247 int16_t cMinDstDelta;
1248#endif
1249 /** closest matching windows time zone index. */
1250 uint32_t idxWindows;
1251 /** Flags, RTTIMEZONEINFO_F_XXX. */
1252 uint32_t fFlags;
1253} RTTIMEZONEINFO;
1254/** Pointer to time zone info. */
1255typedef RTTIMEZONEINFO const *PCRTTIMEZONEINFO;
1256
1257/** @name RTTIMEZONEINFO_F_XXX - time zone info flags.
1258 * @{ */
1259/** Indicates golden mapping entry for a windows time zone name. */
1260#define RTTIMEZONEINFO_F_GOLDEN RT_BIT_32(0)
1261/** @} */
1262
1263/**
1264 * Looks up static time zone information by unix name.
1265 *
1266 * @returns Pointer to info entry if found, NULL if not.
1267 * @param pszName The unix zone name (TZ).
1268 */
1269RTDECL(PCRTTIMEZONEINFO) RTTimeZoneGetInfoByUnixName(const char *pszName);
1270
1271/**
1272 * Looks up static time zone information by window name.
1273 *
1274 * @returns Pointer to info entry if found, NULL if not.
1275 * @param pszName The windows zone name (reg key).
1276 */
1277RTDECL(PCRTTIMEZONEINFO) RTTimeZoneGetInfoByWindowsName(const char *pszName);
1278
1279/**
1280 * Looks up static time zone information by windows index.
1281 *
1282 * @returns Pointer to info entry if found, NULL if not.
1283 * @param idxZone The windows timezone index.
1284 */
1285RTDECL(PCRTTIMEZONEINFO) RTTimeZoneGetInfoByWindowsIndex(uint32_t idxZone);
1286
1287/**
1288 * Get the current time zone (TZ).
1289 *
1290 * @returns IPRT status code.
1291 * @param pszName Where to return the time zone name.
1292 * @param cbName The size of the name buffer.
1293 */
1294RTDECL(int) RTTimeZoneGetCurrent(char *pszName, size_t cbName);
1295
1296/** @} */
1297
1298RT_C_DECLS_END
1299
1300#endif /* !IPRT_INCLUDED_time_h */
1301
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette