+
+overflow:
+ tv->tv_sec = PA_INT_TYPE_MAX(time_t);
+ tv->tv_usec = (suseconds_t) (PA_USEC_PER_SEC-1);
+ return tv;
+}
+
+struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) {
+ time_t secs;
+ pa_assert(tv);
+
+ secs = (time_t) (v/PA_USEC_PER_SEC);
+
+ if (PA_UNLIKELY(tv->tv_sec < secs))
+ goto underflow;
+
+ tv->tv_sec -= secs;
+ v -= (pa_usec_t) secs * PA_USEC_PER_SEC;
+
+ if (tv->tv_usec >= (suseconds_t) v)
+ tv->tv_usec -= (suseconds_t) v;
+ else {
+
+ if (PA_UNLIKELY(tv->tv_sec <= 0))
+ goto underflow;
+
+ tv->tv_sec --;
+ tv->tv_usec += (suseconds_t) (PA_USEC_PER_SEC - v);
+ }
+
+ return tv;
+
+underflow:
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ return tv;
+}
+
+struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) {
+ pa_assert(tv);
+
+ if (PA_UNLIKELY(v == PA_USEC_INVALID)) {
+ tv->tv_sec = PA_INT_TYPE_MAX(time_t);
+ tv->tv_usec = (suseconds_t) (PA_USEC_PER_SEC-1);
+
+ return tv;
+ }
+
+ tv->tv_sec = (time_t) (v / PA_USEC_PER_SEC);
+ tv->tv_usec = (suseconds_t) (v % PA_USEC_PER_SEC);
+
+ return tv;
+}
+
+pa_usec_t pa_timeval_load(const struct timeval *tv) {
+
+ if (PA_UNLIKELY(!tv))
+ return PA_USEC_INVALID;
+
+ return
+ (pa_usec_t) tv->tv_sec * PA_USEC_PER_SEC +
+ (pa_usec_t) tv->tv_usec;