1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 * OS independent time-manipulation functions.
32 * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
36 #include "pipe/p_config.h"
38 #if defined(PIPE_OS_LINUX)
40 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
43 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
45 extern VOID
KeQuerySystemTime(PLARGE_INTEGER
);
46 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
52 #include "util/u_time.h"
55 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
57 static int64_t frequency
= 0;
60 util_time_get_frequency(void)
63 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
65 EngQueryPerformanceFrequency(&temp
);
67 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
69 QueryPerformanceFrequency(&temp
);
70 frequency
= temp
.QuadPart
;
78 util_time_get(struct util_time
*t
)
80 #if defined(PIPE_OS_LINUX)
81 gettimeofday(&t
->tv
, NULL
);
82 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
84 EngQueryPerformanceCounter(&temp
);
86 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
87 /* Updated every 10 miliseconds, measured in units of 100 nanoseconds.
88 * http://msdn.microsoft.com/en-us/library/ms801642.aspx */
90 KeQuerySystemTime(&temp
);
91 t
->counter
= temp
.QuadPart
;
92 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
94 QueryPerformanceCounter(&temp
);
95 t
->counter
= temp
.QuadPart
;
101 util_time_add(const struct util_time
*t1
,
103 struct util_time
*t2
)
105 #if defined(PIPE_OS_LINUX)
106 t2
->tv
.tv_sec
= t1
->tv
.tv_sec
+ usecs
/ 1000000;
107 t2
->tv
.tv_usec
= t1
->tv
.tv_usec
+ usecs
% 1000000;
108 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
109 util_time_get_frequency();
110 t2
->counter
= t1
->counter
+ (usecs
* frequency
+ INT64_C(999999))/INT64_C(1000000);
111 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
112 /* 1 tick = 100 nano seconds. */
113 t2
->counter
= t1
->counter
+ usecs
* 10;
117 freq
= temp
.QuadPart
;
118 t2
->counter
= t1
->counter
+ (usecs
* freq
)/1000000L;
124 util_time_diff(const struct util_time
*t1
,
125 const struct util_time
*t2
)
127 #if defined(PIPE_OS_LINUX)
128 return (t2
->tv
.tv_usec
- t1
->tv
.tv_usec
) +
129 (t2
->tv
.tv_sec
- t1
->tv
.tv_sec
)*1000000;
130 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
131 util_time_get_frequency();
132 return (t2
->counter
- t1
->counter
)*INT64_C(1000000)/frequency
;
133 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
134 return (t2
->counter
- t1
->counter
)/10;
141 util_time_micros( void )
147 #if defined(PIPE_OS_LINUX)
148 return t1
.tv
.tv_usec
+ t1
.tv
.tv_sec
*1000000LL;
149 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
150 util_time_get_frequency();
151 return t1
.counter
*INT64_C(1000000)/frequency
;
152 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
153 return t1
.counter
/10;
160 * Compare two time values.
162 * Not publicly available because it does not take in account wrap-arounds.
163 * Use util_time_timeout instead.
166 util_time_compare(const struct util_time
*t1
,
167 const struct util_time
*t2
)
169 #if defined(PIPE_OS_LINUX)
170 if (t1
->tv
.tv_sec
< t2
->tv
.tv_sec
)
172 else if(t1
->tv
.tv_sec
> t2
->tv
.tv_sec
)
174 else if (t1
->tv
.tv_usec
< t2
->tv
.tv_usec
)
176 else if(t1
->tv
.tv_usec
> t2
->tv
.tv_usec
)
180 #elif defined(PIPE_OS_WINDOWS)
181 if (t1
->counter
< t2
->counter
)
183 else if(t1
->counter
> t2
->counter
)
192 util_time_timeout(const struct util_time
*start
,
193 const struct util_time
*end
,
194 const struct util_time
*curr
)
196 if(util_time_compare(start
, end
) <= 0)
197 return !(util_time_compare(start
, curr
) <= 0 && util_time_compare(curr
, end
) < 0);
199 return !(util_time_compare(start
, curr
) <= 0 || util_time_compare(curr
, end
) < 0);
203 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
204 void util_time_sleep(unsigned usecs
)
206 LONGLONG start
, curr
, end
;
208 EngQueryPerformanceCounter(&start
);
211 EngQueryPerformanceFrequency(&frequency
);
213 end
= start
+ (usecs
* frequency
+ 999999LL)/1000000LL;
216 EngQueryPerformanceCounter(&curr
);
217 } while(start
<= curr
&& curr
< end
||
218 end
< start
&& (curr
< end
|| start
<= curr
));