Skip to content

Commit

Permalink
libutils: Improve support for POSIX timers
Browse files Browse the repository at this point in the history
 * Don't repeatedly try to open nonexistent devices where possible.

Change-Id: Id1f18d05943a66978d430556fa16ed761e8e464b
  • Loading branch information
ryzenforce990 authored and Flinny committed Jul 15, 2015
1 parent 7797843 commit e65bcdf
Showing 1 changed file with 42 additions and 17 deletions.
59 changes: 42 additions & 17 deletions libutils/SystemClock.cpp
Expand Up @@ -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();
*/
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down

0 comments on commit e65bcdf

Please sign in to comment.