1/*
2 * Copyright (c) 2000-2001,2003-2004,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// timeflow - abstract view of the flow of time
27//
28#include "timeflow.h"
29#include <stdint.h>
30#include <math.h>
31
32
33namespace Security {
34namespace Time {
35
36
37//
38// Get "now"
39//
40Absolute now()
41{
42    struct timeval tv;
43    gettimeofday(&tv, NULL);
44    return tv.tv_sec + double(tv.tv_usec) / 1E6;
45}
46
47
48//
49// OOL Conversions
50//
51Absolute::Absolute(const struct timeval &tv)
52{ mValue = tv.tv_sec + double(tv.tv_usec) / 1E6; }
53
54Absolute::Absolute(const struct timespec &tv)
55{ mValue = tv.tv_sec + double(tv.tv_nsec) / 1E9; }
56
57Absolute::operator struct timeval () const
58{
59    struct timeval tv;
60    if (mValue > LONG_MAX) {
61        tv.tv_sec = LONG_MAX;
62        tv.tv_usec = 0;
63    } else {
64        tv.tv_sec = int32_t(mValue);
65        double intPart;
66        tv.tv_usec = int32_t(modf(mValue, &intPart) * 1E6);
67    }
68    return tv;
69}
70
71Absolute::operator struct timespec () const
72{
73    struct timespec ts;
74    if (mValue > LONG_MAX) {
75        ts.tv_sec = LONG_MAX;
76        ts.tv_nsec = 0;
77    } else {
78        ts.tv_sec = time_t(mValue);
79        double intPart;
80        ts.tv_nsec = int32_t(modf(mValue, &intPart) * 1E9);
81    }
82    return ts;
83}
84
85struct timeval Interval::timevalInterval() const
86{
87    struct timeval tv;
88    if (mValue > LONG_MAX) {
89        tv.tv_sec = LONG_MAX;
90        tv.tv_usec = 0;
91    } else if (mValue < 0) {
92        tv.tv_sec = tv.tv_usec = 0;
93    } else {
94        tv.tv_sec = int32_t(mValue);
95        double intPart;
96        tv.tv_usec = int32_t(modf(mValue, &intPart) * 1E6);
97    }
98    return tv;
99}
100
101
102//
103// Estimate resolution at given time.
104//
105// BSD select(2) has theoretical microsecond resolution, but the underlying
106// Mach system deals with milliseconds, so we report that conservatively.
107// Sometime in the future when the sun is near collapse, residual resolution
108// of a double will drop under 1E-3, but we won't worry about that just yet.
109//
110Interval resolution(Absolute)
111{
112    return 0.001;
113}
114
115
116}	// end namespace Time
117}	// end namespace Security
118