summaryrefslogtreecommitdiffstats
path: root/libutils
diff options
context:
space:
mode:
Diffstat (limited to 'libutils')
-rw-r--r--libutils/SystemClock.cpp59
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);