Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2008 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/base/timing.h"
     12 #include "webrtc/base/timeutils.h"
     13 
     14 #if defined(WEBRTC_POSIX)
     15 #include <errno.h>
     16 #include <math.h>
     17 #include <sys/time.h>
     18 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
     19 #include <mach/mach.h>
     20 #include <mach/clock.h>
     21 #endif
     22 #elif defined(WEBRTC_WIN)
     23 #include <sys/timeb.h>
     24 #include "webrtc/base/win32.h"
     25 #endif
     26 
     27 namespace rtc {
     28 
     29 Timing::Timing() {
     30 #if defined(WEBRTC_WIN)
     31   // This may fail, but we handle failure gracefully in the methods
     32   // that use it (use alternative sleep method).
     33   //
     34   // TODO: Make it possible for user to tell if IdleWait will
     35   // be done at lesser resolution because of this.
     36   timer_handle_ = CreateWaitableTimer(NULL,     // Security attributes.
     37                                       FALSE,    // Manual reset?
     38                                       NULL);    // Timer name.
     39 #endif
     40 }
     41 
     42 Timing::~Timing() {
     43 #if defined(WEBRTC_WIN)
     44   if (timer_handle_ != NULL)
     45     CloseHandle(timer_handle_);
     46 #endif
     47 }
     48 
     49 // static
     50 double Timing::WallTimeNow() {
     51 #if defined(WEBRTC_POSIX)
     52   struct timeval time;
     53   gettimeofday(&time, NULL);
     54   // Convert from second (1.0) and microsecond (1e-6).
     55   return (static_cast<double>(time.tv_sec) +
     56           static_cast<double>(time.tv_usec) * 1.0e-6);
     57 
     58 #elif defined(WEBRTC_WIN)
     59   struct _timeb time;
     60   _ftime(&time);
     61   // Convert from second (1.0) and milliseconds (1e-3).
     62   return (static_cast<double>(time.time) +
     63           static_cast<double>(time.millitm) * 1.0e-3);
     64 #endif
     65 }
     66 
     67 double Timing::TimerNow() {
     68   return (static_cast<double>(TimeNanos()) / kNumNanosecsPerSec);
     69 }
     70 
     71 double Timing::BusyWait(double period) {
     72   double start_time = TimerNow();
     73   while (TimerNow() - start_time < period) {
     74   }
     75   return TimerNow() - start_time;
     76 }
     77 
     78 double Timing::IdleWait(double period) {
     79   double start_time = TimerNow();
     80 
     81 #if defined(WEBRTC_POSIX)
     82   double sec_int, sec_frac = modf(period, &sec_int);
     83   struct timespec ts;
     84   ts.tv_sec = static_cast<time_t>(sec_int);
     85   ts.tv_nsec = static_cast<long>(sec_frac * 1.0e9);  // NOLINT
     86 
     87   // NOTE(liulk): for the NOLINT above, long is the appropriate POSIX
     88   // type.
     89 
     90   // POSIX nanosleep may be interrupted by signals.
     91   while (nanosleep(&ts, &ts) == -1 && errno == EINTR) {
     92   }
     93 
     94 #elif defined(WEBRTC_WIN)
     95   if (timer_handle_ != NULL) {
     96     LARGE_INTEGER due_time;
     97 
     98     // Negative indicates relative time.  The unit is 100 nanoseconds.
     99     due_time.QuadPart = -LONGLONG(period * 1.0e7);
    100 
    101     SetWaitableTimer(timer_handle_, &due_time, 0, NULL, NULL, TRUE);
    102     WaitForSingleObject(timer_handle_, INFINITE);
    103   } else {
    104     // Still attempts to sleep with lesser resolution.
    105     // The unit is in milliseconds.
    106     Sleep(DWORD(period * 1.0e3));
    107   }
    108 #endif
    109 
    110   return TimerNow() - start_time;
    111 }
    112 
    113 }  // namespace rtc
    114