diff options
Diffstat (limited to 'libutils/SystemClock.cpp')
-rw-r--r-- | libutils/SystemClock.cpp | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp index ac3dd98..c3b5d74 100644 --- a/libutils/SystemClock.cpp +++ b/libutils/SystemClock.cpp @@ -40,6 +40,9 @@ namespace android { +static pthread_mutex_t clock_lock = PTHREAD_MUTEX_INITIALIZER; +static int clock_method = -1; + /* * native public static long uptimeMillis(); */ @@ -119,29 +122,47 @@ int64_t elapsedRealtimeNano() static int s_fd = -1; - if (s_fd == -1) { - int fd = open("/dev/alarm", O_RDONLY); - if (android_atomic_cmpxchg(-1, fd, &s_fd)) { - close(fd); - } + if (clock_method < 0) { + pthread_mutex_lock(&clock_lock); } - result = ioctl(s_fd, - ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); + if (clock_method < 0 || clock_method == METHOD_IOCTL) { + if (s_fd == -1) { + int fd = open("/dev/alarm", O_RDONLY); + if (android_atomic_cmpxchg(-1, fd, &s_fd)) { + close(fd); + } + } - if (result == 0) { - timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; - checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL); - return timestamp; + if (s_fd > -1) { + result = ioctl(s_fd, + ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); + + if (result == 0) { + timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; + checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL); + if (clock_method < 0) { + clock_method = METHOD_IOCTL; + pthread_mutex_unlock(&clock_lock); + } + return timestamp; + } + } } // /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME - result = clock_gettime(CLOCK_BOOTTIME, &ts); - if (result == 0) { - timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; - checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, - METHOD_CLOCK_GETTIME); - return timestamp; + if (clock_method < 0 || clock_method == METHOD_CLOCK_GETTIME) { + result = clock_gettime(CLOCK_BOOTTIME, &ts); + if (result == 0) { + timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; + checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, + METHOD_CLOCK_GETTIME); + if (clock_method < 0) { + clock_method = METHOD_CLOCK_GETTIME; + pthread_mutex_unlock(&clock_lock); + } + return timestamp; + } } // XXX: there was an error, probably because the driver didn't @@ -150,6 +171,10 @@ int64_t elapsedRealtimeNano() timestamp = systemTime(SYSTEM_TIME_MONOTONIC); checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_SYSTEMTIME); + if (clock_method < 0) { + clock_method = METHOD_SYSTEMTIME; + pthread_mutex_unlock(&clock_lock); + } return timestamp; #else return systemTime(SYSTEM_TIME_MONOTONIC); |