1cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
2cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
4cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * you may not use this file except in compliance with the License.
6cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * You may obtain a copy of the License at
7cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
8cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
10cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * See the License for the specific language governing permissions and
14cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * limitations under the License.
15cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
16cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
17cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
18cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
19cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * System clock functions.
20cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
21cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
22dafff0bcc10fe1ff80e68a31793bbdea2ec8d0c3Kenny Root#ifdef HAVE_ANDROID_OS
23cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <linux/ioctl.h>
24cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <linux/rtc.h>
25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Atomic.h>
26cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <linux/android_alarm.h>
27cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
29cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <sys/time.h>
30cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <limits.h>
31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <fcntl.h>
32cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <errno.h>
33cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <string.h>
34cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
35cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/SystemClock.h>
36cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Timers.h>
37cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
38cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define LOG_TAG "SystemClock"
399eb2a3b1c0cc1ff3082a9283e24c8babc112f56bMathias Agopian#include <utils/Log.h>
40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
41cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android {
42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
43cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * native public static long uptimeMillis();
45cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
46cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint64_t uptimeMillis()
47cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
49cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return (int64_t) nanoseconds_to_milliseconds(when);
50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
51cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * native public static long elapsedRealtime();
54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint64_t elapsedRealtime()
56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
57af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly	return nanoseconds_to_milliseconds(elapsedRealtimeNano());
58af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly}
59af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly
60ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#define METHOD_CLOCK_GETTIME    0
61ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#define METHOD_IOCTL            1
62ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#define METHOD_SYSTEMTIME       2
63ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
645cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng/*
655cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng * To debug/verify the timestamps returned by the kernel, change
665cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng * DEBUG_TIMESTAMP to 1 and call the timestamp routine from a single thread
675cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng * in the test program. b/10899829
685cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng */
695cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#define DEBUG_TIMESTAMP         0
705cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng
71ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Chengstatic const char *gettime_method_names[] = {
72ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    "clock_gettime",
73ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    "ioctl",
74ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    "systemTime",
75ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng};
76ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
775cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#if DEBUG_TIMESTAMP
78ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Chengstatic inline void checkTimeStamps(int64_t timestamp,
79ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                                   int64_t volatile *prevTimestampPtr,
80ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                                   int volatile *prevMethodPtr,
81ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                                   int curMethod)
82ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng{
83ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    /*
84ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     * Disable the check for SDK since the prebuilt toolchain doesn't contain
85ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     * gettid, and int64_t is different on the ARM platform
86ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     * (ie long vs long long).
87ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     */
88ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#ifdef ARCH_ARM
89ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    int64_t prevTimestamp = *prevTimestampPtr;
90ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    int prevMethod = *prevMethodPtr;
91ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
92ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    if (timestamp < prevTimestamp) {
93ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d",
94ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng              prevTimestamp, gettime_method_names[prevMethod],
95ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng              timestamp, gettime_method_names[curMethod],
96ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng              gettid());
97ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    }
98ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    // NOTE - not atomic and may generate spurious warnings if the 64-bit
99ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    // write is interrupted or not observed as a whole.
100ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    *prevTimestampPtr = timestamp;
101ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    *prevMethodPtr = curMethod;
102ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#endif
103ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng}
1045cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#else
1055cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#define checkTimeStamps(timestamp, prevTimestampPtr, prevMethodPtr, curMethod)
1065cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#endif
107ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
108af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly/*
109af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly * native public static long elapsedRealtimeNano();
110af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly */
111af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pellyint64_t elapsedRealtimeNano()
112af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly{
113dafff0bcc10fe1ff80e68a31793bbdea2ec8d0c3Kenny Root#ifdef HAVE_ANDROID_OS
114af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    struct timespec ts;
115f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng    int result;
116ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    int64_t timestamp;
1175cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#if DEBUG_TIMESTAMP
118ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    static volatile int64_t prevTimestamp;
119ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    static volatile int prevMethod;
1205cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#endif
121ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
122f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng#if 0
123f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng    /*
124f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng     * b/7100774
125f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng     * clock_gettime appears to have clock skews and can sometimes return
126f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng     * backwards values. Disable its use until we find out what's wrong.
127f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng     */
128f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng    result = clock_gettime(CLOCK_BOOTTIME, &ts);
129af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    if (result == 0) {
130ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
131ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
132ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                        METHOD_CLOCK_GETTIME);
133ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        return timestamp;
134af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    }
135f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng#endif
136af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly
137af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm
138cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    static int s_fd = -1;
139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
140cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (s_fd == -1) {
141cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        int fd = open("/dev/alarm", O_RDONLY);
142cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
143cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            close(fd);
144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
145cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
146cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
147ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    result = ioctl(s_fd,
148ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
149ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
150cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (result == 0) {
151ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
152ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);
153ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        return timestamp;
154cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
155af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly
156af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // XXX: there was an error, probably because the driver didn't
157af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // exist ... this should return
158af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // a real error, like an exception!
159ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
160ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
161ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                    METHOD_SYSTEMTIME);
162ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    return timestamp;
163cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#else
164af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    return systemTime(SYSTEM_TIME_MONOTONIC);
165cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
166cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
167cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
168cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android
169