2 * transsip - the telephony network
3 * By Daniel Borkmann <daniel@transsip.org>
4 * Copyright 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
14 #include <sys/types.h>
20 extern void fsync_or_die(int fd
, const char *msg
);
21 extern int open_or_die(const char *file
, int flags
);
22 extern int open_or_die_m(const char *file
, int flags
, mode_t mode
);
23 extern ssize_t
read_or_die(int fd
, void *buf
, size_t count
);
24 extern ssize_t
read_exact(int fd
, void *buf
, size_t len
, int mayexit
);
25 extern ssize_t
write_exact(int fd
, void *buf
, size_t len
, int mayexit
);
26 extern ssize_t
write_or_die(int fd
, const void *buf
, size_t count
);
27 extern ssize_t
write_or_whine_pipe(int fd
, const void *buf
, size_t len
,
29 extern ssize_t
write_or_whine(int fd
, const void *buf
, size_t len
,
31 extern size_t strlcpy(char *dest
, const char *src
, size_t size
);
32 extern int slprintf(char *dst
, size_t size
, const char *fmt
, ...);
33 extern char **strntoargv(char *str
, size_t len
, int *argc
);
35 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
36 #define TYPE_MAXIMUM(t) \
37 ((t) (! TYPE_SIGNED(t) \
39 : ~ (~ (t) 0 << (sizeof(t) * CHAR_BIT - 1))))
42 # define TIME_T_MAX TYPE_MAXIMUM(time_t)
45 static inline int timespec_subtract(struct timespec
*result
,
46 struct timespec
*after
,
47 struct timespec
*before
)
49 result
->tv_nsec
= after
->tv_nsec
- before
->tv_nsec
;
51 if (result
->tv_nsec
< 0) {
52 /* Borrow 1sec from 'tv_sec' if subtraction -ve */
53 result
->tv_nsec
+= 1000000000;
54 result
->tv_sec
= after
->tv_sec
- before
->tv_sec
- 1;
58 result
->tv_sec
= after
->tv_sec
- before
->tv_sec
;
64 static inline void xusleep(const struct timespec
*ts_delay
)
66 struct timeval tv_delay
;
68 tv_delay
.tv_sec
= ts_delay
->tv_sec
;
69 tv_delay
.tv_usec
= (ts_delay
->tv_nsec
+ 999) / 1000;
71 if (tv_delay
.tv_usec
== 1000000) {
72 time_t t1
= tv_delay
.tv_sec
+ 1;
73 if (t1
< tv_delay
.tv_sec
)
74 tv_delay
.tv_usec
= 1000000 - 1; /* Close enough */
81 select(0, NULL
, NULL
, NULL
, &tv_delay
);
84 static inline void xusleep2(long usecs
)
86 struct timespec ts
= {
88 .tv_nsec
= usecs
* 1000,
94 /* By Paul Eggert, Jim Meyering */
95 static inline int xnanosleep(double seconds
)
101 bool overflow
= false;
103 struct timespec ts_sleep
;
105 assert(0 <= seconds
);
108 * Separate whole seconds from nanoseconds.
109 * Be careful to detect any overflow.
112 ts_sleep
.tv_sec
= seconds
;
113 ns
= BILLION
* (seconds
- ts_sleep
.tv_sec
);
114 overflow
|= !(ts_sleep
.tv_sec
<= seconds
&& 0 <= ns
&& ns
<= BILLION
);
115 ts_sleep
.tv_nsec
= ns
;
118 * Round up to the next whole number, if necessary, so that we
119 * always sleep for at least the requested amount of time. Assuming
120 * the default rounding mode, we don't have to worry about the
121 * rounding error when computing 'ns' above, since the error won't
122 * cause 'ns' to drop below an integer boundary.
125 ts_sleep
.tv_nsec
+= (ts_sleep
.tv_nsec
< ns
);
127 /* Normalize the interval length. nanosleep requires this. */
129 if (BILLION
<= ts_sleep
.tv_nsec
) {
130 time_t t
= ts_sleep
.tv_sec
+ 1;
132 /* Detect integer overflow. */
133 overflow
|= (t
< ts_sleep
.tv_sec
);
136 ts_sleep
.tv_nsec
-= BILLION
;
141 ts_sleep
.tv_sec
= TIME_T_MAX
;
142 ts_sleep
.tv_nsec
= BILLION
- 1;
146 * Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno
147 * when resumed after being suspended. Earlier versions would
148 * set errno to EINTR. nanosleep from linux-2.6.10, as well as
149 * implementations by (all?) other vendors, doesn't return -1
150 * in that case; either it continues sleeping (if time remains)
151 * or it returns zero (if the wake-up time has passed).
156 if (nanosleep(&ts_sleep
, NULL
) == 0)
158 if (errno
!= EINTR
&& errno
!= 0)
165 static inline int set_timeout(struct timeval
*timeval
, unsigned int msec
)
171 timeval
->tv_usec
= 0;
174 timeval
->tv_usec
= msec
* 1000;
178 timeval
->tv_sec
= (long) (msec
/ 1000);
179 timeval
->tv_usec
= (long) ((msec
- (timeval
->tv_sec
* 1000)) * 1000);
185 static inline unsigned long long getticks(void)
187 unsigned int __a
,__d
;
188 __asm__
__volatile__("rdtsc" : "=a" (__a
), "=d" (__d
));
189 return ((long long)__a
) | (((long long)__d
)<<32);
192 #endif /* XUTILS_H */