VirtualBox

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

Last change on this file since 26209 was 26209, checked in by vboxsync, 15 years ago

IPRT: Added RTTimeSet.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.9 KB
Line 
1/** @file
2 * IPRT - 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
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/** 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) || defined(_LINUX_TIME_H)
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_OFFSET_DOS_TIME;
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 * Sets the system time.
610 *
611 * @returns IPRT status code
612 * @param pTime The new system time (UTC).
613 *
614 * @remarks This will usually fail because changing the wall time is usually
615 * requires extra privileges.
616 */
617RTDECL(int) RTTimeSet(PCRTTIMESPEC pTime);
618
619/**
620 * Explodes a time spec (UTC).
621 *
622 * @returns pTime.
623 * @param pTime Where to store the exploded time.
624 * @param pTimeSpec The time spec to exploded.
625 */
626RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
627
628/**
629 * Implodes exploded time to a time spec (UTC).
630 *
631 * @returns pTime on success.
632 * @returns NULL if the pTime data is invalid.
633 * @param pTimeSpec Where to store the imploded UTC time.
634 * If pTime specifies a time which outside the range, maximum or
635 * minimum values will be returned.
636 * @param pTime Pointer to the exploded time to implode.
637 * The fields u8Month, u8WeekDay and u8MonthDay are not used,
638 * and all the other fields are expected to be within their
639 * bounds. Use RTTimeNormalize() to calculate u16YearDay and
640 * normalize the ranges of the fields.
641 */
642RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
643
644/**
645 * Normalizes the fields of a time structure.
646 *
647 * It is possible to calculate year-day from month/day and vice
648 * versa. If you adjust any of of these, make sure to zero the
649 * other so you make it clear which of the fields to use. If
650 * it's ambiguous, the year-day field is used (and you get
651 * assertions in debug builds).
652 *
653 * All the time fields and the year-day or month/day fields will
654 * be adjusted for overflows. (Since all fields are unsigned, there
655 * is no underflows.) It is possible to exploit this for simple
656 * date math, though the recommended way of doing that to implode
657 * the time into a timespec and do the math on that.
658 *
659 * @returns pTime on success.
660 * @returns NULL if the data is invalid.
661 *
662 * @param pTime The time structure to normalize.
663 *
664 * @remarks This function doesn't work with local time, only with UTC time.
665 */
666RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
667
668/**
669 * Gets the current local system time.
670 *
671 * @returns pTime.
672 * @param pTime Where to store the local time.
673 */
674RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
675
676/**
677 * Gets the delta between UTC and local time.
678 *
679 * @code
680 * RTTIMESPEC LocalTime;
681 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
682 * @endcode
683 *
684 * @returns Returns the nanosecond delta between UTC and local time.
685 */
686RTDECL(int64_t) RTTimeLocalDeltaNano(void);
687
688/**
689 * Explodes a time spec to the localized timezone.
690 *
691 * @returns pTime.
692 * @param pTime Where to store the exploded time.
693 * @param pTimeSpec The time spec to exploded (UTC).
694 */
695RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
696
697/**
698 * Normalizes the fields of a time structure containing local time.
699 *
700 * See RTTimeNormalize for details.
701 *
702 * @returns pTime on success.
703 * @returns NULL if the data is invalid.
704 * @param pTime The time structure to normalize.
705 */
706RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
707
708/**
709 * Converts a time spec to a ISO date string.
710 *
711 * @returns psz on success.
712 * @returns NULL on buffer underflow.
713 * @param pTime The time. Caller should've normalized this.
714 * @param psz Where to store the string.
715 * @param cb The size of the buffer.
716 */
717RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
718
719/**
720 * Checks if a year is a leap year or not.
721 *
722 * @returns true if it's a leap year.
723 * @returns false if it's a common year.
724 * @param i32Year The year in question.
725 */
726RTDECL(bool) RTTimeIsLeapYear(int32_t i32Year);
727
728/**
729 * Gets the current nanosecond timestamp.
730 *
731 * @returns nanosecond timestamp.
732 */
733RTDECL(uint64_t) RTTimeNanoTS(void);
734
735/**
736 * Gets the current millisecond timestamp.
737 *
738 * @returns millisecond timestamp.
739 */
740RTDECL(uint64_t) RTTimeMilliTS(void);
741
742/**
743 * Debugging the time api.
744 *
745 * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
746 */
747RTDECL(uint32_t) RTTimeDbgSteps(void);
748
749/**
750 * Debugging the time api.
751 *
752 * @returns the number of times the TSC interval expired RTTimeNanoTS().
753 */
754RTDECL(uint32_t) RTTimeDbgExpired(void);
755
756/**
757 * Debugging the time api.
758 *
759 * @returns the number of bad previous values encountered by RTTimeNanoTS().
760 */
761RTDECL(uint32_t) RTTimeDbgBad(void);
762
763/**
764 * Debugging the time api.
765 *
766 * @returns the number of update races in RTTimeNanoTS().
767 */
768RTDECL(uint32_t) RTTimeDbgRaces(void);
769
770/** @name RTTimeNanoTS GIP worker functions, for TM.
771 * @{ */
772/** Pointer to a RTTIMENANOTSDATA structure. */
773typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
774
775/**
776 * Nanosecond timestamp data.
777 *
778 * This is used to keep track of statistics and callback so IPRT
779 * and TM (VirtualBox) can share code.
780 *
781 * @remark Keep this in sync with the assembly version in timesupA.asm.
782 */
783typedef struct RTTIMENANOTSDATA
784{
785 /** Where the previous timestamp is stored.
786 * This is maintained to ensure that time doesn't go backwards or anything. */
787 uint64_t volatile *pu64Prev;
788
789 /**
790 * Helper function that's used by the assembly routines when something goes bust.
791 *
792 * @param pData Pointer to this structure.
793 * @param u64NanoTS The calculated nano ts.
794 * @param u64DeltaPrev The delta relative to the previously returned timestamp.
795 * @param u64PrevNanoTS The previously returned timestamp (as it was read it).
796 */
797 DECLCALLBACKMEMBER(void, pfnBad)(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
798
799 /**
800 * Callback for when rediscovery is required.
801 *
802 * @returns Nanosecond timestamp.
803 * @param pData Pointer to this structure.
804 */
805 DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
806
807 /** Just a dummy alignment member. */
808 void *pvDummy;
809
810 /** Number of 1ns steps because of overshooting the period. */
811 uint32_t c1nsSteps;
812 /** The number of times the interval expired (overflow). */
813 uint32_t cExpired;
814 /** Number of "bad" previous values. */
815 uint32_t cBadPrev;
816 /** The number of update races. */
817 uint32_t cUpdateRaces;
818} RTTIMENANOTSDATA;
819
820#ifndef IN_RING3
821/**
822 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
823 */
824typedef struct RTTIMENANOTSDATAR3
825{
826 R3PTRTYPE(uint64_t volatile *) pu64Prev;
827 DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
828 DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
829 RTR3PTR pvDummy;
830 uint32_t c1nsSteps;
831 uint32_t cExpired;
832 uint32_t cBadPrev;
833 uint32_t cUpdateRaces;
834} RTTIMENANOTSDATAR3;
835#else
836typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
837#endif
838
839#ifndef IN_RING0
840/**
841 * The Ring-3 layout of the RTTIMENANOTSDATA structure.
842 */
843typedef struct RTTIMENANOTSDATAR0
844{
845 R0PTRTYPE(uint64_t volatile *) pu64Prev;
846 DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
847 DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
848 RTR0PTR pvDummy;
849 uint32_t c1nsSteps;
850 uint32_t cExpired;
851 uint32_t cBadPrev;
852 uint32_t cUpdateRaces;
853} RTTIMENANOTSDATAR0;
854#else
855typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
856#endif
857
858#ifndef IN_RC
859/**
860 * The RC layout of the RTTIMENANOTSDATA structure.
861 */
862typedef struct RTTIMENANOTSDATARC
863{
864 RCPTRTYPE(uint64_t volatile *) pu64Prev;
865 DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
866 DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
867 RCPTRTYPE(void *) pvDummy;
868 uint32_t c1nsSteps;
869 uint32_t cExpired;
870 uint32_t cBadPrev;
871 uint32_t cUpdateRaces;
872} RTTIMENANOTSDATARC;
873#else
874typedef RTTIMENANOTSDATA RTTIMENANOTSDATARC;
875#endif
876
877/** Internal RTTimeNanoTS worker (assembly). */
878typedef DECLCALLBACK(uint64_t) FNTIMENANOTSINTERNAL(PRTTIMENANOTSDATA pData);
879/** Pointer to an internal RTTimeNanoTS worker (assembly). */
880typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
881
882RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);
883RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
884RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData);
885RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
886/** @} */
887
888
889/**
890 * Gets the current nanosecond timestamp.
891 *
892 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
893 * resolution or performance optimizations.
894 *
895 * @returns nanosecond timestamp.
896 */
897RTDECL(uint64_t) RTTimeSystemNanoTS(void);
898
899/**
900 * Gets the current millisecond timestamp.
901 *
902 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
903 * resolution or performance optimizations.
904 *
905 * @returns millisecond timestamp.
906 */
907RTDECL(uint64_t) RTTimeSystemMilliTS(void);
908
909/**
910 * Get the nanosecond timestamp relative to program startup.
911 *
912 * @returns Timestamp relative to program startup.
913 */
914RTDECL(uint64_t) RTTimeProgramNanoTS(void);
915
916/**
917 * Get the microsecond timestamp relative to program startup.
918 *
919 * @returns Timestamp relative to program startup.
920 */
921RTDECL(uint64_t) RTTimeProgramMicroTS(void);
922
923/**
924 * Get the millisecond timestamp relative to program startup.
925 *
926 * @returns Timestamp relative to program startup.
927 */
928RTDECL(uint64_t) RTTimeProgramMilliTS(void);
929
930/**
931 * Get the second timestamp relative to program startup.
932 *
933 * @returns Timestamp relative to program startup.
934 */
935RTDECL(uint32_t) RTTimeProgramSecTS(void);
936
937/**
938 * Get the RTTimeNanoTS() of when the program started.
939 *
940 * @returns Program startup timestamp.
941 */
942RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
943
944/** @} */
945
946RT_C_DECLS_END
947
948#endif
949
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