VirtualBox

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

Last change on this file since 5999 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1/** @file
2 * innotek Portable Runtime - Time.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
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_time_h
27#define ___iprt_time_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31
32__BEGIN_DECLS
33
34/** @defgroup grp_rt_time RTTime - Time
35 * @ingroup grp_rt
36 * @{
37 */
38
39/** Time Specification.
40 *
41 * Use the inline RTTimeSpecGet/Set to operate on structure this so we
42 * can easily change the representation if required later.
43 *
44 * The current representation is in nanoseconds relative to the unix epoch
45 * (1970-01-01 00:00:00 UTC). This gives us an approximate span from
46 * 1678 to 2262 without sacrifying the resolution offered by the various
47 * host OSes (BSD & LINUX 1ns, NT 100ns).
48 */
49typedef struct RTTIMESPEC
50{
51 /** Nanoseconds since epoch.
52 * The name is intentially too long to be comfortable to use because you should be
53 * using inline helpers! */
54 int64_t i64NanosecondsRelativeToUnixEpoch;
55} RTTIMESPEC;
56/** Pointer to a time spec structure. */
57typedef RTTIMESPEC *PRTTIMESPEC;
58/** Pointer to a const time spec structure. */
59typedef const RTTIMESPEC *PCRTTIMESPEC;
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 / 1000;
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 * 1000;
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 / 1000000;
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 * 1000000;
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 / 1000000000;
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 * 1000000000;
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 * 1000;
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 * 1000000;
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 * 1000000000;
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 * 1000;
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 * 1000000;
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 * 100000000;
332 return pTime;
333}
334
335
336/* PORTME: Add struct timeval guard macro here. */
337#if defined(RTTIME_INCL_TIMEVAL) || defined(_STRUCT_TIMEVAL) || defined(_SYS__TIMEVAL_H_) || defined(_SYS_TIME_H) || defined(_TIMEVAL)
338/**
339 * Gets the time as POSIX timeval.
340 *
341 * @returns pTime.
342 * @param pTime The time spec to interpret.
343 * @param pTimeval Where to store the time as POSIX timeval.
344 */
345DECLINLINE(struct timeval *) RTTimeSpecGetTimeval(PCRTTIMESPEC pTime, struct timeval *pTimeval)
346{
347 int64_t i64 = RTTimeSpecGetMicro(pTime);
348 int32_t i32Micro = (int32_t)(i64 % 1000000);
349 i64 /= 1000000;
350 if (i32Micro < 0)
351 {
352 i32Micro += 1000000;
353 i64++;
354 }
355 pTimeval->tv_sec = (time_t)i64;
356 pTimeval->tv_usec = i32Micro;
357 return pTimeval;
358}
359
360/**
361 * Sets the time as POSIX timeval.
362 *
363 * @returns pTime.
364 * @param pTime The time spec to modify.
365 * @param pTimeval Pointer to the POSIX timeval struct with the new time.
366 */
367DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimeval(PRTTIMESPEC pTime, const struct timeval *pTimeval)
368{
369 return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
370}
371#endif /* various ways of detecting struct timeval */
372
373
374/* PORTME: Add struct timespec guard macro here. */
375#if defined(RTTIME_INCL_TIMESPEC) || defined(_STRUCT_TIMESPEC) || defined(_SYS__TIMESPEC_H_) || defined(TIMEVAL_TO_TIMESPEC) || defined(_TIMESPEC)
376/**
377 * Gets the time as POSIX timespec.
378 *
379 * @returns pTime.
380 * @param pTime The time spec to interpret.
381 * @param pTimespec Where to store the time as POSIX timespec.
382 */
383DECLINLINE(struct timespec *) RTTimeSpecGetTimespec(PCRTTIMESPEC pTime, struct timespec *pTimespec)
384{
385 int64_t i64 = RTTimeSpecGetNano(pTime);
386 int32_t i32Nano = (int32_t)(i64 % 1000000000);
387 i64 /= 1000000000;
388 if (i32Nano < 0)
389 {
390 i32Nano += 1000000000;
391 i64++;
392 }
393 pTimespec->tv_sec = (time_t)i64;
394 pTimespec->tv_nsec = i32Nano;
395 return pTimespec;
396}
397
398/**
399 * Sets the time as POSIX timespec.
400 *
401 * @returns pTime.
402 * @param pTime The time spec to modify.
403 * @param pTimespec Pointer to the POSIX timespec struct with the new time.
404 */
405DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec(PRTTIMESPEC pTime, const struct timespec *pTimespec)
406{
407 return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
408}
409#endif /* various ways of detecting struct timespec */
410
411
412
413/** The offset of the unix epoch and the base for NT time (in 100ns units).
414 * Nt time starts at 1601-01-01 00:00:00. */
415#define RTTIME_NT_TIME_OFFSET_UNIX (116444736000000000LL)
416
417
418/**
419 * Gets the time as NT time.
420 *
421 * @returns Nt time.
422 * @param pTime The time spec to interpret.
423 */
424DECLINLINE(uint64_t) RTTimeSpecGetNtTime(PCRTTIMESPEC pTime)
425{
426 return pTime->i64NanosecondsRelativeToUnixEpoch / 100
427 + RTTIME_NT_TIME_OFFSET_UNIX;
428}
429
430
431/**
432 * Sets the time given by Nt time.
433 *
434 * @returns pTime.
435 * @param pTime The time spec to modify.
436 * @param u64NtTime The new time in Nt time.
437 */
438DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtTime(PRTTIMESPEC pTime, uint64_t u64NtTime)
439{
440 pTime->i64NanosecondsRelativeToUnixEpoch =
441 ((int64_t)u64NtTime - RTTIME_NT_TIME_OFFSET_UNIX) * 100;
442 return pTime;
443}
444
445
446#ifdef _FILETIME_
447/**
448 * Gets the time as NT file time.
449 *
450 * @returns pFileTime.
451 * @param pTime The time spec to interpret.
452 * @param pFileTime Pointer to NT filetime structure.
453 */
454DECLINLINE(PFILETIME) RTTimeSpecGetNtFileTime(PCRTTIMESPEC pTime, PFILETIME pFileTime)
455{
456 *((uint64_t *)pFileTime) = RTTimeSpecGetNtTime(pTime);
457 return pFileTime;
458}
459
460/**
461 * Sets the time as NT file time.
462 *
463 * @returns pTime.
464 * @param pTime The time spec to modify.
465 * @param pFileTime Where to store the time as Nt file time.
466 */
467DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtFileTime(PRTTIMESPEC pTime, const FILETIME *pFileTime)
468{
469 return RTTimeSpecSetNtTime(pTime, *(const uint64_t *)pFileTime);
470}
471#endif
472
473
474/** The offset to the start of DOS time.
475 * DOS time starts 1980-01-01 00:00:00. */
476#define RTTIME_OFFSET_DOS_TIME (315532800000000000LL)
477
478
479/**
480 * Gets the time as seconds relative to the start of dos time.
481 *
482 * @returns seconds relative to the start of dos time.
483 * @param pTime The time spec to interpret.
484 */
485DECLINLINE(int64_t) RTTimeSpecGetDosSeconds(PCRTTIMESPEC pTime)
486{
487 return (pTime->i64NanosecondsRelativeToUnixEpoch + RTTIME_OFFSET_DOS_TIME)
488 / 1000000000;
489}
490
491
492/**
493 * Sets the time given by seconds relative to the start of dos time.
494 *
495 * @returns pTime.
496 * @param pTime The time spec to modify.
497 * @param i64Seconds The new time in seconds relative to the start of dos time.
498 */
499DECLINLINE(PRTTIMESPEC) RTTimeSpecSetDosSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
500{
501 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000
502 - RTTIME_NT_TIME_OFFSET_UNIX;
503 return pTime;
504}
505
506
507/**
508 * Compare two time specs.
509 *
510 * @returns true they are equal.
511 * @returns false they are not equal.
512 * @param pTime1 The 1st time spec.
513 * @param pTime2 The 2nd time spec.
514 */
515DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2)
516{
517 return pTime1->i64NanosecondsRelativeToUnixEpoch == pTime2->i64NanosecondsRelativeToUnixEpoch;
518}
519
520/**
521 * Converts a time spec to a ISO date string.
522 *
523 * @returns psz on success.
524 * @returns NULL on buffer underflow.
525 * @param pTime The time spec.
526 * @param psz Where to store the string.
527 * @param cb The size of the buffer.
528 */
529RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb);
530
531/** @} */
532
533
534/**
535 * Exploded time.
536 */
537#pragma pack(1)
538typedef struct RTTIME
539{
540 /** The year number. */
541 int32_t i32Year;
542 /** The month of the year (1-12). January is 1. */
543 uint8_t u8Month;
544 /** The day of the week (0-6). Monday is 0. */
545 uint8_t u8WeekDay;
546 /** The day of the year (1-366). January the 1st is 1. */
547 uint16_t u16YearDay;
548 /** The day of the month (1-31). */
549 uint8_t u8MonthDay;
550 /** Hour of the day (0-23). */
551 uint8_t u8Hour;
552 /** The minute of the hour (0-59). */
553 uint8_t u8Minute;
554 /** The second of the minute (0-60).
555 * (u32Nanosecond / 1000000) */
556 uint8_t u8Second;
557 /** The nanoseconds of the second (0-999999999). */
558 uint32_t u32Nanosecond;
559 /** Flags, of the RTTIME_FLAGS_* \#defines. */
560 uint32_t fFlags;
561 /** UCT time offset in minutes (-840-840).
562 * @remarks The implementation of RTTimeLocal* isn't quite there yet, so this might not be 100% correct. */
563 int32_t offUTC;
564} RTTIME;
565#pragma pack()
566/** Pointer to a exploded time structure. */
567typedef RTTIME *PRTTIME;
568/** Pointer to a const exploded time structure. */
569typedef const RTTIME *PCRTTIME;
570
571/** @name RTTIME::fFlags values.
572 * @{ */
573/** Set if the time is UTC. If clear the time local time. */
574#define RTTIME_FLAGS_TYPE_MASK 3
575/** the time is UTC time. */
576#define RTTIME_FLAGS_TYPE_UTC 2
577/** The time is local time. */
578#define RTTIME_FLAGS_TYPE_LOCAL 3
579
580/** Set if the time is local and daylight saving time is in effect.
581 * Not bit is not valid if RTTIME_FLAGS_NO_DST_DATA is set. */
582#define RTTIME_FLAGS_DST RT_BIT(4)
583/** Set if the time is local and there is no data available on daylight saving time. */
584#define RTTIME_FLAGS_NO_DST_DATA RT_BIT(5)
585/** Set if the year is a leap year.
586 * This is mutual exclusiv with RTTIME_FLAGS_COMMON_YEAR. */
587#define RTTIME_FLAGS_LEAP_YEAR RT_BIT(6)
588/** Set if the year is a common year.
589 * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
590#define RTTIME_FLAGS_COMMON_YEAR RT_BIT(7)
591/** The mask of valid flags. */
592#define RTTIME_FLAGS_MASK UINT32_C(0xff)
593/** @} */
594
595
596/**
597 * Gets the current system time (UTC).
598 *
599 * @returns pTime.
600 * @param pTime Where to store the time.
601 */
602RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime);
603
604/**
605 * Explodes a time spec (UTC).
606 *
607 * @returns pTime.
608 * @param pTime Where to store the exploded time.
609 * @param pTimeSpec The time spec to exploded.
610 */
611RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
612
613/**
614 * Implodes exploded time to a time spec (UTC).
615 *
616 * @returns pTime on success.
617 * @returns NULL if the pTime data is invalid.
618 * @param pTimeSpec Where to store the imploded UTC time.
619 * If pTime specifies a time which outside the range, maximum or
620 * minimum values will be returned.
621 * @param pTime Pointer to the exploded time to implode.
622 * The fields u8Month, u8WeekDay and u8MonthDay are not used,
623 * and all the other fields are expected to be within their
624 * bounds. Use RTTimeNormalize() to calculate u16YearDay and
625 * normalize the ranges of the fields.
626 */
627RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
628
629/**
630 * Normalizes the fields of a time structure.
631 *
632 * It is possible to calculate year-day from month/day and vice
633 * versa. If you adjust any of of these, make sure to zero the
634 * other so you make it clear which of the fields to use. If
635 * it's ambiguous, the year-day field is used (and you get
636 * assertions in debug builds).
637 *
638 * All the time fields and the year-day or month/day fields will
639 * be adjusted for overflows. (Since all fields are unsigned, there
640 * is no underflows.) It is possible to exploit this for simple
641 * date math, though the recommended way of doing that to implode
642 * the time into a timespec and do the math on that.
643 *
644 * @returns pTime on success.
645 * @returns NULL if the data is invalid.
646 *
647 * @param pTime The time structure to normalize.
648 *
649 * @remarks This function doesn't work with local time, only with UTC time.
650 */
651RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
652
653/**
654 * Gets the current local system time.
655 *
656 * @returns pTime.
657 * @param pTime Where to store the local time.
658 */
659RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
660
661/**
662 * Gets the delta between UTC and local time.
663 *
664 * @code
665 * RTTIMESPEC LocalTime;
666 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
667 * @endcode
668 *
669 * @returns Returns the nanosecond delta between UTC and local time.
670 */
671RTDECL(int64_t) RTTimeLocalDeltaNano(void);
672
673/**
674 * Explodes a time spec to the localized timezone.
675 *
676 * @returns pTime.
677 * @param pTime Where to store the exploded time.
678 * @param pTimeSpec The time spec to exploded (UTC).
679 */
680RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
681
682/**
683 * Normalizes the fields of a time structure containing local time.
684 *
685 * See RTTimeNormalize for details.
686 *
687 * @returns pTime on success.
688 * @returns NULL if the data is invalid.
689 * @param pTime The time structure to normalize.
690 */
691RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
692
693/**
694 * Converts a time spec to a ISO date string.
695 *
696 * @returns psz on success.
697 * @returns NULL on buffer underflow.
698 * @param pTime The time. Caller should've normalized this.
699 * @param psz Where to store the string.
700 * @param cb The size of the buffer.
701 */
702RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
703
704/**
705 * Gets the current nanosecond timestamp.
706 *
707 * @returns nanosecond timestamp.
708 */
709RTDECL(uint64_t) RTTimeNanoTS(void);
710
711/**
712 * Gets the current millisecond timestamp.
713 *
714 * @returns millisecond timestamp.
715 */
716RTDECL(uint64_t) RTTimeMilliTS(void);
717
718/**
719 * Debugging the time api.
720 *
721 * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
722 */
723RTDECL(uint32_t) RTTimeDbgSteps(void);
724
725/**
726 * Debugging the time api.
727 *
728 * @returns the number of times the TSC interval expired RTTimeNanoTS().
729 */
730RTDECL(uint32_t) RTTimeDbgExpired(void);
731
732/**
733 * Debugging the time api.
734 *
735 * @returns the number of bad previous values encountered by RTTimeNanoTS().
736 */
737RTDECL(uint32_t) RTTimeDbgBad(void);
738
739/**
740 * Debugging the time api.
741 *
742 * @returns the number of update races in RTTimeNanoTS().
743 */
744RTDECL(uint32_t) RTTimeDbgRaces(void);
745
746/** @name RTTimeNanoTS GIP worker functions, for TM.
747 * @{ */
748/** Pointer to a RTTIMENANOTSDATA structure. */
749typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
750
751/**
752 * Nanosecond timestamp data.
753 *
754 * This is used to keep track of statistics and callback so IPRT
755 * and TM (VirtualBox) can share code.
756 *
757 * @remark Keep this in sync with the assembly version in timesupA.asm.
758 */
759typedef struct RTTIMENANOTSDATA
760{
761 /** Where the previous timestamp is stored.
762 * This is maintained to ensure that time doesn't go backwards or anything. */
763 uint64_t volatile *pu64Prev;
764
765 /**
766 * Helper function that's used by the assembly routines when something goes bust.
767 *
768 * @param pData Pointer to this structure.
769 * @param u64NanoTS The calculated nano ts.
770 * @param u64DeltaPrev The delta relative to the previously returned timestamp.
771 * @param u64PrevNanoTS The previously returned timestamp (as it was read it).
772 */
773 DECLCALLBACKMEMBER(void, pfnBad)(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
774
775 /**
776 * Callback for when rediscovery is required.
777 *
778 * @returns Nanosecond timestamp.
779 * @param pData Pointer to this structure.
780 */
781 DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
782
783 /** Just a dummy alignment member. */
784 void *pvDummy;
785
786 /** Number of 1ns steps because of overshooting the period. */
787 uint32_t c1nsSteps;
788 /** The number of times the interval expired (overflow). */
789 uint32_t cExpired;
790 /** Number of "bad" previous values. */
791 uint32_t cBadPrev;
792 /** The number of update races. */
793 uint32_t cUpdateRaces;
794} RTTIMENANOTSDATA;
795
796#ifndef IN_RING3
797/**
798 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
799 */
800typedef struct RTTIMENANOTSDATAR3
801{
802 R3PTRTYPE(uint64_t volatile *) pu64Prev;
803 DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
804 DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
805 RTR3PTR pvDummy;
806 uint32_t c1nsSteps;
807 uint32_t cExpired;
808 uint32_t cBadPrev;
809 uint32_t cUpdateRaces;
810} RTTIMENANOTSDATAR3;
811#else
812typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
813#endif
814
815#ifndef IN_RING0
816/**
817 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
818 */
819typedef struct RTTIMENANOTSDATAR0
820{
821 R0PTRTYPE(uint64_t volatile *) pu64Prev;
822 DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
823 DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
824 RTR0PTR pvDummy;
825 uint32_t c1nsSteps;
826 uint32_t cExpired;
827 uint32_t cBadPrev;
828 uint32_t cUpdateRaces;
829} RTTIMENANOTSDATAR0;
830#else
831typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
832#endif
833
834#ifndef IN_GC
835/**
836 * The GC layout of the RTTIMENANOTSDATA structure.
837 */
838typedef struct RTTIMENANOTSDATAGC
839{
840 GCPTRTYPE(uint64_t volatile *) pu64Prev;
841 DECLGCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
842 DECLGCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
843 RTGCPTR pvDummy;
844 uint32_t c1nsSteps;
845 uint32_t cExpired;
846 uint32_t cBadPrev;
847 uint32_t cUpdateRaces;
848} RTTIMENANOTSDATAGC;
849#else
850typedef RTTIMENANOTSDATA RTTIMENANOTSDATAGC;
851#endif
852
853/** Internal RTTimeNanoTS worker (assembly). */
854typedef DECLCALLBACK(uint64_t) FNTIMENANOTSINTERNAL(PRTTIMENANOTSDATA pData);
855/** Pointer to an internal RTTimeNanoTS worker (assembly). */
856typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
857
858RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);
859RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
860RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData);
861RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
862/** @} */
863
864
865/**
866 * Gets the current nanosecond timestamp.
867 *
868 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
869 * resolution or performance optimizations.
870 *
871 * @returns nanosecond timestamp.
872 */
873RTDECL(uint64_t) RTTimeSystemNanoTS(void);
874
875/**
876 * Gets the current millisecond timestamp.
877 *
878 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
879 * resolution or performance optimizations.
880 *
881 * @returns millisecond timestamp.
882 */
883RTDECL(uint64_t) RTTimeSystemMilliTS(void);
884
885/**
886 * Get the nanosecond timestamp relative to program startup.
887 *
888 * @returns Timestamp relative to program startup.
889 */
890RTDECL(uint64_t) RTTimeProgramNanoTS(void);
891
892/**
893 * Get the microsecond timestamp relative to program startup.
894 *
895 * @returns Timestamp relative to program startup.
896 */
897RTDECL(uint64_t) RTTimeProgramMicroTS(void);
898
899/**
900 * Get the millisecond timestamp relative to program startup.
901 *
902 * @returns Timestamp relative to program startup.
903 */
904RTDECL(uint64_t) RTTimeProgramMilliTS(void);
905
906/**
907 * Get the second timestamp relative to program startup.
908 *
909 * @returns Timestamp relative to program startup.
910 */
911RTDECL(uint32_t) RTTimeProgramSecTS(void);
912
913/**
914 * Get the RTTimeNanoTS() of when the program started.
915 *
916 * @returns Program startup timestamp.
917 */
918RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
919
920/** @} */
921
922__END_DECLS
923
924#endif
925
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use