You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.9 KiB
104 lines
2.9 KiB
/* |
|
* 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
|
|
|