Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/libartbase/base/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 7 kB image not shown  

Quelle  time_utils.cc

  Sprache: C
 

/*
 * Copyright (C) 2015 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.
 */


#define _POSIX_THREAD_SAFE_FUNCTIONS  // For mingw localtime_r().

#include "time_utils.h"

#include <inttypes.h>
#include <stdio.h>

#include <limits>
#include <sstream>

#include "android-base/stringprintf.h"

#include "logging.h"

#if defined(__APPLE__)
#include <sys/time.h>
#endif

namespace art {

namespace {

#if !defined(__linux__)
int GetTimeOfDay(struct timeval* tv, struct timezone* tz) {
#ifdef _WIN32
  return mingw_gettimeofday(tv, tz);
#else
  return gettimeofday(tv, tz);
#endif
}
#endif

}  // namespace

using android::base::StringPrintf;

std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) {
  if (nano_duration == 0) {
    return "0";
  } else {
    return FormatDuration(nano_duration, GetAppropriateTimeUnit(nano_duration),
                          max_fraction_digits);
  }
}

TimeUnit GetAppropriateTimeUnit(uint64_t nano_duration) {
  const uint64_t one_sec = 1000 * 1000 * 1000;
  const uint64_t one_ms  = 1000 * 1000;
  const uint64_t one_us  = 1000;
  if (nano_duration >= one_sec) {
    return kTimeUnitSecond;
  } else if (nano_duration >= one_ms) {
    return kTimeUnitMillisecond;
  } else if (nano_duration >= one_us) {
    return kTimeUnitMicrosecond;
  } else {
    return kTimeUnitNanosecond;
  }
}

uint64_t GetNsToTimeUnitDivisor(TimeUnit time_unit) {
  const uint64_t one_sec = 1000 * 1000 * 1000;
  const uint64_t one_ms  = 1000 * 1000;
  const uint64_t one_us  = 1000;

  switch (time_unit) {
    case kTimeUnitSecond:
      return one_sec;
    case kTimeUnitMillisecond:
      return one_ms;
    case kTimeUnitMicrosecond:
      return one_us;
    case kTimeUnitNanosecond:
      return 1;
  }
  return 0;
}

std::string FormatDuration(uint64_t nano_duration, TimeUnit time_unit,
                           size_t max_fraction_digits) {
  const char* unit = nullptr;
  uint64_t divisor = GetNsToTimeUnitDivisor(time_unit);
  switch (time_unit) {
    case kTimeUnitSecond:
      unit = "s";
      break;
    case kTimeUnitMillisecond:
      unit = "ms";
      break;
    case kTimeUnitMicrosecond:
      unit = "us";
      break;
    case kTimeUnitNanosecond:
      unit = "ns";
      break;
  }
  const uint64_t whole_part = nano_duration / divisor;
  uint64_t fractional_part = nano_duration % divisor;
  if (fractional_part == 0) {
    return StringPrintf("%" PRIu64 "%s", whole_part, unit);
  } else {
    static constexpr size_t kMaxDigits = 30;
    size_t avail_digits = kMaxDigits;
    char fraction_buffer[kMaxDigits];
    char* ptr = fraction_buffer;
    uint64_t multiplier = 10;
    // This infinite loops if fractional part is 0.
    while (avail_digits > 1 && fractional_part * multiplier < divisor) {
      multiplier *= 10;
      *ptr++ = '0';
      avail_digits--;
    }
    snprintf(ptr, avail_digits, "%" PRIu64, fractional_part);
    fraction_buffer[std::min(kMaxDigits - 1, max_fraction_digits)] = '\0';
    return StringPrintf("%" PRIu64 ".%s%s", whole_part, fraction_buffer, unit);
  }
}

