2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL, version 2.
14 #include <sys/types.h>
20 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
21 #define TYPE_MAXIMUM(t) \
22 ((t) (! TYPE_SIGNED(t) \
24 : ~ (~ (t) 0 << (sizeof(t) * CHAR_BIT - 1))))
27 # define TIME_T_MAX TYPE_MAXIMUM(time_t)
30 static inline int timespec_subtract(struct timespec
*result
,
31 struct timespec
*after
,
32 struct timespec
*before
)
34 result
->tv_nsec
= after
->tv_nsec
- before
->tv_nsec
;
36 if (result
->tv_nsec
< 0) {
37 /* Borrow 1sec from 'tv_sec' if subtraction -ve */
38 result
->tv_nsec
+= 1000000000;
39 result
->tv_sec
= after
->tv_sec
- before
->tv_sec
- 1;
43 result
->tv_sec
= after
->tv_sec
- before
->tv_sec
;
49 static inline void xusleep(const struct timespec
*ts_delay
)
51 struct timeval tv_delay
;
53 tv_delay
.tv_sec
= ts_delay
->tv_sec
;
54 tv_delay
.tv_usec
= (ts_delay
->tv_nsec
+ 999) / 1000;
56 if (tv_delay
.tv_usec
== 1000000) {
57 time_t t1
= tv_delay
.tv_sec
+ 1;
58 if (t1
< tv_delay
.tv_sec
)
59 tv_delay
.tv_usec
= 1000000 - 1; /* Close enough */
66 select(0, NULL
, NULL
, NULL
, &tv_delay
);
69 static inline void xusleep2(long usecs
)
71 struct timespec ts
= {
73 .tv_nsec
= usecs
* 1000,
79 /* By Paul Eggert, Jim Meyering */
80 static inline int xnanosleep(double seconds
)
86 bool overflow
= false;
88 struct timespec ts_sleep
;
93 * Separate whole seconds from nanoseconds.
94 * Be careful to detect any overflow.
97 ts_sleep
.tv_sec
= seconds
;
98 ns
= BILLION
* (seconds
- ts_sleep
.tv_sec
);
99 overflow
|= !(ts_sleep
.tv_sec
<= seconds
&& 0 <= ns
&& ns
<= BILLION
);
100 ts_sleep
.tv_nsec
= ns
;
103 * Round up to the next whole number, if necessary, so that we
104 * always sleep for at least the requested amount of time. Assuming
105 * the default rounding mode, we don't have to worry about the
106 * rounding error when computing 'ns' above, since the error won't
107 * cause 'ns' to drop below an integer boundary.
110 ts_sleep
.tv_nsec
+= (ts_sleep
.tv_nsec
< ns
);
112 /* Normalize the interval length. nanosleep requires this. */
114 if (BILLION
<= ts_sleep
.tv_nsec
) {
115 time_t t
= ts_sleep
.tv_sec
+ 1;
117 /* Detect integer overflow. */
118 if (ts_sleep
.tv_sec
>= TIME_T_MAX
)
122 ts_sleep
.tv_nsec
-= BILLION
;
127 ts_sleep
.tv_sec
= TIME_T_MAX
;
128 ts_sleep
.tv_nsec
= BILLION
- 1;
132 * Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno
133 * when resumed after being suspended. Earlier versions would
134 * set errno to EINTR. nanosleep from linux-2.6.10, as well as
135 * implementations by (all?) other vendors, doesn't return -1
136 * in that case; either it continues sleeping (if time remains)
137 * or it returns zero (if the wake-up time has passed).
142 if (nanosleep(&ts_sleep
, NULL
) == 0)
144 if (errno
!= EINTR
&& errno
!= 0)
151 static inline int set_timeout(struct timeval
*timeval
, unsigned int msec
)
158 timeval
->tv_usec
= 0;
161 timeval
->tv_usec
= msec
* 1000;
165 timeval
->tv_sec
= (long) (msec
/ 1000);
166 timeval
->tv_usec
= (long) ((msec
- (timeval
->tv_sec
* 1000)) * 1000);
172 static inline unsigned long long getticks(void)
174 unsigned int __a
,__d
;
176 __asm__
__volatile__("rdtsc" : "=a" (__a
), "=d" (__d
));
177 return ((long long)__a
) | (((long long)__d
)<<32);
180 #endif /* TIMESPEC_H */