u_time.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00036 #include "pipe/p_config.h"
00037 
00038 #if defined(PIPE_OS_LINUX)
00039 #include <sys/time.h>
00040 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
00041 #include <windows.h>
00042 #include <winddi.h>
00043 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
00044 #include <windows.h>
00045 extern VOID KeQuerySystemTime(PLARGE_INTEGER);
00046 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00047 #include <windows.h>
00048 #else
00049 #error Unsupported OS
00050 #endif
00051 
00052 #include "util/u_time.h"
00053 
00054 
00055 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00056 
00057 static int64_t frequency = 0;
00058 
00059 static INLINE void 
00060 util_time_get_frequency(void)
00061 {
00062    if(!frequency) {
00063 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
00064       LONGLONG temp;
00065       EngQueryPerformanceFrequency(&temp);
00066       frequency = temp;
00067 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00068       LARGE_INTEGER temp;
00069       QueryPerformanceFrequency(&temp);
00070       frequency = temp.QuadPart;
00071 #endif
00072    }
00073 }
00074 #endif
00075 
00076 
00077 void 
00078 util_time_get(struct util_time *t)
00079 {
00080 #if defined(PIPE_OS_LINUX)
00081    gettimeofday(&t->tv, NULL);
00082 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
00083    LONGLONG temp;
00084    EngQueryPerformanceCounter(&temp);
00085    t->counter = temp;
00086 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
00087    /* Updated every 10 miliseconds, measured in units of 100 nanoseconds.
00088     * http://msdn.microsoft.com/en-us/library/ms801642.aspx */
00089    LARGE_INTEGER temp;
00090    KeQuerySystemTime(&temp);
00091    t->counter = temp.QuadPart;
00092 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00093    LARGE_INTEGER temp;
00094    QueryPerformanceCounter(&temp);
00095    t->counter = temp.QuadPart;
00096 #endif
00097 }
00098 
00099 
00100 void 
00101 util_time_add(const struct util_time *t1,
00102               int64_t usecs,
00103               struct util_time *t2)
00104 {
00105 #if defined(PIPE_OS_LINUX)
00106    t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000;
00107    t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000;
00108 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00109    util_time_get_frequency();
00110    t2->counter = t1->counter + (usecs * frequency + INT64_C(999999))/INT64_C(1000000);
00111 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
00112    /* 1 tick = 100 nano seconds. */
00113    t2->counter = t1->counter + usecs * 10;
00114 #else
00115    LARGE_INTEGER temp;
00116    LONGLONG freq;
00117    freq = temp.QuadPart;
00118    t2->counter = t1->counter + (usecs * freq)/1000000L;
00119 #endif
00120 }
00121 
00122 
00123 int64_t
00124 util_time_diff(const struct util_time *t1, 
00125                const struct util_time *t2)
00126 {
00127 #if defined(PIPE_OS_LINUX)
00128    return (t2->tv.tv_usec - t1->tv.tv_usec) + 
00129           (t2->tv.tv_sec - t1->tv.tv_sec)*1000000;
00130 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00131    util_time_get_frequency();
00132    return (t2->counter - t1->counter)*INT64_C(1000000)/frequency;
00133 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
00134    return (t2->counter - t1->counter)/10;
00135 #endif
00136 }
00137 
00138 
00139 
00140 uint64_t
00141 util_time_micros( void )
00142 {
00143    struct util_time t1;
00144    
00145    util_time_get(&t1);
00146    
00147 #if defined(PIPE_OS_LINUX)
00148    return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL;
00149 #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00150    util_time_get_frequency();
00151    return t1.counter*INT64_C(1000000)/frequency;
00152 #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
00153    return t1.counter/10;
00154 #endif
00155 }
00156 
00157 
00158 
00165 static INLINE int
00166 util_time_compare(const struct util_time *t1, 
00167                   const struct util_time *t2)
00168 {
00169 #if defined(PIPE_OS_LINUX)
00170    if (t1->tv.tv_sec < t2->tv.tv_sec)
00171       return -1;
00172    else if(t1->tv.tv_sec > t2->tv.tv_sec)
00173       return 1;
00174    else if (t1->tv.tv_usec < t2->tv.tv_usec)
00175       return -1;
00176    else if(t1->tv.tv_usec > t2->tv.tv_usec)
00177       return 1;
00178    else 
00179       return 0;
00180 #elif defined(PIPE_OS_WINDOWS)
00181    if (t1->counter < t2->counter)
00182       return -1;
00183    else if(t1->counter > t2->counter)
00184       return 1;
00185    else 
00186       return 0;
00187 #endif
00188 }
00189 
00190 
00191 boolean 
00192 util_time_timeout(const struct util_time *start, 
00193                   const struct util_time *end,
00194                   const struct util_time *curr) 
00195 {
00196    if(util_time_compare(start, end) <= 0)
00197       return !(util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0);
00198    else
00199       return !(util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0);
00200 }
00201 
00202 
00203 #if defined(PIPE_SUBSYSYEM_WINDOWS_DISPLAY)
00204 void util_time_sleep(unsigned usecs)
00205 {
00206    LONGLONG start, curr, end;
00207    
00208    EngQueryPerformanceCounter(&start);
00209    
00210    if(!frequency)
00211       EngQueryPerformanceFrequency(&frequency);
00212    
00213    end = start + (usecs * frequency + 999999LL)/1000000LL;
00214    
00215    do {
00216       EngQueryPerformanceCounter(&curr);
00217    } while(start <= curr && curr < end || 
00218            end < start && (curr < end || start <= curr));
00219 }
00220 #endif

Generated on Tue Sep 29 06:25:15 2009 for Gallium3D by  doxygen 1.5.4