std::string GetIsoDate() {
  tm tmbuf;
  int ns;
  if (__builtin_available(macOS 10.12, *)) {
    timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
    localtime_r(&now.tv_sec, &tmbuf);
    ns = now.tv_nsec;
  } else {
    time_t now = time(nullptr);
    localtime_r(&now, &tmbuf);
    ns = 0;
  }
  char zone[16] = {};
  strftime(zone, sizeof(zone), "%z", &tmbuf);
  return StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%09d%s",
      tmbuf.tm_year + 1900, tmbuf.tm_mon+1, tmbuf.tm_mday,
      tmbuf.tm_hour, tmbuf.tm_min, tmbuf.tm_sec, ns, zone);
}

uint64_t MilliTime() {
#if defined(__linux__)
  timespec now;
  clock_gettime(CLOCK_MONOTONIC, &now);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_nsec / UINT64_C(1000000);
#else
  timeval now;
  GetTimeOfDay(&now, nullptr);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_usec / UINT64_C(1000);
#endif
}

uint64_t MicroTime() {
#if defined(__linux__)
  timespec now;
  clock_gettime(CLOCK_MONOTONIC, &now);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_nsec / UINT64_C(1000);
#else
  timeval now;
  GetTimeOfDay(&now, nullptr);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_usec;
#endif
}

uint64_t NanoTime() {
#if defined(__linux__)
  timespec now;
  clock_gettime(CLOCK_MONOTONIC, &now);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
#else
  timeval now;
  GetTimeOfDay(&now, nullptr);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_usec * UINT64_C(1000);
#endif
}

uint64_t ThreadCpuNanoTime() {
#if defined(__linux__)
  timespec now;
  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now) != 0) {
    // TODO(415170313): For now just log an error. Once we have verified that
    // these don't happen often change this to a CHECK.
    PLOG(ERROR) << "Failed to get thread cpu time";
  }
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
#else
  UNIMPLEMENTED(WARNING);
  return -1;
#endif
}

uint64_t ProcessCpuNanoTime() {
#if defined(__linux__)
  timespec now;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now);
  return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
#else
  // We cannot use clock_gettime() here. Return the process wall clock time
  // (using art::NanoTime, which relies on gettimeofday()) as approximation of
  // the process CPU time instead.
  //
  // Note: clock_gettime() is available from macOS 10.12 (Darwin 16), but we try
  // to keep things simple here.
  return NanoTime();
#endif
}

void NanoSleep(uint64_t ns) {
  timespec tm;
  tm.tv_sec = SaturatedTimeT(ns / MsToNs(1000));
  tm.tv_nsec = ns - static_cast<uint64_t>(tm.tv_sec) * MsToNs(1000);
  nanosleep(&tm, nullptr);
}

void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts) {
  if (absolute) {
#if defined(__linux__)
    clock_gettime(clock, ts);
#else
    UNUSED(clock);
    timeval tv;
    GetTimeOfDay(&tv, nullptr);
    ts->tv_sec = tv.tv_sec;
    ts->tv_nsec = tv.tv_usec * 1000;
#endif
  } else {
    ts->tv_sec = 0;
    ts->tv_nsec = 0;
  }

  int64_t end_sec = ts->tv_sec + ms / 1000;
  constexpr int32_t int32_max = std::numeric_limits<int32_t>::max();
  if (UNLIKELY(end_sec >= int32_max)) {
    // Either ms was intended to denote an infinite timeout, or we have a
    // problem. The former generally uses the largest possible millisecond
    // or nanosecond value.  Log only in the latter case.
    constexpr int64_t int64_max = std::numeric_limits<int64_t>::max();
    if (ms != int64_max && ms != int64_max / (1000 * 1000)) {
      LOG(INFO) << "Note: end time exceeds INT32_MAX: " << end_sec;
    }
    end_sec = int32_max - 1;  // Allow for increment below.
  }
  ts->tv_sec = end_sec;
  ts->tv_nsec = (ts->tv_nsec + (ms % 1000) * 1000000) + ns;

  // Catch rollover.
  if (ts->tv_nsec >= 1000000000L) {
    ts->tv_sec++;
    ts->tv_nsec -= 1000000000L;
  }
}

}  // namespace art

Messung V0.5 in Prozent
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.