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