VirtualBox

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

Last change on this file since 8155 was 8155, checked in by vboxsync, 16 years ago

The Big Sun Rebranding Header Change

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

© 2023 Oracle
ContactPrivacy policyTerms of Use