1/* GLIB - Library of useful routines for C programming 2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public 15 * License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20/* 21 * Modified by the GLib Team and others 1997-1999. See the AUTHORS 22 * file for a list of people on the GLib Team. See the ChangeLog 23 * files for a list of changes. These files are distributed with 24 * GLib at ftp://ftp.gtk.org/pub/gtk/. 25 */ 26 27/* 28 * MT safe 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include <config.h> 33#endif 34 35#include "glib.h" 36#ifdef HAVE_UNISTD_H 37#include <unistd.h> 38#endif /* HAVE_UNISTD_H */ 39#ifndef NATIVE_WIN32 40#include <sys/time.h> 41#endif /* NATIVE_WIN32 */ 42 43#ifdef NATIVE_WIN32 44#include <windows.h> 45#endif /* NATIVE_WIN32 */ 46 47typedef struct _GRealTimer GRealTimer; 48 49struct _GRealTimer 50{ 51#ifdef NATIVE_WIN32 52 DWORD start; 53 DWORD end; 54#else /* !NATIVE_WIN32 */ 55 struct timeval start; 56 struct timeval end; 57#endif /* !NATIVE_WIN32 */ 58 59 guint active : 1; 60}; 61 62GTimer* 63g_timer_new (void) 64{ 65 GRealTimer *timer; 66 67 timer = g_new (GRealTimer, 1); 68 timer->active = TRUE; 69 70#ifdef NATIVE_WIN32 71 timer->start = GetTickCount (); 72#else /* !NATIVE_WIN32 */ 73 gettimeofday (&timer->start, NULL); 74#endif /* !NATIVE_WIN32 */ 75 76 return ((GTimer*) timer); 77} 78 79void 80g_timer_destroy (GTimer *timer) 81{ 82 g_return_if_fail (timer != NULL); 83 84 g_free (timer); 85} 86 87void 88g_timer_start (GTimer *timer) 89{ 90 GRealTimer *rtimer; 91 92 g_return_if_fail (timer != NULL); 93 94 rtimer = (GRealTimer*) timer; 95 rtimer->active = TRUE; 96 97#ifdef NATIVE_WIN32 98 rtimer->start = GetTickCount (); 99#else /* !NATIVE_WIN32 */ 100 gettimeofday (&rtimer->start, NULL); 101#endif /* !NATIVE_WIN32 */ 102} 103 104void 105g_timer_stop (GTimer *timer) 106{ 107 GRealTimer *rtimer; 108 109 g_return_if_fail (timer != NULL); 110 111 rtimer = (GRealTimer*) timer; 112 rtimer->active = FALSE; 113 114#ifdef NATIVE_WIN32 115 rtimer->end = GetTickCount (); 116#else /* !NATIVE_WIN32 */ 117 gettimeofday (&rtimer->end, NULL); 118#endif /* !NATIVE_WIN32 */ 119} 120 121void 122g_timer_reset (GTimer *timer) 123{ 124 GRealTimer *rtimer; 125 126 g_return_if_fail (timer != NULL); 127 128 rtimer = (GRealTimer*) timer; 129 130#ifdef NATIVE_WIN32 131 rtimer->start = GetTickCount (); 132#else /* !NATIVE_WIN32 */ 133 gettimeofday (&rtimer->start, NULL); 134#endif /* !NATIVE_WIN32 */ 135} 136 137gdouble 138g_timer_elapsed (GTimer *timer, 139 gulong *microseconds) 140{ 141 GRealTimer *rtimer; 142 gdouble total; 143#ifndef NATIVE_WIN32 144 struct timeval elapsed; 145#endif /* NATIVE_WIN32 */ 146 147 g_return_val_if_fail (timer != NULL, 0); 148 149 rtimer = (GRealTimer*) timer; 150 151#ifdef NATIVE_WIN32 152 if (rtimer->active) 153 rtimer->end = GetTickCount (); 154 155 /* Check for wraparound, which happens every 49.7 days. 156 * No, Win95 machines probably are never running for that long, 157 * but NT machines are. 158 */ 159 if (rtimer->end < rtimer->start) 160 total = (UINT_MAX - (rtimer->start - rtimer->end)) / 1000.0; 161 else 162 total = (rtimer->end - rtimer->start) / 1000.0; 163 164 if (microseconds) 165 { 166 if (rtimer->end < rtimer->start) 167 *microseconds = 168 ((UINT_MAX - (rtimer->start - rtimer->end)) % 1000) * 1000; 169 else 170 *microseconds = 171 ((rtimer->end - rtimer->start) % 1000) * 1000; 172 } 173#else /* !NATIVE_WIN32 */ 174 if (rtimer->active) 175 gettimeofday (&rtimer->end, NULL); 176 177 if (rtimer->start.tv_usec > rtimer->end.tv_usec) 178 { 179 rtimer->end.tv_usec += 1000000; 180 rtimer->end.tv_sec--; 181 } 182 183 elapsed.tv_usec = rtimer->end.tv_usec - rtimer->start.tv_usec; 184 elapsed.tv_sec = rtimer->end.tv_sec - rtimer->start.tv_sec; 185 186 total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6); 187 if (total < 0) 188 { 189 total = 0; 190 191 if (microseconds) 192 *microseconds = 0; 193 } 194 else 195 if (microseconds) 196 *microseconds = elapsed.tv_usec; 197 198#endif /* !NATIVE_WIN32 */ 199 200 return total; 201} 202