VirtualBox

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

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

Implemented RTTimeNormalize. Added a offUTC field to RTTIME (only partly implemented). Made RTTimeToString/RTTimeSpecToString print offUTC for local times (it incorrectly printed Z for them).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.8 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 as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#ifndef ___iprt_time_h
18#define ___iprt_time_h
19
20#include <iprt/cdefs.h>
21#include <iprt/types.h>
22
23__BEGIN_DECLS
24
25/** @defgroup grp_rt_time RTTime - Time
26 * @ingroup grp_rt
27 * @{
28 */
29
30/** Time Specification.
31 *
32 * Use the inline RTTimeSpecGet/Set to operate on structure this so we
33 * can easily change the representation if required later.
34 *
35 * The current representation is in nanoseconds relative to the unix epoch
36 * (1970-01-01 00:00:00 UTC). This gives us an approximate span from
37 * 1678 to 2262 without sacrifying the resolution offered by the various
38 * host OSes (BSD & LINUX 1ns, NT 100ns).
39 */
40typedef struct RTTIMESPEC
41{
42 /** Nanoseconds since epoch.
43 * The name is intentially too long to be comfortable to use because you should be
44 * using inline helpers! */
45 int64_t i64NanosecondsRelativeToUnixEpoch;
46} RTTIMESPEC;
47/** Pointer to a time spec structure. */
48typedef RTTIMESPEC *PRTTIMESPEC;
49/** Pointer to a const time spec structure. */
50typedef const RTTIMESPEC *PCRTTIMESPEC;
51
52
53/** @name RTTIMESPEC methods
54 * @{ */
55
56/**
57 * Gets the time as nanoseconds relative to the unix epoch.
58 *
59 * @returns Nanoseconds relative to unix epoch.
60 * @param pTime The time spec to interpret.
61 */
62DECLINLINE(int64_t) RTTimeSpecGetNano(PCRTTIMESPEC pTime)
63{
64 return pTime->i64NanosecondsRelativeToUnixEpoch;
65}
66
67
68/**
69 * Sets the time give by nanoseconds relative to the unix epoch.
70 *
71 * @returns pTime.
72 * @param pTime The time spec to modify.
73 * @param i64Nano The new time in nanoseconds.
74 */
75DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNano(PRTTIMESPEC pTime, int64_t i64Nano)
76{
77 pTime->i64NanosecondsRelativeToUnixEpoch = i64Nano;
78 return pTime;
79}
80
81
82/**
83 * Gets the time as microseconds relative to the unix epoch.
84 *
85 * @returns microseconds relative to unix epoch.
86 * @param pTime The time spec to interpret.
87 */
88DECLINLINE(int64_t) RTTimeSpecGetMicro(PCRTTIMESPEC pTime)
89{
90 return pTime->i64NanosecondsRelativeToUnixEpoch / 1000;
91}
92
93
94/**
95 * Sets the time given by microseconds relative to the unix epoch.
96 *
97 * @returns pTime.
98 * @param pTime The time spec to modify.
99 * @param i64Micro The new time in microsecond.
100 */
101DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMicro(PRTTIMESPEC pTime, int64_t i64Micro)
102{
103 pTime->i64NanosecondsRelativeToUnixEpoch = i64Micro * 1000;
104 return pTime;
105}
106
107
108/**
109 * Gets the time as milliseconds relative to the unix epoch.
110 *
111 * @returns milliseconds relative to unix epoch.
112 * @param pTime The time spec to interpret.
113 */
114DECLINLINE(int64_t) RTTimeSpecGetMilli(PCRTTIMESPEC pTime)
115{
116 return pTime->i64NanosecondsRelativeToUnixEpoch / 1000000;
117}
118
119
120/**
121 * Sets the time given by milliseconds relative to the unix epoch.
122 *
123 * @returns pTime.
124 * @param pTime The time spec to modify.
125 * @param i64Milli The new time in milliseconds.
126 */
127DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMilli(PRTTIMESPEC pTime, int64_t i64Milli)
128{
129 pTime->i64NanosecondsRelativeToUnixEpoch = i64Milli * 1000000;
130 return pTime;
131}
132
133
134/**
135 * Gets the time as seconds relative to the unix epoch.
136 *
137 * @returns seconds relative to unix epoch.
138 * @param pTime The time spec to interpret.
139 */
140DECLINLINE(int64_t) RTTimeSpecGetSeconds(PCRTTIMESPEC pTime)
141{
142 return pTime->i64NanosecondsRelativeToUnixEpoch / 1000000000;
143}
144
145
146/**
147 * Sets the time given by seconds relative to the unix epoch.
148 *
149 * @returns pTime.
150 * @param pTime The time spec to modify.
151 * @param i64Seconds The new time in seconds.
152 */
153DECLINLINE(PRTTIMESPEC) RTTimeSpecSetSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
154{
155 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000;
156 return pTime;
157}
158
159
160/**
161 * Makes the time spec absolute like abs() does (i.e. a positive value).
162 *
163 * @returns pTime.
164 * @param pTime The time spec to modify.
165 */
166DECLINLINE(PRTTIMESPEC) RTTimeSpecAbsolute(PRTTIMESPEC pTime)
167{
168 if (pTime->i64NanosecondsRelativeToUnixEpoch < 0)
169 pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
170 return pTime;
171}
172
173
174/**
175 * Negates the time.
176 *
177 * @returns pTime.
178 * @param pTime The time spec to modify.
179 */
180DECLINLINE(PRTTIMESPEC) RTTimeSpecNegate(PRTTIMESPEC pTime)
181{
182 pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
183 return pTime;
184}
185
186
187/**
188 * Adds a time period to the time.
189 *
190 * @returns pTime.
191 * @param pTime The time spec to modify.
192 * @param pTimeAdd The time spec to add to pTime.
193 */
194DECLINLINE(PRTTIMESPEC) RTTimeSpecAdd(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeAdd)
195{
196 pTime->i64NanosecondsRelativeToUnixEpoch += pTimeAdd->i64NanosecondsRelativeToUnixEpoch;
197 return pTime;
198}
199
200
201/**
202 * Adds a time period give as nanoseconds from the time.
203 *
204 * @returns pTime.
205 * @param pTime The time spec to modify.
206 * @param i64Nano The time period in nanoseconds.
207 */
208DECLINLINE(PRTTIMESPEC) RTTimeSpecAddNano(PRTTIMESPEC pTime, int64_t i64Nano)
209{
210 pTime->i64NanosecondsRelativeToUnixEpoch += i64Nano;
211 return pTime;
212}
213
214
215/**
216 * Adds a time period give as microseconds from the time.
217 *
218 * @returns pTime.
219 * @param pTime The time spec to modify.
220 * @param i64Micro The time period in microseconds.
221 */
222DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMicro(PRTTIMESPEC pTime, int64_t i64Micro)
223{
224 pTime->i64NanosecondsRelativeToUnixEpoch += i64Micro * 1000;
225 return pTime;
226}
227
228
229/**
230 * Adds a time period give as milliseconds from the time.
231 *
232 * @returns pTime.
233 * @param pTime The time spec to modify.
234 * @param i64Milli The time period in milliseconds.
235 */
236DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMilli(PRTTIMESPEC pTime, int64_t i64Milli)
237{
238 pTime->i64NanosecondsRelativeToUnixEpoch += i64Milli * 1000000;
239 return pTime;
240}
241
242
243/**
244 * Adds a time period give as seconds from the time.
245 *
246 * @returns pTime.
247 * @param pTime The time spec to modify.
248 * @param i64Seconds The time period in seconds.
249 */
250DECLINLINE(PRTTIMESPEC) RTTimeSpecAddSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
251{
252 pTime->i64NanosecondsRelativeToUnixEpoch += i64Seconds * 1000000000;
253 return pTime;
254}
255
256
257/**
258 * Subtracts a time period from the time.
259 *
260 * @returns pTime.
261 * @param pTime The time spec to modify.
262 * @param pTimeSub The time spec to subtract from pTime.
263 */
264DECLINLINE(PRTTIMESPEC) RTTimeSpecSub(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeSub)
265{
266 pTime->i64NanosecondsRelativeToUnixEpoch -= pTimeSub->i64NanosecondsRelativeToUnixEpoch;
267 return pTime;
268}
269
270
271/**
272 * Subtracts a time period give as nanoseconds from the time.
273 *
274 * @returns pTime.
275 * @param pTime The time spec to modify.
276 * @param i64Nano The time period in nanoseconds.
277 */
278DECLINLINE(PRTTIMESPEC) RTTimeSpecSubNano(PRTTIMESPEC pTime, int64_t i64Nano)
279{
280 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Nano;
281 return pTime;
282}
283
284
285/**
286 * Subtracts a time period give as microseconds from the time.
287 *
288 * @returns pTime.
289 * @param pTime The time spec to modify.
290 * @param i64Micro The time period in microseconds.
291 */
292DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMicro(PRTTIMESPEC pTime, int64_t i64Micro)
293{
294 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Micro * 1000;
295 return pTime;
296}
297
298
299/**
300 * Subtracts a time period give as milliseconds from the time.
301 *
302 * @returns pTime.
303 * @param pTime The time spec to modify.
304 * @param i64Milli The time period in milliseconds.
305 */
306DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMilli(PRTTIMESPEC pTime, int64_t i64Milli)
307{
308 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Milli * 1000000;
309 return pTime;
310}
311
312
313/**
314 * Subtracts a time period give as seconds from the time.
315 *
316 * @returns pTime.
317 * @param pTime The time spec to modify.
318 * @param i64Seconds The time period in seconds.
319 */
320DECLINLINE(PRTTIMESPEC) RTTimeSpecSubSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
321{
322 pTime->i64NanosecondsRelativeToUnixEpoch -= i64Seconds * 100000000;
323 return pTime;
324}
325
326
327/* PORTME: Add struct timeval guard macro here. */
328#if defined(RTTIME_INCL_TIMEVAL) || defined(_STRUCT_TIMEVAL) || defined(_SYS__TIMEVAL_H_) || defined(_SYS_TIME_H) || defined(_TIMEVAL)
329/**
330 * Gets the time as POSIX timeval.
331 *
332 * @returns pTime.
333 * @param pTime The time spec to interpret.
334 * @param pTimeval Where to store the time as POSIX timeval.
335 */
336DECLINLINE(struct timeval *) RTTimeSpecGetTimeval(PCRTTIMESPEC pTime, struct timeval *pTimeval)
337{
338 int64_t i64 = RTTimeSpecGetMicro(pTime);
339 int32_t i32Micro = (int32_t)(i64 % 1000000);
340 i64 /= 1000000;
341 if (i32Micro < 0)
342 {
343 i32Micro += 1000000;
344 i64++;
345 }
346 pTimeval->tv_sec = (time_t)i64;
347 pTimeval->tv_usec = i32Micro;
348 return pTimeval;
349}
350
351/**
352 * Sets the time as POSIX timeval.
353 *
354 * @returns pTime.
355 * @param pTime The time spec to modify.
356 * @param pTimeval Pointer to the POSIX timeval struct with the new time.
357 */
358DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimeval(PRTTIMESPEC pTime, const struct timeval *pTimeval)
359{
360 return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
361}
362#endif /* various ways of detecting struct timeval */
363
364
365/* PORTME: Add struct timespec guard macro here. */
366#if defined(RTTIME_INCL_TIMESPEC) || defined(_STRUCT_TIMESPEC) || defined(_SYS__TIMESPEC_H_) || defined(TIMEVAL_TO_TIMESPEC) || defined(_TIMESPEC)
367/**
368 * Gets the time as POSIX timespec.
369 *
370 * @returns pTime.
371 * @param pTime The time spec to interpret.
372 * @param pTimespec Where to store the time as POSIX timespec.
373 */
374DECLINLINE(struct timespec *) RTTimeSpecGetTimespec(PCRTTIMESPEC pTime, struct timespec *pTimespec)
375{
376 int64_t i64 = RTTimeSpecGetNano(pTime);
377 int32_t i32Nano = (int32_t)(i64 % 1000000000);
378 i64 /= 1000000000;
379 if (i32Nano < 0)
380 {
381 i32Nano += 1000000000;
382 i64++;
383 }
384 pTimespec->tv_sec = (time_t)i64;
385 pTimespec->tv_nsec = i32Nano;
386 return pTimespec;
387}
388
389/**
390 * Sets the time as POSIX timespec.
391 *
392 * @returns pTime.
393 * @param pTime The time spec to modify.
394 * @param pTimespec Pointer to the POSIX timespec struct with the new time.
395 */
396DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec(PRTTIMESPEC pTime, const struct timespec *pTimespec)
397{
398 return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
399}
400#endif /* various ways of detecting struct timespec */
401
402
403
404/** The offset of the unix epoch and the base for NT time (in 100ns units).
405 * Nt time starts at 1601-01-01 00:00:00. */
406#define RTTIME_NT_TIME_OFFSET_UNIX (116444736000000000LL)
407
408
409/**
410 * Gets the time as NT time.
411 *
412 * @returns Nt time.
413 * @param pTime The time spec to interpret.
414 */
415DECLINLINE(uint64_t) RTTimeSpecGetNtTime(PCRTTIMESPEC pTime)
416{
417 return pTime->i64NanosecondsRelativeToUnixEpoch / 100
418 + RTTIME_NT_TIME_OFFSET_UNIX;
419}
420
421
422/**
423 * Sets the time given by Nt time.
424 *
425 * @returns pTime.
426 * @param pTime The time spec to modify.
427 * @param u64NtTime The new time in Nt time.
428 */
429DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtTime(PRTTIMESPEC pTime, uint64_t u64NtTime)
430{
431 pTime->i64NanosecondsRelativeToUnixEpoch =
432 ((int64_t)u64NtTime - RTTIME_NT_TIME_OFFSET_UNIX) * 100;
433 return pTime;
434}
435
436
437#ifdef _FILETIME_
438/**
439 * Gets the time as NT file time.
440 *
441 * @returns pFileTime.
442 * @param pTime The time spec to interpret.
443 * @param pFileTime Pointer to NT filetime structure.
444 */
445DECLINLINE(PFILETIME) RTTimeSpecGetNtFileTime(PCRTTIMESPEC pTime, PFILETIME pFileTime)
446{
447 *((uint64_t *)pFileTime) = RTTimeSpecGetNtTime(pTime);
448 return pFileTime;
449}
450
451/**
452 * Sets the time as NT file time.
453 *
454 * @returns pTime.
455 * @param pTime The time spec to modify.
456 * @param pFileTime Where to store the time as Nt file time.
457 */
458DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtFileTime(PRTTIMESPEC pTime, const FILETIME *pFileTime)
459{
460 return RTTimeSpecSetNtTime(pTime, *(const uint64_t *)pFileTime);
461}
462#endif
463
464
465/** The offset to the start of DOS time.
466 * DOS time starts 1980-01-01 00:00:00. */
467#define RTTIME_OFFSET_DOS_TIME (315532800000000000LL)
468
469
470/**
471 * Gets the time as seconds relative to the start of dos time.
472 *
473 * @returns seconds relative to the start of dos time.
474 * @param pTime The time spec to interpret.
475 */
476DECLINLINE(int64_t) RTTimeSpecGetDosSeconds(PCRTTIMESPEC pTime)
477{
478 return (pTime->i64NanosecondsRelativeToUnixEpoch + RTTIME_OFFSET_DOS_TIME)
479 / 1000000000;
480}
481
482
483/**
484 * Sets the time given by seconds relative to the start of dos time.
485 *
486 * @returns pTime.
487 * @param pTime The time spec to modify.
488 * @param i64Seconds The new time in seconds relative to the start of dos time.
489 */
490DECLINLINE(PRTTIMESPEC) RTTimeSpecSetDosSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
491{
492 pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000
493 - RTTIME_NT_TIME_OFFSET_UNIX;
494 return pTime;
495}
496
497
498/**
499 * Compare two time specs.
500 *
501 * @returns true they are equal.
502 * @returns false they are not equal.
503 * @param pTime1 The 1st time spec.
504 * @param pTime2 The 2nd time spec.
505 */
506DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2)
507{
508 return pTime1->i64NanosecondsRelativeToUnixEpoch == pTime2->i64NanosecondsRelativeToUnixEpoch;
509}
510
511/**
512 * Converts a time spec to a ISO date string.
513 *
514 * @returns psz on success.
515 * @returns NULL on buffer underflow.
516 * @param pTime The time spec.
517 * @param psz Where to store the string.
518 * @param cb The size of the buffer.
519 */
520RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb);
521
522/** @} */
523
524
525/**
526 * Exploded time.
527 */
528#pragma pack(1)
529typedef struct RTTIME
530{
531 /** The year number. */
532 int32_t i32Year;
533 /** The month of the year (1-12). January is 1. */
534 uint8_t u8Month;
535 /** The day of the week (0-6). Monday is 0. */
536 uint8_t u8WeekDay;
537 /** The day of the year (1-366). January the 1st is 1. */
538 uint16_t u16YearDay;
539 /** The day of the month (1-31). */
540 uint8_t u8MonthDay;
541 /** Hour of the day (0-23). */
542 uint8_t u8Hour;
543 /** The minute of the hour (0-59). */
544 uint8_t u8Minute;
545 /** The second of the minute (0-60).
546 * (u32Nanosecond / 1000000) */
547 uint8_t u8Second;
548 /** The nanoseconds of the second (0-999999999). */
549 uint32_t u32Nanosecond;
550 /** Flags, of the RTTIME_FLAGS_* \#defines. */
551 uint32_t fFlags;
552 /** UCT time offset in minutes (-840-840).
553 * @remarks The implementation of RTTimeLocal* isn't quite there yet, so this might not be 100% correct. */
554 int32_t offUTC;
555} RTTIME;
556#pragma pack()
557/** Pointer to a exploded time structure. */
558typedef RTTIME *PRTTIME;
559/** Pointer to a const exploded time structure. */
560typedef const RTTIME *PCRTTIME;
561
562/** @name RTTIME::fFlags values.
563 * @{ */
564/** Set if the time is UTC. If clear the time local time. */
565#define RTTIME_FLAGS_TYPE_MASK 3
566/** the time is UTC time. */
567#define RTTIME_FLAGS_TYPE_UTC 2
568/** The time is local time. */
569#define RTTIME_FLAGS_TYPE_LOCAL 3
570
571/** Set if the time is local and daylight saving time is in effect.
572 * Not bit is not valid if RTTIME_FLAGS_NO_DST_DATA is set. */
573#define RTTIME_FLAGS_DST RT_BIT(4)
574/** Set if the time is local and there is no data available on daylight saving time. */
575#define RTTIME_FLAGS_NO_DST_DATA RT_BIT(5)
576/** Set if the year is a leap year.
577 * This is mutual exclusiv with RTTIME_FLAGS_COMMON_YEAR. */
578#define RTTIME_FLAGS_LEAP_YEAR RT_BIT(6)
579/** Set if the year is a common year.
580 * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
581#define RTTIME_FLAGS_COMMON_YEAR RT_BIT(7)
582/** The mask of valid flags. */
583#define RTTIME_FLAGS_MASK UINT32_C(0xff)
584/** @} */
585
586
587/**
588 * Gets the current system time (UTC).
589 *
590 * @returns pTime.
591 * @param pTime Where to store the time.
592 */
593RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime);
594
595/**
596 * Explodes a time spec (UTC).
597 *
598 * @returns pTime.
599 * @param pTime Where to store the exploded time.
600 * @param pTimeSpec The time spec to exploded.
601 */
602RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
603
604/**
605 * Implodes exploded time to a time spec (UTC).
606 *
607 * @returns pTime on success.
608 * @returns NULL if the pTime data is invalid.
609 * @param pTimeSpec Where to store the imploded UTC time.
610 * If pTime specifies a time which outside the range, maximum or
611 * minimum values will be returned.
612 * @param pTime Pointer to the exploded time to implode.
613 * The fields u8Month, u8WeekDay and u8MonthDay are not used,
614 * and all the other fields are expected to be within their
615 * bounds. Use RTTimeNormalize() to calculate u16YearDay and
616 * normalize the ranges of the fields.
617 */
618RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
619
620/**
621 * Normalizes the fields of a time structure.
622 *
623 * It is possible to calculate year-day from month/day and vice
624 * versa. If you adjust any of of these, make sure to zero the
625 * other so you make it clear which of the fields to use. If
626 * it's ambiguous, the year-day field is used (and you get
627 * assertions in debug builds).
628 *
629 * All the time fields and the year-day or month/day fields will
630 * be adjusted for overflows. (Since all fields are unsigned, there
631 * is no underflows.) It is possible to exploit this for simple
632 * date math, though the recommended way of doing that to implode
633 * the time into a timespec and do the math on that.
634 *
635 * @returns pTime on success.
636 * @returns NULL if the data is invalid.
637 *
638 * @param pTime The time structure to normalize.
639 *
640 * @remarks This function doesn't work with local time, only with UTC time.
641 */
642RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
643
644/**
645 * Gets the current local system time.
646 *
647 * @returns pTime.
648 * @param pTime Where to store the local time.
649 */
650RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
651
652/**
653 * Gets the delta between UTC and local time.
654 *
655 * @code
656 * RTTIMESPEC LocalTime;
657 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
658 * @endcode
659 *
660 * @returns Returns the nanosecond delta between UTC and local time.
661 */
662RTDECL(int64_t) RTTimeLocalDeltaNano(void);
663
664/**
665 * Explodes a time spec to the localized timezone.
666 *
667 * @returns pTime.
668 * @param pTime Where to store the exploded time.
669 * @param pTimeSpec The time spec to exploded (UTC).
670 */
671RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
672
673/**
674 * Normalizes the fields of a time structure containing local time.
675 *
676 * See RTTimeNormalize for details.
677 *
678 * @returns pTime on success.
679 * @returns NULL if the data is invalid.
680 * @param pTime The time structure to normalize.
681 */
682RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
683
684/**
685 * Converts a time spec to a ISO date string.
686 *
687 * @returns psz on success.
688 * @returns NULL on buffer underflow.
689 * @param pTime The time. Caller should've normalized this.
690 * @param psz Where to store the string.
691 * @param cb The size of the buffer.
692 */
693RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
694
695/**
696 * Gets the current nanosecond timestamp.
697 *
698 * @returns nanosecond timestamp.
699 */
700RTDECL(uint64_t) RTTimeNanoTS(void);
701
702/**
703 * Gets the current millisecond timestamp.
704 *
705 * @returns millisecond timestamp.
706 */
707RTDECL(uint64_t) RTTimeMilliTS(void);
708
709/**
710 * Debugging the time api.
711 *
712 * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
713 */
714RTDECL(uint32_t) RTTimeDbgSteps(void);
715
716/**
717 * Debugging the time api.
718 *
719 * @returns the number of times the TSC interval expired RTTimeNanoTS().
720 */
721RTDECL(uint32_t) RTTimeDbgExpired(void);
722
723/**
724 * Debugging the time api.
725 *
726 * @returns the number of bad previous values encountered by RTTimeNanoTS().
727 */
728RTDECL(uint32_t) RTTimeDbgBad(void);
729
730/**
731 * Debugging the time api.
732 *
733 * @returns the number of update races in RTTimeNanoTS().
734 */
735RTDECL(uint32_t) RTTimeDbgRaces(void);
736
737/** @name RTTimeNanoTS GIP worker functions, for TM.
738 * @{ */
739/** Pointer to a RTTIMENANOTSDATA structure. */
740typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
741
742/**
743 * Nanosecond timestamp data.
744 *
745 * This is used to keep track of statistics and callback so IPRT
746 * and TM (VirtualBox) can share code.
747 *
748 * @remark Keep this in sync with the assembly version in timesupA.asm.
749 */
750typedef struct RTTIMENANOTSDATA
751{
752 /** Where the previous timestamp is stored.
753 * This is maintained to ensure that time doesn't go backwards or anything. */
754 uint64_t volatile *pu64Prev;
755
756 /**
757 * Helper function that's used by the assembly routines when something goes bust.
758 *
759 * @param pData Pointer to this structure.
760 * @param u64NanoTS The calculated nano ts.
761 * @param u64DeltaPrev The delta relative to the previously returned timestamp.
762 * @param u64PrevNanoTS The previously returned timestamp (as it was read it).
763 */
764 DECLCALLBACKMEMBER(void, pfnBad)(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
765
766 /**
767 * Callback for when rediscovery is required.
768 *
769 * @returns Nanosecond timestamp.
770 * @param pData Pointer to this structure.
771 */
772 DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
773
774 /** Just a dummy alignment member. */
775 void *pvDummy;
776
777 /** Number of 1ns steps because of overshooting the period. */
778 uint32_t c1nsSteps;
779 /** The number of times the interval expired (overflow). */
780 uint32_t cExpired;
781 /** Number of "bad" previous values. */
782 uint32_t cBadPrev;
783 /** The number of update races. */
784 uint32_t cUpdateRaces;
785} RTTIMENANOTSDATA;
786
787#ifndef IN_RING3
788/**
789 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
790 */
791typedef struct RTTIMENANOTSDATAR3
792{
793 R3PTRTYPE(uint64_t volatile *) pu64Prev;
794 DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
795 DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
796 RTR3PTR pvDummy;
797 uint32_t c1nsSteps;
798 uint32_t cExpired;
799 uint32_t cBadPrev;
800 uint32_t cUpdateRaces;
801} RTTIMENANOTSDATAR3;
802#else
803typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
804#endif
805
806#ifndef IN_RING0
807/**
808 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
809 */
810typedef struct RTTIMENANOTSDATAR0
811{
812 R0PTRTYPE(uint64_t volatile *) pu64Prev;
813 DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
814 DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
815 RTR0PTR pvDummy;
816 uint32_t c1nsSteps;
817 uint32_t cExpired;
818 uint32_t cBadPrev;
819 uint32_t cUpdateRaces;
820} RTTIMENANOTSDATAR0;
821#else
822typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
823#endif
824
825#ifndef IN_GC
826/**
827 * The GC layout of the RTTIMENANOTSDATA structure.
828 */
829typedef struct RTTIMENANOTSDATAGC
830{
831 GCPTRTYPE(uint64_t volatile *) pu64Prev;
832 DECLGCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
833 DECLGCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
834 RTGCPTR pvDummy;
835 uint32_t c1nsSteps;
836 uint32_t cExpired;
837 uint32_t cBadPrev;
838 uint32_t cUpdateRaces;
839} RTTIMENANOTSDATAGC;
840#else
841typedef RTTIMENANOTSDATA RTTIMENANOTSDATAGC;
842#endif
843
844/** Internal RTTimeNanoTS worker (assembly). */
845typedef DECLCALLBACK(uint64_t) FNTIMENANOTSINTERNAL(PRTTIMENANOTSDATA pData);
846/** Pointer to an internal RTTimeNanoTS worker (assembly). */
847typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
848
849RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);
850RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
851RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData);
852RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
853/** @} */
854
855
856/**
857 * Gets the current nanosecond timestamp.
858 *
859 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
860 * resolution or performance optimizations.
861 *
862 * @returns nanosecond timestamp.
863 */
864RTDECL(uint64_t) RTTimeSystemNanoTS(void);
865
866/**
867 * Gets the current millisecond timestamp.
868 *
869 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
870 * resolution or performance optimizations.
871 *
872 * @returns millisecond timestamp.
873 */
874RTDECL(uint64_t) RTTimeSystemMilliTS(void);
875
876/**
877 * Get the nanosecond timestamp relative to program startup.
878 *
879 * @returns Timestamp relative to program startup.
880 */
881RTDECL(uint64_t) RTTimeProgramNanoTS(void);
882
883/**
884 * Get the microsecond timestamp relative to program startup.
885 *
886 * @returns Timestamp relative to program startup.
887 */
888RTDECL(uint64_t) RTTimeProgramMicroTS(void);
889
890/**
891 * Get the millisecond timestamp relative to program startup.
892 *
893 * @returns Timestamp relative to program startup.
894 */
895RTDECL(uint64_t) RTTimeProgramMilliTS(void);
896
897/**
898 * Get the second timestamp relative to program startup.
899 *
900 * @returns Timestamp relative to program startup.
901 */
902RTDECL(uint32_t) RTTimeProgramSecTS(void);
903
904/**
905 * Get the RTTimeNanoTS() of when the program started.
906 *
907 * @returns Program startup timestamp.
908 */
909RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
910
911/** @} */
912
913__END_DECLS
914
915#endif
916
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