X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/f44ba092651aa75055e109e04b4164ea92ae7fdc..856e78f45e1ecf16fc05b98b86aeb92236f4917c:/src/pulse/timeval.c diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 11285230..a394dbea 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -1,18 +1,19 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. - + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + PulseAudio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License along with PulseAudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 @@ -23,7 +24,6 @@ #include #endif -#include #include #include @@ -31,32 +31,28 @@ #include #endif -#include "../pulsecore/winsock.h" +#include +#include #include "timeval.h" struct timeval *pa_gettimeofday(struct timeval *tv) { -#ifdef HAVE_GETTIMEOFDAY - assert(tv); - - return gettimeofday(tv, NULL) < 0 ? NULL : tv; -#elif defined(OS_IS_WIN32) + pa_assert(tv); + +#if defined(OS_IS_WIN32) /* * Copied from implementation by Steven Edwards (LGPL). * Found on wine mailing list. */ - #if defined(_MSC_VER) || defined(__BORLANDC__) #define EPOCHFILETIME (116444736000000000i64) #else #define EPOCHFILETIME (116444736000000000LL) #endif - - FILETIME ft; - LARGE_INTEGER li; - __int64 t; - - assert(tv); +{ + FILETIME ft; + LARGE_INTEGER li; + int64_t t; GetSystemTimeAsFileTime(&ft); li.LowPart = ft.dwLowDateTime; @@ -64,21 +60,26 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { t = li.QuadPart; /* In 100-nanosecond intervals */ t -= EPOCHFILETIME; /* Offset to the Epoch time */ t /= 10; /* In microseconds */ - tv->tv_sec = (long)(t / 1000000); - tv->tv_usec = (long)(t % 1000000); - - return tv; + tv->tv_sec = (time_t) (t / PA_USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (t % PA_USEC_PER_SEC); +} +#elif defined(HAVE_GETTIMEOFDAY) + pa_assert_se(gettimeofday(tv, NULL) == 0); #else #error "Platform lacks gettimeofday() or equivalent function." #endif + + return tv; } pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { pa_usec_t r; - assert(a && b); - /* Check which whan is the earlier time and swap the two arguments if reuqired. */ - if (pa_timeval_cmp(a, b) < 0) { + pa_assert(a); + pa_assert(b); + + /* Check which is the earlier time and swap the two arguments if required. */ + if (PA_UNLIKELY(pa_timeval_cmp(a, b) < 0)) { const struct timeval *c; c = a; a = b; @@ -86,19 +87,20 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { } /* Calculate the second difference*/ - r = ((pa_usec_t) a->tv_sec - b->tv_sec)* 1000000; + r = ((pa_usec_t) a->tv_sec - (pa_usec_t) b->tv_sec) * PA_USEC_PER_SEC; /* Calculate the microsecond difference */ if (a->tv_usec > b->tv_usec) - r += ((pa_usec_t) a->tv_usec - 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 - a->tv_usec); + r -= (pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec; return r; } int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) { - assert(a && b); + pa_assert(a); + pa_assert(b); if (a->tv_sec < b->tv_sec) return -1; @@ -117,26 +119,95 @@ int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) { pa_usec_t pa_timeval_age(const struct timeval *tv) { struct timeval now; - assert(tv); - + pa_assert(tv); + return pa_timeval_diff(pa_gettimeofday(&now), tv); } struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { - unsigned long secs; - assert(tv); - - secs = (v/1000000); - tv->tv_sec += (unsigned long) secs; - v -= secs*1000000; + time_t secs; + pa_assert(tv); + + 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_usec += v; + tv->tv_sec += secs; + v -= (pa_usec_t) secs * PA_USEC_PER_SEC; + tv->tv_usec += (suseconds_t) v; /* Normalize */ - while (tv->tv_usec >= 1000000) { + 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 -= 1000000; + 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) { + 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; }