/*
 *  Copyright 2008 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/base/timing.h"
#include "webrtc/base/timeutils.h"

#if defined(WEBRTC_POSIX)
#include <errno.h>
#include <math.h>
#include <sys/time.h>
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
#include <mach/mach.h>
#include <mach/clock.h>
#endif
#elif defined(WEBRTC_WIN)
#include <sys/timeb.h>
#include "webrtc/base/win32.h"
#endif

namespace rtc {

Timing::Timing() {
#if defined(WEBRTC_WIN)
  // This may fail, but we handle failure gracefully in the methods
  // that use it (use alternative sleep method).
  //
  // TODO: Make it possible for user to tell if IdleWait will
  // be done at lesser resolution because of this.
  timer_handle_ = CreateWaitableTimer(NULL,     // Security attributes.
                                      FALSE,    // Manual reset?
                                      NULL);    // Timer name.
#endif
}

Timing::~Timing() {
#if defined(WEBRTC_WIN)
  if (timer_handle_ != NULL)
    CloseHandle(timer_handle_);
#endif
}

double Timing::WallTimeNow() {
#if defined(WEBRTC_POSIX)
  struct timeval time;
  gettimeofday(&time, NULL);
  // Convert from second (1.0) and microsecond (1e-6).
  return (static_cast<double>(time.tv_sec) +
          static_cast<double>(time.tv_usec) * 1.0e-6);

#elif defined(WEBRTC_WIN)
  struct _timeb time;
  _ftime(&time);
  // Convert from second (1.0) and milliseconds (1e-3).
  return (static_cast<double>(time.time) +
          static_cast<double>(time.millitm) * 1.0e-3);
#endif
}

double Timing::TimerNow() {
  return (static_cast<double>(TimeNanos()) / kNumNanosecsPerSec);
}

double Timing::BusyWait(double period) {
  double start_time = TimerNow();
  while (TimerNow() - start_time < period) {
  }
  return TimerNow() - start_time;
}

double Timing::IdleWait(double period) {
  double start_time = TimerNow();

#if defined(WEBRTC_POSIX)
  double sec_int, sec_frac = modf(period, &sec_int);
  struct timespec ts;
  ts.tv_sec = static_cast<time_t>(sec_int);
  ts.tv_nsec = static_cast<long>(sec_frac * 1.0e9);  // NOLINT

  // NOTE(liulk): for the NOLINT above, long is the appropriate POSIX
  // type.

  // POSIX nanosleep may be interrupted by signals.
  while (nanosleep(&ts, &ts) == -1 && errno == EINTR) {
  }

#elif defined(WEBRTC_WIN)
  if (timer_handle_ != NULL) {
    LARGE_INTEGER due_time;

    // Negative indicates relative time.  The unit is 100 nanoseconds.
    due_time.QuadPart = -LONGLONG(period * 1.0e7);

    SetWaitableTimer(timer_handle_, &due_time, 0, NULL, NULL, TRUE);
    WaitForSingleObject(timer_handle_, INFINITE);
  } else {
    // Still attempts to sleep with lesser resolution.
    // The unit is in milliseconds.
    Sleep(DWORD(period * 1.0e3));
  }
#endif

  return TimerNow() - start_time;
}

}  // namespace rtc
