#include <fcntl.h>
#include <utils/Log.h>
#include <hardware/sensors.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+
#include "common.h"
#include "utils.h"
}
+int sysfs_write_float(const char path[PATH_MAX], float value)
+{
+ int ret;
+ int fd;
+ int len;
+ char buf[20];
+
+ len = snprintf(buf, sizeof(buf), "%g", value);
+
+ if (!path[0] || len <= 0) {
+ ALOGE("Unexpected condition in sysfs_write_float\n");
+ return -1;
+ }
+
+ fd = open(path, O_WRONLY);
+
+ if (fd == -1) {
+ ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
+ return -1;
+ }
+
+ ret = write(fd, buf, len);
+
+ if (ret != len) {
+ ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
+ strerror(errno));
+ }
+
+ close(fd);
+
+ return ret;
+}
+
+
int sysfs_read_float(const char path[PATH_MAX], float *value)
{
int fd;
*value = (float) strtod(buf, NULL);
- ALOGV("Read %f from %s\n", *value, path);
+ ALOGV("Read %g from %s\n", *value, path);
return 0;
}
return storagebits / 8;
}
+int64_t load_timestamp_monotonic(struct timespec *ts)
+{
+ clock_gettime(CLOCK_MONOTONIC, ts);
-int64_t get_timestamp(void)
+ return (1000000000LL * ts->tv_sec + ts->tv_nsec);
+}
+
+int64_t load_timestamp_sys_clock(void)
{
- struct timespec ts = {0};
+ static int s_fd = -1;
+ int fd, result = 0;
+ struct timespec ts;
+
+ if (s_fd == -1) {
+ fd = open("/dev/alarm", O_RDONLY);
+ if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
+ close(fd);
+ }
+ }
+
+ result = ioctl(s_fd,
+ ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (result != 0) {
+ /** /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME */
+ result = clock_gettime(CLOCK_BOOTTIME, &ts);
+ }
return 1000000000LL * ts.tv_sec + ts.tv_nsec;
}
+
+int64_t get_timestamp_monotonic(void)
+{
+ struct timespec ts = {0};
+
+ return load_timestamp_monotonic(&ts);
+}
+
+int64_t get_timestamp(void)
+{
+ return (get_timestamp_monotonic() + ts_delta);
+}
+
+void set_timestamp(struct timespec *out, int64_t target_ns)
+{
+ out->tv_sec = target_ns / 1000000000LL;
+ out->tv_nsec = target_ns % 1000000000LL;
+}
+