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.
30 \brief A microsecond precise timestamp.
32 included in the sf_pkthdr or the bpf_hdr that NPF associates with every packet.
36 long tv_sec
; ///< seconds
37 long tv_usec
; ///< microseconds
40 #endif /*WIN_NT_DRIVER*/
49 void TIME_DESYNCHRONIZE(struct time_conv
*data
);
50 VOID
TIME_SYNCHRONIZE(struct time_conv
*data
);
51 void FORCE_TIME(struct timeval
*src
, struct time_conv
*dest
);
52 void GET_TIME(struct timeval
*dst
, struct time_conv
*data
);
58 __inline
void TIME_DESYNCHRONIZE(struct time_conv
*data
)
61 data
->start
.tv_sec
= 0;
62 data
->start
.tv_usec
= 0;
67 /* KeQueryPerformanceCounter TimeStamps */
69 __inline VOID
TIME_SYNCHRONIZE(struct time_conv
*data
)
72 LARGE_INTEGER SystemTime
;
75 LARGE_INTEGER TimeFreq
,PTime
;
77 if (data
->reference
!=0)
80 // get the absolute value of the system boot time.
81 PTime
=KeQueryPerformanceCounter(&TimeFreq
);
82 KeQuerySystemTime(&SystemTime
);
83 tmp
.tv_sec
=(LONG
)(SystemTime
.QuadPart
/10000000-11644473600);
84 tmp
.tv_usec
=(LONG
)((SystemTime
.QuadPart
%10000000)/10);
85 tmp
.tv_sec
-=(ULONG
)(PTime
.QuadPart
/TimeFreq
.QuadPart
);
86 tmp
.tv_usec
-=(LONG
)((PTime
.QuadPart
%TimeFreq
.QuadPart
)*1000000/TimeFreq
.QuadPart
);
95 __inline
void GET_TIME(struct timeval
*dst
, struct time_conv
*data
)
97 LARGE_INTEGER PTime
, TimeFreq
;
100 PTime
=KeQueryPerformanceCounter(&TimeFreq
);
101 tmp
=(LONG
)(PTime
.QuadPart
/TimeFreq
.QuadPart
);
102 dst
->tv_sec
=data
->start
.tv_sec
+tmp
;
103 dst
->tv_usec
=data
->start
.tv_usec
+(LONG
)((PTime
.QuadPart
%TimeFreq
.QuadPart
)*1000000/TimeFreq
.QuadPart
);
104 if (dst
->tv_usec
>=1000000) {
106 dst
->tv_usec
-=1000000;
110 __inline
void FORCE_TIME(struct timeval
*src
, struct time_conv
*dest
)
119 /* callers must be at IRQL=PASSIVE_LEVEL */
120 __inline VOID
TIME_SYNCHRONIZE(struct time_conv
*data
)
123 LARGE_INTEGER system_time
;
124 ULONGLONG curr_ticks
;
126 LARGE_INTEGER start_kqpc
,stop_kqpc
,start_freq
,stop_freq
;
127 ULONGLONG start_ticks
,stop_ticks
;
128 ULONGLONG delta
,delta2
;
133 if (data
->reference
!=0)
136 KeInitializeEvent(&event
,NotificationEvent
,FALSE
);
138 KeRaiseIrql(HIGH_LEVEL
,&old
);
139 start_kqpc
=KeQueryPerformanceCounter(&start_freq
);
157 KeWaitForSingleObject(&event
,UserRequest
,KernelMode
,TRUE
,&i
);
158 KeRaiseIrql(HIGH_LEVEL
,&old
);
159 stop_kqpc
=KeQueryPerformanceCounter(&stop_freq
);
177 delta
=stop_ticks
-start_ticks
;
178 delta2
=stop_kqpc
.QuadPart
-start_kqpc
.QuadPart
;
179 if (delta
>10000000000) {
183 reference
=delta
*(start_freq
.QuadPart
)/delta2
;
184 data
->reference
=reference
/1000;
185 if (reference
%1000>500)
187 data
->reference
*=1000;
188 reference
=data
->reference
;
189 KeQuerySystemTime(&system_time
);
206 tmp
.tv_sec
=-(LONG
)(curr_ticks
/reference
);
207 tmp
.tv_usec
=-(LONG
)((curr_ticks
%reference
)*1000000/reference
);
208 system_time
.QuadPart
-=116444736000000000;
209 tmp
.tv_sec
+=(LONG
)(system_time
.QuadPart
/10000000);
210 tmp
.tv_usec
+=(LONG
)((system_time
.QuadPart
%10000000)/10);
213 tmp
.tv_usec
+=1000000;
216 IF_LOUD(DbgPrint("Frequency %I64u MHz\n",data
->reference
);)
219 __inline
void FORCE_TIME(struct timeval
*src
, struct time_conv
*dest
)
224 __inline
void GET_TIME(struct timeval
*dst
, struct time_conv
*data
)
243 if (data
->reference
==0) {
246 dst
->tv_sec
=(LONG
)(tmp
/data
->reference
);
247 dst
->tv_usec
=(LONG
)((tmp
-dst
->tv_sec
*data
->reference
)*1000000/data
->reference
);
248 dst
->tv_sec
+=data
->start
.tv_sec
;
249 dst
->tv_usec
+=data
->start
.tv_usec
;
250 if (dst
->tv_usec
>=1000000) {
252 dst
->tv_usec
-=1000000;
258 #endif /*WIN_NT_DRIVER*/
260 #endif /* __GNUC__ */
262 #endif /*_time_calls*/