1
/* cairo - a vector graphics library with display and print output
2
 *
3
 * Copyright (c) 2007 Netlabs
4
 * Copyright (c) 2006 Mozilla Corporation
5
 * Copyright (c) 2006 Red Hat, Inc.
6
 * Copyright (c) 2011 Andrea Canciani
7
 *
8
 * Permission to use, copy, modify, distribute, and sell this software
9
 * and its documentation for any purpose is hereby granted without
10
 * fee, provided that the above copyright notice appear in all copies
11
 * and that both that copyright notice and this permission notice
12
 * appear in supporting documentation, and that the name of
13
 * the authors not be used in advertising or publicity pertaining to
14
 * distribution of the software without specific, written prior
15
 * permission. The authors make no representations about the
16
 * suitability of this software for any purpose.  It is provided "as
17
 * is" without express or implied warranty.
18
 *
19
 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
20
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
 * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
22
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
23
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
24
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
25
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
 *
27
 * Authors: Peter Weilbacher <mozilla@weilbacher.org>
28
 *	    Vladimir Vukicevic <vladimir@pobox.com>
29
 *	    Carl Worth <cworth@cworth.org>
30
 *          Andrea Canciani <ranma42@gmail.com>
31
 */
32

            
33
#include "cairoint.h"
34

            
35
#include "cairo-time-private.h"
36

            
37
#if HAVE_CLOCK_GETTIME
38
#if defined(CLOCK_MONOTONIC_RAW)
39
#define CAIRO_CLOCK CLOCK_MONOTONIC_RAW
40
#elif defined(CLOCK_MONOTONIC)
41
#define CAIRO_CLOCK CLOCK_MONOTONIC
42
#endif
43
#endif
44

            
45
#if defined(__APPLE__)
46
#include <mach/mach_time.h>
47

            
48
static cairo_always_inline double
49
_cairo_time_1s (void)
50
{
51
    mach_timebase_info_data_t freq;
52

            
53
    mach_timebase_info (&freq);
54

            
55
    return 1000000000. * freq.denom / freq.numer;
56
}
57

            
58
cairo_time_t
59
_cairo_time_get (void)
60
{
61
    return mach_absolute_time ();
62
}
63

            
64
#elif _WIN32
65
#include <windows.h>
66

            
67
static cairo_always_inline double
68
_cairo_time_1s (void)
69
{
70
    LARGE_INTEGER freq;
71

            
72
    QueryPerformanceFrequency (&freq);
73

            
74
    return freq.QuadPart;
75
}
76

            
77
#ifndef HAVE_UINT64_T
78
static cairo_always_inline cairo_time_t
79
_cairo_time_from_large_integer (LARGE_INTEGER t)
80
{
81
    cairo_int64_t r;
82

            
83
    r = _cairo_int64_lsl (_cairo_int32_to_int64 (t.HighPart), 32);
84
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.LowPart));
85

            
86
    return r;
87
}
88
#else
89
static cairo_always_inline cairo_time_t
90
_cairo_time_from_large_integer (LARGE_INTEGER t)
91
{
92
    return t.QuadPart;
93
}
94
#endif
95

            
96
cairo_time_t
97
_cairo_time_get (void)
98
{
99
    LARGE_INTEGER t;
100

            
101
    QueryPerformanceCounter (&t);
102

            
103
    return _cairo_time_from_large_integer(t);
104
}
105

            
106
#elif defined(CAIRO_CLOCK)
107
#include <time.h>
108

            
109
static cairo_always_inline double
110
_cairo_time_1s (void)
111
{
112
    return 1000000000;
113
}
114

            
115
cairo_time_t
116
_cairo_time_get (void)
117
{
118
    struct timespec t;
119
    cairo_time_t r;
120

            
121
    clock_gettime (CAIRO_CLOCK, &t);
122

            
123
    r = _cairo_double_to_int64 (_cairo_time_1s ());
124
    r = _cairo_int64_mul (r, _cairo_int32_to_int64 (t.tv_sec));
125
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.tv_nsec));
126

            
127
    return r;
128
}
129

            
130
#else
131
#include <sys/time.h>
132

            
133
static cairo_always_inline double
134
_cairo_time_1s (void)
135
{
136
    return 1000000;
137
}
138

            
139
cairo_time_t
140
_cairo_time_get (void)
141
{
142
    struct timeval t;
143
    cairo_time_t r;
144

            
145
    gettimeofday (&t, NULL);
146

            
147
    r = _cairo_double_to_int64 (_cairo_time_1s ());
148
    r = _cairo_int64_mul (r, _cairo_int32_to_int64 (t.tv_sec));
149
    r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.tv_usec));
150

            
151
    return r;
152
}
153

            
154
#endif
155

            
156
int
157
_cairo_time_cmp (const void *a,
158
		 const void *b)
159
{
160
    const cairo_time_t *ta = a, *tb = b;
161
    return _cairo_int64_cmp (*ta, *tb);
162
}
163

            
164
static double
165
_cairo_time_ticks_per_sec (void)
166
{
167
    static double ticks = 0;
168

            
169
    if (unlikely (ticks == 0))
170
	ticks = _cairo_time_1s ();
171

            
172
    return ticks;
173
}
174

            
175
static double
176
_cairo_time_s_per_tick (void)
177
{
178
    static double s = 0;
179

            
180
    if (unlikely (s == 0))
181
	s = 1. / _cairo_time_ticks_per_sec ();
182

            
183
    return s;
184
}
185

            
186
double
187
_cairo_time_to_s (cairo_time_t t)
188
{
189
    return _cairo_int64_to_double (t) * _cairo_time_s_per_tick ();
190
}
191

            
192
cairo_time_t
193
_cairo_time_from_s (double t)
194
{
195
    return _cairo_double_to_int64 (t * _cairo_time_ticks_per_sec ());
196
}