3 * Politecnico di Torino. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the Politecnico
13 * di Torino, and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 #include "time_calls.h"
27 void TIME_DESYNCHRONIZE(struct time_conv
*data
)
30 data
->start
.tv_sec
= 0;
31 data
->start
.tv_usec
= 0;
36 /* KeQueryPerformanceCounter TimeStamps */
38 VOID
TIME_SYNCHRONIZE(struct time_conv
*data
)
41 LARGE_INTEGER SystemTime
;
42 LARGE_INTEGER TimeFreq
,PTime
;
44 if (data
->reference
!=0)
47 // get the absolute value of the system boot time.
48 PTime
=KeQueryPerformanceCounter(&TimeFreq
);
49 KeQuerySystemTime(&SystemTime
);
51 tmp
.tv_sec
=(LONG
)(SystemTime
.QuadPart
/10000000-11644473600);
52 tmp
.tv_usec
=(LONG
)((SystemTime
.QuadPart
%10000000)/10);
53 tmp
.tv_sec
-=(ULONG
)(PTime
.QuadPart
/TimeFreq
.QuadPart
);
54 tmp
.tv_usec
-=(LONG
)((PTime
.QuadPart
%TimeFreq
.QuadPart
)*1000000/TimeFreq
.QuadPart
);
68 void FORCE_TIME(struct timeval
*src
, struct time_conv
*dest
)
73 void GET_TIME(struct timeval
*dst
, struct time_conv
*data
)
75 LARGE_INTEGER PTime
, TimeFreq
;
77 PTime
=KeQueryPerformanceCounter(&TimeFreq
);
79 tmp
=(LONG
)(PTime
.QuadPart
/TimeFreq
.QuadPart
);
80 dst
->tv_sec
=data
->start
.tv_sec
+tmp
;
81 dst
->tv_usec
=data
->start
.tv_usec
+(LONG
)((PTime
.QuadPart
%TimeFreq
.QuadPart
)*1000000/TimeFreq
.QuadPart
);
85 if (dst
->tv_usec
>=1000000) {
87 dst
->tv_usec
-=1000000;
95 /* callers must be at IRQL=PASSIVE_LEVEL */
96 VOID
TIME_SYNCHRONIZE(struct time_conv
*data
)
98 LARGE_INTEGER system_time
;
101 LARGE_INTEGER start_kqpc
,stop_kqpc
,start_freq
,stop_freq
;
102 ULONGLONG start_ticks
,stop_ticks
;
103 ULONGLONG delta
,delta2
;
108 if (data
->reference
!=0)
111 KeInitializeEvent(&event
,NotificationEvent
,FALSE
);
113 KeRaiseIrql(HIGH_LEVEL
,&old
);
114 start_kqpc
=KeQueryPerformanceCounter(&start_freq
);
135 "mov %%edx,(%%ecx+4);"
140 :"=c"(start_ticks
): );
143 KeWaitForSingleObject(&event
,UserRequest
,KernelMode
,TRUE
,&i
);
144 KeRaiseIrql(HIGH_LEVEL
,&old
);
145 stop_kqpc
=KeQueryPerformanceCounter(&stop_freq
);
166 "mov %%edx,(%%ecx+4);"
171 :"=c"(stop_ticks
): );
174 delta
=stop_ticks
-start_ticks
;
175 delta2
=stop_kqpc
.QuadPart
-start_kqpc
.QuadPart
;
176 if (delta
>10000000000) {
180 reference
=delta
*(start_freq
.QuadPart
)/delta2
;
181 data
->reference
=reference
/1000;
182 if (reference
%1000>500)
184 data
->reference
*=1000;
185 reference
=data
->reference
;
186 KeQuerySystemTime(&system_time
);
207 "mov %%edx,(%%ecx+4);"
212 :"=c"(curr_ticks
): );
214 tmp
.tv_sec
=-(LONG
)(curr_ticks
/reference
);
215 tmp
.tv_usec
=-(LONG
)((curr_ticks
%reference
)*1000000/reference
);
216 system_time
.QuadPart
-=116444736000000000;
217 tmp
.tv_sec
+=(LONG
)(system_time
.QuadPart
/10000000);
218 tmp
.tv_usec
+=(LONG
)((system_time
.QuadPart
%10000000)/10);
221 tmp
.tv_usec
+=1000000;
224 IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data
->reference
);)
227 void FORCE_TIME(struct timeval
*src
, struct time_conv
*dest
)
232 void GET_TIME(struct timeval
*dst
, struct time_conv
*data
)
255 "mov %%edx,(%%ecx+4);"
262 if (data
->reference
==0) {
265 dst
->tv_sec
=(LONG
)(tmp
/data
->reference
);
266 dst
->tv_usec
=(LONG
)((tmp
-dst
->tv_sec
*data
->reference
)*1000000/data
->reference
);
267 dst
->tv_sec
+=data
->start
.tv_sec
;
268 dst
->tv_usec
+=data
->start
.tv_usec
;
269 if (dst
->tv_usec
>=1000000) {
271 dst
->tv_usec
-=1000000;