diff options
| author | Daniel Mack <daniel@caiaq.de> | 2009-09-22 11:30:30 +0800 | 
|---|---|---|
| committer | Daniel Mack <daniel@caiaq.de> | 2009-09-22 11:30:30 +0800 | 
| commit | 94aa9097f4ded68623160d754a4bf2632b8efc79 (patch) | |
| tree | 94a5e1192a18f760dc00ff5b36e1f7ba36fd449b /src/pulse/timeval.c | |
| parent | c1e59f7d762fb147bc5250ebddb9cf5639aba522 (diff) | |
| parent | c194db71b0ff853b4f46df26e135edf63b215451 (diff) | |
Merge branch 'master' of git://0pointer.de/pulseaudio
Diffstat (limited to 'src/pulse/timeval.c')
| -rw-r--r-- | src/pulse/timeval.c | 67 | 
1 files changed, 51 insertions, 16 deletions
| diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 376cf13c..cde4417c 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -33,6 +33,7 @@  #include <pulsecore/winsock.h>  #include <pulsecore/macro.h> +#include <pulsecore/core-util.h>  #include "timeval.h" @@ -54,9 +55,9 @@ struct timeval *pa_gettimeofday(struct timeval *tv) {  #define EPOCHFILETIME (116444736000000000LL)  #endif -    FILETIME        ft; -    LARGE_INTEGER   li; -    __int64         t; +    FILETIME ft; +    LARGE_INTEGER li; +    int64_t t;      pa_assert(tv); @@ -82,7 +83,7 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) {      pa_assert(b);      /* Check which whan is the earlier time and swap the two arguments if required. */ -    if (pa_timeval_cmp(a, b) < 0) { +    if (PA_UNLIKELY(pa_timeval_cmp(a, b) < 0)) {          const struct timeval *c;          c = a;          a = b; @@ -94,9 +95,9 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) {      /* Calculate the microsecond difference */      if (a->tv_usec > b->tv_usec) -        r += ((pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec); +        r += (pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec;      else if (a->tv_usec < b->tv_usec) -        r -= ((pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec); +        r -= (pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec;      return r;  } @@ -128,45 +129,77 @@ pa_usec_t pa_timeval_age(const struct timeval *tv) {  }  struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { -    unsigned long secs; +    time_t secs;      pa_assert(tv); -    secs = (unsigned long) (v/PA_USEC_PER_SEC); -    tv->tv_sec += (time_t) secs; -    v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; +    secs = (time_t) (v/PA_USEC_PER_SEC); +    if (PA_UNLIKELY(tv->tv_sec > PA_INT_TYPE_MAX(time_t) - secs)) +        goto overflow; + +    tv->tv_sec += secs; +    v -= (pa_usec_t) secs * PA_USEC_PER_SEC;      tv->tv_usec += (suseconds_t) v;      /* Normalize */ -    while ((unsigned) tv->tv_usec >= PA_USEC_PER_SEC) { +    while ((pa_usec_t) tv->tv_usec >= PA_USEC_PER_SEC) { + +        if (PA_UNLIKELY(tv->tv_sec >= PA_INT_TYPE_MAX(time_t))) +            goto overflow; +          tv->tv_sec++;          tv->tv_usec -= (suseconds_t) PA_USEC_PER_SEC;      }      return tv; + +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) { -    unsigned long secs; +    time_t secs;      pa_assert(tv); -    secs = (unsigned long) (v/PA_USEC_PER_SEC); -    tv->tv_sec -= (time_t) secs; -    v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; +    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); @@ -174,7 +207,9 @@ struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) {  }  pa_usec_t pa_timeval_load(const struct timeval *tv) { -    pa_assert(tv); + +    if (PA_UNLIKELY(!tv)) +        return PA_USEC_INVALID;      return          (pa_usec_t) tv->tv_sec * PA_USEC_PER_SEC + | 
