Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2004--2005, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifdef POSIX
     29 #include <sys/time.h>
     30 #endif
     31 
     32 #ifdef WIN32
     33 #define WIN32_LEAN_AND_MEAN
     34 #include <windows.h>
     35 #endif
     36 
     37 #include "talk/base/common.h"
     38 #include "talk/base/time.h"
     39 
     40 #define EFFICIENT_IMPLEMENTATION 1
     41 
     42 namespace talk_base {
     43 
     44 const uint32 LAST = 0xFFFFFFFF;
     45 const uint32 HALF = 0x80000000;
     46 
     47 #ifdef POSIX
     48 uint32 Time() {
     49   struct timeval tv;
     50   gettimeofday(&tv, 0);
     51   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
     52 }
     53 #endif
     54 
     55 #ifdef WIN32
     56 uint32 Time() {
     57   return GetTickCount();
     58 }
     59 #endif
     60 
     61 uint32 StartTime() {
     62   // Close to program execution time
     63   static const uint32 g_start = Time();
     64   return g_start;
     65 }
     66 
     67 // Make sure someone calls it so that it gets initialized
     68 static uint32 ignore = StartTime();
     69 
     70 uint32 TimeAfter(int32 elapsed) {
     71   ASSERT(elapsed >= 0);
     72   ASSERT(static_cast<uint32>(elapsed) < HALF);
     73   return Time() + elapsed;
     74 }
     75 
     76 bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later) {
     77   if (earlier <= later) {
     78     return ((earlier <= middle) && (middle <= later));
     79   } else {
     80     return !((later < middle) && (middle < earlier));
     81   }
     82 }
     83 
     84 bool TimeIsLaterOrEqual(uint32 earlier, uint32 later) {
     85 #if EFFICIENT_IMPLEMENTATION
     86   int32 diff = later - earlier;
     87   return (diff >= 0 && static_cast<uint32>(diff) < HALF);
     88 #else
     89   const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF);
     90   return later_or_equal;
     91 #endif
     92 }
     93 
     94 bool TimeIsLater(uint32 earlier, uint32 later) {
     95 #if EFFICIENT_IMPLEMENTATION
     96   int32 diff = later - earlier;
     97   return (diff > 0 && static_cast<uint32>(diff) < HALF);
     98 #else
     99   const bool earlier_or_equal = TimeIsBetween(later, earlier, later + HALF);
    100   return !earlier_or_equal;
    101 #endif
    102 }
    103 
    104 int32 TimeDiff(uint32 later, uint32 earlier) {
    105 #if EFFICIENT_IMPLEMENTATION
    106   return later - earlier;
    107 #else
    108   const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF);
    109   if (later_or_equal) {
    110     if (earlier <= later) {
    111       return static_cast<long>(later - earlier);
    112     } else {
    113       return static_cast<long>(later + (LAST - earlier) + 1);
    114     }
    115   } else {
    116     if (later <= earlier) {
    117       return -static_cast<long>(earlier - later);
    118     } else {
    119       return -static_cast<long>(earlier + (LAST - later) + 1);
    120     }
    121   }
    122 #endif
    123 }
    124 
    125 } // namespace talk_base
    126