1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "time_utils.h" 6 7 #include <sys/time.h> 8 #include <sys/timerfd.h> 9 #include <time.h> 10 #include <unistd.h> 11 12 #include "logging.h" 13 14 namespace time_utils { 15 GetTimestamp()16uint64_t GetTimestamp() { 17 struct timespec ts = {}; 18 CHECK(clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0); 19 return ts.tv_sec * 1000 + ts.tv_nsec / 1000000ul; 20 } 21 PeriodicTimer(int interval_ms)22PeriodicTimer::PeriodicTimer(int interval_ms) : interval_ms_(interval_ms) { 23 timer_fd_ = -1; 24 } 25 ~PeriodicTimer()26PeriodicTimer::~PeriodicTimer() { 27 Stop(); 28 } 29 Start()30void PeriodicTimer::Start() { 31 Stop(); 32 timer_fd_ = timerfd_create(CLOCK_MONOTONIC, 0); 33 CHECK(timer_fd_ >= 0); 34 int sec = interval_ms_ / 1000; 35 int nsec = (interval_ms_ % 1000) * 1000000; 36 struct itimerspec ts = {}; 37 ts.it_value.tv_nsec = nsec; 38 ts.it_value.tv_sec = sec; 39 ts.it_interval.tv_nsec = nsec; 40 ts.it_interval.tv_sec = sec; 41 CHECK(timerfd_settime(timer_fd_, 0, &ts, nullptr) == 0); 42 } 43 Stop()44void PeriodicTimer::Stop() { 45 if (timer_fd_ < 0) 46 return; 47 close(timer_fd_); 48 timer_fd_ = -1; 49 } 50 Wait()51bool PeriodicTimer::Wait() { 52 if (timer_fd_ < 0) 53 return false; // Not started yet. 54 uint64_t stub = 0; 55 int res = read(timer_fd_, &stub, sizeof(stub)); 56 if (res < 0 && errno == EBADF) 57 return false; // Interrupted by Stop(). 58 CHECK(res > 0); 59 return true; 60 } 61 62 } // namespace time_utils 63