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
229b828adfad09200f3f1bd3602187fe3dd5335774Elliott Hughes#if defined(__ANDROID__)
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 <string.h>
33cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
34cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/SystemClock.h>
35cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Timers.h>
36cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
37cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define LOG_TAG "SystemClock"
389eb2a3b1c0cc1ff3082a9283e24c8babc112f56bMathias Agopian#include <utils/Log.h>
39cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android {
41cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
43cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * native public static long uptimeMillis();
44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
45cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint64_t uptimeMillis()
46cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
47cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return (int64_t) nanoseconds_to_milliseconds(when);
49cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
51cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * native public static long elapsedRealtime();
53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint64_t elapsedRealtime()
55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
56af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly	return nanoseconds_to_milliseconds(elapsedRealtimeNano());
57af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly}
58af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly
59ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#define METHOD_CLOCK_GETTIME    0
60ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#define METHOD_IOCTL            1
61ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng#define METHOD_SYSTEMTIME       2
62ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
635cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng/*
645cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng * To debug/verify the timestamps returned by the kernel, change
655cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng * DEBUG_TIMESTAMP to 1 and call the timestamp routine from a single thread
665cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng * in the test program. b/10899829
675cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng */
685cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#define DEBUG_TIMESTAMP         0
695cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng
7022a40e6a7a8e313cea310503fb42c4b66f535843Elliott Hughes#if DEBUG_TIMESTAMP && defined(__arm__)
71ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Chengstatic inline void checkTimeStamps(int64_t timestamp,
72ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                                   int64_t volatile *prevTimestampPtr,
73ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                                   int volatile *prevMethodPtr,
74ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                                   int curMethod)
75ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng{
76ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    /*
77ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     * Disable the check for SDK since the prebuilt toolchain doesn't contain
78ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     * gettid, and int64_t is different on the ARM platform
79ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     * (ie long vs long long).
80ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng     */
81ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    int64_t prevTimestamp = *prevTimestampPtr;
82ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    int prevMethod = *prevMethodPtr;
83ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
84ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    if (timestamp < prevTimestamp) {
855bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn        static const char *gettime_method_names[] = {
865bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn            "clock_gettime",
875bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn            "ioctl",
885bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn            "systemTime",
895bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn        };
905bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn
91ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d",
92ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng              prevTimestamp, gettime_method_names[prevMethod],
93ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng              timestamp, gettime_method_names[curMethod],
94ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng              gettid());
95ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    }
96ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    // NOTE - not atomic and may generate spurious warnings if the 64-bit
97ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    // write is interrupted or not observed as a whole.
98ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    *prevTimestampPtr = timestamp;
99ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    *prevMethodPtr = curMethod;
100ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng}
1015cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#else
1025cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#define checkTimeStamps(timestamp, prevTimestampPtr, prevMethodPtr, curMethod)
1035cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#endif
104ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
105af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly/*
106af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly * native public static long elapsedRealtimeNano();
107af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly */
108af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pellyint64_t elapsedRealtimeNano()
109af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly{
1109b828adfad09200f3f1bd3602187fe3dd5335774Elliott Hughes#if defined(__ANDROID__)
111af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    struct timespec ts;
112f4722b5910eb4e1394763da636b72a8431baea5bBen Cheng    int result;
113ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    int64_t timestamp;
1145cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#if DEBUG_TIMESTAMP
115ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    static volatile int64_t prevTimestamp;
116ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    static volatile int prevMethod;
1175cd118178e87c4a6590dc8d8446effa5d5193a9fBen Cheng#endif
118ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
119cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    static int s_fd = -1;
120cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
121cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (s_fd == -1) {
122cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        int fd = open("/dev/alarm", O_RDONLY);
123cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
124cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            close(fd);
125cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
126cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
127cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
128ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    result = ioctl(s_fd,
129ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
130ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng
131cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (result == 0) {
132ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
133ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);
134ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng        return timestamp;
135cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
136af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly
13764289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann    // /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME
13864289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann    result = clock_gettime(CLOCK_BOOTTIME, &ts);
13964289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann    if (result == 0) {
14064289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann        timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
14164289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann        checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
14264289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann                        METHOD_CLOCK_GETTIME);
14364289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann        return timestamp;
14464289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann    }
14564289760a2df9409d8f4fa5becb4a49f0acb20a5Greg Hackmann
146af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // XXX: there was an error, probably because the driver didn't
147af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // exist ... this should return
148af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    // a real error, like an exception!
149ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
150ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    checkTimeStamps(timestamp, &prevTimestamp, &prevMethod,
151ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng                    METHOD_SYSTEMTIME);
152ad0a959aeec262971c64e68ca1b78f4c69ab9139Ben Cheng    return timestamp;
153cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#else
154af1e7b77217430cc2d423e9f552dcfb4e004539bNick Pelly    return systemTime(SYSTEM_TIME_MONOTONIC);
155cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
156cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
157cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
158cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android
159