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*/