allwinner_a64/android/system/chre/platform/slpi/system_time.cc
2018-08-08 17:48:24 +08:00

104 lines
2.9 KiB
C++

/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "chre/platform/system_time.h"
#include "chre/platform/slpi/system_time.h"
#include "chre/platform/fatal_error.h"
#include "chre/platform/host_link.h"
#include "chre/platform/log.h"
#include "chre/platform/system_timer.h"
extern "C" {
#include "uTimetick.h"
} // extern "C"
namespace chre {
namespace {
int64_t gEstimatedHostTimeOffset = 0;
// A timer for scheduling a time sync request.
SystemTimer gTimeSyncRequestTimer;
bool gTimeSyncRequestTimerInitialized = false;
Nanoseconds gLastTimeSyncRequestNanos(0);
void setTimeSyncRequestTimer(Nanoseconds delay) {
// Check for timer init since this method might be called before CHRE
// init is called.
if (!gTimeSyncRequestTimerInitialized) {
if (!gTimeSyncRequestTimer.init()) {
FATAL_ERROR("Failed to initialize time sync request timer.");
} else {
gTimeSyncRequestTimerInitialized = true;
}
}
if (gTimeSyncRequestTimer.isActive()) {
gTimeSyncRequestTimer.cancel();
}
auto callback = [](void* /* data */) {
sendTimeSyncRequest();
};
if (!gTimeSyncRequestTimer.set(callback, nullptr, delay)) {
LOGE("Failed to set time sync request timer.");
}
}
} // anonymous namespace
Nanoseconds SystemTime::getMonotonicTime() {
constexpr uint64_t kClockFreq = 19200000; // 19.2MHz QTimer clock
uint64_t ticks = uTimetick_Get();
uint64_t nsec = 0;
if (ticks >= kClockFreq) {
uint64_t seconds = (ticks / kClockFreq);
ticks %= kClockFreq;
nsec = (seconds * kOneSecondInNanoseconds);
}
nsec += (ticks * kOneSecondInNanoseconds) / kClockFreq;
return Nanoseconds(nsec);
}
int64_t SystemTime::getEstimatedHostTimeOffset() {
return gEstimatedHostTimeOffset;
}
void setEstimatedHostTimeOffset(int64_t offset) {
gEstimatedHostTimeOffset = offset;
// Schedule a time sync request since offset may drift
constexpr Seconds kTimeSyncLongInterval = Seconds(60 * 60 * 6); // 6 hours
setTimeSyncRequestTimer(kTimeSyncLongInterval);
}
void requestTimeSyncIfStale() {
constexpr Seconds kTimeSyncShortInterval = Seconds(60 * 60 * 1); // 1 hour
if (SystemTime::getMonotonicTime() >
gLastTimeSyncRequestNanos + kTimeSyncShortInterval) {
sendTimeSyncRequest();
}
}
void updateLastTimeSyncRequest() {
gLastTimeSyncRequestNanos = SystemTime::getMonotonicTime();
}
} // namespace chre