diff options
Diffstat (limited to 'libs/utils/Timers.cpp')
-rw-r--r-- | libs/utils/Timers.cpp | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp deleted file mode 100644 index 2abc811..0000000 --- a/libs/utils/Timers.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// Timer functions. -// -#include <utils/Timers.h> -#include <utils/ported.h> // may need usleep -#include <utils/Log.h> - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/time.h> -#include <time.h> -#include <errno.h> - -#ifdef HAVE_WIN32_THREADS -#include <windows.h> -#endif - -nsecs_t systemTime(int clock) -{ -#if defined(HAVE_POSIX_CLOCKS) - static const clockid_t clocks[] = { - CLOCK_REALTIME, - CLOCK_MONOTONIC, - CLOCK_PROCESS_CPUTIME_ID, - CLOCK_THREAD_CPUTIME_ID - }; - struct timespec t; - t.tv_sec = t.tv_nsec = 0; - clock_gettime(clocks[clock], &t); - return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec; -#else - // we don't support the clocks here. - struct timeval t; - t.tv_sec = t.tv_usec = 0; - gettimeofday(&t, NULL); - return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL; -#endif -} - -//#define MONITOR_USLEEP - -/* - * Sleep long enough that we'll wake up "interval" milliseconds after - * the previous snooze. - * - * The "nextTick" argument is updated on each call, and should be passed - * in every time. Set its fields to zero on the first call. - * - * Returns the #of intervals we have overslept, which will be zero if we're - * on time. [Currently just returns 0 or 1.] - */ -int sleepForInterval(long interval, struct timeval* pNextTick) -{ - struct timeval now; - long long timeBeforeNext; - long sleepTime = 0; - bool overSlept = false; - //int usleepBias = 0; - -#ifdef USLEEP_BIAS - /* - * Linux likes to add 9000ms or so. - * [not using this for now] - */ - //usleepBias = USLEEP_BIAS; -#endif - - gettimeofday(&now, NULL); - - if (pNextTick->tv_sec == 0) { - /* special-case for first time through */ - *pNextTick = now; - sleepTime = interval; - android::DurationTimer::addToTimeval(pNextTick, interval); - } else { - /* - * Compute how much time there is before the next tick. If this - * value is negative, we've run over. If we've run over a little - * bit we can shorten the next frame to keep the pace steady, but - * if we've dramatically overshot we need to re-sync. - */ - timeBeforeNext = android::DurationTimer::subtractTimevals(pNextTick, &now); - //printf("TOP: now=%ld.%ld next=%ld.%ld diff=%ld\n", - // now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec, - // (long) timeBeforeNext); - if (timeBeforeNext < -interval) { - /* way over */ - overSlept = true; - sleepTime = 0; - *pNextTick = now; - } else if (timeBeforeNext <= 0) { - /* slightly over, keep the pace steady */ - overSlept = true; - sleepTime = 0; - } else if (timeBeforeNext <= interval) { - /* right on schedule */ - sleepTime = timeBeforeNext; - } else if (timeBeforeNext > interval && timeBeforeNext <= 2*interval) { - /* sleep call returned early; do a longer sleep this time */ - sleepTime = timeBeforeNext; - } else if (timeBeforeNext > interval) { - /* we went back in time -- somebody updated system clock? */ - /* (could also be a *seriously* broken usleep()) */ - LOG(LOG_DEBUG, "", - " Impossible: timeBeforeNext = %ld\n", (long)timeBeforeNext); - sleepTime = 0; - *pNextTick = now; - } - android::DurationTimer::addToTimeval(pNextTick, interval); - } - //printf(" Before sleep: now=%ld.%ld next=%ld.%ld sleepTime=%ld\n", - // now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec, - // sleepTime); - - /* - * Sleep for the designated period of time. - * - * Linux tends to sleep for longer than requested, often by 17-18ms. - * MinGW tends to sleep for less than requested, by as much as 14ms, - * but occasionally oversleeps for 40+ms (looks like some external - * factors plus round-off on a 64Hz clock). Cygwin is pretty steady. - * - * If you start the MinGW version, and then launch the Cygwin version, - * the MinGW clock becomes more erratic. Not entirely sure why. - * - * (There's a lot of stuff here; it's really just a usleep() call with - * a bunch of instrumentation.) - */ - if (sleepTime > 0) { -#if defined(MONITOR_USLEEP) - struct timeval before, after; - long long actual; - - gettimeofday(&before, NULL); - usleep((long) sleepTime); - gettimeofday(&after, NULL); - - /* check usleep() accuracy; default Linux threads are pretty sloppy */ - actual = android::DurationTimer::subtractTimevals(&after, &before); - if ((long) actual < sleepTime - 14000 /*(sleepTime/10)*/ || - (long) actual > sleepTime + 20000 /*(sleepTime/10)*/) - { - LOG(LOG_DEBUG, "", " Odd usleep: req=%ld, actual=%ld\n", sleepTime, - (long) actual); - } -#else -#ifdef HAVE_WIN32_THREADS - Sleep( sleepTime/1000 ); -#else - usleep((long) sleepTime); -#endif -#endif - } - - //printf("slept %d\n", sleepTime); - - if (overSlept) - return 1; // close enough - else - return 0; -} - - -/* - * =========================================================================== - * DurationTimer - * =========================================================================== - */ - -using namespace android; - -// Start the timer. -void DurationTimer::start(void) -{ - gettimeofday(&mStartWhen, NULL); -} - -// Stop the timer. -void DurationTimer::stop(void) -{ - gettimeofday(&mStopWhen, NULL); -} - -// Get the duration in microseconds. -long long DurationTimer::durationUsecs(void) const -{ - return (long) subtractTimevals(&mStopWhen, &mStartWhen); -} - -// Subtract two timevals. Returns the difference (ptv1-ptv2) in -// microseconds. -/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1, - const struct timeval* ptv2) -{ - long long stop = ((long long) ptv1->tv_sec) * 1000000LL + - ((long long) ptv1->tv_usec); - long long start = ((long long) ptv2->tv_sec) * 1000000LL + - ((long long) ptv2->tv_usec); - return stop - start; -} - -// Add the specified amount of time to the timeval. -/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec) -{ - if (usec < 0) { - LOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n"); - return; - } - - // normalize tv_usec if necessary - if (ptv->tv_usec >= 1000000) { - ptv->tv_sec += ptv->tv_usec / 1000000; - ptv->tv_usec %= 1000000; - } - - ptv->tv_usec += usec % 1000000; - if (ptv->tv_usec >= 1000000) { - ptv->tv_usec -= 1000000; - ptv->tv_sec++; - } - ptv->tv_sec += usec / 1000000; -} - |