brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · cc409cf Raw
141 lines · c
1//===-- DNBTimer.h ----------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  Created by Greg Clayton on 12/13/07.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTIMER_H14#define LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTIMER_H15 16#include "DNBDefs.h"17#include <cstdint>18#include <mutex>19#include <optional>20#include <sys/time.h>21 22class DNBTimer {23public:24  // Constructors and Destructors25  DNBTimer(bool threadSafe) {26    if (threadSafe)27      m_mutex.emplace();28    Reset();29  }30 31  DNBTimer(const DNBTimer &rhs) {32    // Create a new mutex to make this timer thread safe as well if33    // the timer we are copying is thread safe34    if (rhs.IsThreadSafe())35      m_mutex.emplace();36    m_timeval = rhs.m_timeval;37  }38 39  DNBTimer &operator=(const DNBTimer &rhs) {40    // Create a new mutex to make this timer thread safe as well if41    // the timer we are copying is thread safe42    if (rhs.IsThreadSafe())43      m_mutex.emplace();44    m_timeval = rhs.m_timeval;45    return *this;46  }47 48  ~DNBTimer() {}49 50  bool IsThreadSafe() const { return m_mutex.has_value(); }51  // Reset the time value to now52  void Reset() {53    auto lock = m_mutex ? std::unique_lock<std::recursive_mutex>(*m_mutex)54                        : std::unique_lock<std::recursive_mutex>();55    gettimeofday(&m_timeval, NULL);56  }57  // Get the total microseconds since Jan 1, 197058  uint64_t TotalMicroSeconds() const {59    std::unique_lock<std::recursive_mutex> lock =60        m_mutex ? std::unique_lock<std::recursive_mutex>(*m_mutex)61                : std::unique_lock<std::recursive_mutex>();62    return (uint64_t)(m_timeval.tv_sec) * 1000000ull +63           (uint64_t)m_timeval.tv_usec;64  }65 66  void GetTime(uint64_t &sec, uint32_t &usec) const {67    auto lock = m_mutex ? std::unique_lock<std::recursive_mutex>(*m_mutex)68                        : std::unique_lock<std::recursive_mutex>();69    sec = m_timeval.tv_sec;70    usec = m_timeval.tv_usec;71  }72  // Return the number of microseconds elapsed between now and the73  // m_timeval74  uint64_t ElapsedMicroSeconds(bool update) {75    std::unique_lock<std::recursive_mutex> lock =76        m_mutex ? std::unique_lock<std::recursive_mutex>(*m_mutex)77                : std::unique_lock<std::recursive_mutex>();78    struct timeval now;79    gettimeofday(&now, NULL);80    uint64_t now_usec =81        (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;82    uint64_t this_usec =83        (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec;84    uint64_t elapsed = now_usec - this_usec;85    // Update the timer time value if requeseted86    if (update)87      m_timeval = now;88    return elapsed;89  }90 91  static uint64_t GetTimeOfDay() {92    struct timeval now;93    gettimeofday(&now, NULL);94    uint64_t now_usec =95        (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;96    return now_usec;97  }98 99  static void OffsetTimeOfDay(struct timespec *ts,100                              __darwin_time_t sec_offset = 0,101                              long nsec_offset = 0) {102    if (ts == NULL)103      return;104    // Get the current time in a timeval structure105    struct timeval now;106    gettimeofday(&now, NULL);107    // Morph it into a timespec108    TIMEVAL_TO_TIMESPEC(&now, ts);109    // Offset the timespec if requested110    if (sec_offset != 0 || nsec_offset != 0) {111      // Offset the nano seconds112      ts->tv_nsec += nsec_offset;113      // Offset the seconds taking into account a nano-second overflow114      ts->tv_sec = ts->tv_sec + ts->tv_nsec / 1000000000 + sec_offset;115      // Trim the nanoseconds back there was an overflow116      ts->tv_nsec = ts->tv_nsec % 1000000000;117    }118  }119  static bool TimeOfDayLaterThan(struct timespec &ts) {120    struct timespec now;121    OffsetTimeOfDay(&now);122    if (now.tv_sec > ts.tv_sec)123      return true;124    else if (now.tv_sec < ts.tv_sec)125      return false;126    else {127      if (now.tv_nsec > ts.tv_nsec)128        return true;129      else130        return false;131    }132  }133 134protected:135  // Classes that inherit from DNBTimer can see and modify these136  mutable std::optional<std::recursive_mutex> m_mutex;137  struct timeval m_timeval;138};139 140#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBTIMER_H141