d26ab69de33649a47804e9967cd0fdc61a0cd176
[yaz-moved-to-github.git] / src / timing.c
1 /*
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: timing.c,v 1.6 2007-06-06 16:32:34 adam Exp $
6  */
7
8 /**
9  * \file timing.c
10  * \brief Timing Utilities
11  */
12
13 #if HAVE_CONFIG_H
14 #include <config.h>
15 #endif
16
17 #ifdef WIN32
18 #include <windows.h>
19 #endif
20 #include <stdlib.h>
21
22 #if HAVE_SYS_TIMES_H
23 #include <sys/times.h>
24 #endif
25 #if HAVE_SYS_TIME_H
26 #include <sys/time.h>
27 #endif
28 #include <time.h>
29
30 #include <yaz/xmalloc.h>
31 #include <yaz/timing.h>
32
33 struct yaz_timing {
34 #if HAVE_SYS_TIMES_H
35     struct tms tms1, tms2;
36 #endif
37 #if HAVE_SYS_TIME_H
38     struct timeval start_time, end_time;
39 #endif
40 #ifdef WIN32
41     LONGLONG start_time, end_time;
42     LONGLONG start_time_sys, start_time_user;
43     LONGLONG end_time_sys, end_time_user;
44 #endif
45     double real_sec, user_sec, sys_sec;
46 };
47
48 yaz_timing_t yaz_timing_create(void)
49 {
50     yaz_timing_t t = (yaz_timing_t) xmalloc(sizeof(*t));
51     yaz_timing_start(t);
52     return t;
53 }
54
55 #ifdef WIN32
56 static void get_process_time(ULONGLONG *lp_user, ULONGLONG *lp_sys)
57 {
58     FILETIME create_t, exit_t, sys_t, user_t;
59     ULARGE_INTEGER li;
60
61     GetProcessTimes(GetCurrentProcess(), &create_t, &exit_t, &sys_t, &user_t);
62     li.LowPart = user_t.dwLowDateTime;
63     li.HighPart = user_t.dwHighDateTime;
64     *lp_user = li.QuadPart;
65
66     li.LowPart = sys_t.dwLowDateTime;
67     li.HighPart = sys_t.dwHighDateTime;
68     *lp_sys = li.QuadPart;
69 }
70 static void get_date_as_largeinteger(LONGLONG *lp)
71 {
72     FILETIME f;
73     ULARGE_INTEGER li;
74     GetSystemTimeAsFileTime(&f);
75     li.LowPart = f.dwLowDateTime;
76     li.HighPart = f.dwHighDateTime;
77
78     *lp = li.QuadPart;
79 }
80 #endif
81
82 void yaz_timing_start(yaz_timing_t t)
83 {
84 #if HAVE_SYS_TIMES_H
85     times(&t->tms1);
86     t->user_sec = 0.0;
87     t->sys_sec = 0.0;
88 #else
89     t->user_sec = -1.0;
90     t->sys_sec = -1.0;
91 #endif
92     t->real_sec = -1.0;
93 #if HAVE_SYS_TIME_H
94     gettimeofday(&t->start_time, 0);
95     t->real_sec = 0.0;
96 #endif
97 #ifdef WIN32
98     t->real_sec = 0.0;
99     t->user_sec = 0.0;
100     t->sys_sec = 0.0;
101     get_date_as_largeinteger(&t->start_time);
102     get_process_time(&t->start_time_user, &t->start_time_sys);
103 #endif
104 }
105
106 void yaz_timing_stop(yaz_timing_t t)
107 {
108 #if HAVE_SYS_TIMES_H
109     times(&t->tms2);
110     
111     t->user_sec = (double) (t->tms2.tms_utime - t->tms1.tms_utime)/100;
112     t->sys_sec = (double) (t->tms2.tms_stime - t->tms1.tms_stime)/100;
113 #endif
114 #if HAVE_SYS_TIME_H
115     gettimeofday(&t->end_time, 0);
116     t->real_sec = ((t->end_time.tv_sec - t->start_time.tv_sec) * 1000000.0 +
117                    t->end_time.tv_usec - t->start_time.tv_usec) / 1000000;
118     
119 #endif
120 #ifdef WIN32
121     get_date_as_largeinteger(&t->end_time);
122     t->real_sec = (t->end_time - t->start_time) / 10000000.0;
123
124     get_process_time(&t->end_time_user, &t->end_time_sys);
125     t->user_sec = (t->end_time_user - t->start_time_user) / 10000000.0;
126     t->sys_sec = (t->end_time_sys - t->start_time_sys) / 10000000.0;
127 #endif
128 }
129
130 double yaz_timing_get_real(yaz_timing_t t)
131 {
132     return t->real_sec;
133 }
134
135 double yaz_timing_get_user(yaz_timing_t t)
136 {
137     return t->user_sec;
138 }
139
140 double yaz_timing_get_sys(yaz_timing_t t)
141 {
142     return t->sys_sec;
143 }
144
145 void yaz_timing_destroy(yaz_timing_t *tp)
146 {
147     if (*tp)
148     {
149         xfree(*tp);
150         *tp = 0;
151     }
152 }
153
154 /*
155  * Local variables:
156  * c-basic-offset: 4
157  * indent-tabs-mode: nil
158  * End:
159  * vim: shiftwidth=4 tabstop=8 expandtab
160  */
161