chromium/components/cross_device/nearby/system_clock.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/nearby/src/internal/platform/implementation/system_clock.h"

#include "base/check_op.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/time/time.h"

#if BUILDFLAG(IS_MAC)
#include <mach/mach_time.h>
#include <time.h>
#elif BUILDFLAG(IS_POSIX)
#include <time.h>
#else
#include "base/system/sys_info.h"
#endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_POSIX)

namespace nearby {

void SystemClock::Init() {}

absl::Time SystemClock::ElapsedRealtime() {
#if BUILDFLAG(IS_MAC)
  return absl::FromUnixMicros(
      base::TimeDelta::FromMachTime(mach_continuous_time()).InMicroseconds());
#elif BUILDFLAG(IS_POSIX)
  // SystemClock::ElapsedRealtime() must provide monotonically increasing time,
  // but is not expected to be convertible to wall clock time. Unfortunately,
  // the POSIX implementation of base::SysInfo::Uptime(), i.e. TimeTicks::Now(),
  // does not increase when system is suspended. We instead use clock_gettime
  // directly. See https://crbug.com/166153.
  struct timespec ts = {};
  const int ret = clock_gettime(CLOCK_BOOTTIME, &ts);
  DCHECK_EQ(ret, 0);
  return absl::TimeFromTimespec(ts);
#else
  return absl::FromUnixMicros(base::SysInfo::Uptime().InMicroseconds());
#endif  // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_POSIX)
}

Exception SystemClock::Sleep(absl::Duration duration) {
  base::PlatformThread::Sleep(
      base::Microseconds(absl::ToInt64Microseconds(duration)));
  return {Exception::kSuccess};
}

}  // namespace nearby