2007-10-19 Marek Habersack <mhabersack@novell.com>
[mono.git] / eglib / src / gtimer.c
1 /*
2  * Timer
3  *
4  * Author:
5  *   Gonzalo Paniagua Javier (gonzalo@novell.com
6  *
7  * (C) 2006 Novell, Inc.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  */
28 #include <glib.h>
29 #ifdef _MSC_VER
30 #include <windows.h>
31 #else
32 #include <sys/time.h>
33 #endif
34
35 struct _GTimer {
36 #ifdef _MSC_VER
37         guint64 start;
38         guint64 stop;
39 #else
40         struct timeval start;
41         struct timeval stop;
42 #endif
43 };
44
45 GTimer *g_timer_new (void)
46 {
47         GTimer *timer;
48
49         timer = g_new0 (GTimer, 1);
50         g_timer_start (timer);
51         return timer;
52 }
53
54 void
55 g_timer_destroy (GTimer *timer)
56 {
57         g_return_if_fail (timer != NULL);
58         g_free (timer);
59 }
60
61 void
62 g_timer_start (GTimer *timer)
63 {
64         g_return_if_fail (timer != NULL);
65 #ifdef _MSC_VER
66         QueryPerformanceCounter ((LARGE_INTEGER*)&timer->start);
67 #else
68         gettimeofday (&timer->start, NULL);
69         memset (&timer->stop, 0, sizeof (struct timeval));
70 #endif
71
72 }
73
74 void
75 g_timer_stop (GTimer *timer)
76 {
77         g_return_if_fail (timer != NULL);
78 #ifdef _MSC_VER
79         QueryPerformanceCounter ((LARGE_INTEGER*)&timer->stop);
80 #else
81         gettimeofday (&timer->stop, NULL);
82 #endif
83 }
84
85 gdouble
86 g_timer_elapsed (GTimer *timer, gulong *microseconds)
87 {
88 #ifdef _MSC_VER
89         guint64 stop;
90         guint64 freq;
91         gdouble seconds;
92         if (timer->stop == 0) {
93                 QueryPerformanceCounter ((LARGE_INTEGER*)&stop);
94         }
95         else {
96                 stop = timer->stop;
97         }
98
99         QueryPerformanceFrequency ((LARGE_INTEGER*)&freq);
100         seconds = 1.0 * (stop - timer->start) / freq;
101
102         if (microseconds) {
103                 *microseconds = (gulong)(1000000.0 * (stop - timer->start) / freq);
104         }
105         return seconds;
106 #else
107         struct timeval tv;
108         gulong seconds;
109         long usec;
110         gdouble result;
111
112         g_return_val_if_fail (timer != NULL, 0.0);
113
114         if (timer->stop.tv_sec == 0 && timer->stop.tv_usec == 0) {
115                 gettimeofday (&tv, NULL);
116         } else {
117                 tv = timer->stop;
118         }
119
120         usec = (tv.tv_usec) - (timer->start.tv_usec);
121         seconds = tv.tv_sec - timer->start.tv_sec;
122         if (microseconds) {
123                 if (usec < 0) {
124                         usec += 1000000;
125                         seconds--;
126                 }
127                 *microseconds = usec;
128         }
129         result = seconds * 1000000 + usec;
130         return (result / 1000000);
131 #endif
132 }
133
134