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